Compare commits

...

294 Commits

Author SHA1 Message Date
Carl 4237a26517
added new constructor and tests (#7514) 2025-07-28 19:32:25 -07:00
renovate[bot] 590f11213c
chore(deps): update weekly update (#7515)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 19:26:58 -07:00
Jay DeLuca ff4d32646a
Update okhttp dependency to okhttp-jvm (#7517) 2025-07-28 19:26:15 -07:00
renovate[bot] 17b4065d6c
fix(deps): update dependency io.grpc:grpc-bom to v1.74.0 (#7518)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 13:37:37 -07:00
renovate[bot] b79242d858
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.59.2 (#7509)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-26 22:06:51 -07:00
renovate[bot] dfd35c7a8d
fix(deps): update junit-framework monorepo to v5.13.4 (#7507)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-26 22:06:29 -07:00
renovate[bot] c0855e867a
fix(deps): update spotless packages to v7.2.1 (#7505)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-26 22:05:59 -07:00
renovate[bot] 5764814b8e
fix(deps): update dependency io.opentelemetry.contrib:opentelemetry-aws-xray-propagator to v1.48.0-alpha (#7510)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-26 11:21:35 -07:00
renovate[bot] 42c4091802
fix(deps): update errorproneversion to v2.41.0 (#7512)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jason Plumb <jplumb@splunk.com>
2025-07-26 11:18:31 -07:00
Gregor Zeitlinger dc2874e2fa
fix typo (#7497) 2025-07-20 10:08:40 -07:00
renovate[bot] 352acfb24b
fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.19.2 (#7504)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-18 17:44:36 -07:00
Gregor Zeitlinger 3e5368eba8
update kotlin (#7501)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-18 07:47:15 -07:00
Gregor Zeitlinger 80da2ab3d9
show the wrong file format (#7498) 2025-07-17 18:27:09 -07:00
renovate[bot] 29a7fe8f13
fix(deps): update dependency io.netty:netty-bom to v4.2.3.final (#7490)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 15:16:47 -07:00
renovate[bot] 887778fa0b
fix(deps): update junit-framework monorepo to v5.13.3 (#7494)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 15:15:08 -07:00
renovate[bot] 8e232157d1
chore(deps): update plugin com.gradle.develocity to v4.1 (#7492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 12:23:37 -07:00
renovate[bot] b185cfb94f
fix(deps): update dependency com.gradle.develocity:com.gradle.develocity.gradle.plugin to v4.1 (#7493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 12:23:10 -07:00
renovate[bot] 57580f56e5
fix(deps): update junit-framework monorepo to v5.13.2 (#7462)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jason Plumb <jplumb@splunk.com>
Co-authored-by: John Watson <jkwatson@gmail.com>
2025-07-15 10:38:14 -07:00
Lauri Tulmin 7781706de2
Rename variables (#7486) 2025-07-15 10:37:27 -07:00
renovate[bot] ce1e26f579
fix(deps): update dependency org.snakeyaml:snakeyaml-engine to v2.10 (#7487)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 09:04:30 -07:00
renovate[bot] 80094155e9
chore(deps): update python:3.13.5 docker digest to 28f60ab (#7485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-13 19:12:22 -07:00
renovate[bot] 38207b740e
fix(deps): update prometheusserverversion to v1.3.10 (#7466)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: John Watson <jkwatson@gmail.com>
2025-07-12 18:02:46 -07:00
renovate[bot] c54a301e5e
fix(deps): update errorproneversion to v2.40.0 (#7484)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-12 15:48:41 -07:00
renovate[bot] 804d5f3a07
fix(deps): update errorproneversion to v2.39.0 (#7448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: John Watson <jkwatson@gmail.com>
2025-07-12 12:40:01 -07:00
otelbot[bot] 40f71ed52a
Update apidiff baseline and documentation versions to released version 1.52.0 (#7483)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-07-11 17:11:22 -05:00
otelbot[bot] 95dc35b2dd
Update version to 1.53.0 (#7481)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-07-11 15:40:05 -05:00
jack-berg 6cac14d649
Prepare for 1.52.0 release (#7478) 2025-07-11 13:34:51 -05:00
jack-berg 78a917da2e
Promote ComponentLoader to new opentelemetry-api-util, standardize SPI loading (#7446) 2025-07-10 17:29:25 -05:00
jack-berg 4821c37ec0
Add custom stacktrace renderer which is length limit aware (#7281) 2025-07-10 17:16:20 -05:00
jack-berg cecfb835be
Extend prometheus declarative config support to include without_scope_info, with_resource_constant_labels (#6840) 2025-07-10 17:10:00 -05:00
jack-berg 915c64a365
Add new convenience methods for converting DeclarativeConfigProperties to config model (#7453) 2025-07-10 17:05:24 -05:00
renovate[bot] de491791a4
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.59.1 (#7476)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-10 16:23:27 -05:00
Gregor Zeitlinger 05f67023da
add scope schema URL and attributes to prom attributes (#7356)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
2025-07-10 09:52:12 -05:00
renovate[bot] e949555a70
fix(deps): update dependency com.squareup.wire:wire-bom to v5.3.5 (#7477)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-09 07:56:31 -07:00
jack-berg d9c9583409
Add context and severity params to ExtendedLogger#isEnabled (#7268) 2025-07-08 17:00:08 -05:00
renovate[bot] 15ae8c0f35
fix(deps): update dependency com.squareup.wire:wire-bom to v5.3.4 (#7474)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-08 08:00:30 -07:00
renovate[bot] 518623882b
fix(deps): update spotless packages to v7.1.0 (#7471)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 16:39:58 -07:00
renovate[bot] 7768b2d106
fix(deps): update dependency com.squareup.okhttp3:okhttp-bom to v5.1.0 (#7470)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 16:38:57 -07:00
renovate[bot] e0fdeb3dae
fix(deps): update dependency io.opentelemetry.contrib:opentelemetry-aws-xray-propagator to v1.47.0-alpha (#7464)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-05 09:31:42 -07:00
renovate[bot] ab078e0f35
chore(deps): update dependency gradle to v8.14.3 (#7465)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 20:48:59 -07:00
renovate[bot] 9406936154
fix(deps): update dependency com.squareup.okhttp3:okhttp-bom to v5 (#7463)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-03 15:53:26 -07:00
renovate[bot] 85f662abfe
chore(deps): update weekly update (#7459)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-03 10:10:17 -07:00
renovate[bot] 317c00261b
chore(deps): update plugin com.gradleup.shadow to v8.3.8 (#7461)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 09:17:51 -07:00
renovate[bot] 9db6f62129
fix(deps): update dependency com.squareup.okio:okio-bom to v3.15.0 (#7455)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 09:16:57 -07:00
renovate[bot] 0309b30c44
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.59.0 (#7444)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 10:58:42 -07:00
Trask Stalnaker 43f3f7d059
Standardize contributing section (#7456) 2025-06-30 17:51:30 -05:00
renovate[bot] 360897b98e
fix(deps): update dependency checkstyle to v10.26.1 (#7458)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 10:15:15 -07:00
renovate[bot] 6dd69e96e8
fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.21.3 (#7457)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-28 19:06:15 -07:00
Dominic Lüchinger 50e3d4d949
docs: Update the version in the README.md to algin with the latest release (#7454) 2025-06-28 19:05:27 -07:00
Dominic Lüchinger 2c0ee00508
fix: Resolve environment variable substitution for mixed quotes (#7433) 2025-06-27 10:37:40 -05:00
Teja a7315c63b6
7181: Loading Compressor using ClassLoader configured through setServiceClassLoader (#7428) 2025-06-27 09:20:11 -05:00
OpenTelemetry Bot edd51d45a1
Fix outdated community membership link (#7450)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-06-26 16:08:39 -07:00
renovate[bot] e2e2dbbc26
fix(deps): update dependency net.ltgt.gradle:gradle-errorprone-plugin to v4.3.0 (#7449)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-26 12:17:50 -07:00
Jonathan Halliday b203d2f23e
profile exporters fix and test improvements (#7442) 2025-06-25 15:49:01 -05:00
OpenTelemetry Bot 6e8a466ca4
Update community member listings (#7447)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-06-25 14:12:29 -05:00
renovate[bot] 0ca502bddd
fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.19.1 (#7422)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 16:13:33 -05:00
Paul Nienaber 9329f8675e
fixes #7427: Patch LazyStorage to pass its ClassLoader to ServiceLoader (#7424) 2025-06-24 14:43:46 -05:00
jack-berg 9262a81432
Update to declarative config 1.0-rc.1 (#7436) 2025-06-24 14:42:53 -05:00
Trask Stalnaker 11e424de8d
Slightly faster CodeQL (#7414)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
2025-06-24 14:42:42 -05:00
Tyler Benson aeb08f40a0
Propagate flush to PeriodicMetricReader's metricExporter. (#7410) 2025-06-24 14:42:28 -05:00
Francesco Andreuzzi b0a9deb7d8
Fix race condition of `GlobalOpenTelemetry` initialization with `AutoConfiguredOpenTelemetrySdkBuilder` (#7365)
Co-authored-by: Jack Berg <jberg@newrelic.com>
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
2025-06-24 14:22:10 -05:00
renovate[bot] 76913bb224
fix(deps): update dependency checkstyle to v10.26.0 (#7443)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 11:20:22 -07:00
renovate[bot] 55a1b57644
chore(deps): update plugin com.gradleup.shadow to v8.3.7 (#7439)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 11:17:33 -07:00
renovate[bot] bf65026b71
chore(deps): update weekly update (#7423)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-23 09:14:58 -07:00
renovate[bot] fa31e52722
fix(deps): update dependency checkstyle to v10.25.1 (#7437)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-23 09:12:39 -07:00
jason plumb ada5af60d1
Prevent major version bump in equalsverifier. (#7416) 2025-06-20 14:47:56 -05:00
renovate[bot] 2eb84bf417
fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.21.2 (#7431)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 20:30:40 -07:00
renovate[bot] d90cf44c87
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.58.2 (#7426)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 20:30:17 -07:00
renovate[bot] cc2844d867
fix(deps): update dependency com.squareup.okio:okio-bom to v3.13.0 (#7421)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-13 18:13:46 -07:00
jason plumb 07f01c363f
ContextKey update example code (#7420) 2025-06-13 18:11:43 -07:00
Trask Stalnaker 3f73f12f83
Update sonatype snapshot repo location (#7411) 2025-06-12 18:09:35 -05:00
renovate[bot] fe315a3a23
fix(deps): update dependency org.owasp:dependency-check-gradle to v12.1.3 (#7417)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 07:51:44 -07:00
renovate[bot] f9dc916a80
fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.34.0-alpha (#7413)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 07:51:09 -07:00
renovate[bot] 4a33b66996
fix(deps): update dependency org.owasp:dependency-check-gradle to v12.1.2 (#7409)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 18:33:56 -07:00
jack-berg d5a2fa2bda
Cleanup test resources to quiet logs (#7387) 2025-06-09 16:28:47 -05:00
Felix Barnsteiner 6a164a9a36
fix(httpclient): ensure proper closure of HttpClient in shutdown method (#7390) 2025-06-09 13:34:36 -05:00
Trask Stalnaker 67e3f7baf0
Reduce repo settings we need to doc (#7397) 2025-06-09 13:16:31 -05:00
Trask Stalnaker e35ba16e55
Fix workflow permission (#7408) 2025-06-09 09:38:09 -05:00
Trask Stalnaker 289bebaf15
Fix benchmark workflows (#7406) 2025-06-09 09:37:46 -05:00
Nan Chen 7a4a452603
Update argument name for set(long value) (#7405) 2025-06-06 16:52:42 -05:00
jason plumb 5a25bb6fe1
Update repos for sonatype central (#7407) 2025-06-06 16:50:05 -05:00
jack-berg 07e8d434f3
Fix prepare-release-branch.sh interaction with update-version.sh (#7404) 2025-06-06 14:39:08 -05:00
OpenTelemetry Bot d37f6bd93a
Use more specific self-hosted runner name (#7399)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-06-06 14:38:48 -05:00
otelbot[bot] e25b776840
Update apidiff baseline to released version 1.51.0 (#7403)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-06-06 14:38:35 -05:00
otelbot[bot] c34a25efd5
Update version to 1.52.0-SNAPSHOT (#7401)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-06-06 13:27:30 -05:00
jack-berg d034464ffd
Prepare for 1.51.0 release (#7396) 2025-06-06 11:46:10 -05:00
renovate[bot] f2f29f5976
fix(deps): update prometheusserverversion to v1.3.8 (#7367)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-06-06 09:29:48 -05:00
jack-berg 8ed10f2ad7
OTLP exporter should tolerate instances of LogRecordData when incubator is present (#7393) 2025-06-06 09:23:58 -05:00
Gregor Zeitlinger 5e50aa7ee6
prom exporter: exclude shaded protobuf (#7355)
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-06-05 17:12:45 -05:00
renovate[bot] cb92d970d4
chore(deps): update dependency gradle to v8.14.2 (#7394)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-05 17:08:36 -05:00
renovate[bot] 5fada737bf
fix(deps): update dependency com.squareup.wire:wire-bom to v5.3.3 (#7395)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-05 17:05:28 -05:00
renovate[bot] c874197d64
chore(config): migrate renovate config (#7351)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
2025-06-05 16:57:54 -05:00
renovate[bot] d41c099e62
chore(deps): update weekly update (#7352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-05 16:57:05 -05:00
renovate[bot] 9e76c90a04
fix(deps): update dependency io.netty:netty-bom to v4.2.2.final (#7389)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-05 16:40:43 -05:00
renovate[bot] 93d9e7278f
fix(deps): update dependency io.opentelemetry.proto:opentelemetry-proto to v1.7.0-alpha (#7362)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-06-05 11:20:40 -05:00
jack-berg b11316b0bd
Configurable exception.* attribute resolution (#7266) 2025-06-05 11:20:14 -05:00
renovate[bot] a756317511
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.58.0 (#7384)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 17:15:48 -05:00
renovate[bot] 3b596aae1b
fix(deps): update dependency io.zipkin.brave:brave-bom to v6.3.0 (#7385)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 17:15:35 -05:00
Onur Kayabasi d239b7017d
Prometheus label conversion refactored to align with spec (#7291)
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-06-03 17:06:21 -05:00
Jonas Kunz f7207352a1
Implement new SemConv exporter health metrics (#7265)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-06-03 16:40:38 -05:00
renovate[bot] 2c762e0be8
fix(deps): update dependency checkstyle to v10.25.0 (#7383)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:34:05 -05:00
renovate[bot] dfbea872b1
fix(deps): update dependency com.squareup.wire:wire-bom to v5.3.2 (#7382)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:33:51 -05:00
renovate[bot] fd93c2b8c4
fix(deps): update dependency com.squareup.okio:okio-bom to v3.12.0 (#7372)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:33:36 -05:00
renovate[bot] ba37bf1a69
fix(deps): update spotless packages to v7.0.4 (#7371)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:10:06 -05:00
renovate[bot] 6982730ffb
fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.21.1 (#7377)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:08:57 -05:00
Kevin Burke f94b056f83
sdk-extensions: remove 'Visible for test' comment (#7381) 2025-06-03 14:08:41 -05:00
renovate[bot] 5898a425c5
fix(deps): update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.5.1 (#7379)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:06:55 -05:00
renovate[bot] afe3440e91
fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.31.1 (#7375)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:06:38 -05:00
renovate[bot] 53b1f7c624
fix(deps): update dependency io.grpc:grpc-bom to v1.73.0 (#7370)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 14:06:19 -05:00
Robert Niedziela 90e030f213
Handle instrumentation node changes in yaml config file format 0.4 (#7357) 2025-05-27 17:34:26 -05:00
renovate[bot] 03e7f98965
chore(deps): update plugin com.gradle.develocity to v4.0.2 (#7368)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-27 12:21:34 -07:00
renovate[bot] 145ceaa94c
fix(deps): update dependency com.gradle.develocity:com.gradle.develocity.gradle.plugin to v4.0.2 (#7369)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-27 12:21:04 -07:00
renovate[bot] 6153023d98
chore(deps): update dependency gradle to v8.14.1 (#7364)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-23 09:51:54 -07:00
renovate[bot] 04fc212451
fix(deps): update dependency checkstyle to v10.24.0 (#7361)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-23 09:51:34 -07:00
renovate[bot] cc7d0855e7
chore(deps): update weekly update (#7306)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-15 16:42:07 -05:00
renovate[bot] 452464820a
fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.31.0 (#7350)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-15 16:41:52 -05:00
Alex Brown deeceebe8d
Run JDK HTTP sender on non-daemon threads. (#7322)
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-05-15 16:12:25 -05:00
OpenTelemetry Bot 6bd13ffcbc
Update Renovate configuration (#7345)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-05-15 15:47:24 -05:00
renovate[bot] 3c1f556831
fix(deps): update prometheusserverversion to v1.3.7 (#7348)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-05-15 15:34:54 -05:00
renovate[bot] 4c6ba0aed1
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.57.0 (#7349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-15 14:56:09 -05:00
renovate[bot] d698c1d326
fix(deps): update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.1.21 (#7347)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-15 14:54:55 -05:00
Trask Stalnaker 3219437316
Fix release workflow (#7341) 2025-05-15 14:37:01 -05:00
Jonathan Halliday bed02d5f61
Add gRPC export for profiles signal type. (#7301)
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-05-13 10:53:53 -05:00
jack-berg 394cd354a3
Post release 1.50.0 (#7344) 2025-05-13 10:22:30 -05:00
Laurent Tréguier e419b5d588
Fix context storage provider property name (#7318) (#7342) 2025-05-11 09:55:11 -07:00
otelbot[bot] acc64ee012
Update version to 1.51.0 (#7338)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-05-09 17:58:04 -05:00
jack-berg e8305ee3f5
Prepare 1.50.0 (#7335) 2025-05-09 09:52:01 -05:00
Francesco Andreuzzi 983133fd0d
Add `setLoggerConfigurator` support to `LoggerProvider` (#7332) 2025-05-09 09:14:27 -05:00
jason plumb 58acb531c5
Add test that shows how context keys are special (#7330) 2025-05-08 16:26:53 -05:00
renovate[bot] 18548f47ad
fix(deps): update dependency com.tngtech.archunit:archunit-junit5 to v1.4.1 (#7331)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-08 16:25:31 -05:00
renovate[bot] f0f263031a
fix(deps): update dependency io.netty:netty-bom to v4.2.1.final (#7324)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-08 16:25:21 -05:00
Alex Brown 288907d349
Avoid HTTP 429 errors (#7328) 2025-05-08 16:25:08 -05:00
jack-berg eec21201b1
Add DeclarativeConfigContext (#7293) 2025-05-06 14:19:33 -05:00
jack-berg 54e5ea7bf2
Update cralwer to crawl all io.opentelemetry.* groups (#7316) 2025-05-06 14:19:18 -05:00
jack-berg d70fe5b029
Fix Otlp*MetricExporterBuilderTests (#7313) 2025-05-06 14:19:01 -05:00
renovate[bot] 5bda810da8
fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.19.4 (#7311)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 19:25:14 -07:00
renovate[bot] 39ba216f00
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.56.0 (#7320)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 19:24:43 -07:00
renovate[bot] 804714d28e
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.55.3 (#7317)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 08:00:04 -07:00
Francesco Andreuzzi 7cbcdd65b6
Spatial aggregation for async instruments with filtering views (#7264)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-05-02 16:50:30 -05:00
Jay DeLuca 4aeb2f79be
Javadoc site crawler (#7300) 2025-05-02 15:55:13 -05:00
renovate[bot] 29523e62ea
fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.7 (#7310) 2025-04-30 06:32:55 -07:00
renovate[bot] 3ef4be2d84
fix(deps): update dependency ru.vyarus:gradle-animalsniffer-plugin to v2.0.1 (#7308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-29 19:30:33 -07:00
renovate[bot] 56ae62e2d6
chore(deps): update dependency gradle to v8.14 (#7304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-29 19:30:07 -07:00
renovate[bot] 2e59170339
fix(deps): update dependency checkstyle to v10.23.1 (#7305)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-29 19:29:23 -07:00
renovate[bot] e2a5d20955
fix(deps): update dependency io.zipkin.brave:brave-bom to v6.2.0 (#7307)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-29 15:32:45 -07:00
renovate[bot] 33a1a9e5fe
fix(deps): update dependency com.gradle.develocity:com.gradle.develocity.gradle.plugin to v4.0.1 (#7303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-29 15:32:02 -07:00
renovate[bot] eb14ef665e
chore(deps): update plugin com.gradle.develocity to v4.0.1 (#7302)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 13:13:28 -07:00
renovate[bot] d114161694
fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.19.0 (#7299)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 13:09:48 -07:00
renovate[bot] 8c1e348fb8
fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.21.0 (#7296)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-26 18:17:31 -07:00
renovate[bot] beb5917939
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.55.2 (#7295)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-26 18:16:53 -07:00
renovate[bot] b8d9c027fd
fix(deps): update errorproneversion to v2.38.0 (#7285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-04-24 11:31:16 -05:00
Tyler Benson b468a2e9bf
Allow Otlp*MetricExporter's to publish export stats (#7255) 2025-04-21 17:35:41 -05:00
renovate[bot] 2460c92400
chore(deps): update actions/create-github-app-token action to v2 (#7288)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-21 17:28:25 -05:00
renovate[bot] 86b7e76082
chore(deps): update weekly update (#7287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-21 17:09:53 -05:00
renovate[bot] 5c4a0ad78f
fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.55.0 (#7286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-18 20:47:36 -07:00
Onur Kayabasi 8fda429ae6
Sdk builders extended with addProcessorFirst methods (#7243) 2025-04-18 16:16:29 -05:00
jack-berg 9e3f702d5b
Declarative config 0.4 (#7064) 2025-04-18 14:20:38 -05:00
renovate[bot] 04677f93b3
fix(deps): update dependency net.ltgt.gradle:gradle-errorprone-plugin to v4.2.0 (#7284)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-17 13:34:58 -05:00
renovate[bot] 349052c34d
fix(deps): update dependency io.grpc:grpc-bom to v1.72.0 (#7278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-17 13:32:39 -05:00
jack-berg 9e1e9c6e9f
Stabilize log record event name (#7277) 2025-04-17 12:30:43 -05:00
Jonas Kunz 65472798f6
Fix OTLP metric exporter toBuilder() loosing temporality (#7280) 2025-04-17 11:39:35 -05:00
jack-berg f17b8b0414
Update maven badge to new host (#7283) 2025-04-16 16:53:47 -05:00
renovate[bot] e392b11bbf
fix(deps): update armeriaversion to v1.32.5 (#7275)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-16 13:05:54 -05:00
jack-berg 4e457f75a8
Fix link checker (#7282) 2025-04-16 13:03:44 -05:00
Tyler Benson d13f04d084
Clarify that AttributesBuilder.put allows nulls (#7271) 2025-04-16 11:08:03 -05:00
Trask Stalnaker 14e2fefe7a
Switch to otelbot and streamline post release process (#7273) 2025-04-15 14:22:19 -05:00
jack-berg ccfcecf8fe
Promote getAll to TextMapGetter stable API (#7267) 2025-04-15 12:38:07 -05:00
renovate[bot] 8a998225d0
fix(deps): update dependency com.google.guava:guava-bom to v33.4.8-jre (#7274)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-14 19:42:13 -07:00
renovate[bot] a01bf6cfd0
fix(deps): update junit5 monorepo to v5.12.2 (#7269)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 15:31:53 -05:00
renovate[bot] 0191a01b3b
fix(deps): update dependency io.opentelemetry.contrib:opentelemetry-aws-xray-propagator to v1.46.0-alpha (#7270)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 14:41:21 -05:00
Trask Stalnaker e695b66950
Add FOSSA badges (#7094) 2025-04-11 14:15:09 -05:00
renovate[bot] 563087f0f0
chore(deps): update weekly update (#7218)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 10:59:57 -05:00
renovate[bot] 00fbeb2695
chore(deps): update plugin com.gradle.develocity to v4 (#7260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 10:59:33 -05:00
renovate[bot] 6855cd3143
fix(deps): update armeriaversion to v1.32.4 (#7257)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 10:59:14 -05:00
renovate[bot] 5d3ae0199f
fix(deps): update dependency com.gradle.develocity:com.gradle.develocity.gradle.plugin to v4 (#7261)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 10:58:46 -05:00
jack-berg dc0b4acd86
Add support for escaping declarative config env var substitution (#7033) 2025-04-11 10:46:59 -05:00
jack-berg 2d1c14ee56
Add experimental support for log extended attributes (#7123) 2025-04-11 10:46:38 -05:00
Teja 9cb636502e
6195: DelegatingMetricData. (#7229)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
2025-04-11 09:20:03 -05:00
jack-berg 4e243f2b63
Add ExtendedLogRecordBuilder#setException (#7182) 2025-04-11 09:18:19 -05:00
renovate[bot] d7fb208d06
fix(deps): update dependency com.google.guava:guava-bom to v33.4.7-jre (#7259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-10 14:20:26 -05:00
renovate[bot] 1f5a560fbb
fix(deps): update dependency com.squareup.okio:okio-bom to v3.11.0 (#7263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-10 14:20:09 -05:00
renovate[bot] 58bf4e4018
fix(deps): update spotless packages to v7.0.3 (#7256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-10 14:19:52 -05:00
jack-berg a8493271bc
Update min kotlin version to 1.8 (#7155) 2025-04-10 14:18:44 -05:00
jack-berg 00b61a2d87
Remove guava dependency from buildSrc/build.gradle.kts (#7262) 2025-04-09 13:00:15 -05:00
jack-berg 10eda198c0
Remove Java9VersionSpecific clock implementation (#7221) 2025-04-07 16:50:55 -05:00
renovate[bot] aa17528ec1
fix(deps): update dependency org.owasp:dependency-check-gradle to v12.1.1 (#7252)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-07 16:48:52 -05:00
OpenTelemetry Bot 688e1031c6
Post release for version 1.49.0 (#7254) 2025-04-07 11:29:32 -05:00
Onur Kayabasi 7f86458580
Fix duplicated ExecutorService wrap (#7245) 2025-04-07 10:34:28 -05:00
Onur Kayabasi 3eb7ef00ad
Authenticator added for PrometheusHttpServer (#7225) 2025-04-07 10:32:52 -05:00
OpenTelemetry Bot f801a159f3
Update version to 1.50.0 (#7249) 2025-04-04 15:20:35 -05:00
jack-berg b3126023db
Prepare for 1.49.0 release (#7248) 2025-04-04 14:14:04 -05:00
renovate[bot] 233e111a09
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>
2025-04-04 11:53:05 -05:00
renovate[bot] 4ecc0becfd
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>
2025-04-04 11:50:59 -05:00
renovate[bot] 184090914e
fix(deps): update dependency jacoco to v0.8.13 (#7241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 15:39:40 -05:00
renovate[bot] 8fe071afee
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 <jberg@newrelic.com>
2025-04-02 15:33:01 -05:00
renovate[bot] a7e92dfe81
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>
2025-04-02 14:22:51 -05:00
renovate[bot] dc44948c4f
fix(deps): update dependency checkstyle to v10.23.0 (#7237)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 14:22:33 -05:00
renovate[bot] a48b48fa29
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 <jberg@newrelic.com>
2025-04-02 14:04:24 -05:00
renovate[bot] e34049b74e
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>
2025-04-01 18:27:58 -07:00
jack-berg 1500b0f3ba
Fix jmh link (#7233) 2025-04-01 14:56:22 -05:00
jack-berg 0c6a04710b
Remove armeria log decorator to clean up build logs (#7232) 2025-04-01 11:29:49 -05:00
renovate[bot] 22acb3e8ec
fix(deps): update dependency checkstyle to v10.22.0 (#7228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-30 17:48:44 -07:00
renovate[bot] f2f990c81d
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>
2025-03-29 12:29:01 -07:00
Lauri Tulmin e46742d944
Don't initialize DeclarativeConfiguration in incubator available test (#7227) 2025-03-28 11:17:29 -05:00
jack-berg 2cf5f0128b
Fix declarative config xray todo (#7226) 2025-03-27 13:30:24 -05:00
Anton Rybochkin e6f90f58ce
Avoid linear queue.size() calls in span producers by storing queue size separately (#7141)
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
2025-03-26 17:21:13 -05:00
renovate[bot] 9698d24fdf
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>
2025-03-26 17:20:13 -05:00
jack-berg 526137fd64
Add more attribute advice tests to show interaction with views (#7143) 2025-03-25 20:24:19 -07:00
renovate[bot] 7b732c8498
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>
2025-03-25 20:21:42 -07:00
renovate[bot] a1fed61742
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 <jberg@newrelic.com>
2025-03-25 16:33:03 -07:00
Yuriy Holinko 3c12e3af1a
Refine delay jitter for exponential backoff (#7206) 2025-03-25 11:20:12 -05:00
renovate[bot] 9e0efd4267
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>
2025-03-22 15:12:43 -07:00
renovate[bot] cc7b268cec
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>
2025-03-22 15:12:27 -07:00
renovate[bot] 3ac1f9f695
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>
2025-03-22 15:12:09 -07:00
renovate[bot] 747368a94b
fix(deps): update armeriaversion to v1.32.3 (#7197)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-22 15:07:47 -07:00
Gregor Zeitlinger 000fd0f209
add config model customizer (#7118)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
2025-03-21 12:40:16 -05:00
renovate[bot] 9172089ab9
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>
2025-03-21 07:44:54 -07:00
renovate[bot] 9b596d03d1
fix(deps): update junit5 monorepo to v5.12.1 (#7203)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-21 07:41:31 -07:00
renovate[bot] 9c1b9f609f
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>
2025-03-17 10:13:02 -07:00
jack-berg 09bac7d077
Stable cardinality limit property otel.java.metrics.cardinality.limit (#7199) 2025-03-17 09:44:49 -05:00
jack-berg 490173b0da
Remove support for otel.experimental.exporter.otlp.retry.enabled (#7200) 2025-03-14 13:51:46 -05:00
jack-berg 0673fcfda5
Add support for setting OTLP exporter executor service (#7152) 2025-03-13 11:53:19 -05:00
renovate[bot] a3dd67739a
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>
2025-03-12 09:53:45 -05:00
renovate[bot] d0848e3351
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>
2025-03-12 09:53:26 -05:00
renovate[bot] d511a28df9
chore(deps): update github/codeql-action action to v3.28.11 (#7189)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-10 11:18:12 -05:00
OpenTelemetry Bot 708244ec48
Post release for version 1.48.0 (#7190) 2025-03-10 10:55:16 -05:00
renovate[bot] 9d4f61ad0b
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>
2025-03-10 09:36:10 -05:00
OpenTelemetry Bot 974653fe66
Update version to 1.49.0 (#7186) 2025-03-07 16:47:00 -06:00
jack-berg 2e4f9ede58
Prepare for 1.48.0 release (#7183)
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
2025-03-07 10:03:15 -06:00
jack-berg 8efade69a1
Extract sender parameters to config carrier class (#7151) 2025-03-06 11:57:46 -06:00
renovate[bot] 4d34b53e0c
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>
2025-03-05 09:51:29 -06:00
renovate[bot] 0de9fc084d
fix(deps): update armeriaversion to v1.32.0 (#7174)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-05 09:50:44 -06:00
chukun 1b1d537375
Reduce warning log about maxExportBatchSize. (#7148) 2025-03-05 09:50:22 -06:00
jack-berg 42056f57c8
Introduce ConfigProvider API (#6549) 2025-03-04 17:21:19 -06:00
renovate[bot] b3e3fff83c
chore(deps): update weekly update (#7163)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-04 16:59:28 -06:00
renovate[bot] cd86405148
fix(deps): update dependency checkstyle to v10.21.4 (#7166)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-04 16:56:30 -06:00
renovate[bot] 33b37abe9a
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>
2025-03-04 16:56:12 -06:00
renovate[bot] 0618791928
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>
2025-03-04 16:55:57 -06:00
jack-berg 5015698d2b
Remove obsolete SdkMeterProviderUtil#setCardinalitylimit API (#7169) 2025-03-04 16:49:05 -06:00
jack-berg 3c71b798a5
Test with graalvm 23 (#7167) 2025-03-04 12:46:56 -06:00
jack-berg 0a993b392c
Update android animalsniffer min API version to 23 (#7153) 2025-03-04 09:47:13 -06:00
tianlan xu 16f3637b0b
fix bug: throttledRateLimiter is not once per minute, but five times (#7156) 2025-03-03 17:01:53 -06:00
jack-berg dc46ccd2c9
Add support for setting OTLP exporter service class loader (#7150) 2025-03-03 17:01:10 -06:00
renovate[bot] d1ce438e00
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>
2025-02-28 16:04:13 -08:00
renovate[bot] 173e80b9c2
chore(deps): update dependency gradle to v8.13 (#7145)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-28 16:03:43 -08:00
renovate[bot] 3dd7134f81
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>
2025-02-28 09:10:44 -08:00
jack-berg cd1f61725c
Suppress a variety of noisy test logs (#7154) 2025-02-27 10:57:03 -06:00
renovate[bot] 313d391e55
fix(deps): update slf4j monorepo to v2.0.17 (#7146)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-26 17:17:18 -06:00
renovate[bot] 865c89f47d
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>
2025-02-26 17:17:00 -06:00
renovate[bot] 5a10b685d4
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>
2025-02-26 17:16:40 -06:00
jack-berg 3d3bff5bda
Fix bug preventing accurate reporting of dropped attribute count (#7142) 2025-02-26 16:26:59 -06:00
chukun 31f484f39f
#6454 log warning and adjust maxExportBatchSize when exceeds maxQueueSize. (#7045)
Co-authored-by: Jack Berg <jberg@newrelic.com>
2025-02-25 12:00:37 -06:00
renovate[bot] 2de5a2c484
fix(deps): update dependency org.awaitility:awaitility to v4.3.0 (#7131)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-24 14:22:38 -06:00
renovate[bot] 9f5b67b3c3
fix(deps): update junit5 monorepo to v5.12.0 (#7132)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-24 14:22:22 -06:00
renovate[bot] 80af8a33a0
fix(deps): update dependency checkstyle to v10.21.3 (#7138)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-24 14:21:58 -06:00
renovate[bot] c91f56ece8
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>
2025-02-24 14:21:29 -06:00
renovate[bot] f33cba3b1d
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 <jberg@newrelic.com>
2025-02-24 11:15:47 -06:00
Trask Stalnaker b5daeb0871
Fix otlp logging exporter test to be more realistic (#7136) 2025-02-24 10:24:08 -06:00
renovate[bot] 3c77016788
chore(deps): update weekly update (#7114)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-24 10:23:07 -06:00
jason plumb ee731aabd3
Add some helpful logging attribute methods (#7089)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
2025-02-24 10:13:35 -06:00
jack-berg 56941a5ba6
Remove support for otel.java.experimental.exporter.memory_mode (#7127) 2025-02-21 10:13:57 -06:00
jack-berg 37969926d1
Disable owasp dependency check on :custom-checks (#7128) 2025-02-20 15:58:18 -06:00
Trask Stalnaker 0465c79151
Fix OWASP dependency check workflow (#7126) 2025-02-20 11:19:22 -06:00
Trask Stalnaker 5879f48dc8
Fix OWASP dependency check workflow (#7115) 2025-02-19 09:57:55 -06:00
renovate[bot] f937eff1ee
chore(deps): update plugin com.gradle.develocity to v3.19.2 (#7120)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-18 18:52:21 -08:00
renovate[bot] 5b93c08eed
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>
2025-02-18 16:36:32 -08:00
renovate[bot] a9d7f1ebda
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>
2025-02-18 16:35:36 -08:00
renovate[bot] d08c5030d3
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>
2025-02-18 18:12:09 -06:00
renovate[bot] 3f3b42483a
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>
2025-02-18 14:41:25 -08:00
renovate[bot] 8ed2e0c79f
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>
2025-02-18 14:30:19 -08:00
renovate[bot] d69ea6c37d
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>
2025-02-18 12:52:27 -08:00
renovate[bot] ca6fa4e801
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>
2025-02-18 12:51:51 -08:00
renovate[bot] 41e54f7481
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>
2025-02-18 12:45:11 -08:00
jack-berg fe73fb737a
Retry tests in CI (#7106) 2025-02-18 09:58:58 -06:00
Trask Stalnaker 3d3355305b
Add FOSSA team (#7104) 2025-02-18 09:58:16 -06:00
Trask Stalnaker e47963612e
Convert branch protections to rule sets (#7095) 2025-02-18 09:57:55 -06:00
Trask Stalnaker 3e1d9536f8
Less frequent Renovate (#7102) 2025-02-11 20:54:30 -08:00
Trask Stalnaker 43fba2e984
Update from ubuntu-20.04 (#7100) 2025-02-11 15:01:57 -06:00
Trask Stalnaker b56b10ff57
Another CLOMonitor exemption (#7096) 2025-02-11 15:01:23 -06:00
renovate[bot] 27d863375b
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>
2025-02-10 18:27:11 -08:00
renovate[bot] c285def1d9
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>
2025-02-10 18:26:46 -08:00
renovate[bot] 8e71517fdb
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>
2025-02-10 18:26:11 -08:00
Trask Stalnaker 768e789160
Renovate best practices (#7069) 2025-02-10 12:37:51 -06:00
Trask Stalnaker 517893e817
Add FOSSA license scanning (#7090) 2025-02-10 12:34:29 -06:00
Trask Stalnaker c77e66475a
Add OSSF scorecard badge (#7073) 2025-02-10 12:33:19 -06:00
jack-berg 00f00433f3
Continue limiting workflow permissions (#7092) 2025-02-10 11:40:56 -06:00
StepSecurity Bot 06449488ce
[StepSecurity] Apply security best practices (#7088)
Signed-off-by: StepSecurity Bot <bot@stepsecurity.io>
2025-02-10 10:31:39 -06:00
renovate[bot] 92b089ab2c
chore(deps): update github/codeql-action action to v3.28.9 (#7081)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-09 14:42:14 -08:00
Trask Stalnaker 89a830cfb4
Add CLOMonitor exemption for Artifact Hub badge (#7091) 2025-02-09 11:06:49 -08:00
OpenTelemetry Bot 867bb1f24e
Post release for version 1.47.0 (#7087) 2025-02-07 14:26:00 -06:00
Trask Stalnaker 5b1e444980
Always run gradle wrapper validation (#7071) 2025-02-07 14:21:19 -06:00
Trask Stalnaker d22baecc95
Restrict token permissions (#7072) 2025-02-07 14:21:04 -06:00
Trask Stalnaker 41c51a052c
Run CodeQL on PRs (#7070) 2025-02-07 14:20:41 -06:00
OpenTelemetry Bot bd6b974e99
Update version to 1.48.0 (#7084) 2025-02-07 13:34:44 -06:00
671 changed files with 20810 additions and 5900 deletions

8
.clomonitor.yml Normal file
View File

@ -0,0 +1,8 @@
# see https://github.com/cncf/clomonitor/blob/main/docs/checks.md#exemptions
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"
- check: openssf_badge
reason: "ETOOMANYBADGES, but the work has been done: https://www.bestpractices.dev/projects/9991"

40
.fossa.yml Normal file
View File

@ -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

View File

@ -1,48 +1,85 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: [
'config:best-practices',
'helpers:pinGitHubActionDigestsToSemver',
],
"packageRules": [
packageRules: [
{
"matchPackageNames": [
"io.opentelemetry.proto:opentelemetry-proto",
"io.opentelemetry.semconv:opentelemetry-semconv-incubating"
// this is to reduce the number of renovate PRs
matchManagers: [
'github-actions',
'dockerfile',
],
extends: [
'schedule:weekly',
],
groupName: 'weekly update',
},
{
matchPackageNames: [
'io.opentelemetry.contrib:opentelemetry-aws-xray-propagator',
'io.opentelemetry.proto:opentelemetry-proto',
'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
// 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$/"
ignoreUnstable: false,
allowedVersions: '!/\\-SNAPSHOT$/',
},
{
// junit-pioneer 2+ requires Java 11+
"matchPackageNames": ["org.junit-pioneer:junit-pioneer"],
"matchUpdateTypes": ["major"],
"enabled": false
matchPackageNames: [
'org.junit-pioneer:junit-pioneer',
],
matchUpdateTypes: [
'major',
],
enabled: false,
},
{
// mockito 5+ requires Java 11+
"matchPackagePrefixes": ["org.mockito:"],
"matchUpdateTypes": ["major"],
"enabled": false
matchUpdateTypes: [
'major',
],
enabled: false,
matchPackageNames: [
'org.mockito:{/,}**',
],
},
{
// jqf-fuzz version 1.8+ requires Java 11+
"matchPackageNames": ["edu.berkeley.cs.jqf:jqf-fuzz"],
"matchUpdateTypes": ["major", "minor"],
"enabled": false
matchPackageNames: [
'edu.berkeley.cs.jqf:jqf-fuzz',
],
matchUpdateTypes: [
'major',
'minor',
],
enabled: false,
},
{
// pinned version for compatibility
"matchPackageNames": ["org.jetbrains.kotlinx:kotlinx-coroutines-core"],
"matchCurrentVersion": "1.5.2",
"enabled": false
matchPackageNames: [
'org.jetbrains.kotlinx:kotlinx-coroutines-core',
],
matchCurrentVersion: '1.5.2',
enabled: false,
},
{
"matchPackagePrefixes": ["com.diffplug.spotless"],
"groupName": "spotless packages"
groupName: 'spotless packages',
matchPackageNames: [
'com.diffplug.spotless{/,}**',
],
},
{
// equals verifier v4+ requires java 17+
groupName: 'nl.jqno.equalsverifier',
matchPackageNames: [ 'equalsverifier'],
matchUpdateTypes: [ 'major' ],
enabled: false
}
]
],
}

View File

@ -1,75 +1,24 @@
# Repository settings
Repository settings in addition to what's documented already at
<https://github.com/open-telemetry/community/blob/main/docs/how-to-configure-new-repository.md>.
## General > Pull Requests
* Allow squash merging > Default to pull request title
## Actions > General
* 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:
* 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
(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)
This document describes any changes that have been made to the
settings in this repository outside the settings tracked in the
private admin repo.
## 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
- `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)
### Organization secrets
- `FOSSA_API_KEY`
- `OTELBOT_PRIVATE_KEY`
### Organization variables
- `OTELBOT_APP_ID`

View File

@ -86,5 +86,5 @@ echo $contributors1 $contributors2 \
| grep -v github-actions \
| grep -v renovate \
| grep -v codecov \
| grep -v opentelemetrybot \
| grep -v otelbot \
| sed 's/^/@/'

8
.github/scripts/update-version.sh vendored Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash -e
version=$1
versionWithSnapshot="$version-SNAPSHOT"
sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$version/" version.gradle.kts
sed -Ei "1 s/(Comparing source compatibility of [a-z-]+)-[0-9]+\.[0-9]+\.[0-9]+(-SNAPSHOT)?.jar/\1-$versionWithSnapshot.jar/" docs/apidiffs/current_vs_latest/*.txt

View File

@ -1,4 +1,4 @@
#!/bin/bash -e
git config user.name opentelemetrybot
git config user.email 107717825+opentelemetrybot@users.noreply.github.com
git config user.name otelbot
git config user.email 197425009+otelbot@users.noreply.github.com

View File

@ -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: |
@ -16,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
@ -24,16 +29,22 @@ jobs:
- name: Use CLA approved github bot
run: .github/scripts/use-cla-approved-github-bot.sh
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- name: Create pull request
env:
NUMBER: ${{ github.event.inputs.number }}
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
run: |
commit=$(gh pr view $NUMBER --json mergeCommit --jq .mergeCommit.oid)
title=$(gh pr view $NUMBER --json title --jq .title)
branch="opentelemetrybot/backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
branch="otelbot/backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
git checkout -b $branch
git cherry-pick $commit

View File

@ -3,10 +3,15 @@ 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
runs-on: equinix-bare-metal
timeout-minutes: 10
strategy:
fail-fast: false
@ -39,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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Run jmh
run: ./gradlew jmhJar
@ -61,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

View File

@ -5,23 +5,28 @@ 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
runs-on: equinix-bare-metal
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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Run jmh
run: ./gradlew jmhJar
@ -31,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

View File

@ -9,21 +9,27 @@ on:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
publish:
permissions:
contents: read
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@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.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@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: integration-tests/tracecontext/docker
push: true

View File

@ -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
@ -32,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
@ -49,24 +52,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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Build
run: >
./gradlew build
@ -79,10 +82,10 @@ 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, or for bot-generated PRs
# The jApiCmp diff compares current to latest, which isn't appropriate for release branches
# 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') }}
if: ${{ matrix.os != 'windows-latest' && !startsWith(github.ref_name, 'release/') && !startsWith(github.base_ref, 'release/') }}
run: |
# need to "git add" in case any generated files did not already exist
git add docs/apidiffs
@ -96,12 +99,12 @@ jobs:
exit 1
fi
- uses: codecov/codecov-action@v5
- uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
if: ${{ matrix.coverage }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: ${{ matrix.coverage }}
with:
name: coverage-report
@ -132,17 +135,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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
# 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' }}
@ -158,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@v4
- uses: graalvm/setup-graalvm@v1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: graalvm/setup-graalvm@7f488cf82a3629ee755e4e97342c01d6bed318fa # v1.3.5
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 }}

View File

@ -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

65
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,65 @@
name: CodeQL
on:
pull_request:
branches:
- main
- release/*
- benchmarks
push:
branches:
- main
- release/*
- benchmarks
schedule:
- cron: "23 16 * * 2" # weekly at 16:23 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
strategy:
fail-fast: false
matrix:
include:
- language: actions
- language: java
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Java 17
if: matrix.language == 'java'
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
if: matrix.language == 'java'
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Initialize CodeQL
uses: github/codeql-action/init@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
with:
languages: ${{ matrix.language }}
# 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
if: matrix.language == 'java'
# --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@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
with:
category: "/language:${{matrix.language}}"

View File

@ -5,8 +5,14 @@ on:
- cron: "23 3 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
copy-images:
permissions:
contents: read
packages: write
strategy:
matrix:
include:
@ -21,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Docker login
uses: docker/login-action@v3
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}

20
.github/workflows/fossa.yml vendored Normal file
View File

@ -0,0 +1,20 @@
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@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0
with:
api-key: ${{secrets.FOSSA_API_KEY}}
team: OpenTelemetry

View File

@ -1,69 +0,0 @@
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
- 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: |
version=$(.github/scripts/get-version.sh)
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]}"
patch="${BASH_REMATCH[3]}"
two_releases_ago="$major.$((minor - 1)).$patch"
else
echo "unexpected prior version: $prior_version"
exit 1
fi
echo "TWO_VERSIONS_AGO=$two_releases_ago" >> $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=$PRIOR_VERSION
./gradlew japicmp -PapiBaseVersion=$TWO_VERSIONS_AGO -PapiNewVersion=$PRIOR_VERSION
./gradlew --refresh-dependencies japicmp
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 add docs/apidiffs
git commit -a -m "$message"
git push --set-upstream origin $branch
gh pr create --title "$message" \
--body "$body" \
--base main

View File

@ -1,16 +1,16 @@
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
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: gradle/actions/wrapper-validation@v4.3.0
- uses: gradle/actions/wrapper-validation@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1

View File

@ -4,14 +4,21 @@ on:
issue_comment:
types: [created]
permissions:
contents: read
jobs:
issue_comment:
permissions:
contents: read
issues: write
pull-requests: write
if: >
contains(github.event.issue.labels.*.name, 'needs author feedback') &&
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:

View File

@ -5,11 +5,18 @@ 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
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 7

26
.github/workflows/javadoc-crawler.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: Javadoc.io site crawler (daily)
on:
schedule:
- cron: "30 1 * * *" # daily at 1:30 UTC
workflow_dispatch:
permissions:
contents: read
jobs:
crawl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Run crawler
run: ./gradlew :javadoc-crawler:crawl

View File

@ -23,7 +23,7 @@ jobs:
with:
persist-credentials: false
- uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
- uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
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@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
uses: github/codeql-action/upload-sarif@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
with:
sarif_file: results.sarif

View File

@ -4,28 +4,44 @@ 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
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-java@v4
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Check dependencies
run: ./gradlew dependencyCheckAnalyze
env:
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
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' }}

View File

@ -2,11 +2,16 @@ 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@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: |
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x$ ]]; then
@ -32,7 +37,7 @@ jobs:
echo "VERSION=$major_minor.$((patch + 1))" >> $GITHUB_ENV
- name: Update version
run: sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION/" version.gradle.kts
run: .github/scripts/update-version.sh $VERSION
- name: Update the change log with the approximate release date
run: |
@ -42,13 +47,19 @@ jobs:
- name: Use CLA approved github bot
run: .github/scripts/use-cla-approved-github-bot.sh
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- name: Create pull request
env:
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
run: |
message="Prepare release $VERSION"
branch="opentelemetrybot/prepare-release-${VERSION}"
branch="otelbot/prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"

View File

@ -2,11 +2,14 @@ name: Prepare release branch
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prereqs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Verify prerequisites
run: |
@ -21,11 +24,13 @@ jobs:
fi
create-pull-request-against-release-branch:
permissions:
contents: write # for git push to PR branch
runs-on: ubuntu-latest
needs:
- prereqs
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Create release branch
run: |
@ -54,13 +59,19 @@ jobs:
- name: Use CLA approved github bot
run: .github/scripts/use-cla-approved-github-bot.sh
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- name: Create pull request against the release branch
env:
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
run: |
message="Prepare release $VERSION"
branch="opentelemetrybot/prepare-release-${VERSION}"
branch="otelbot/prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
@ -70,11 +81,13 @@ 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
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set environment variables
run: |
@ -87,11 +100,11 @@ jobs:
echo "unexpected version: $version"
exit 1
fi
echo "NEXT_VERSION=$next_version" >> $GITHUB_ENV
echo "NEXT_VERSION=${next_version}" >> $GITHUB_ENV
echo "VERSION=$version" >> $GITHUB_ENV
- name: Update version
run: sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$NEXT_VERSION/" version.gradle.kts
run: .github/scripts/update-version.sh $NEXT_VERSION
- name: Update the change log on main
run: |
@ -102,14 +115,20 @@ jobs:
- name: Use CLA approved github bot
run: .github/scripts/use-cla-approved-github-bot.sh
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- 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 }}
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
run: |
message="Update version to $NEXT_VERSION"
body="Update version to \`$NEXT_VERSION\`."
branch="opentelemetrybot/update-version-to-${NEXT_VERSION}"
branch="otelbot/update-version-to-${NEXT_VERSION}"
git checkout -b $branch
git commit -a -m "$message"

View File

@ -2,11 +2,17 @@ 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 }}
prior-version: ${{ steps.create-github-release.outputs.prior-version }}
steps:
- run: |
if [[ $GITHUB_REF_NAME != release/* ]]; then
@ -14,15 +20,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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Build and publish artifacts
run: ./gradlew assemble publishToSonatype closeAndReleaseSonatypeStagingRepository
@ -59,7 +65,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 +80,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
@ -123,14 +129,20 @@ jobs:
--notes-file /tmp/release-notes.txt \
v$VERSION
# these are used as job outputs
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "prior-version=$PRIOR_VERSION" >> $GITHUB_OUTPUT
merge-change-log-to-main:
update-apidiff-baseline-and-docs-to-released-version:
permissions:
contents: write # for git push to PR branch
runs-on: ubuntu-latest
needs:
- release
steps:
- uses: actions/checkout@v4
# add change log sync (if any) into this PR since the apidiff update
# is required before any other PR can be merged anyway
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Copy change log section from release branch
env:
@ -139,7 +151,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
@ -150,32 +162,59 @@ jobs:
run: |
release_date=$(gh release view v$VERSION --json publishedAt --jq .publishedAt | sed 's/T.*//')
RELEASE_DATE=$release_date .github/scripts/merge-change-log-after-release.sh
git add CHANGELOG.md
- name: Use CLA approved github bot
- name: Wait for release to be available in maven central
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
until curl --silent \
--show-error \
--output /dev/null \
--head \
--fail \
https://repo1.maven.org/maven2/io/opentelemetry/opentelemetry-api/$VERSION/opentelemetry-api-$VERSION.jar
do
sleep 60
done
- name: Update apidiff baseline
env:
VERSION: ${{ needs.release.outputs.version }}
PRIOR_VERSION: ${{ needs.release.outputs.prior-version }}
run: |
./gradlew japicmp -PapiBaseVersion=$PRIOR_VERSION -PapiNewVersion=$VERSION
./gradlew --refresh-dependencies japicmp
git add docs/apidiffs
- name: Update versions in README.md
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
./gradlew updateVersionInDocs -Prelease.version=$VERSION
git add README.md
- name: Use CLA approved bot
run: .github/scripts/use-cla-approved-github-bot.sh
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- name: Create pull request against main
env:
VERSION: ${{ needs.release.outputs.version }}
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
run: |
if git diff --quiet; then
if [[ $VERSION =~ ^[0-9]+\.[0-9]+\.0 ]]; then
echo there are no updates to merge, not creating pull request
exit 0 # success
else
echo patch release notes did not get applied for some reason
exit 1 # failure
fi
fi
message="Merge change log updates from $GITHUB_REF_NAME"
body="Merge log updates from \`$GITHUB_REF_NAME\`."
branch="opentelemetrybot/merge-change-log-updates-from-${GITHUB_REF_NAME//\//-}"
message="Update apidiff baseline and documentation versions to released version $VERSION"
body="Update apidiff baseline and documentation versions to released version \`$VERSION\`."
branch="otelbot/update-apidiff-baseline-and-documentation-to-released-version-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
git commit -m "$message"
git push --set-upstream origin $branch
gh pr create --title "$message" \
--body "$body" \

View File

@ -3,17 +3,22 @@ name: Reusable - Markdown link check
on:
workflow_call:
permissions:
contents: read
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@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 # v2.4.1
with:
# 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+$"
--exclude "^https://github.com/open-telemetry/opentelemetry-java/(issues|pull)/\\d+$"
--max-retries 6
--retry-wait-time 10
--max-concurrency 1
.

View File

@ -3,11 +3,14 @@ name: Reusable - Misspell check
on:
workflow_call:
permissions:
contents: read
jobs:
misspell-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install misspell
run: |

View File

@ -3,11 +3,17 @@ 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@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Open issue
env:

View File

@ -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

View File

@ -2,6 +2,240 @@
## Unreleased
## Version 1.52.0 (2025-07-11)
### API
#### Common
* Promote `ComponentLoader` to new `opentelemetry-common` artifact,
standardize SPI loading
([#7446](https://github.com/open-telemetry/opentelemetry-java/pull/7446))
#### Context
* LazyStorage passes its ClassLoader when loading ContextStorageProvider SPI
([#7424](https://github.com/open-telemetry/opentelemetry-java/pull/7424))
#### Incubator
* Add context and severity params to ExtendedLogger#isEnabled
([#7268](https://github.com/open-telemetry/opentelemetry-java/pull/7268))
* Add new convenience methods for converting DeclarativeConfigProperties to config model
([#7453](https://github.com/open-telemetry/opentelemetry-java/pull/7453))
### SDK
* Add custom stacktrace renderer which is length limit aware
([#7281](https://github.com/open-telemetry/opentelemetry-java/pull/7281))
#### Metrics
* Propagate flush to PeriodicMetricReader's metricExporter.
([#7410](https://github.com/open-telemetry/opentelemetry-java/pull/7410))
#### Exporters
* OTLP - JdkHttpSender: ensure proper closure of HttpClient in shutdown method
([#7390](https://github.com/open-telemetry/opentelemetry-java/pull/7390))
* OTLP: profile exporters fix and test improvements
([#7442](https://github.com/open-telemetry/opentelemetry-java/pull/7442))
* OTLP: Loading Compressor SPI via ComponentLoader configured through setComponentLoader
([#7428](https://github.com/open-telemetry/opentelemetry-java/pull/7428))
* Prometheus: add scope schema URL and attributes
([#7356](https://github.com/open-telemetry/opentelemetry-java/pull/7356))
* Prometheus: extend prometheus declarative config support to include without_scope_info,
with_resource_constant_labels
([#6840](https://github.com/open-telemetry/opentelemetry-java/pull/6840))
#### Extensions
* Autoconfigure: fix race condition of `GlobalOpenTelemetry` initialization with
`AutoConfiguredOpenTelemetrySdkBuilder`
([#7365](https://github.com/open-telemetry/opentelemetry-java/pull/7365))
* Declarative config: update to declarative config 1.0-rc.1
([#7436](https://github.com/open-telemetry/opentelemetry-java/pull/7436))
* Declarative config: resolve environment variable substitution for mixed quotes
([#7433](https://github.com/open-telemetry/opentelemetry-java/pull/7433))
## Version 1.51.0 (2025-06-06)
### API
#### Context
* Fix context storage provider property name in log message
([#7342](https://github.com/open-telemetry/opentelemetry-java/pull/7342))
### SDK
* Experimental configurable exception.* attribute resolution for SdkTracerProvider,
SdkLoggerProvider
([#7266](https://github.com/open-telemetry/opentelemetry-java/pull/7266))
#### Exporters
* All exporters: implement new SemConv exporter health metrics, with configuration API for selecting
schema version
([#7265](https://github.com/open-telemetry/opentelemetry-java/pull/7265))
* OTLP: Add gRPC export for profiles signal type.
([#7301](https://github.com/open-telemetry/opentelemetry-java/pull/7301))
* OTLP: Run JDK HTTP sender on non-daemon threads.
([#7322](https://github.com/open-telemetry/opentelemetry-java/pull/7322))
* Prometheus: fix serialization of arrays
([#7291](https://github.com/open-telemetry/opentelemetry-java/pull/7291))
* OTLP: exporter tolerates instances of LogRecordData when incubator is present
([#7393](https://github.com/open-telemetry/opentelemetry-java/pull/7393))
#### Extensions
* Declarative config: Handle instrumentation node changes in yaml config file format 0.4
([#7357](https://github.com/open-telemetry/opentelemetry-java/pull/7357))
## Version 1.50.0 (2025-05-09)
### API
* Clarify that AttributesBuilder.put allows nulls
([#7271](https://github.com/open-telemetry/opentelemetry-java/pull/7271))
* Stabilize log record event name
([#7277](https://github.com/open-telemetry/opentelemetry-java/pull/7277))
#### Context
* Fix duplicated ExecutorService wrap
([#7245](https://github.com/open-telemetry/opentelemetry-java/pull/7245))
* Promote getAll to TextMapGetter stable API
([#7267](https://github.com/open-telemetry/opentelemetry-java/pull/7267))
#### Incubator
* Add ExtendedLogRecordBuilder#setException
([#7182](https://github.com/open-telemetry/opentelemetry-java/pull/7182))
* Add experimental support for log extended attributes
([#7123](https://github.com/open-telemetry/opentelemetry-java/pull/7123))
### SDK
* Remove Java9VersionSpecific clock implementation
([#7221](https://github.com/open-telemetry/opentelemetry-java/pull/7221))
* Add addProcessorFirst to SdkTracerProviderBuilder, SdkLoggerProviderBuilder
([#7243](https://github.com/open-telemetry/opentelemetry-java/pull/7243))
#### Logs
* Add `setLoggerConfigurator` support to `LoggerProvider`
([#7332](https://github.com/open-telemetry/opentelemetry-java/pull/7332))
#### Metrics
* Add DelegatingMetricData
([#7229](https://github.com/open-telemetry/opentelemetry-java/pull/7229))
* Spatial aggregation for async instruments with filtering views
([#7264](https://github.com/open-telemetry/opentelemetry-java/pull/7264))
#### Exporters
* Prometheus: Add Authenticator support for PrometheusHttpServer
([#7225](https://github.com/open-telemetry/opentelemetry-java/pull/7225))
* OTLP: Fix OTLP metric exporter toBuilder() loosing temporality
([#7280](https://github.com/open-telemetry/opentelemetry-java/pull/7280))
* OTLP: Allow Otlp*MetricExporter's to publish export stats
([#7255](https://github.com/open-telemetry/opentelemetry-java/pull/7255))
#### Extensions
* Declarative config: Add support for escaping env var substitution
([#7033](https://github.com/open-telemetry/opentelemetry-java/pull/7033))
* Declarative config: update to opentelemetry-configuration 0.4
([#7064](https://github.com/open-telemetry/opentelemetry-java/pull/7064))
* Declarativeconfig: Refactor internals to add DeclarativeConfigContext
([#7293](https://github.com/open-telemetry/opentelemetry-java/pull/7293))
### Project tooling
* Kotlin extension: Update min kotlin version to 1.8
([#7155](https://github.com/open-telemetry/opentelemetry-java/pull/7155))
* Add javadoc site crawler
([#7300](https://github.com/open-telemetry/opentelemetry-java/pull/7300),
[#7316](https://github.com/open-telemetry/opentelemetry-java/pull/7316))
## Version 1.49.0 (2025-04-04)
### 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
* 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
#### Incubator
@ -1736,7 +1970,7 @@ This release is a notable release for metrics:
* Autoconfigure performs percent decoding on `otel.resource.attributes` values.
[(#4653)](https://github.com/open-telemetry/opentelemetry-java/issues/4653)
* Unify compression configuration for exporters including
[(#4775)](https://github.com/open-telemetry/opentelemetry-java/issues/4775):
[(#4775)](https://github.com/open-telemetry/opentelemetry-java/pull/4775):
* Fix handling of `none` in OTLP exporters.
* Add `JaegerGrpcSpanExporterBuilder#setCompression(String)`.
* Add `ZipkinSpanExporterBuilder#setCompression(String)`.

112
README.md
View File

@ -1,7 +1,10 @@
# OpenTelemetry Java
[![Continuous Build][ci-image]][ci-url]
[![Coverage Status][codecov-image]][codecov-url]
[![Maven Central][maven-image]][maven-url]
[![Coverage Status][codecov-image]][codecov-url]
[![FOSSA License Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-java.svg?type=shield&issueType=license)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-java?ref=badge_shield&issueType=license)
[![FOSSA Security Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-java.svg?type=shield&issueType=security)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-java?ref=badge_shield&issueType=security)
[![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)
[![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)
`opentelemetry-java` is the home of the Java implementation of the OpenTelemetry API for recording
@ -54,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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | N/A |
| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | <!--VERSION_UNSTABLE-->1.46.0-alpha<!--/VERSION_UNSTABLE--> | N/A |
| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | N/A |
| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | <!--VERSION_UNSTABLE-->1.52.0-alpha<!--/VERSION_UNSTABLE--> | N/A |
</details>
<details open>
@ -65,9 +68,10 @@ The OpenTelemetry API for recording telemetry.
| Component | Description | Artifact ID | Version | Javadoc |
|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.46.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.52.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |
| [Common](./common) | Common utility methods used across API components | `opentelemetry-common` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-common) |
</details>
<details>
@ -77,8 +81,8 @@ Extensions to the OpenTelemetry API.
| Component | Description | Artifact ID | Version | Javadoc |
|---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) |
</details>
<details open>
@ -88,12 +92,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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) |
</details>
<details>
@ -103,16 +107,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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.46.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.52.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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) | |
</details>
<details>
@ -122,10 +126,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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.46.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.52.0-alpha<!--/VERSION_UNSTABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) |
</details>
<details>
@ -135,8 +139,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` | <!--VERSION_UNSTABLE-->1.46.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.46.0<!--/VERSION_STABLE--> | [![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` | <!--VERSION_UNSTABLE-->1.52.0-alpha<!--/VERSION_UNSTABLE--> | [![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` | <!--VERSION_STABLE-->1.52.0<!--/VERSION_STABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) |
</details>
## Dependencies
@ -173,11 +177,11 @@ Snapshots of the `main` branch are available as follows:
```groovy
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://central.sonatype.com/repository/maven-snapshots/' }
}
dependencies {
implementation platform("io.opentelemetry:opentelemetry-bom:1.47.0-SNAPSHOT")
implementation platform("io.opentelemetry:opentelemetry-bom:1.53.0-SNAPSHOT")
implementation('io.opentelemetry:opentelemetry-api')
}
```
@ -190,8 +194,8 @@ dependencies {
<project>
<repositories>
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<id>sonatype-snapshot-repository</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependencyManagement>
@ -199,7 +203,7 @@ dependencies {
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.47.0-SNAPSHOT</version>
<version>1.53.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -251,35 +255,35 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for:
* Keys to successful PRs
* Guide to using gradle composite builds
### Code owners
### Maintainers
Triagers:
- [Jack Berg](https://github.com/jack-berg), New Relic
- [John Watson](https://github.com/jkwatson), Verta.ai
- [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana Labs
For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).
*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)):
### Approvers
- [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/main/guides/contributor/membership.md#approver).*
For more information about the approver role, see the [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)):
### Triagers
- [Jack Berg](https://github.com/jack-berg), New Relic
- [John Watson](https://github.com/jkwatson), Verta.ai
- [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana Labs
Emeritus:
For more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).
### Emeritus
- 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/main/guides/contributor/membership.md#maintainer).*
For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).
### Help wanted
@ -290,18 +294,14 @@ We are currently resource constrained and are actively seeking new contributors
- 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
### Thanks to all of our contributors!
<a href="https://github.com/open-telemetry/opentelemetry-java/graphs/contributors">
<img src="https://contrib.rocks/image?repo=open-telemetry/opentelemetry-java" />
<img alt="Repo contributors" src="https://contrib.rocks/image?repo=open-telemetry/opentelemetry-java" />
</a>
Made with [contrib.rocks](https://contrib.rocks).
[ci-image]: https://github.com/open-telemetry/opentelemetry-java/workflows/Build/badge.svg
[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/
[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
[maven-image]: https://maven-badges.sml.io/maven-central/io.opentelemetry/opentelemetry-api/badge.svg
[maven-url]: https://maven-badges.sml.io/maven-central/io.opentelemetry/opentelemetry-api

View File

@ -57,27 +57,17 @@ and deadlocks.
* Review and merge the pull request that it creates for updating the change log in main
(note that if this is not a patch release then the change log on main may already be up-to-date,
in which case no pull request will be created).
* Once the release artifacts become available on Maven Central, the system will automatically
generate a new pull request titled `Update apidiff baseline and documentation versions to
released version $VERSION`. This pull request will contain updates to both the API diff baseline
and version references in the documentation files (README.md). Please review and merge this
automated pull request.
* 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
After releasing is done, you need to first update the docs. This needs to happen after artifacts have propagated
to Maven Central so should probably be done an hour or two after the release workflow finishes.
```
./gradlew updateVersionInDocs -Prelease.version=x.y.z
./gradlew japicmp -PapiBaseVersion=a.b.c -PapiNewVersion=x.y.z
./gradlew --refresh-dependencies japicmp
```
Where `x.y.z` is the version just released and `a.b.c` is the previous version.
Create a PR against the main branch with the changes.
## Credentials
The following credentials are required for building or publishing (and automatically set in Github Actions):

View File

@ -72,8 +72,8 @@ 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. |
| 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.8+ | 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

View File

@ -28,7 +28,7 @@ class SdkDesignTest {
* Ensures that all SDK methods that: - are defined in classes that extend or implement API model
* and are public (to exclude protected builders) - are public (avoids issues with protected
* methods returning classes unavailable to test's CL) - override or implement parent method
* return only API, Context or generic Java type.
* return only API, Context, Common, or generic Java type.
*/
@Test
void sdkImplementationOfApiClassesShouldReturnApiTypeOnly() {
@ -45,7 +45,11 @@ class SdkDesignTest {
.and(implementOrOverride())
.should()
.haveRawReturnType(
inPackage("io.opentelemetry.api..", "io.opentelemetry.context..", "java.."))
inPackage(
"io.opentelemetry.api..",
"io.opentelemetry.context..",
"io.opentelemetry.common..",
"java.."))
.orShould()
.haveRawReturnType("void");

View File

@ -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.12.0@signature")
signatureJar("com.android.tools:desugar_jdk_libs")
}

View File

@ -17,6 +17,7 @@ import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
@ -116,6 +117,21 @@ public final class GlobalOpenTelemetry {
}
}
/**
* Sets the {@link OpenTelemetry} that should be the global instance.
*
* <p>This method calls the given {@code supplier} and calls {@link #set(OpenTelemetry)}, all
* while holding the {@link GlobalOpenTelemetry} mutex.
*
* @since 1.52.0
*/
public static void set(Supplier<OpenTelemetry> supplier) {
synchronized (mutex) {
OpenTelemetry openTelemetry = supplier.get();
set(openTelemetry);
}
}
/** Returns the globally registered {@link TracerProvider}. */
public static TracerProvider getTracerProvider() {
return get().getTracerProvider();

View File

@ -16,7 +16,6 @@ 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.context.propagation.internal.ExtendedTextMapGetter;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@ -97,33 +96,11 @@ public final class W3CBaggagePropagator implements TextMapPropagator {
return context;
}
if (getter instanceof ExtendedTextMapGetter) {
return extractMulti(context, carrier, (ExtendedTextMapGetter<C>) getter);
}
return extractSingle(context, carrier, getter);
}
private static <C> Context extractSingle(
Context context, @Nullable C carrier, TextMapGetter<C> getter) {
String baggageHeader = getter.get(carrier, FIELD);
if (baggageHeader == null) {
return context;
}
if (baggageHeader.isEmpty()) {
return context;
}
BaggageBuilder baggageBuilder = Baggage.builder();
try {
extractEntries(baggageHeader, baggageBuilder);
} catch (RuntimeException e) {
return context;
}
return context.with(baggageBuilder.build());
return extractMulti(context, carrier, getter);
}
private static <C> Context extractMulti(
Context context, @Nullable C carrier, ExtendedTextMapGetter<C> getter) {
Context context, @Nullable C carrier, TextMapGetter<C> getter) {
Iterator<String> baggageHeaders = getter.getAll(carrier, FIELD);
if (baggageHeaders == null) {
return context;

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import javax.annotation.Nullable;
class ArrayBackedAttributesBuilder implements AttributesBuilder {
private final List<Object> data;
@ -37,7 +38,7 @@ class ArrayBackedAttributesBuilder implements AttributesBuilder {
}
@Override
public <T> AttributesBuilder put(AttributeKey<T> key, T value) {
public <T> AttributesBuilder put(AttributeKey<T> key, @Nullable T value) {
if (key == null || key.getKey().isEmpty() || value == null) {
return this;
}

View File

@ -26,6 +26,11 @@ public interface AttributeKey<T> {
/** Returns the type of attribute for this key. Useful for building switch statements. */
AttributeType getType();
// TODO (jack-berg): uncomment when extended attributes are promoted from incubator to API
// default ExtendedAttributeKey<T> asExtendedAttributeKey() {
// return InternalAttributeKeyImpl.toExtendedAttributeKey(this);
// }
/** Returns a new AttributeKey for String valued attributes. */
static AttributeKey<String> stringKey(String key) {
return InternalAttributeKeyImpl.create(key, AttributeType.STRING);

View File

@ -18,6 +18,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import javax.annotation.Nullable;
/** A builder of {@link Attributes} supporting an arbitrary number of key-value pairs. */
public interface AttributesBuilder {
@ -35,18 +36,22 @@ public interface AttributesBuilder {
// version.
<T> AttributesBuilder put(AttributeKey<Long> key, int value);
/** Puts a {@link AttributeKey} with associated value into this. */
<T> AttributesBuilder put(AttributeKey<T> key, T value);
/**
* Puts an {@link AttributeKey} with an associated value into this if the value is non-null.
* Providing a null value does not remove or unset previously set values.
*/
<T> AttributesBuilder put(AttributeKey<T> key, @Nullable T value);
/**
* Puts a String attribute into this.
* Puts a String attribute into this if the value is non-null. Providing a null value does not
* remove or unset previously set values.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
default AttributesBuilder put(String key, String value) {
default AttributesBuilder put(String key, @Nullable String value) {
return put(stringKey(key), value);
}

View File

@ -10,6 +10,7 @@ import io.opentelemetry.api.common.Value;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
class DefaultLogger implements Logger {
@ -77,7 +78,7 @@ class DefaultLogger implements Logger {
}
@Override
public <T> LogRecordBuilder setAttribute(AttributeKey<T> key, T value) {
public <T> LogRecordBuilder setAttribute(AttributeKey<T> key, @Nullable T value) {
return this;
}

View File

@ -5,12 +5,18 @@
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;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
/**
* Used to construct and emit log records from a {@link Logger}.
@ -98,8 +104,111 @@ public interface LogRecordBuilder {
return this;
}
/** Sets an attribute. */
<T> LogRecordBuilder setAttribute(AttributeKey<T> key, T value);
/**
* 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.
*
* <p>Note: Providing a null value is a no-op and will not remove previously set values.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
*/
<T> LogRecordBuilder setAttribute(AttributeKey<T> key, @Nullable 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.
*
* <p>Note: Providing a null value is a no-op and will not remove previously set values.
*
* <p>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.
* @since 1.48.0
*/
default LogRecordBuilder setAttribute(String key, @Nullable 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.
*
* <p>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.
* @since 1.48.0
*/
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.
*
* <p>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.
* @since 1.48.0
*/
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.
*
* <p>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.
* @since 1.48.0
*/
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.
*
* <p>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.
* @since 1.48.0
*/
default LogRecordBuilder setAttribute(String key, int value) {
return setAttribute(key, (long) value);
}
/**
* Sets the event name, which identifies the class / type of the Event.
*
* <p>This name should uniquely identify the event structure (both attributes and body). A log
* record with a non-empty event name is an Event.
*
* @since 1.50.0
*/
default LogRecordBuilder setEventName(String eventName) {
return this;
}
/** Emit the log record. */
void emit();

View File

@ -8,6 +8,7 @@ package io.opentelemetry.api.trace;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
@ -42,7 +43,7 @@ final class PropagatedSpan implements Span {
}
@Override
public Span setAttribute(String key, String value) {
public Span setAttribute(String key, @Nullable String value) {
return this;
}
@ -62,7 +63,7 @@ final class PropagatedSpan implements Span {
}
@Override
public <T> Span setAttribute(AttributeKey<T> key, T value) {
public <T> Span setAttribute(AttributeKey<T> key, @Nullable T value) {
return this;
}

View File

@ -88,7 +88,9 @@ public interface Span extends ImplicitContextKeyed {
* Sets an attribute to the {@code Span}. If the {@code Span} previously contained a mapping for
* the key, the old value is replaced by the specified value.
*
* <p>Empty String "" and null are valid attribute {@code value}, but not valid keys.
* <p>Empty String "" and null are valid attribute {@code value}s, but not valid keys.
*
* <p>Note: Providing a null value is a no-op and will not remove previously set values.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
@ -97,7 +99,7 @@ public interface Span extends ImplicitContextKeyed {
* @param value the value for this attribute.
* @return this.
*/
default Span setAttribute(String key, String value) {
default Span setAttribute(String key, @Nullable String value) {
return setAttribute(AttributeKey.stringKey(key), value);
}
@ -150,13 +152,13 @@ public interface Span extends ImplicitContextKeyed {
* Sets an attribute to the {@code Span}. If the {@code Span} previously contained a mapping for
* the key, the old value is replaced by the specified value.
*
* <p>Note: the behavior of null values is undefined, and hence strongly discouraged.
* <p>Note: Providing a null value is a no-op.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
*/
<T> Span setAttribute(AttributeKey<T> key, T value);
<T> Span setAttribute(AttributeKey<T> key, @Nullable T value);
/**
* Sets an attribute to the {@code Span}. If the {@code Span} previously contained a mapping for

View File

@ -14,7 +14,6 @@ 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;
@ -40,8 +39,8 @@ class W3CBaggagePropagatorTest {
}
};
private static final ExtendedTextMapGetter<Map<String, List<String>>> multiGetter =
new ExtendedTextMapGetter<Map<String, List<String>>>() {
private static final TextMapGetter<Map<String, List<String>>> multiGetter =
new TextMapGetter<Map<String, List<String>>>() {
@Override
public Iterable<String> keys(Map<String, List<String>> carrier) {
return carrier.keySet();

View File

@ -26,6 +26,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nullable;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link Attributes}s. */
@ -565,7 +566,7 @@ class AttributesTest {
}
@Override
public <T> AttributesBuilder put(AttributeKey<T> key, T value) {
public <T> AttributesBuilder put(AttributeKey<T> key, @Nullable T value) {
return null;
}

View File

@ -7,6 +7,7 @@ Experimental APIs, including Event API, extended Log Bridge APIs, extended Metri
Features:
* Check if logger is enabled before emitting logs to avoid unnecessary computation
* Add extended attributes to log records to encode complex data structures
See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java).

View File

@ -12,8 +12,14 @@ otelJava.moduleName.set("io.opentelemetry.api.incubator")
dependencies {
api(project(":api:all"))
// Supports optional InstrumentationConfigUtil#convertToModel
compileOnly("com.fasterxml.jackson.core:jackson-databind")
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"))
@ -21,3 +27,16 @@ dependencies {
testImplementation("com.google.guava:guava")
}
testing {
suites {
register<JvmTestSuite>("testConvertToModel") {
dependencies {
implementation("com.fasterxml.jackson.core:jackson-databind")
implementation(project(":sdk-extensions:incubator"))
implementation(project(":sdk-extensions:autoconfigure"))
implementation("com.google.guava:guava")
}
}
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
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.ArrayList;
import java.util.Comparator;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
final class ArrayBackedExtendedAttributes
extends ImmutableKeyValuePairs<ExtendedAttributeKey<?>, Object> implements ExtendedAttributes {
// We only compare the key name, not type, when constructing, to allow deduping keys with the
// same name but different type.
private static final Comparator<ExtendedAttributeKey<?>> KEY_COMPARATOR_FOR_CONSTRUCTION =
Comparator.comparing(ExtendedAttributeKey::getKey);
static final ExtendedAttributes EMPTY = ExtendedAttributes.builder().build();
@Nullable private Attributes attributes;
private ArrayBackedExtendedAttributes(
Object[] data, Comparator<ExtendedAttributeKey<?>> keyComparator) {
super(data, keyComparator);
}
/**
* Only use this constructor if you can guarantee that the data has been de-duped, sorted by key
* and contains no null values or null/empty keys.
*
* @param data the raw data
*/
ArrayBackedExtendedAttributes(Object[] data) {
super(data);
}
@Override
public ExtendedAttributesBuilder toBuilder() {
return new ArrayBackedExtendedAttributesBuilder(new ArrayList<>(data()));
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> T get(ExtendedAttributeKey<T> key) {
return (T) super.get(key);
}
@SuppressWarnings("unchecked")
@Override
public Attributes asAttributes() {
if (attributes == null) {
AttributesBuilder builder = Attributes.builder();
forEach(
(extendedAttributeKey, value) -> {
AttributeKey<Object> attributeKey =
(AttributeKey<Object>) extendedAttributeKey.asAttributeKey();
if (attributeKey != null) {
builder.put(attributeKey, value);
}
});
attributes = builder.build();
}
return attributes;
}
static ExtendedAttributes sortAndFilterToAttributes(Object... data) {
// null out any empty keys or keys with null values
// so they will then be removed by the sortAndFilter method.
for (int i = 0; i < data.length; i += 2) {
ExtendedAttributeKey<?> key = (ExtendedAttributeKey<?>) data[i];
if (key != null && key.getKey().isEmpty()) {
data[i] = null;
}
}
return new ArrayBackedExtendedAttributes(data, KEY_COMPARATOR_FOR_CONSTRUCTION);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
class ArrayBackedExtendedAttributesBuilder implements ExtendedAttributesBuilder {
private final List<Object> data;
ArrayBackedExtendedAttributesBuilder() {
data = new ArrayList<>();
}
ArrayBackedExtendedAttributesBuilder(List<Object> data) {
this.data = data;
}
@Override
public ExtendedAttributes build() {
// If only one key-value pair AND the entry hasn't been set to null (by #remove(AttributeKey<T>)
// or #removeIf(Predicate<AttributeKey<?>>)), then we can bypass sorting and filtering
if (data.size() == 2 && data.get(0) != null) {
return new ArrayBackedExtendedAttributes(data.toArray());
}
return ArrayBackedExtendedAttributes.sortAndFilterToAttributes(data.toArray());
}
@Override
public <T> ExtendedAttributesBuilder put(ExtendedAttributeKey<T> key, T value) {
if (key == null || key.getKey().isEmpty() || value == null) {
return this;
}
data.add(key);
data.add(value);
return this;
}
@Override
public ExtendedAttributesBuilder removeIf(Predicate<ExtendedAttributeKey<?>> predicate) {
if (predicate == null) {
return this;
}
for (int i = 0; i < data.size() - 1; i += 2) {
Object entry = data.get(i);
if (entry instanceof ExtendedAttributeKey
&& predicate.test((ExtendedAttributeKey<?>) entry)) {
// null items are filtered out in ArrayBackedAttributes
data.set(i, null);
data.set(i + 1, null);
}
}
return this;
}
static List<Double> toList(double... values) {
Double[] boxed = new Double[values.length];
for (int i = 0; i < values.length; i++) {
boxed[i] = values[i];
}
return Arrays.asList(boxed);
}
static List<Long> toList(long... values) {
Long[] boxed = new Long[values.length];
for (int i = 0; i < values.length; i++) {
boxed[i] = values[i];
}
return Arrays.asList(boxed);
}
static List<Boolean> toList(boolean... values) {
Boolean[] boxed = new Boolean[values.length];
for (int i = 0; i < values.length; i++) {
boxed[i] = values[i];
}
return Arrays.asList(boxed);
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.incubator.internal.InternalExtendedAttributeKeyImpl;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
* This interface provides a handle for setting the values of {@link ExtendedAttributes}. The type
* of value that can be set with an implementation of this key is denoted by the type parameter.
*
* <p>Implementations MUST be immutable, as these are used as the keys to Maps.
*
* <p>The allowed {@link #getType()}s is a superset of those allowed in {@link AttributeKey}.
*
* <p>Convenience methods are provided for translating to / from {@link AttributeKey}:
*
* <ul>
* <li>{@link #asAttributeKey()} converts from {@link ExtendedAttributeKey} to {@link
* AttributeKey}
* <li>{@link #fromAttributeKey(AttributeKey)} converts from {@link AttributeKey} to {@link
* ExtendedAttributeKey}
* </ul>
*
* @param <T> The type of value that can be set with the key.
*/
@Immutable
public interface ExtendedAttributeKey<T> {
/** Returns the underlying String representation of the key. */
String getKey();
/** Returns the type of attribute for this key. Useful for building switch statements. */
ExtendedAttributeType getType();
/**
* Return the equivalent {@link AttributeKey}, or {@code null} if the {@link #getType()} has no
* equivalent {@link io.opentelemetry.api.common.AttributeType}.
*/
@Nullable
default AttributeKey<T> asAttributeKey() {
return InternalExtendedAttributeKeyImpl.toAttributeKey(this);
}
/** Return an ExtendedAttributeKey equivalent to the {@code attributeKey}. */
// TODO (jack-berg): remove once AttributeKey.asExtendedAttributeKey is available
static <T> ExtendedAttributeKey<T> fromAttributeKey(AttributeKey<T> attributeKey) {
return InternalExtendedAttributeKeyImpl.toExtendedAttributeKey(attributeKey);
}
/** Returns a new ExtendedAttributeKey for String valued attributes. */
static ExtendedAttributeKey<String> stringKey(String key) {
return fromAttributeKey(AttributeKey.stringKey(key));
}
/** Returns a new ExtendedAttributeKey for Boolean valued attributes. */
static ExtendedAttributeKey<Boolean> booleanKey(String key) {
return fromAttributeKey(AttributeKey.booleanKey(key));
}
/** Returns a new ExtendedAttributeKey for Long valued attributes. */
static ExtendedAttributeKey<Long> longKey(String key) {
return fromAttributeKey(AttributeKey.longKey(key));
}
/** Returns a new ExtendedAttributeKey for Double valued attributes. */
static ExtendedAttributeKey<Double> doubleKey(String key) {
return fromAttributeKey(AttributeKey.doubleKey(key));
}
/** Returns a new ExtendedAttributeKey for List&lt;String&gt; valued attributes. */
static ExtendedAttributeKey<List<String>> stringArrayKey(String key) {
return fromAttributeKey(AttributeKey.stringArrayKey(key));
}
/** Returns a new ExtendedAttributeKey for List&lt;Boolean&gt; valued attributes. */
static ExtendedAttributeKey<List<Boolean>> booleanArrayKey(String key) {
return fromAttributeKey(AttributeKey.booleanArrayKey(key));
}
/** Returns a new ExtendedAttributeKey for List&lt;Long&gt; valued attributes. */
static ExtendedAttributeKey<List<Long>> longArrayKey(String key) {
return fromAttributeKey(AttributeKey.longArrayKey(key));
}
/** Returns a new ExtendedAttributeKey for List&lt;Double&gt; valued attributes. */
static ExtendedAttributeKey<List<Double>> doubleArrayKey(String key) {
return fromAttributeKey(AttributeKey.doubleArrayKey(key));
}
/** Returns a new ExtendedAttributeKey for Map valued attributes. */
static ExtendedAttributeKey<ExtendedAttributes> extendedAttributesKey(String key) {
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.EXTENDED_ATTRIBUTES);
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
/**
* An enum that represents all the possible value types for an {@link ExtendedAttributeKey} and
* hence the types of values that are allowed for {@link ExtendedAttributes}.
*
* <p>This is a superset of {@link io.opentelemetry.api.common.AttributeType},
*/
public enum ExtendedAttributeType {
// Types copied AttributeType
STRING,
BOOLEAN,
LONG,
DOUBLE,
STRING_ARRAY,
BOOLEAN_ARRAY,
LONG_ARRAY,
DOUBLE_ARRAY,
// Extended types unique to ExtendedAttributes
EXTENDED_ATTRIBUTES;
}

View File

@ -0,0 +1,103 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import java.util.Map;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
* An immutable container for extended attributes.
*
* <p>"extended" refers an extended set of allowed value types compared to standard {@link
* Attributes}. Notably, {@link ExtendedAttributes} values can be of type {@link
* ExtendedAttributeType#EXTENDED_ATTRIBUTES}, allowing nested {@link ExtendedAttributes} of
* arbitrary depth.
*
* <p>Where standard {@link Attributes} are accepted everyone that OpenTelemetry represents key /
* value pairs, {@link ExtendedAttributes} are only accepted in select places, such as log records
* (e.g. {@link ExtendedLogRecordBuilder#setAttribute(ExtendedAttributeKey, Object)}).
*
* <p>The keys are {@link ExtendedAttributeKey}s and the values are Object instances that match the
* type of the provided key.
*
* <p>Null keys will be silently dropped.
*
* <p>Note: The behavior of null-valued attributes is undefined, and hence strongly discouraged.
*
* <p>Implementations of this interface *must* be immutable and have well-defined value-based
* equals/hashCode implementations. If an implementation does not strictly conform to these
* requirements, behavior of the OpenTelemetry APIs and default SDK cannot be guaranteed.
*
* <p>For this reason, it is strongly suggested that you use the implementation that is provided
* here via the factory methods and the {@link ExtendedAttributesBuilder}.
*
* <p>Convenience methods are provided for translating to / from {@link Attributes}:
*
* <ul>
* <li>{@link #asAttributes()} converts from {@link ExtendedAttributes} to {@link Attributes}
* <li>{@link ExtendedAttributesBuilder#putAll(Attributes)} converts from {@link Attributes} to
* {@link ExtendedAttributes}
* <li>{@link #get(AttributeKey)} supports reading values using standard {@link AttributeKey}
* </ul>
*/
@Immutable
public interface ExtendedAttributes {
/** Returns the value for the given {@link AttributeKey}, or {@code null} if not found. */
@Nullable
default <T> T get(AttributeKey<T> key) {
if (key == null) {
return null;
}
return get(ExtendedAttributeKey.fromAttributeKey(key));
}
/** Returns the value for the given {@link ExtendedAttributeKey}, or {@code null} if not found. */
@Nullable
<T> T get(ExtendedAttributeKey<T> key);
/** Iterates over all the key-value pairs of attributes contained by this instance. */
void forEach(BiConsumer<? super ExtendedAttributeKey<?>, ? super Object> consumer);
/** The number of attributes contained in this. */
int size();
/** Whether there are any attributes contained in this. */
boolean isEmpty();
/** Returns a read-only view of this {@link ExtendedAttributes} as a {@link Map}. */
Map<ExtendedAttributeKey<?>, Object> asMap();
/**
* Return a view of this extended attributes with entries limited to those representable as
* standard attributes.
*/
Attributes asAttributes();
/** Returns a {@link ExtendedAttributes} instance with no attributes. */
static ExtendedAttributes empty() {
return ArrayBackedExtendedAttributes.EMPTY;
}
/**
* Returns a new {@link ExtendedAttributesBuilder} instance for creating arbitrary {@link
* ExtendedAttributes}.
*/
static ExtendedAttributesBuilder builder() {
return new ArrayBackedExtendedAttributesBuilder();
}
/**
* Returns a new {@link ExtendedAttributesBuilder} instance populated with the data of this {@link
* ExtendedAttributes}.
*/
ExtendedAttributesBuilder toBuilder();
}

View File

@ -0,0 +1,233 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
import static io.opentelemetry.api.incubator.common.ArrayBackedExtendedAttributesBuilder.toList;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.booleanArrayKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.booleanKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.doubleArrayKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.doubleKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.longArrayKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.longKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.stringArrayKey;
import static io.opentelemetry.api.incubator.common.ExtendedAttributeKey.stringKey;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/** A builder of {@link ExtendedAttributes} supporting an arbitrary number of key-value pairs. */
public interface ExtendedAttributesBuilder {
/** Create the {@link ExtendedAttributes} from this. */
ExtendedAttributes build();
/** Puts a {@link AttributeKey} with associated value into this. */
default <T> ExtendedAttributesBuilder put(AttributeKey<T> key, T value) {
if (key == null || key.getKey().isEmpty() || value == null) {
return this;
}
return put(ExtendedAttributeKey.fromAttributeKey(key), value);
}
/** Puts a {@link ExtendedAttributeKey} with associated value into this. */
<T> ExtendedAttributesBuilder put(ExtendedAttributeKey<T> key, T value);
/**
* Puts a String attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, String value) {
return put(stringKey(key), value);
}
/**
* Puts a long attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, long value) {
return put(longKey(key), value);
}
/**
* Puts a double attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, double value) {
return put(doubleKey(key), value);
}
/**
* Puts a boolean attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, boolean value) {
return put(booleanKey(key), value);
}
/**
* Puts a {@link ExtendedAttributes} attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default <T> ExtendedAttributesBuilder put(String key, ExtendedAttributes value) {
return put(ExtendedAttributeKey.extendedAttributesKey(key), value);
}
/**
* Puts a String array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, String... value) {
if (value == null) {
return this;
}
return put(stringArrayKey(key), Arrays.asList(value));
}
/**
* Puts a List attribute into this.
*
* @return this Builder
*/
@SuppressWarnings("unchecked")
default <T> ExtendedAttributesBuilder put(AttributeKey<List<T>> key, T... value) {
if (value == null) {
return this;
}
return put(key, Arrays.asList(value));
}
/**
* Puts a Long array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, long... value) {
if (value == null) {
return this;
}
return put(longArrayKey(key), toList(value));
}
/**
* Puts a Double array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, double... value) {
if (value == null) {
return this;
}
return put(doubleArrayKey(key), toList(value));
}
/**
* Puts a Boolean array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
default ExtendedAttributesBuilder put(String key, boolean... value) {
if (value == null) {
return this;
}
return put(booleanArrayKey(key), toList(value));
}
/**
* Puts all the provided attributes into this Builder.
*
* @return this Builder
*/
@SuppressWarnings({"unchecked"})
default ExtendedAttributesBuilder putAll(Attributes attributes) {
if (attributes == null) {
return this;
}
attributes.forEach((key, value) -> put((AttributeKey<Object>) key, value));
return this;
}
/**
* Puts all the provided attributes into this Builder.
*
* @return this Builder
*/
@SuppressWarnings({"unchecked"})
default ExtendedAttributesBuilder putAll(ExtendedAttributes attributes) {
if (attributes == null) {
return this;
}
attributes.forEach((key, value) -> put((ExtendedAttributeKey<Object>) key, value));
return this;
}
/**
* Remove all attributes where {@link AttributeKey#getKey()} and {@link AttributeKey#getType()}
* match the {@code key}.
*
* @return this Builder
*/
default <T> ExtendedAttributesBuilder remove(AttributeKey<T> key) {
return remove(ExtendedAttributeKey.fromAttributeKey(key));
}
/**
* Remove all attributes where {@link ExtendedAttributeKey#getKey()} and {@link
* ExtendedAttributeKey#getType()} match the {@code key}.
*
* @return this Builder
*/
default <T> ExtendedAttributesBuilder remove(ExtendedAttributeKey<T> key) {
if (key == null || key.getKey().isEmpty()) {
return this;
}
return removeIf(
entryKey ->
key.getKey().equals(entryKey.getKey()) && key.getType().equals(entryKey.getType()));
}
/**
* Remove all attributes that satisfy the given predicate. Errors or runtime exceptions thrown by
* the predicate are relayed to the caller.
*
* @return this Builder
*/
ExtendedAttributesBuilder removeIf(Predicate<ExtendedAttributeKey<?>> filter);
}

View File

@ -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.
*
* <p>The name <i>Provider</i> is for consistency with other languages and it is <b>NOT</b> loaded
* using reflection.
*
* <p>See {@link InstrumentationConfigUtil} for convenience methods for extracting config from
* {@link ConfigProvider}.
*/
@ThreadSafe
public interface ConfigProvider {
/**
* Returns the {@link DeclarativeConfigProperties} corresponding to <a
* href="https://github.com/open-telemetry/opentelemetry-configuration/blob/main/schema/instrumentation.json">instrumentation
* config</a>, or {@code null} if unavailable.
*
* @return the instrumentation {@link DeclarativeConfigProperties}
*/
@Nullable
DeclarativeConfigProperties getInstrumentationConfig();
/** Returns a no-op {@link ConfigProvider}. */
static ConfigProvider noop() {
return () -> null;
}
}

View File

@ -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);
}
}

View File

@ -3,20 +3,20 @@
* 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 io.opentelemetry.common.ComponentLoader;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
/**
* An interface for accessing structured configuration data.
* An interface for accessing declarative configuration data.
*
* <p>An instance of {@link StructuredConfigProperties} is equivalent to a <a
* <p>An instance of {@link DeclarativeConfigProperties} is equivalent to a <a
* href="https://yaml.org/spec/1.2.2/#3211-nodes">YAML mapping node</a>. 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 +25,29 @@ import javax.annotation.Nullable;
* <p>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.
*
* <p>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();
}
/** Return a map representation of the {@code declarativeConfigProperties}. */
static Map<String, Object> toMap(DeclarativeConfigProperties declarativeConfigProperties) {
return DeclarativeConfigPropertyUtil.toMap(declarativeConfigProperties);
}
/**
* 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 +57,7 @@ public interface StructuredConfigProperties {
*
* @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 +68,7 @@ public interface StructuredConfigProperties {
* {@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 +78,7 @@ public interface StructuredConfigProperties {
*
* @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 +91,7 @@ public interface StructuredConfigProperties {
* {@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 +104,7 @@ public interface StructuredConfigProperties {
*
* @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 +114,7 @@ public interface StructuredConfigProperties {
* 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 +124,7 @@ public interface StructuredConfigProperties {
*
* @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 +134,7 @@ public interface StructuredConfigProperties {
* 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 +144,7 @@ public interface StructuredConfigProperties {
*
* @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 +158,8 @@ public interface StructuredConfigProperties {
* @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
<T> List<T> getScalarList(String name, Class<T> scalarType);
@ -163,56 +168,58 @@ public interface StructuredConfigProperties {
* 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 <T> List<T> getScalarList(String name, Class<T> scalarType, List<T> 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<StructuredConfigProperties> getStructuredList(String name);
List<DeclarativeConfigProperties> 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<StructuredConfigProperties> getStructuredList(
String name, List<StructuredConfigProperties> defaultValue) {
default List<DeclarativeConfigProperties> getStructuredList(
String name, List<DeclarativeConfigProperties> defaultValue) {
return defaultIfNull(getStructuredList(name), defaultValue);
}
@ -222,4 +229,7 @@ public interface StructuredConfigProperties {
* @return the configuration property keys
*/
Set<String> getPropertyKeys();
/** Return a {@link ComponentLoader} that should be used to load SPIs. */
ComponentLoader getComponentLoader();
}

View File

@ -0,0 +1,126 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.config;
import static java.util.stream.Collectors.toList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import javax.annotation.Nullable;
final class DeclarativeConfigPropertyUtil {
private DeclarativeConfigPropertyUtil() {}
private static final List<BiFunction<String, DeclarativeConfigProperties, Object>>
valueResolvers =
Arrays.asList(
DeclarativeConfigPropertyUtil::getString,
DeclarativeConfigPropertyUtil::getBoolean,
DeclarativeConfigPropertyUtil::getLong,
DeclarativeConfigPropertyUtil::getDouble,
DeclarativeConfigPropertyUtil::getStringList,
DeclarativeConfigPropertyUtil::getBooleanList,
DeclarativeConfigPropertyUtil::getLongList,
DeclarativeConfigPropertyUtil::getDoubleList,
DeclarativeConfigPropertyUtil::getStringList,
DeclarativeConfigPropertyUtil::getStructuredList,
DeclarativeConfigPropertyUtil::getStructured);
static Map<String, Object> toMap(DeclarativeConfigProperties declarativeConfigProperties) {
Set<String> propertyKeys = declarativeConfigProperties.getPropertyKeys();
Map<String, Object> result = new HashMap<>(propertyKeys.size());
for (String key : declarativeConfigProperties.getPropertyKeys()) {
result.put(key, resolveValue(key, declarativeConfigProperties));
}
return result;
}
@Nullable
private static Object resolveValue(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
for (int i = 0; i < valueResolvers.size(); i++) {
try {
Object value = valueResolvers.get(i).apply(key, declarativeConfigProperties);
if (value != null) {
return value;
}
} catch (DeclarativeConfigException e) {
// Ignore and continue
}
}
return null;
}
@Nullable
private static Object getString(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getString(key);
}
@Nullable
private static Object getBoolean(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getBoolean(key);
}
@Nullable
private static Object getLong(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getLong(key);
}
@Nullable
private static Object getDouble(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getDouble(key);
}
@Nullable
private static Object getStringList(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getScalarList(key, String.class);
}
@Nullable
private static Object getBooleanList(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getScalarList(key, Boolean.class);
}
@Nullable
private static Object getLongList(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getScalarList(key, Long.class);
}
@Nullable
private static Object getDoubleList(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return declarativeConfigProperties.getScalarList(key, Double.class);
}
@Nullable
private static Object getStructuredList(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return Optional.ofNullable(declarativeConfigProperties.getStructuredList(key))
.map(list -> list.stream().map(DeclarativeConfigPropertyUtil::toMap).collect(toList()))
.orElse(null);
}
@Nullable
private static Object getStructured(
String key, DeclarativeConfigProperties declarativeConfigProperties) {
return Optional.ofNullable(declarativeConfigProperties.getStructured(key))
.map(DeclarativeConfigPropertyUtil::toMap)
.orElse(null);
}
}

View File

@ -3,22 +3,25 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure.spi.internal;
package io.opentelemetry.api.incubator.config;
import io.opentelemetry.common.ComponentLoader;
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 static final ComponentLoader COMPONENT_LOADER =
ComponentLoader.forClassLoader(EmptyDeclarativeConfigProperties.class.getClassLoader());
private EmptyStructuredConfigProperties() {}
private EmptyDeclarativeConfigProperties() {}
static EmptyStructuredConfigProperties getInstance() {
static EmptyDeclarativeConfigProperties getInstance() {
return INSTANCE;
}
@ -60,13 +63,13 @@ final class EmptyStructuredConfigProperties implements StructuredConfigPropertie
@Nullable
@Override
public StructuredConfigProperties getStructured(String name) {
public DeclarativeConfigProperties getStructured(String name) {
return null;
}
@Nullable
@Override
public List<StructuredConfigProperties> getStructuredList(String name) {
public List<DeclarativeConfigProperties> getStructuredList(String name) {
return null;
}
@ -74,4 +77,9 @@ final class EmptyStructuredConfigProperties implements StructuredConfigPropertie
public Set<String> getPropertyKeys() {
return Collections.emptySet();
}
@Override
public ComponentLoader getComponentLoader() {
return COMPONENT_LOADER;
}
}

View File

@ -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<ConfigProvider> 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());
}
}

View File

@ -0,0 +1,197 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.config;
import com.fasterxml.jackson.databind.ObjectMapper;
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<String, String> peerServiceMapping(ConfigProvider configProvider) {
List<DeclarativeConfigProperties> serviceMappingList =
getOrNull(
configProvider,
config -> config.getStructuredList("service_mapping"),
"general",
"peer");
if (serviceMappingList == null) {
return null;
}
Map<String, String> 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<String> 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<String> 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<String> 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<String> httpServerResponseCapturedHeaders(ConfigProvider configProvider) {
return getOrNull(
configProvider,
config -> config.getScalarList("response_captured_headers", String.class),
"general",
"http",
"server");
}
/**
* Return {@code .instrumentation.java.<instrumentationName>}, 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.
*
* <p>See other methods in {@link InstrumentationConfigUtil} for usage examples.
*/
@Nullable
public static <T> T getOrNull(
ConfigProvider configProvider,
Function<DeclarativeConfigProperties, T> 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() {}
/**
* Return {@code .instrumentation.java.<instrumentationName>}, after converting it to the {@code
* modelType} using the {@code objectMapper}. If no configuration exists for the {@code
* instrumentationName}, returns {@code null}.
*
* <p>This method is a convenience method for a common instrumentation library workflow:
*
* <ul>
* <li>During initialization, an instrumentation library is given an {@link ConfigProvider} and
* must initialize according to the relevant config
* <li>It checks if the user has provided configuration for it, and if so...
* <li>It converts the configuration to an in-memory model representing all of its relevant
* properties
* <li>It initializes using the strongly typed in-memory model
* </ul>
*
* <p>Conversion is done using {@link ObjectMapper#convertValue(Object, Class)} from {@code
* com.fasterxml.jackson.databind}, and assumes the {@code modelType} is a POJO written /
* annotated to support jackson databinding.
*
* <p>NOTE: callers MUST add their own dependency on {@code
* com.fasterxml.jackson.core:jackson-databind}. This module's dependency is {@code compileOnly}
* since jackson is a large dependency that many users will not require. It's very possible to
* convert between {@link DeclarativeConfigProperties} (or a map representation from {@link
* DeclarativeConfigProperties#toMap(DeclarativeConfigProperties)}) and a target model type
* without jackson. This method is provided as an optional convenience method.
*
* @throws IllegalArgumentException if conversion fails. See {@link
* ObjectMapper#convertValue(Object, Class)} for details.
*/
@Nullable
public static <T> T getInstrumentationConfigModel(
ConfigProvider configProvider,
String instrumentationName,
ObjectMapper objectMapper,
Class<T> modelType) {
DeclarativeConfigProperties properties =
javaInstrumentationConfig(configProvider, instrumentationName);
if (properties == null) {
return null;
}
Map<String, Object> configPropertiesMap = DeclarativeConfigProperties.toMap(properties);
return objectMapper.convertValue(configPropertiesMap, modelType);
}
}

View File

@ -0,0 +1,178 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.internal;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributeType;
import io.opentelemetry.api.incubator.common.ExtendedAttributeKey;
import io.opentelemetry.api.incubator.common.ExtendedAttributeType;
import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
import java.nio.charset.StandardCharsets;
import javax.annotation.Nullable;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class InternalExtendedAttributeKeyImpl<T> implements ExtendedAttributeKey<T> {
private final ExtendedAttributeType type;
private final String key;
private final int hashCode;
@Nullable private byte[] keyUtf8;
@Nullable private AttributeKey<T> attributeKey;
private InternalExtendedAttributeKeyImpl(ExtendedAttributeType type, String key) {
if (type == null) {
throw new NullPointerException("Null type");
}
this.type = type;
if (key == null) {
throw new NullPointerException("Null key");
}
this.key = key;
this.hashCode = buildHashCode(type, key);
}
public static <T> ExtendedAttributeKey<T> create(
@Nullable String key, ExtendedAttributeType type) {
return new InternalExtendedAttributeKeyImpl<>(type, key != null ? key : "");
}
@Override
public ExtendedAttributeType getType() {
return type;
}
@Override
public String getKey() {
return key;
}
@Nullable
@Override
public AttributeKey<T> asAttributeKey() {
if (attributeKey == null) {
attributeKey = toAttributeKey(this);
}
return attributeKey;
}
/** Returns the key, encoded as UTF-8 bytes. */
public byte[] getKeyUtf8() {
byte[] keyUtf8 = this.keyUtf8;
if (keyUtf8 == null) {
keyUtf8 = key.getBytes(StandardCharsets.UTF_8);
this.keyUtf8 = keyUtf8;
}
return keyUtf8;
}
@Override
public boolean equals(@Nullable Object o) {
if (o == this) {
return true;
}
if (o instanceof InternalExtendedAttributeKeyImpl) {
InternalExtendedAttributeKeyImpl<?> that = (InternalExtendedAttributeKeyImpl<?>) o;
return this.type.equals(that.getType()) && this.key.equals(that.getKey());
}
return false;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public String toString() {
return key;
}
// this method exists to make EqualsVerifier happy
@SuppressWarnings("unused")
private int buildHashCode() {
return buildHashCode(type, key);
}
private static int buildHashCode(ExtendedAttributeType type, String key) {
int result = 1;
result *= 1000003;
result ^= type.hashCode();
result *= 1000003;
result ^= key.hashCode();
return result;
}
/**
* Return the equivalent {@link AttributeKey} for the {@link ExtendedAttributeKey}, or {@code
* null} if the {@link #getType()} has no equivalent {@link
* io.opentelemetry.api.common.AttributeType}.
*/
@Nullable
public static <T> AttributeKey<T> toAttributeKey(ExtendedAttributeKey<T> extendedAttributeKey) {
switch (extendedAttributeKey.getType()) {
case STRING:
return InternalAttributeKeyImpl.create(extendedAttributeKey.getKey(), AttributeType.STRING);
case BOOLEAN:
return InternalAttributeKeyImpl.create(
extendedAttributeKey.getKey(), AttributeType.BOOLEAN);
case LONG:
return InternalAttributeKeyImpl.create(extendedAttributeKey.getKey(), AttributeType.LONG);
case DOUBLE:
return InternalAttributeKeyImpl.create(extendedAttributeKey.getKey(), AttributeType.DOUBLE);
case STRING_ARRAY:
return InternalAttributeKeyImpl.create(
extendedAttributeKey.getKey(), AttributeType.STRING_ARRAY);
case BOOLEAN_ARRAY:
return InternalAttributeKeyImpl.create(
extendedAttributeKey.getKey(), AttributeType.BOOLEAN_ARRAY);
case LONG_ARRAY:
return InternalAttributeKeyImpl.create(
extendedAttributeKey.getKey(), AttributeType.LONG_ARRAY);
case DOUBLE_ARRAY:
return InternalAttributeKeyImpl.create(
extendedAttributeKey.getKey(), AttributeType.DOUBLE_ARRAY);
case EXTENDED_ATTRIBUTES:
return null;
}
throw new IllegalArgumentException(
"Unrecognized extendedAttributeKey type: " + extendedAttributeKey.getType());
}
/** Return the equivalent {@link ExtendedAttributeKey} for the {@link AttributeKey}. */
public static <T> ExtendedAttributeKey<T> toExtendedAttributeKey(AttributeKey<T> attributeKey) {
switch (attributeKey.getType()) {
case STRING:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.STRING);
case BOOLEAN:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.BOOLEAN);
case LONG:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.LONG);
case DOUBLE:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.DOUBLE);
case STRING_ARRAY:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.STRING_ARRAY);
case BOOLEAN_ARRAY:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.BOOLEAN_ARRAY);
case LONG_ARRAY:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.LONG_ARRAY);
case DOUBLE_ARRAY:
return InternalExtendedAttributeKeyImpl.create(
attributeKey.getKey(), ExtendedAttributeType.DOUBLE_ARRAY);
}
throw new IllegalArgumentException("Unrecognized attributeKey type: " + attributeKey.getType());
}
}

View File

@ -7,12 +7,13 @@ 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.incubator.common.ExtendedAttributeKey;
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;
import javax.annotation.Nullable;
class ExtendedDefaultLogger implements ExtendedLogger {
@ -26,6 +27,11 @@ class ExtendedDefaultLogger implements ExtendedLogger {
return INSTANCE;
}
@Override
public boolean isEnabled(Severity severity, Context context) {
return false;
}
@Override
public ExtendedLogRecordBuilder logRecordBuilder() {
return NOOP_LOG_RECORD_BUILDER;
@ -41,52 +47,62 @@ class ExtendedDefaultLogger implements ExtendedLogger {
}
@Override
public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
public ExtendedLogRecordBuilder setException(Throwable throwable) {
return this;
}
@Override
public LogRecordBuilder setTimestamp(Instant instant) {
public <T> ExtendedLogRecordBuilder setAttribute(ExtendedAttributeKey<T> key, T value) {
return this;
}
@Override
public LogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) {
public <T> ExtendedLogRecordBuilder setAttribute(AttributeKey<T> key, @Nullable T value) {
return this;
}
@Override
public LogRecordBuilder setObservedTimestamp(Instant instant) {
public ExtendedLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
return this;
}
@Override
public LogRecordBuilder setContext(Context context) {
public ExtendedLogRecordBuilder setTimestamp(Instant instant) {
return this;
}
@Override
public LogRecordBuilder setSeverity(Severity severity) {
public ExtendedLogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) {
return this;
}
@Override
public LogRecordBuilder setSeverityText(String severityText) {
public ExtendedLogRecordBuilder setObservedTimestamp(Instant instant) {
return this;
}
@Override
public LogRecordBuilder setBody(String body) {
public ExtendedLogRecordBuilder setContext(Context context) {
return this;
}
@Override
public LogRecordBuilder setBody(Value<?> body) {
public ExtendedLogRecordBuilder setSeverity(Severity severity) {
return this;
}
@Override
public <T> LogRecordBuilder setAttribute(AttributeKey<T> key, T value) {
public ExtendedLogRecordBuilder setSeverityText(String severityText) {
return this;
}
@Override
public ExtendedLogRecordBuilder setBody(String body) {
return this;
}
@Override
public ExtendedLogRecordBuilder setBody(Value<?> body) {
return this;
}

View File

@ -5,18 +5,134 @@
package io.opentelemetry.api.incubator.logs;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.Value;
import io.opentelemetry.api.incubator.common.ExtendedAttributeKey;
import io.opentelemetry.api.incubator.common.ExtendedAttributes;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
/** Extended {@link LogRecordBuilder} with experimental APIs. */
public interface ExtendedLogRecordBuilder extends LogRecordBuilder {
// keep this class even if it is empty, since experimental methods may be added in the future.
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setTimestamp(Instant instant);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setObservedTimestamp(Instant instant);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setContext(Context context);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setSeverity(Severity severity);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setSeverityText(String severityText);
/** {@inheritDoc} */
@Override
ExtendedLogRecordBuilder setBody(String body);
/** {@inheritDoc} */
@Override
default ExtendedLogRecordBuilder setBody(Value<?> body) {
setBody(body.asString());
return this;
}
/**
* Sets the event name, which identifies the class / type of the Event.
*
* <p>This name should uniquely identify the event structure (both attributes and body). A log
* record with a non-empty event name is an Event.
*/
@Override
ExtendedLogRecordBuilder setEventName(String eventName);
/**
* {@inheritDoc}
*
* <p>NOTE: all standard {@link AttributeKey}-value pairs can also be represented as {@link
* ExtendedAttributeKey}-value pairs, but not all {@link ExtendedAttributeKey}-value pairs can be
* represented as standard {@link AttributeKey}-value pairs. From the standpoint of the emitted
* log record, there is no difference between adding attributes using the standard or extended
* attribute APIs.
*/
@SuppressWarnings("unchecked")
@Override
default ExtendedLogRecordBuilder setAllAttributes(Attributes attributes) {
if (attributes == null || attributes.isEmpty()) {
return this;
}
attributes.forEach(
(attributeKey, value) -> setAttribute((AttributeKey<Object>) attributeKey, value));
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.
*
* <p>NOTE: all standard {@link AttributeKey}-value pairs can also be represented as {@link
* ExtendedAttributeKey}-value pairs, but not all {@link ExtendedAttributeKey}-value pairs can be
* represented as standard {@link AttributeKey}-value pairs. From the standpoint of the emitted
* log record, there is no difference between adding attributes using the standard or extended
* attribute APIs.
*/
@SuppressWarnings("unchecked")
default ExtendedLogRecordBuilder setAllAttributes(ExtendedAttributes attributes) {
if (attributes == null || attributes.isEmpty()) {
return this;
}
attributes.forEach(
(attributeKey, value) -> setAttribute((ExtendedAttributeKey<Object>) attributeKey, value));
return this;
}
/**
* {@inheritDoc}
*
* <p>NOTE: all standard {@link AttributeKey}-value pairs can also be represented as {@link
* ExtendedAttributeKey}-value pairs, but not all {@link ExtendedAttributeKey}-value pairs can be
* represented as standard {@link AttributeKey}-value pairs. From the standpoint of the emitted
* log record, there is no difference between adding attributes using the standard or extended
* attribute APIs.
*/
@Override
<T> ExtendedLogRecordBuilder setAttribute(AttributeKey<T> key, @Nullable T value);
/**
* Set an attribute.
*
* <p>NOTE: all standard {@link AttributeKey}-value pairs can also be represented as {@link
* ExtendedAttributeKey}-value pairs, but not all {@link ExtendedAttributeKey}-value pairs can be
* represented as standard {@link AttributeKey}-value pairs. From the standpoint of the emitted
* log record, there is no difference between adding attributes using the standard or extended
* attribute APIs.
*/
<T> ExtendedLogRecordBuilder setAttribute(ExtendedAttributeKey<T> key, T value);
/** Set standard {@code exception.*} attributes based on the {@code throwable}. */
ExtendedLogRecordBuilder setException(Throwable throwable);
}

View File

@ -6,21 +6,41 @@
package io.opentelemetry.api.incubator.logs;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
/** Extended {@link Logger} with experimental APIs. */
public interface ExtendedLogger extends Logger {
/**
* Returns {@code true} if the logger is enabled.
* Returns {@code true} if the logger is enabled for the given {@code context} and {@code
* severity}.
*
* <p>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() {
default boolean isEnabled(Severity severity, Context context) {
return true;
}
/** Overload of {@link #isEnabled(Severity, Context)} assuming {@link Context#current()}. */
default boolean isEnabled(Severity severity) {
return isEnabled(severity, Context.current());
}
/**
* Overload of {@link #isEnabled(Severity, Context)} assuming {@link
* Severity#UNDEFINED_SEVERITY_NUMBER} and {@link Context#current()}.
*
* @deprecated for removal after 1.55.0. Use {@link #isEnabled(Severity, Context)} or {@link
* #isEnabled(Severity)} instead.
*/
@Deprecated
default boolean isEnabled() {
return isEnabled(Severity.UNDEFINED_SEVERITY_NUMBER);
}
@Override
ExtendedLogRecordBuilder logRecordBuilder();
}

View File

@ -94,6 +94,11 @@ class ExtendedDefaultMeter implements Meter {
private ExtendedDefaultMeter() {}
private static class NoopLongCounter implements ExtendedLongCounter {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void add(long value, Attributes attributes, Context context) {}
@ -105,6 +110,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopDoubleCounter implements ExtendedDoubleCounter {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void add(double value, Attributes attributes, Context context) {}
@ -186,6 +196,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopLongUpDownCounter implements ExtendedLongUpDownCounter {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void add(long value, Attributes attributes, Context context) {}
@ -197,6 +212,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopDoubleUpDownCounter implements ExtendedDoubleUpDownCounter {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void add(double value, Attributes attributes, Context context) {}
@ -281,6 +301,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopDoubleHistogram implements ExtendedDoubleHistogram {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void record(double value, Attributes attributes, Context context) {}
@ -292,6 +317,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopLongHistogram implements ExtendedLongHistogram {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void record(long value, Attributes attributes, Context context) {}
@ -385,6 +415,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopDoubleGauge implements ExtendedDoubleGauge {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void set(double value) {}
@ -426,6 +461,11 @@ class ExtendedDefaultMeter implements Meter {
}
private static class NoopLongGauge implements ExtendedLongGauge {
@Override
public boolean isEnabled() {
return false;
}
@Override
public void set(long value) {}

View File

@ -31,6 +31,11 @@ final class ExtendedDefaultTracer implements ExtendedTracer {
return INSTANCE;
}
@Override
public boolean isEnabled() {
return false;
}
@Override
public ExtendedSpanBuilder spanBuilder(String spanName) {
return NoopSpanBuilder.create();

View File

@ -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);
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.AttributeKey;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class ExtendedAttributeKeyTest {
@ParameterizedTest
@MethodSource("attributeKeyArgs")
void test(
ExtendedAttributeKey<?> key,
String expectedKey,
ExtendedAttributeType expectedType,
@Nullable AttributeKey<?> expectedAttributeKey) {
assertThat(key.getKey()).isEqualTo(expectedKey);
assertThat(key.getType()).isEqualTo(expectedType);
assertThat(key.asAttributeKey()).isEqualTo(expectedAttributeKey);
if (expectedAttributeKey != null) {
ExtendedAttributeKey<?> extendedAttributeKey =
ExtendedAttributeKey.fromAttributeKey(expectedAttributeKey);
assertThat(extendedAttributeKey).isEqualTo(key);
}
}
private static Stream<Arguments> attributeKeyArgs() {
return Stream.of(
Arguments.of(
ExtendedAttributeKey.stringKey("key"),
"key",
ExtendedAttributeType.STRING,
AttributeKey.stringKey("key")),
Arguments.of(
ExtendedAttributeKey.booleanKey("key"),
"key",
ExtendedAttributeType.BOOLEAN,
AttributeKey.booleanKey("key")),
Arguments.of(
ExtendedAttributeKey.longKey("key"),
"key",
ExtendedAttributeType.LONG,
AttributeKey.longKey("key")),
Arguments.of(
ExtendedAttributeKey.doubleKey("key"),
"key",
ExtendedAttributeType.DOUBLE,
AttributeKey.doubleKey("key")),
Arguments.of(
ExtendedAttributeKey.stringArrayKey("key"),
"key",
ExtendedAttributeType.STRING_ARRAY,
AttributeKey.stringArrayKey("key")),
Arguments.of(
ExtendedAttributeKey.booleanArrayKey("key"),
"key",
ExtendedAttributeType.BOOLEAN_ARRAY,
AttributeKey.booleanArrayKey("key")),
Arguments.of(
ExtendedAttributeKey.longArrayKey("key"),
"key",
ExtendedAttributeType.LONG_ARRAY,
AttributeKey.longArrayKey("key")),
Arguments.of(
ExtendedAttributeKey.doubleArrayKey("key"),
"key",
ExtendedAttributeType.DOUBLE_ARRAY,
AttributeKey.doubleArrayKey("key")),
Arguments.of(
ExtendedAttributeKey.extendedAttributesKey("key"),
"key",
ExtendedAttributeType.EXTENDED_ATTRIBUTES,
null));
}
}

View File

@ -0,0 +1,360 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.common;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 ExtendedAttributesTest {
@ParameterizedTest
@MethodSource("attributesArgs")
void get_ExtendedAttributeKey(
ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
expectedMap.forEach(
(key, value) -> {
ExtendedAttributeKey<?> extendedAttributeKey = getKey(key, value);
Object actualValue = extendedAttributes.get(extendedAttributeKey);
if (actualValue instanceof ExtendedAttributes) {
Map<String, Object> mapValue = toMap((ExtendedAttributes) actualValue);
actualValue = mapValue;
}
assertThat(actualValue)
.describedAs(key + "(" + extendedAttributeKey.getType() + ")")
.isEqualTo(value);
});
}
@ParameterizedTest
@MethodSource("attributesArgs")
void get_AttributeKey(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
expectedMap.forEach(
(key, value) -> {
ExtendedAttributeKey<?> extendedAttributeKey = getKey(key, value);
AttributeKey<?> attributeKey = extendedAttributeKey.asAttributeKey();
// Skip attribute keys which cannot be represented as AttributeKey
if (attributeKey == null) {
return;
}
Object actualValue = extendedAttributes.get(attributeKey);
assertThat(actualValue)
.describedAs(key + "(" + attributeKey.getType() + ")")
.isEqualTo(value);
});
}
@ParameterizedTest
@MethodSource("attributesArgs")
void forEach(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
// toMap uses .forEach to convert
Map<String, Object> seenEntries = toMap(extendedAttributes);
assertThat(seenEntries).isEqualTo(expectedMap);
}
@ParameterizedTest
@MethodSource("attributesArgs")
void size(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
assertThat(extendedAttributes.size()).isEqualTo(expectedMap.size());
}
@ParameterizedTest
@MethodSource("attributesArgs")
void isEmpty(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
assertThat(extendedAttributes.isEmpty()).isEqualTo(expectedMap.isEmpty());
}
@ParameterizedTest
@MethodSource("attributesArgs")
void asMap(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
assertEquals(extendedAttributes.asMap(), expectedMap);
}
@SuppressWarnings("unchecked")
private static void assertEquals(
Map<ExtendedAttributeKey<?>, Object> actual, Map<String, Object> expected) {
assertThat(actual.size()).isEqualTo(expected.size());
actual.forEach(
(key, value) -> {
if (key.getType() == ExtendedAttributeType.EXTENDED_ATTRIBUTES) {
assertEquals(
((ExtendedAttributes) value).asMap(),
(Map<String, Object>) expected.get(key.getKey()));
return;
}
assertThat(expected.get(key.getKey())).isEqualTo(value);
});
}
@ParameterizedTest
@MethodSource("attributesArgs")
void asAttributes(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
Attributes attributes = extendedAttributes.asAttributes();
attributes.forEach(
(key, value) -> {
assertThat(value).isEqualTo(expectedMap.get(key.getKey()));
});
long expectedSize =
expectedMap.values().stream().filter(value -> !(value instanceof Map)).count();
assertThat(attributes.size()).isEqualTo(expectedSize);
}
@ParameterizedTest
@MethodSource("attributesArgs")
void toBuilder(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
ExtendedAttributesBuilder builder = extendedAttributes.toBuilder();
builder.put("extraKey", "value");
ExtendedAttributes extendedAttributes1 = builder.build();
assertThat(extendedAttributes1.size()).isEqualTo(expectedMap.size() + 1);
ExtendedAttributes extendedAttributes2 =
extendedAttributes1.toBuilder().remove(ExtendedAttributeKey.stringKey("extraKey")).build();
assertThat(extendedAttributes2).isEqualTo(extendedAttributes);
assertThat(extendedAttributes2.size()).isEqualTo(expectedMap.size());
}
@ParameterizedTest
@MethodSource("attributesArgs")
void equalsAndHashcode(ExtendedAttributes extendedAttributes, Map<String, Object> expectedMap) {
ExtendedAttributes withExtraEntry =
extendedAttributes.toBuilder().put("extraKey", "value").build();
assertThat(extendedAttributes).isNotEqualTo(withExtraEntry);
assertThat(extendedAttributes.hashCode()).isNotEqualTo(withExtraEntry.hashCode());
ExtendedAttributes copy1 =
extendedAttributes.toBuilder().remove(ExtendedAttributeKey.stringKey("extraKey")).build();
assertThat(extendedAttributes).isEqualTo(copy1);
assertThat(extendedAttributes.hashCode()).isEqualTo(copy1.hashCode());
ExtendedAttributes copy2 = fromMap(expectedMap);
assertThat(extendedAttributes).isEqualTo(copy2);
assertThat(extendedAttributes.hashCode()).isEqualTo(copy2.hashCode());
}
@SuppressWarnings("unchecked")
private static ExtendedAttributes fromMap(Map<String, Object> map) {
ExtendedAttributesBuilder builder = ExtendedAttributes.builder();
map.forEach(
(key, value) -> {
ExtendedAttributeKey<?> extendedAttributeKey = getKey(key, value);
if (extendedAttributeKey.getType() == ExtendedAttributeType.EXTENDED_ATTRIBUTES) {
builder.put(
(ExtendedAttributeKey<ExtendedAttributes>) extendedAttributeKey,
fromMap((Map<String, Object>) value));
return;
}
putInBuilder((ExtendedAttributeKey<Object>) extendedAttributeKey, value, builder);
});
return builder.build();
}
private static void putInBuilder(
ExtendedAttributeKey<Object> key, Object value, ExtendedAttributesBuilder builder) {
builder.put(key, value);
}
private static Stream<Arguments> attributesArgs() {
return Stream.of(
// Single entry attributes
Arguments.of(ExtendedAttributes.builder().build(), Collections.emptyMap()),
Arguments.of(
ExtendedAttributes.builder().put("key", "value").build(),
ImmutableMap.builder().put("key", "value").build()),
Arguments.of(
ExtendedAttributes.builder().put("key", true).build(),
ImmutableMap.builder().put("key", true).build()),
Arguments.of(
ExtendedAttributes.builder().put("key", 1L).build(),
ImmutableMap.builder().put("key", 1L).build()),
Arguments.of(
ExtendedAttributes.builder().put("key", 1.1).build(),
ImmutableMap.builder().put("key", 1.1).build()),
Arguments.of(
ExtendedAttributes.builder().put("key", "value1", "value2").build(),
ImmutableMap.builder().put("key", Arrays.asList("value1", "value2")).build()),
Arguments.of(
ExtendedAttributes.builder().put("key", true, false).build(),
ImmutableMap.builder().put("key", Arrays.asList(true, false)).build()),
Arguments.of(
ExtendedAttributes.builder().put("key", 1L, 2L).build(),
ImmutableMap.builder().put("key", Arrays.asList(1L, 2L)).build()),
Arguments.of(
ExtendedAttributes.builder().put("key", 1.1, 2.2).build(),
ImmutableMap.builder().put("key", Arrays.asList(1.1, 2.2)).build()),
Arguments.of(
ExtendedAttributes.builder()
.put("key", ExtendedAttributes.builder().put("child", "value").build())
.build(),
ImmutableMap.builder()
.put("key", ImmutableMap.builder().put("child", "value").build())
.build()),
Arguments.of(
ExtendedAttributes.builder()
.put(ExtendedAttributeKey.stringKey("key"), "value")
.build(),
ImmutableMap.builder().put("key", "value").build()),
Arguments.of(
ExtendedAttributes.builder().put(ExtendedAttributeKey.booleanKey("key"), true).build(),
ImmutableMap.builder().put("key", true).build()),
Arguments.of(
ExtendedAttributes.builder().put(ExtendedAttributeKey.longKey("key"), 1L).build(),
ImmutableMap.builder().put("key", 1L).build()),
Arguments.of(
ExtendedAttributes.builder().put(ExtendedAttributeKey.doubleKey("key"), 1.1).build(),
ImmutableMap.builder().put("key", 1.1).build()),
Arguments.of(
ExtendedAttributes.builder()
.put(ExtendedAttributeKey.stringArrayKey("key"), Arrays.asList("value1", "value2"))
.build(),
ImmutableMap.builder().put("key", Arrays.asList("value1", "value2")).build()),
Arguments.of(
ExtendedAttributes.builder()
.put(ExtendedAttributeKey.booleanArrayKey("key"), Arrays.asList(true, false))
.build(),
ImmutableMap.builder().put("key", Arrays.asList(true, false)).build()),
Arguments.of(
ExtendedAttributes.builder()
.put(ExtendedAttributeKey.longArrayKey("key"), Arrays.asList(1L, 2L))
.build(),
ImmutableMap.builder().put("key", Arrays.asList(1L, 2L)).build()),
Arguments.of(
ExtendedAttributes.builder()
.put(ExtendedAttributeKey.doubleArrayKey("key"), Arrays.asList(1.1, 2.2))
.build(),
ImmutableMap.builder().put("key", Arrays.asList(1.1, 2.2)).build()),
Arguments.of(
ExtendedAttributes.builder()
.put(
ExtendedAttributeKey.extendedAttributesKey("key"),
ExtendedAttributes.builder().put("child", "value").build())
.build(),
ImmutableMap.builder()
.put("key", ImmutableMap.builder().put("child", "value").build())
.build()),
// Multiple entries
Arguments.of(
ExtendedAttributes.builder()
.put("key1", "value1")
.put("key2", "value2")
.put("key3", true)
.put("key4", 1L)
.put("key5", 1.1)
.put("key6", "value1", "value2")
.put("key7", true, false)
.put("key8", 1L, 2L)
.put("key9", 1.1, 2.2)
.put("key10", ExtendedAttributes.builder().put("child", "value").build())
.build(),
ImmutableMap.builder()
.put("key1", "value1")
.put("key2", "value2")
.put("key3", true)
.put("key4", 1L)
.put("key5", 1.1)
.put("key6", Arrays.asList("value1", "value2"))
.put("key7", Arrays.asList(true, false))
.put("key8", Arrays.asList(1L, 2L))
.put("key9", Arrays.asList(1.1, 2.2))
.put("key10", ImmutableMap.builder().put("child", "value").build())
.build()));
}
private static Map<String, Object> toMap(ExtendedAttributes extendedAttributes) {
Map<String, Object> map = new HashMap<>();
extendedAttributes.forEach(
(key, value) -> {
if (key.getType() == ExtendedAttributeType.EXTENDED_ATTRIBUTES) {
map.put(key.getKey(), toMap((ExtendedAttributes) value));
return;
}
map.put(key.getKey(), value);
});
return map;
}
private static ExtendedAttributeKey<?> getKey(String key, Object value) {
switch (getType(value)) {
case STRING:
return ExtendedAttributeKey.stringKey(key);
case BOOLEAN:
return ExtendedAttributeKey.booleanKey(key);
case LONG:
return ExtendedAttributeKey.longKey(key);
case DOUBLE:
return ExtendedAttributeKey.doubleKey(key);
case STRING_ARRAY:
return ExtendedAttributeKey.stringArrayKey(key);
case BOOLEAN_ARRAY:
return ExtendedAttributeKey.booleanArrayKey(key);
case LONG_ARRAY:
return ExtendedAttributeKey.longArrayKey(key);
case DOUBLE_ARRAY:
return ExtendedAttributeKey.doubleArrayKey(key);
case EXTENDED_ATTRIBUTES:
return ExtendedAttributeKey.extendedAttributesKey(key);
}
throw new IllegalArgumentException();
}
@SuppressWarnings("unchecked")
private static ExtendedAttributeType getType(Object value) {
if (value instanceof String) {
return ExtendedAttributeType.STRING;
}
if (value instanceof Boolean) {
return ExtendedAttributeType.BOOLEAN;
}
if ((value instanceof Long) || (value instanceof Integer)) {
return ExtendedAttributeType.LONG;
}
if ((value instanceof Double) || (value instanceof Float)) {
return ExtendedAttributeType.DOUBLE;
}
if (value instanceof List) {
List<Object> list = (List<Object>) value;
if (list.isEmpty()) {
throw new IllegalArgumentException("Empty list");
}
if (list.get(0) instanceof String) {
return ExtendedAttributeType.STRING_ARRAY;
}
if (list.get(0) instanceof Boolean) {
return ExtendedAttributeType.BOOLEAN_ARRAY;
}
if ((list.get(0) instanceof Long) || (list.get(0) instanceof Integer)) {
return ExtendedAttributeType.LONG_ARRAY;
}
if ((list.get(0) instanceof Double) || (list.get(0) instanceof Float)) {
return ExtendedAttributeType.DOUBLE_ARRAY;
}
}
if ((value instanceof Map)) {
return ExtendedAttributeType.EXTENDED_ATTRIBUTES;
}
throw new IllegalArgumentException("Unrecognized value type: " + value);
}
}

View File

@ -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");
}
}

View File

@ -0,0 +1,170 @@
/*
* 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 <a
* href="https://github.com/open-telemetry/opentelemetry-configuration/blob/main/examples/kitchen-sink.yaml">kitchen-sink.yaml</a>.
*/
private static final String kitchenSinkInstrumentationConfig =
"instrumentation/development:\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/development:\n");
private static final ConfigProvider emptyGeneralConfigProvider =
toConfigProvider("instrumentation/development:\n general:\n");
private static final ConfigProvider emptyHttpConfigProvider =
toConfigProvider("instrumentation/development:\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.httpServerResponseCapturedHeaders(kitchenSinkConfigProvider))
.isEqualTo(Arrays.asList("server-response-header1", "server-response-header2"));
assertThat(
InstrumentationConfigUtil.httpServerResponseCapturedHeaders(
emptyInstrumentationConfigProvider))
.isNull();
assertThat(
InstrumentationConfigUtil.httpServerResponseCapturedHeaders(emptyGeneralConfigProvider))
.isNull();
assertThat(InstrumentationConfigUtil.httpServerResponseCapturedHeaders(emptyHttpConfigProvider))
.isNull();
}
@Test
void javaInstrumentationConfig() {
assertThat(
InstrumentationConfigUtil.javaInstrumentationConfig(
kitchenSinkConfigProvider, "example"))
.isNotNull()
.isInstanceOfSatisfying(
YamlDeclarativeConfigProperties.class,
exampleConfig ->
assertThat(DeclarativeConfigProperties.toMap(exampleConfig))
.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();
}
}

View File

@ -10,7 +10,9 @@ import static org.assertj.core.api.Assertions.assertThat;
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.api.testing.internal.AbstractDefaultLoggerTest;
import io.opentelemetry.context.Context;
import org.junit.jupiter.api.Test;
class ExtendedDefaultLoggerTest extends AbstractDefaultLoggerTest {
@ -26,10 +28,18 @@ class ExtendedDefaultLoggerTest extends AbstractDefaultLoggerTest {
}
@Test
@SuppressWarnings("deprecation") // testing deprecated code
void incubatingApiIsLoaded() {
Logger logger = LoggerProvider.noop().get("test");
assertThat(logger).isInstanceOf(ExtendedLogger.class);
assertThat(logger)
.isInstanceOfSatisfying(
ExtendedLogger.class,
extendedLogger -> {
assertThat(extendedLogger.isEnabled(Severity.ERROR, Context.current())).isFalse();
assertThat(extendedLogger.isEnabled(Severity.ERROR)).isFalse();
assertThat(extendedLogger.isEnabled()).isFalse();
});
ExtendedLogRecordBuilder builder = (ExtendedLogRecordBuilder) logger.logRecordBuilder();
assertThat(builder).isInstanceOf(ExtendedLogRecordBuilder.class);
assertThat(builder.setBody(Value.of(0))).isSameAs(builder);

View File

@ -9,19 +9,31 @@ 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 io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.incubator.common.ExtendedAttributeKey;
import io.opentelemetry.api.incubator.common.ExtendedAttributes;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.junit.jupiter.api.Test;
/** Demonstrating usage of extended Logs Bridge API. */
class ExtendedLogsBridgeApiUsageTest {
private static final java.util.logging.Logger logger =
java.util.logging.Logger.getLogger(ExtendedLogsBridgeApiUsageTest.class.getName());
@Test
void loggerEnabled() {
// Setup SdkLoggerProvider
@ -42,24 +54,26 @@ class ExtendedLogsBridgeApiUsageTest {
ExtendedLogger loggerB = (ExtendedLogger) loggerProvider.get("loggerB");
// Check if logger is enabled before emitting log and avoid unnecessary computation
if (loggerA.isEnabled()) {
if (loggerA.isEnabled(Severity.INFO)) {
loggerA
.logRecordBuilder()
.setSeverity(Severity.INFO)
.setBody("hello world!")
.setAllAttributes(Attributes.builder().put("result", flipCoin()).build())
.emit();
}
if (loggerB.isEnabled()) {
if (loggerB.isEnabled(Severity.INFO)) {
loggerB
.logRecordBuilder()
.setSeverity(Severity.INFO)
.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();
assertThat(loggerA.isEnabled(Severity.INFO)).isTrue();
assertThat(loggerB.isEnabled(Severity.INFO)).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
@ -76,4 +90,148 @@ class ExtendedLogsBridgeApiUsageTest {
private static String flipCoin() {
return random.nextBoolean() ? "heads" : "tails";
}
// Primitive keys
AttributeKey<String> strKey = AttributeKey.stringKey("acme.string");
AttributeKey<Long> longKey = AttributeKey.longKey("acme.long");
AttributeKey<Boolean> booleanKey = AttributeKey.booleanKey("acme.boolean");
AttributeKey<Double> doubleKey = AttributeKey.doubleKey("acme.double");
// Primitive array keys
AttributeKey<List<String>> strArrKey = AttributeKey.stringArrayKey("acme.string_array");
AttributeKey<List<Long>> longArrKey = AttributeKey.longArrayKey("acme.long_array");
AttributeKey<List<Boolean>> booleanArrKey = AttributeKey.booleanArrayKey("acme.boolean_array");
AttributeKey<List<Double>> doubleArrKey = AttributeKey.doubleArrayKey("acme.double_array");
// Extended keys
ExtendedAttributeKey<ExtendedAttributes> mapKey =
ExtendedAttributeKey.extendedAttributesKey("acme.map");
@Test
@SuppressLogger(ExtendedLogsBridgeApiUsageTest.class)
void extendedAttributesUsage() {
// Initialize from builder. Varargs style initialization (ExtendedAttributes.of(...) not
// supported.
ExtendedAttributes extendedAttributes =
ExtendedAttributes.builder()
.put(strKey, "value")
.put(longKey, 1L)
.put(booleanKey, true)
.put(doubleKey, 1.1)
.put(strArrKey, Arrays.asList("value1", "value2"))
.put(longArrKey, Arrays.asList(1L, 2L))
.put(booleanArrKey, Arrays.asList(true, false))
.put(doubleArrKey, Arrays.asList(1.1, 2.2))
.put(
mapKey,
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build())
.build();
// Retrieval
assertThat(extendedAttributes.get(strKey)).isEqualTo("value");
assertThat(extendedAttributes.get(longKey)).isEqualTo(1);
assertThat(extendedAttributes.get(booleanKey)).isEqualTo(true);
assertThat(extendedAttributes.get(doubleKey)).isEqualTo(1.1);
assertThat(extendedAttributes.get(strArrKey)).isEqualTo(Arrays.asList("value1", "value2"));
assertThat(extendedAttributes.get(longArrKey)).isEqualTo(Arrays.asList(1L, 2L));
assertThat(extendedAttributes.get(booleanArrKey)).isEqualTo(Arrays.asList(true, false));
assertThat(extendedAttributes.get(doubleArrKey)).isEqualTo(Arrays.asList(1.1, 2.2));
assertThat(extendedAttributes.get(mapKey))
.isEqualTo(
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build());
// Iteration
// Output:
// acme.boolean(BOOLEAN): true
// acme.boolean_array(BOOLEAN_ARRAY): [true, false]
// acme.double(DOUBLE): 1.1
// acme.double_array(DOUBLE_ARRAY): [1.1, 2.2]
// acme.long(LONG): 1
// acme.long_array(LONG_ARRAY): [1, 2]
// acme.map(EXTENDED_ATTRIBUTES): {childLong=1, childStr="value"}
// acme.string(STRING): value
// acme.string_array(STRING_ARRAY): [value1, value2]
extendedAttributes.forEach(
(extendedAttributeKey, object) ->
logger.info(
String.format(
"%s(%s): %s",
extendedAttributeKey.getKey(), extendedAttributeKey.getType(), object)));
}
@Test
@SuppressWarnings("deprecation") // testing deprecated code
void logRecordBuilder_ExtendedAttributes() {
InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create();
SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter))
.build();
Logger logger = loggerProvider.get("logger");
// Can set either standard or extended attributes on
((ExtendedLogRecordBuilder) logger.logRecordBuilder())
.setBody("message")
.setAttribute(strKey, "value")
.setAttribute(longKey, 1L)
.setAttribute(booleanKey, true)
.setAttribute(doubleKey, 1.1)
.setAttribute(strArrKey, Arrays.asList("value1", "value2"))
.setAttribute(longArrKey, Arrays.asList(1L, 2L))
.setAttribute(booleanArrKey, Arrays.asList(true, false))
.setAttribute(doubleArrKey, Arrays.asList(1.1, 2.2))
.setAttribute(
mapKey,
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build())
.setAllAttributes(Attributes.builder().put("key1", "value").build())
.setAllAttributes(ExtendedAttributes.builder().put("key2", "value").build())
.emit();
assertThat(exporter.getFinishedLogRecordItems())
.satisfiesExactly(
logRecordData -> {
assertThat(logRecordData).isInstanceOf(ExtendedLogRecordData.class);
ExtendedLogRecordData extendedLogRecordData = (ExtendedLogRecordData) logRecordData;
// Optionally access standard attributes, which filters out any extended attribute
// types
assertThat(extendedLogRecordData.getAttributes())
.isEqualTo(
Attributes.builder()
.put(strKey, "value")
.put(longKey, 1L)
.put(booleanKey, true)
.put(doubleKey, 1.1)
.put(strArrKey, Arrays.asList("value1", "value2"))
.put(longArrKey, Arrays.asList(1L, 2L))
.put(booleanArrKey, Arrays.asList(true, false))
.put(doubleArrKey, Arrays.asList(1.1, 2.2))
.put("key1", "value")
.put("key2", "value")
.build());
// But preferably access and serialize full extended attributes
assertThat(extendedLogRecordData.getExtendedAttributes())
.isEqualTo(
ExtendedAttributes.builder()
.put(strKey, "value")
.put(longKey, 1L)
.put(booleanKey, true)
.put(doubleKey, 1.1)
.put(strArrKey, Arrays.asList("value1", "value2"))
.put(longArrKey, Arrays.asList(1L, 2L))
.put(booleanArrKey, Arrays.asList(true, false))
.put(doubleArrKey, Arrays.asList(1.1, 2.2))
.put(
mapKey,
ExtendedAttributes.builder()
.put("childStr", "value")
.put("childLong", 1L)
.build())
.put("key1", "value")
.put("key2", "value")
.build());
});
}
}

View File

@ -11,7 +11,6 @@ import io.opentelemetry.api.OpenTelemetry;
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;
class ExtendedDefaultMeterTest extends AbstractDefaultMeterTest {
@ -27,44 +26,53 @@ class ExtendedDefaultMeterTest extends AbstractDefaultMeterTest {
}
@Test
public void incubatingApiIsLoaded() {
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);
assertThat(meter.gaugeBuilder("test").ofLongs()).isInstanceOf(ExtendedLongGaugeBuilder.class);
assertThat(meter.gaugeBuilder("test").ofLongs().build())
.isInstanceOfSatisfying(
ExtendedLongGauge.class, instrument -> assertThat(instrument.isEnabled()).isFalse());
assertThat(meter.gaugeBuilder("test")).isInstanceOf(ExtendedDoubleGaugeBuilder.class);
assertThat(meter.gaugeBuilder("test").build())
.isInstanceOfSatisfying(
ExtendedDoubleGauge.class, instrument -> assertThat(instrument.isEnabled()).isFalse());
Assertions.assertThat(meter.histogramBuilder("test").ofLongs())
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);
assertThat(meter.histogramBuilder("test").ofLongs().build())
.isInstanceOfSatisfying(
ExtendedLongHistogram.class,
instrument -> assertThat(instrument.isEnabled()).isFalse());
assertThat(meter.histogramBuilder("test")).isInstanceOf(ExtendedDoubleHistogramBuilder.class);
assertThat(meter.histogramBuilder("test").build())
.isInstanceOfSatisfying(
ExtendedDoubleHistogram.class,
instrument -> assertThat(instrument.isEnabled()).isFalse());
Assertions.assertThat(meter.counterBuilder("test"))
.isInstanceOf(ExtendedLongCounterBuilder.class);
Assertions.assertThat(meter.counterBuilder("test").build())
.isInstanceOf(ExtendedLongCounter.class);
Assertions.assertThat(meter.counterBuilder("test").ofDoubles())
assertThat(meter.counterBuilder("test")).isInstanceOf(ExtendedLongCounterBuilder.class);
assertThat(meter.counterBuilder("test").build())
.isInstanceOfSatisfying(
ExtendedLongCounter.class, instrument -> assertThat(instrument.isEnabled()).isFalse());
assertThat(meter.counterBuilder("test").ofDoubles())
.isInstanceOf(ExtendedDoubleCounterBuilder.class);
Assertions.assertThat(meter.counterBuilder("test").ofDoubles().build())
.isInstanceOf(ExtendedDoubleCounter.class);
assertThat(meter.counterBuilder("test").ofDoubles().build())
.isInstanceOfSatisfying(
ExtendedDoubleCounter.class,
instrument -> assertThat(instrument.isEnabled()).isFalse());
Assertions.assertThat(meter.upDownCounterBuilder("test"))
assertThat(meter.upDownCounterBuilder("test"))
.isInstanceOf(ExtendedLongUpDownCounterBuilder.class);
Assertions.assertThat(meter.upDownCounterBuilder("test").build())
.isInstanceOf(ExtendedLongUpDownCounter.class);
Assertions.assertThat(meter.upDownCounterBuilder("test").ofDoubles())
assertThat(meter.upDownCounterBuilder("test").build())
.isInstanceOfSatisfying(
ExtendedLongUpDownCounter.class,
instrument -> assertThat(instrument.isEnabled()).isFalse());
assertThat(meter.upDownCounterBuilder("test").ofDoubles())
.isInstanceOf(ExtendedDoubleUpDownCounterBuilder.class);
Assertions.assertThat(meter.upDownCounterBuilder("test").ofDoubles().build())
.isInstanceOf(ExtendedDoubleUpDownCounter.class);
assertThat(meter.upDownCounterBuilder("test").ofDoubles().build())
.isInstanceOfSatisfying(
ExtendedDoubleUpDownCounter.class,
instrument -> assertThat(instrument.isEnabled()).isFalse());
}
}

View File

@ -6,6 +6,8 @@
package io.opentelemetry.api.incubator.trace;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.testing.internal.AbstractDefaultTracerTest;
@ -27,17 +29,20 @@ class ExtendedDefaultTracerTest extends AbstractDefaultTracerTest {
}
@Test
public void incubatingApiIsLoaded() {
void incubatingApiIsLoaded() {
Tracer tracer = TracerProvider.noop().get("test");
assertThat(tracer).isSameAs(OpenTelemetry.noop().getTracer("test"));
assertThat(tracer).isInstanceOf(ExtendedTracer.class);
assertThat(tracer)
.isInstanceOfSatisfying(
ExtendedTracer.class,
extendedTracer -> assertThat(extendedTracer.isEnabled()).isFalse());
assertThat(tracer.spanBuilder("test")).isInstanceOf(ExtendedSpanBuilder.class);
}
@SuppressWarnings("unchecked")
@Test
public void incubatingApi() {
void incubatingApi() {
ExtendedSpanBuilder spanBuilder =
(ExtendedSpanBuilder) ExtendedDefaultTracer.getNoop().spanBuilder("test");
assertThat(spanBuilder.setParentFrom(null, null)).isSameAs(spanBuilder);
@ -45,21 +50,21 @@ class ExtendedDefaultTracerTest extends AbstractDefaultTracerTest {
SpanRunnable<RuntimeException> spanRunnable = Mockito.mock(SpanRunnable.class);
spanBuilder.startAndRun(spanRunnable);
Mockito.verify(spanRunnable).runInSpan();
Mockito.reset(spanRunnable);
verify(spanRunnable).runInSpan();
reset(spanRunnable);
spanBuilder.startAndRun(spanRunnable, null);
Mockito.verify(spanRunnable).runInSpan();
Mockito.reset(spanRunnable);
verify(spanRunnable).runInSpan();
reset(spanRunnable);
SpanCallable<String, RuntimeException> spanCallable = Mockito.mock(SpanCallable.class);
spanBuilder.startAndCall(spanCallable);
Mockito.verify(spanCallable).callInSpan();
Mockito.reset(spanCallable);
verify(spanCallable).callInSpan();
reset(spanCallable);
spanBuilder.startAndCall(spanCallable, null);
Mockito.verify(spanCallable).callInSpan();
Mockito.reset(spanCallable);
verify(spanCallable).callInSpan();
reset(spanCallable);
}
}

View File

@ -0,0 +1,259 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator;
import static org.assertj.core.api.Assertions.assertThat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.incubator.config.ConfigProvider;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil;
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.Test;
class InstrumentationConfigUtilTest {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Test
void toMap_RoundTrip() throws JsonProcessingException {
Map<String, Object> map = new HashMap<>();
map.put("string", "val");
map.put("boolean", true);
map.put("long", 1L);
map.put("double", 1.1);
map.put("null", null);
map.put("stringList", Arrays.asList("val1", "val2"));
map.put("boolList", Arrays.asList(true, false));
map.put("longList", Arrays.asList(1L, 2L));
map.put("doubleList", Arrays.asList(1.1d, 2.2d));
map.put(
"structuredList", Collections.singletonList(Collections.singletonMap("childKey", "val")));
map.put("emptyList", Collections.emptyList());
map.put("structured", Collections.singletonMap("childKey", "val"));
map.put("emptyStructured", Collections.emptyMap());
String mapJson = MAPPER.writeValueAsString(map);
DeclarativeConfigProperties properties =
DeclarativeConfiguration.toConfigProperties(
new ByteArrayInputStream(mapJson.getBytes(StandardCharsets.UTF_8)));
assertThat(DeclarativeConfigProperties.toMap(properties)).isEqualTo(map);
}
@Test
void getInstrumentationConfigModel_UnsetConfig() {
ConfigProvider configProvider = () -> null;
assertThat(
InstrumentationConfigUtil.getInstrumentationConfigModel(
configProvider, "my_instrumentation_library", MAPPER, Model.class))
.isEqualTo(null);
}
@Test
void getInstrumentationConfigModel_EmptyConfig() {
ConfigProvider configProvider =
withInstrumentationConfig("my_instrumentation_library", Collections.emptyMap());
assertThat(
InstrumentationConfigUtil.getInstrumentationConfigModel(
configProvider, "my_instrumentation_library", MAPPER, Model.class))
.isEqualTo(new Model());
}
@Test
void getInstrumentationConfigModel_KitchenSink() {
ConfigProvider configProvider =
withInstrumentationConfig(
"my_instrumentation_library",
ImmutableMap.<String, Object>builder()
.put("string_property", "value")
.put("boolean_property", true)
.put("long_property", 1L)
.put("double_property", 1.1d)
.put("string_list_property", Arrays.asList("val1", "val2"))
.put("boolean_list_property", Arrays.asList(true, false))
.put("long_list_property", Arrays.asList(1L, 2L))
.put("double_list_property", Arrays.asList(1.1d, 2.2d))
.put("map_property", Collections.singletonMap("childKey", "val"))
.put(
"structured_list_property",
Collections.singletonList(
ImmutableMap.of("key", "the_key", "value", "the_value")))
.build());
Model expected = new Model();
expected.stringProperty = "value";
expected.booleanProperty = true;
expected.longProperty = 1L;
expected.doubleProperty = 1.1d;
expected.stringListProperty = Arrays.asList("val1", "val2");
expected.booleanListProperty = Arrays.asList(true, false);
expected.longListProperty = Arrays.asList(1L, 2L);
expected.doubleListProperty = Arrays.asList(1.1d, 2.2d);
expected.mapProperty = Collections.singletonMap("childKey", "val");
ListEntryModel listEntryModel = new ListEntryModel();
listEntryModel.key = "the_key";
listEntryModel.value = "the_value";
expected.structuredListProperty = Collections.singletonList(listEntryModel);
assertThat(
InstrumentationConfigUtil.getInstrumentationConfigModel(
configProvider, "my_instrumentation_library", MAPPER, Model.class))
.isEqualTo(expected);
}
private static ConfigProvider withInstrumentationConfig(
String instrumentationName, Map<String, Object> instrumentationConfig) {
ExperimentalLanguageSpecificInstrumentationModel javaConfig =
new ExperimentalLanguageSpecificInstrumentationModel();
javaConfig.setAdditionalProperty(instrumentationName, instrumentationConfig);
return SdkConfigProvider.create(
new OpenTelemetryConfigurationModel()
.withInstrumentationDevelopment(new InstrumentationModel().withJava(javaConfig)));
}
private static class Model {
@JsonProperty("string_property")
private String stringProperty;
@JsonProperty("boolean_property")
private Boolean booleanProperty;
@JsonProperty("long_property")
private Long longProperty;
@JsonProperty("double_property")
private Double doubleProperty;
@JsonProperty("string_list_property")
private List<String> stringListProperty;
@JsonProperty("boolean_list_property")
private List<Boolean> booleanListProperty;
@JsonProperty("long_list_property")
private List<Long> longListProperty;
@JsonProperty("double_list_property")
private List<Double> doubleListProperty;
;
@JsonProperty("map_property")
private Map<String, Object> mapProperty;
@JsonProperty("structured_list_property")
private List<ListEntryModel> structuredListProperty;
@Override
public boolean equals(Object o) {
if (!(o instanceof Model)) {
return false;
}
Model model = (Model) o;
return Objects.equals(stringProperty, model.stringProperty)
&& Objects.equals(booleanProperty, model.booleanProperty)
&& Objects.equals(longProperty, model.longProperty)
&& Objects.equals(doubleProperty, model.doubleProperty)
&& Objects.equals(stringListProperty, model.stringListProperty)
&& Objects.equals(booleanListProperty, model.booleanListProperty)
&& Objects.equals(longListProperty, model.longListProperty)
&& Objects.equals(doubleListProperty, model.doubleListProperty)
&& Objects.equals(mapProperty, model.mapProperty)
&& Objects.equals(structuredListProperty, model.structuredListProperty);
}
@Override
public int hashCode() {
return Objects.hash(
stringProperty,
booleanProperty,
longProperty,
doubleProperty,
stringListProperty,
booleanListProperty,
longListProperty,
doubleListProperty,
mapProperty,
structuredListProperty);
}
@Override
public String toString() {
return "Model{"
+ "stringProperty='"
+ stringProperty
+ '\''
+ ", booleanProperty='"
+ booleanProperty
+ '\''
+ ", longProperty='"
+ longProperty
+ '\''
+ ", doubleProperty='"
+ doubleProperty
+ '\''
+ ", stringListProperty="
+ stringListProperty
+ ", booleanListProperty="
+ booleanListProperty
+ ", longListProperty="
+ longListProperty
+ ", doubleListProperty="
+ doubleListProperty
+ ", mapProperty="
+ mapProperty
+ ", structuredListProperty="
+ structuredListProperty
+ '}';
}
}
private static final class ListEntryModel {
@JsonProperty("key")
private String key;
@JsonProperty("value")
private String value;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
ListEntryModel that = (ListEntryModel) o;
return Objects.equals(key, that.key) && Objects.equals(value, that.value);
}
@Override
public int hashCode() {
return Objects.hash(key, value);
}
@Override
public String toString() {
return "ListEntryModel{" + "key='" + key + '\'' + ", value='" + value + '\'' + '}';
}
}
}

View File

@ -51,8 +51,7 @@ public abstract class AbstractDefaultLoggerTest {
() ->
getLogger()
.logRecordBuilder()
// TODO (trask) once event name stabilizes
// .setEventName("event name")
.setEventName("event name")
.setTimestamp(100, TimeUnit.SECONDS)
.setTimestamp(Instant.now())
.setObservedTimestamp(100, TimeUnit.SECONDS)

View File

@ -25,7 +25,7 @@ import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import org.junit.jupiter.api.Test;
/** Unit tests for No-op {@link Meter}. */
@SuppressLogger()
@SuppressLogger
public abstract class AbstractDefaultMeterTest {
private final Meter meter = getMeter();

View File

@ -12,7 +12,10 @@ nexusPublishing {
packageGroup.set("io.opentelemetry")
repositories {
// see https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#configuration
sonatype {
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
username.set(System.getenv("SONATYPE_USER"))
password.set(System.getenv("SONATYPE_KEY"))
}

View File

@ -2,7 +2,7 @@ plugins {
`kotlin-dsl`
// When updating, update below in dependencies too
id("com.diffplug.spotless") version "7.0.2"
id("com.diffplug.spotless") version "7.2.1"
}
if (!hasLauncherForJavaVersion(17)) {
@ -50,24 +50,23 @@ repositories {
}
dependencies {
implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.1"))
implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.3.5"))
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")
// Needed for japicmp but not automatically brought in for some reason.
implementation("com.google.guava:guava:33.4.0-jre")
implementation("com.diffplug.spotless:spotless-plugin-gradle:7.2.1")
implementation("com.gradle.develocity:com.gradle.develocity.gradle.plugin:4.1")
implementation("com.squareup:javapoet:1.13.0")
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.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-errorprone-plugin:4.3.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("ru.vyarus:gradle-animalsniffer-plugin:2.0.0")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0")
implementation("org.owasp:dependency-check-gradle:12.1.3")
implementation("ru.vyarus:gradle-animalsniffer-plugin:2.0.1")
}
// We can't apply conventions to this build so include important ones such as the Java compilation

View File

@ -50,7 +50,6 @@ tasks {
disable("UnnecessarilyFullyQualified")
// We use animal sniffer
disable("Java7ApiChecker")
disable("Java8ApiChecker")
disable("AndroidJdkLibsChecker")
@ -87,6 +86,10 @@ tasks {
// cognitive load is dubious.
disable("YodaCondition")
// We annotate packages with @ParametersAreNonnullByDefault from com.google.code.findbugs:jsr305.
// @NullMarked is the equivalent from jspecify.
disable("AddNullMarkedToPackageInfo")
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")

View File

@ -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

View File

@ -142,6 +142,7 @@ if (!project.hasProperty("otel.release") && !project.name.startsWith("bom")) {
// Temporarily suppress warnings from public generated classes from :sdk-extensions:jaeger-remote-sampler
"io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2"
)
annotationExcludes.add("@kotlin.Metadata")
val baseVersionString = if (apiBaseVersion == null) "latest" else baselineVersion
txtOutputFile.set(
apiNewVersion?.let { file("$rootDir/docs/apidiffs/${apiNewVersion}_vs_$baselineVersion/${base.archivesName.get()}.txt") }

View File

@ -42,7 +42,7 @@ java {
checkstyle {
configDirectory.set(file("$rootDir/buildscripts/"))
toolVersion = "10.21.2"
toolVersion = "10.26.1"
isIgnoreFailures = false
configProperties["rootDir"] = rootDir
}
@ -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)
@ -113,6 +114,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

12
common/build.gradle.kts Normal file
View File

@ -0,0 +1,12 @@
plugins {
id("otel.java-conventions")
id("otel.publish-conventions")
id("otel.animalsniffer-conventions")
}
description = "OpenTelemetry API Common"
otelJava.moduleName.set("io.opentelemetry.common")
dependencies {
}

View File

@ -0,0 +1,28 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.common;
import java.util.ServiceLoader;
/** A loader for components that are discovered via SPI. */
public interface ComponentLoader {
/**
* Load implementations of an SPI.
*
* @param spiClass the SPI class
* @param <T> the SPI type
* @return iterable of SPI implementations
*/
<T> Iterable<T> load(Class<T> spiClass);
/**
* Create an instance for the {@code classLoader} using {@link ServiceLoader#load(Class,
* ClassLoader)}.
*/
static ComponentLoader forClassLoader(ClassLoader classLoader) {
return new ServiceLoaderComponentLoader(classLoader);
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.common;
import java.util.ServiceLoader;
class ServiceLoaderComponentLoader implements ComponentLoader {
private final ClassLoader classLoader;
ServiceLoaderComponentLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public <T> Iterable<T> load(Class<T> spiClass) {
return ServiceLoader.load(spiClass, classLoader);
}
@Override
public String toString() {
return "ServiceLoaderComponentLoader{classLoader=" + classLoader + "}";
}
}

View File

@ -10,6 +10,7 @@ description = "OpenTelemetry Context (Incubator)"
otelJava.moduleName.set("io.opentelemetry.context")
dependencies {
api(project(":common"))
// MustBeClosed
compileOnly("com.google.errorprone:error_prone_annotations")

View File

@ -268,6 +268,9 @@ public interface Context {
* making this the {@linkplain Context#current() current context} before each execution.
*/
default ExecutorService wrap(ExecutorService executor) {
if (executor instanceof ContextExecutorService) {
return executor;
}
return new ContextExecutorService(this, executor);
}
@ -277,6 +280,9 @@ public interface Context {
* execution.
*/
default ScheduledExecutorService wrap(ScheduledExecutorService executor) {
if (executor instanceof ContextScheduledExecutorService) {
return executor;
}
return new ContextScheduledExecutorService(this, executor);
}

View File

@ -16,7 +16,7 @@ package io.opentelemetry.context;
* private static final ContextKey<MyState> KEY = ContextKey.named("MyState");
*
* public Context startWork() {
* return Context.withValues(KEY, new MyState());
* return Context.with(KEY, new MyState());
* }
*
* public void continueWork(Context context) {

View File

@ -37,9 +37,9 @@
package io.opentelemetry.context;
import io.opentelemetry.common.ComponentLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.logging.Level;
@ -103,8 +103,10 @@ final class LazyStorage {
return ContextStorage.defaultStorage();
}
ComponentLoader componentLoader =
ComponentLoader.forClassLoader(LazyStorage.class.getClassLoader());
List<ContextStorageProvider> providers = new ArrayList<>();
for (ContextStorageProvider provider : ServiceLoader.load(ContextStorageProvider.class)) {
for (ContextStorageProvider provider : componentLoader.load(ContextStorageProvider.class)) {
if (provider
.getClass()
.getName()
@ -127,7 +129,8 @@ final class LazyStorage {
deferredStorageFailure.set(
new IllegalStateException(
"Found multiple ContextStorageProvider. Set the "
+ "io.opentelemetry.context.ContextStorageProvider property to the fully "
+ CONTEXT_STORAGE_PROVIDER_PROPERTY
+ " property to the fully "
+ "qualified class name of the provider to use. Falling back to default "
+ "ContextStorage. Found providers: "
+ providers));
@ -142,7 +145,8 @@ final class LazyStorage {
deferredStorageFailure.set(
new IllegalStateException(
"io.opentelemetry.context.ContextStorageProvider property set but no matching class "
CONTEXT_STORAGE_PROVIDER_PROPERTY
+ " property set but no matching class "
+ "could be found, requested: "
+ providerClassName
+ " but found providers: "

View File

@ -5,6 +5,8 @@
package io.opentelemetry.context.propagation;
import java.util.Collections;
import java.util.Iterator;
import javax.annotation.Nullable;
/**
@ -33,4 +35,24 @@ public interface TextMapGetter<C> {
*/
@Nullable
String get(@Nullable C carrier, String key);
/**
* If implemented, returns all values for a given {@code key} in order, or returns an empty list.
*
* <p>The default method returns the first value of the given propagation {@code key} as a
* singleton list, or returns an empty list.
*
* @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}.
* @since 1.50.0
*/
default Iterator<String> getAll(@Nullable C carrier, String key) {
String first = get(carrier, key);
if (first == null) {
return Collections.emptyIterator();
}
return Collections.singleton(first).iterator();
}
}

View File

@ -6,39 +6,16 @@
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.
* Extended {@link TextMapGetter} with experimental APIs.
*
* <p>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 <C> carrier of propagation fields, such as an http request.
*/
public interface ExtendedTextMapGetter<C> extends TextMapGetter<C> {
/**
* If implemented, returns all values for a given {@code key} in order, or returns an empty list.
*
* <p>The default method returns the first value of the given propagation {@code key} as a
* singleton list, or returns an empty list.
*
* <p>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<String> getAll(@Nullable C carrier, String key) {
String first = get(carrier, key);
if (first == null) {
return Collections.emptyIterator();
}
return Collections.singleton(first).iterator();
}
// keep this class even if it is empty, since experimental methods may be added in the future.
}

View File

@ -7,6 +7,7 @@ package io.opentelemetry.context;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doNothing;
@ -108,6 +109,12 @@ class ContextTest {
assertThat(Context.current().get(ANIMAL)).isNull();
}
@Test
void keyEqualityIsInstanceCheck() {
Context context = Context.current().with(ContextKey.named("animal"), "cat");
assertNull(context.get(ContextKey.named("animal"))); // yup
}
@Test
void newThreadStartsWithRoot() throws Exception {
Context context = Context.current().with(ANIMAL, "cat");
@ -361,6 +368,24 @@ class ContextTest {
}
}
@Test
void wrapExecutorService() {
// given
ExecutorService executorService = Executors.newSingleThreadExecutor();
// when
ExecutorService firstWrap = CAT.wrap(executorService);
ExecutorService secondWrap = CAT.wrap(firstWrap);
// then
assertThat(firstWrap).isInstanceOf(ContextExecutorService.class);
assertThat(((ContextExecutorService) firstWrap).context()).isEqualTo(CAT);
assertThat(((ContextExecutorService) firstWrap).delegate()).isEqualTo(executorService);
assertThat(secondWrap).isInstanceOf(ContextExecutorService.class);
assertThat(((ContextExecutorService) secondWrap).context()).isEqualTo(CAT);
assertThat(((ContextExecutorService) secondWrap).delegate()).isEqualTo(executorService);
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
class WrapExecutorService {
@ -504,6 +529,25 @@ class ContextTest {
}
}
@Test
void wrapScheduledExecutorService() {
// given
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
// when
ScheduledExecutorService firstWrap = CAT.wrap(executorService);
ScheduledExecutorService secondWrap = CAT.wrap(firstWrap);
// then
assertThat(firstWrap).isInstanceOf(ContextScheduledExecutorService.class);
assertThat(((ContextScheduledExecutorService) firstWrap).context()).isEqualTo(CAT);
assertThat(((ContextScheduledExecutorService) firstWrap).delegate()).isEqualTo(executorService);
assertThat(secondWrap).isInstanceOf(ContextScheduledExecutorService.class);
assertThat(((ContextScheduledExecutorService) secondWrap).context()).isEqualTo(CAT);
assertThat(((ContextScheduledExecutorService) secondWrap).delegate())
.isEqualTo(executorService);
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
class WrapScheduledExecutorService {

View File

@ -3,11 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.context.propagation.internal;
package io.opentelemetry.context.propagation;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import com.google.common.collect.ImmutableList;
import io.opentelemetry.context.propagation.internal.ExtendedTextMapGetter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@ -15,9 +16,9 @@ import java.util.List;
import javax.annotation.Nullable;
import org.junit.jupiter.api.Test;
class ExtendedTextMapGetterTest {
class TextMapGetterTest {
final ExtendedTextMapGetter<Void> nullGet =
final TextMapGetter<Void> nullGet =
new ExtendedTextMapGetter<Void>() {
@Override
public Iterable<String> keys(Void carrier) {
@ -31,7 +32,7 @@ class ExtendedTextMapGetterTest {
}
};
final ExtendedTextMapGetter<Void> nonNullGet =
final TextMapGetter<Void> nonNullGet =
new ExtendedTextMapGetter<Void>() {
@Override
public Iterable<String> keys(Void carrier) {

View File

@ -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")
}
@ -80,3 +80,8 @@ configurations {
}
}
}
// Skip OWASP dependencyCheck task on test module
dependencyCheck {
skip = true
}

View File

@ -11,14 +11,48 @@ import org.junit.jupiter.api.Test;
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();
}
}

View File

@ -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 {}
}

Some files were not shown because too many files have changed in this diff Show More