Compare commits

..

1 Commits

Author SHA1 Message Date
OpenTelemetry Bot a3e7f51425
[release/v1.37.x] Prepare release 1.37.0 (#6355) 2024-04-05 13:02:49 -05:00
1356 changed files with 12822 additions and 51623 deletions

View File

@ -1,8 +0,0 @@
# 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"

View File

@ -11,7 +11,7 @@ coverage:
status:
project:
default:
target: 89%
target: 90%
paths:
- "!opencensus-shim/"
- "!opentracing-shim/"

View File

@ -1,40 +0,0 @@
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

@ -0,0 +1,7 @@
{
"retryOn429": true,
"aliveStatusCodes": [
200,
403
]
}

View File

@ -1,85 +1,36 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: [
'config:best-practices',
'helpers:pinGitHubActionDigestsToSemver',
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
],
packageRules: [
{
// 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$/',
},
"packageRules": [
{
// 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+
matchUpdateTypes: [
'major',
],
enabled: false,
matchPackageNames: [
'org.mockito:{/,}**',
],
"matchPackagePrefixes": ["org.mockito:"],
"matchUpdateTypes": ["major"],
"enabled": false
},
{
// 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
},
{
groupName: 'spotless packages',
matchPackageNames: [
'com.diffplug.spotless{/,}**',
],
},
{
// equals verifier v4+ requires java 17+
groupName: 'nl.jqno.equalsverifier',
matchPackageNames: [ 'equalsverifier'],
matchUpdateTypes: [ 'major' ],
enabled: false
"matchPackagePrefixes": ["com.diffplug.spotless"],
"groupName": "spotless packages"
}
],
]
}

View File

@ -1,24 +1,74 @@
# Repository settings
This document describes any changes that have been made to the
settings in this repository outside the settings tracked in the
private admin repo.
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
### `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)
## Secrets and variables > Actions
- `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`
* `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password
* `GPG_PRIVATE_KEY` - stored in OpenTelemetry-Java 1Password
* `GRADLE_ENTERPRISE_ACCESS_KEY` - owned by [@jack-berg](https://github.com/jack-berg)
* Generated at https://ge.opentelemetry.io > My settings > Access keys
* format of env var is `ge.opentelemetry.io=<access key>`,
see [docs](https://docs.gradle.com/enterprise/gradle-plugin/#via_environment_variable)
* `SONATYPE_KEY` - owned by [@jack-berg](https://github.com/jack-berg)
* `SONATYPE_USER` - owned by [@jack-berg](https://github.com/jack-berg)

View File

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

View File

@ -1,22 +0,0 @@
version=$(.github/scripts/get-version.sh)
if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
patch="${BASH_REMATCH[3]}"
else
echo "unexpected version: $version"
exit 1
fi
if [[ $patch == 0 ]]; then
if [[ $minor == 0 ]]; then
prior_major=$((major - 1))
prior_minor=$(grep -Po "^## Version $prior_major.\K[0-9]+" CHANGELOG.md | head -1)
prior_version="$prior_major.$prior_minor"
else
prior_version="$major.$((minor - 1)).0"
fi
else
prior_version="$major.$minor.$((patch - 1))"
fi
echo $prior_version

View File

@ -0,0 +1,17 @@
#!/bin/bash -e
# this script helps to reduce sporadic link check failures by retrying at a file-by-file level
retry_count=3
for file in "$@"; do
for i in $(seq 1 $retry_count); do
if markdown-link-check --config "$(dirname "$0")/../config/markdown-link-check-config.json" \
"$file"; then
break
elif [[ $i -eq $retry_count ]]; then
exit 1
fi
sleep 5
done
done

View File

@ -1,8 +0,0 @@
#!/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 otelbot
git config user.email 197425009+otelbot@users.noreply.github.com
git config user.name opentelemetrybot
git config user.email 107717825+opentelemetrybot@users.noreply.github.com

View File

@ -6,13 +6,8 @@ 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: |
@ -21,7 +16,7 @@ jobs:
exit 1
fi
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
# history is needed to run git cherry-pick below
fetch-depth: 0
@ -29,22 +24,16 @@ 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: ${{ steps.otelbot-token.outputs.token }}
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
commit=$(gh pr view $NUMBER --json mergeCommit --jq .mergeCommit.oid)
title=$(gh pr view $NUMBER --json title --jq .title)
branch="otelbot/backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
branch="opentelemetrybot/backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
git checkout -b $branch
git cherry-pick $commit

View File

@ -3,15 +3,10 @@ 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: equinix-bare-metal
runs-on: self-hosted
timeout-minutes: 10
strategy:
fail-fast: false
@ -44,21 +39,23 @@ jobs:
- v1.30.0
- v1.30.1
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
ref: ${{ matrix.tag-version }}
- id: setup-java
name: Set up Java for build
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Run jmh
run: ./gradlew jmhJar
- uses: gradle/actions/setup-gradle@v3
with:
arguments: |
jmhJar
env:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- name: Run Benchmark
run: |
@ -66,7 +63,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@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4
uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'jmh'
output-file-path: sdk/trace/build/jmh-result.json

View File

@ -5,30 +5,27 @@ 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: equinix-bare-metal
runs-on: self-hosted
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- id: setup-java
name: Set up Java for build
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Run jmh
run: ./gradlew jmhJar
- uses: gradle/actions/setup-gradle@v3
with:
arguments: |
jmhJar
env:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- name: Run Benchmark
run: |
@ -36,7 +33,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@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4
uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'jmh'
output-file-path: sdk/trace/build/jmh-result.json

View File

@ -9,27 +9,21 @@ on:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
publish:
permissions:
contents: read
packages: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- name: Login to GitHub package registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
uses: docker/build-push-action@v5
with:
context: integration-tests/tracecontext/docker
push: true

View File

@ -12,9 +12,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
name: Build
@ -24,68 +21,50 @@ jobs:
matrix:
os:
- macos-latest
- macos-13
- ubuntu-latest
- windows-latest
test-java-version:
- 8
- 11
- 17
- 21
- 23
- 20
# Collect coverage on latest LTS
include:
- os: ubuntu-latest
test-java-version: 21
- os: ubuntu-20.04
test-java-version: 17
coverage: true
jmh-based-tests: true
# macos-latest drops support for java 8 temurin. Run java 8 on macos-13. Run java 11, 17, 21 on macos-latest.
exclude:
- os: macos-latest
test-java-version: 8
- os: macos-13
test-java-version: 11
- os: macos-13
test-java-version: 17
- os: macos-13
test-java-version: 21
- os: macos-13
test-java-version: 23
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- id: setup-java-test
name: Set up Java ${{ matrix.test-java-version }} for tests
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ matrix.test-java-version }}
- id: setup-java
name: Set up Java for build
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Build
run: >
./gradlew build
- uses: gradle/actions/setup-gradle@v3
with:
arguments: |
build
${{ matrix.coverage && 'jacocoTestReport' || '' }}
-PtestJavaVersion=${{ matrix.test-java-version }}
"-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}"
"-Porg.gradle.java.installations.auto-download=false"
-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }},${{ steps.setup-java.outputs.path }}
env:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
# JMH-based tests run only if this environment variable is set to true
RUN_JMH_BASED_TESTS: ${{ matrix.jmh-based-tests }}
- name: Check for diff
# The jApiCmp diff compares current to latest, which isn't appropriate for release branches
# 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/') }}
if: ${{ !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
@ -99,12 +78,12 @@ jobs:
exit 1
fi
- uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
- uses: codecov/codecov-action@v4
if: ${{ matrix.coverage }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
- uses: actions/upload-artifact@v4
if: ${{ matrix.coverage }}
with:
name: coverage-report
@ -133,27 +112,23 @@ jobs:
name: publish-snapshots${{ (github.ref_name != 'main' || github.repository != 'open-telemetry/opentelemetry-java') && ' (skipped)' || '' }}
# intentionally not blocking snapshot publishing on markdown-link-check or misspell-check
needs: build
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- id: setup-java
name: Set up Java
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set up gradle
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' }}
- name: Publish to Sonatype
run: ./gradlew assemble publishToSonatype
- uses: gradle/actions/setup-gradle@v3
# skipping release branches because the versions in those branches are not snapshots
# (also this skips pull requests)
if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }}
with:
arguments: assemble publishToSonatype
env:
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }}
@ -161,19 +136,13 @@ jobs:
GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }}
build-graal:
name: Build GraalVM
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
test-graal-version:
- 21
- 23
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: graalvm/setup-graalvm@7f488cf82a3629ee755e4e97342c01d6bed318fa # v1.3.5
- uses: actions/checkout@v4
- uses: graalvm/setup-graalvm@v1
with:
java-version: ${{ matrix.test-graal-version }}
# TODO(jack-berg): Which versions do we need to test? Should we use a matrix scheme?
java-version: '21'
distribution: 'graalvm'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}

43
.github/workflows/codeql-daily.yml vendored Normal file
View File

@ -0,0 +1,43 @@
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
- uses: gradle/actions/setup-gradle@v3
with:
# skipping build cache is needed so that all modules will be analyzed
arguments: assemble --no-build-cache
- name: 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

View File

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

View File

@ -1,20 +0,0 @@
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,16 +1,16 @@
name: Gradle wrapper validation
on:
push:
pull_request:
permissions:
contents: read
paths:
- '**/gradle/wrapper/**'
push:
paths:
- '**/gradle/wrapper/**'
jobs:
gradle-wrapper-validation:
validation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/wrapper-validation-action@v2.1.2

View File

@ -4,21 +4,14 @@ 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- name: Remove label
env:

View File

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

View File

@ -1,26 +0,0 @@
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

@ -1,47 +0,0 @@
name: OSSF Scorecard
on:
push:
branches:
- main
schedule:
- cron: "43 6 * * 5" # weekly at 06:43 (UTC) on Friday
workflow_dispatch:
permissions: read-all
jobs:
analysis:
runs-on: ubuntu-latest
permissions:
# Needed for Code scanning upload
security-events: write
# Needed for GitHub OIDC token if publish_results is true
id-token: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
with:
results_file: results.sarif
results_format: sarif
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable
# uploads of run results in SARIF format to the repository Actions tab.
# https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts
- name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
with:
sarif_file: results.sarif

View File

@ -4,44 +4,27 @@ name: OWASP dependency check (daily)
on:
schedule:
- cron: "30 1 * * *" # daily at 1:30 UTC
- cron: '30 1 * * *'
workflow_dispatch:
permissions:
contents: read
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Check dependencies
run: ./gradlew dependencyCheckAnalyze
env:
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
- uses: gradle/actions/setup-gradle@v3
with:
arguments: "dependencyCheckAnalyze"
- name: Upload report
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@v4
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,16 +2,11 @@ name: Prepare patch release
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prepare-patch-release:
permissions:
contents: write # for git push to PR branch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- run: |
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x$ ]]; then
@ -37,7 +32,7 @@ jobs:
echo "VERSION=$major_minor.$((patch + 1))" >> $GITHUB_ENV
- name: Update version
run: .github/scripts/update-version.sh $VERSION
run: sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION/" version.gradle.kts
- name: Update the change log with the approximate release date
run: |
@ -47,19 +42,13 @@ 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: ${{ steps.otelbot-token.outputs.token }}
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
message="Prepare release $VERSION"
branch="otelbot/prepare-release-${VERSION}"
branch="opentelemetrybot/prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"

View File

@ -2,14 +2,11 @@ name: Prepare release branch
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prereqs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- name: Verify prerequisites
run: |
@ -24,13 +21,11 @@ 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- name: Create release branch
run: |
@ -59,19 +54,13 @@ 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: ${{ steps.otelbot-token.outputs.token }}
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
message="Prepare release $VERSION"
branch="otelbot/prepare-release-${VERSION}"
branch="opentelemetrybot/prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
@ -81,13 +70,11 @@ 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- name: Set environment variables
run: |
@ -100,11 +87,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: .github/scripts/update-version.sh $NEXT_VERSION
run: sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$NEXT_VERSION/" version.gradle.kts
- name: Update the change log on main
run: |
@ -115,20 +102,14 @@ 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: ${{ steps.otelbot-token.outputs.token }}
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
message="Update version to $NEXT_VERSION"
body="Update version to \`$NEXT_VERSION\`."
branch="otelbot/update-version-to-${NEXT_VERSION}"
branch="opentelemetrybot/update-version-to-${NEXT_VERSION}"
git checkout -b $branch
git commit -a -m "$message"

View File

@ -2,17 +2,11 @@ name: Release
on:
workflow_dispatch:
permissions:
contents: read
jobs:
release:
permissions:
contents: write # for creating the release
runs-on: ubuntu-24.04
runs-on: ubuntu-22.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
@ -20,18 +14,17 @@ jobs:
exit 1
fi
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set up gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- name: Build and publish artifacts
run: ./gradlew assemble publishToSonatype closeAndReleaseSonatypeStagingRepository
uses: gradle/actions/setup-gradle@v3
with:
arguments: assemble publishToSonatype closeAndReleaseSonatypeStagingRepository
env:
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }}
@ -65,7 +58,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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
ref: main
@ -80,7 +73,7 @@ jobs:
fi
# back to the release branch
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
# tags are needed for the generate-release-contributors.sh script
fetch-depth: 0
@ -129,20 +122,14 @@ 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
update-apidiff-baseline-and-docs-to-released-version:
permissions:
contents: write # for git push to PR branch
merge-change-log-to-main:
runs-on: ubuntu-latest
needs:
- release
steps:
# 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
- uses: actions/checkout@v4
- name: Copy change log section from release branch
env:
@ -151,7 +138,7 @@ jobs:
sed -n "0,/^## Version $VERSION /d;/^## Version /q;p" CHANGELOG.md \
> /tmp/changelog-section.md
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
ref: main
@ -162,59 +149,32 @@ 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: 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
- 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:
VERSION: ${{ needs.release.outputs.version }}
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
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}"
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//\//-}"
git checkout -b $branch
git commit -m "$message"
git commit -a -m "$message"
git push --set-upstream origin $branch
gh pr create --title "$message" \
--body "$body" \

View File

@ -3,22 +3,19 @@ name: Reusable - Markdown link check
on:
workflow_call:
permissions:
contents: read
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- 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/(issues|pull)/\\d+$"
--max-retries 6
--retry-wait-time 10
--max-concurrency 1
.
- name: Install markdown-link-check
# TODO(jack-berg): use latest when config file reading bug is fixed: https://github.com/tcort/markdown-link-check/issues/246
run: npm install -g markdown-link-check@3.10.3
- name: Run markdown-link-check
run: |
find . -type f \
-name '*.md' \
-not -path './CHANGELOG.md' \
| xargs .github/scripts/markdown-link-check-with-retry.sh

View File

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

View File

@ -3,17 +3,11 @@ name: Reusable - Open issue on workflow failure
on:
workflow_call:
permissions:
contents: read
jobs:
open-issue:
permissions:
contents: read
issues: write # for creating the issue
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
- name: Open issue
env:

View File

@ -1,44 +0,0 @@
# 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

1
.gitignore vendored
View File

@ -1,7 +1,6 @@
# Gradle
build
.gradle
.kotlin
local.properties
out/

View File

@ -1,750 +1,5 @@
# Changelog
## 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
* Make `ExtendedTracer` easier to use
([#6943](https://github.com/open-telemetry/opentelemetry-java/pull/6943))
* Add `ExtendedLogRecordBuilder#setEventName` and corresponding SDK and OTLP serialization
([#7012](https://github.com/open-telemetry/opentelemetry-java/pull/7012))
* BREAKING: Drop event API / SDK
([#7053](https://github.com/open-telemetry/opentelemetry-java/pull/7053))
### SDK
* Remove -alpha artifacts from runtime classpath of stable components
([#6944](https://github.com/open-telemetry/opentelemetry-java/pull/6944))
#### Traces
* Bugfix: Follow spec on span limits, batch processors
([#7030](https://github.com/open-telemetry/opentelemetry-java/pull/7030))
* Add experimental `SdkTracerProvider.setScopeConfigurator(ScopeConfigurator)` for
updating `TracerConfig` at runtime
([#7021](https://github.com/open-telemetry/opentelemetry-java/pull/7021))
#### Profiles
* Add AttributeKeyValue abstraction to common otlp exporters
([#7026](https://github.com/open-telemetry/opentelemetry-java/pull/7026))
* Improve profiles attribute table handling
([#7031](https://github.com/open-telemetry/opentelemetry-java/pull/7031))
#### Exporters
* Interpret timeout zero value as no limit
([#7023](https://github.com/open-telemetry/opentelemetry-java/pull/7023))
* Bugfix - OTLP: Fix concurrent span reusable data marshaler
([#7041](https://github.com/open-telemetry/opentelemetry-java/pull/7041))
* OTLP: Add ability to customize retry exception predicate
([#6991](https://github.com/open-telemetry/opentelemetry-java/pull/6991))
* OTLP: Expand default OkHttp sender retry exception predicate
([#7047](https://github.com/open-telemetry/opentelemetry-java/pull/7047),
[#7057](https://github.com/open-telemetry/opentelemetry-java/pull/7057))
#### Extensions
* Autoconfigure: Consistent application of exporter customizers when otel.{signal}.exporter=none
([#7017](https://github.com/open-telemetry/opentelemetry-java/pull/7017))
* Autoconfigure: Promote EnvironmentResourceProvider to public API
([#7052](https://github.com/open-telemetry/opentelemetry-java/pull/7052))
* Autoconfigure: Ensure `OTEL_PROPAGATORS` still works when `OTEL_SDK_DISABLED=true`.
([#7062](https://github.com/open-telemetry/opentelemetry-java/pull/7062))%
#### Testing
* Add W3CBaggagePropagator to `OpenTelemetryRule`, `OpenTelemetryExtension`.
([#7056](https://github.com/open-telemetry/opentelemetry-java/pull/7056))
## Version 1.46.0 (2025-01-10)
### SDK
* Remove unused dependencies, cleanup code after stabilizing Value
([#6948](https://github.com/open-telemetry/opentelemetry-java/pull/6948))
* Explicitly allow null into CompletableResultCode.failExceptionally()
([#6963](https://github.com/open-telemetry/opentelemetry-java/pull/6963))
#### Traces
* Fix span setStatus
([#6990](https://github.com/open-telemetry/opentelemetry-java/pull/6990))
#### Logs
* Add getters/accessors for readable fields in ReadWriteLogRecord.
([#6924](https://github.com/open-telemetry/opentelemetry-java/pull/6924))
#### Exporters
* OTLP: Update to opentelemetry-proto 1.5
([#6999](https://github.com/open-telemetry/opentelemetry-java/pull/6999))
* Bugfix - OTLP: Ensure Serializer runtime exceptions are rethrown as IOException
([#6969](https://github.com/open-telemetry/opentelemetry-java/pull/6969))
* BREAKING - OTLP: Delete experimental OTLP authenticator concept.
See [OTLP authentication docs](https://opentelemetry.io/docs/languages/java/sdk/#authentication)
for supported solutions.
([#6984](https://github.com/open-telemetry/opentelemetry-java/pull/6984))
#### Extensions
* BREAKING - Autoconfigure: Remove support for deprecated otel.experimental.resource.disabled.keys
([#6931](https://github.com/open-telemetry/opentelemetry-java/pull/6931))
## Version 1.45.0 (2024-12-06)
### API
* Add convenience method `setAttribute(Attribute<Long>, int)` to SpanBuilder (matching the existing
convenience method in Span)
([#6884](https://github.com/open-telemetry/opentelemetry-java/pull/6884))
* Extends TextMapGetter with experimental GetAll() method, implement usage in W3CBaggagePropagator
([#6852](https://github.com/open-telemetry/opentelemetry-java/pull/6852))
### SDK
#### Traces
* Add synchronization to SimpleSpanProcessor to ensure thread-safe export of spans
([#6885](https://github.com/open-telemetry/opentelemetry-java/pull/6885))
#### Metrics
* Lazily initialize ReservoirCells
([#6851](https://github.com/open-telemetry/opentelemetry-java/pull/6851))
#### Logs
* Add synchronization to SimpleLogRecordProcessor to ensure thread-safe export of logs
([#6885](https://github.com/open-telemetry/opentelemetry-java/pull/6885))
#### Exporters
* OTLP: Update opentelementry-proto to 1.4
([#6906](https://github.com/open-telemetry/opentelemetry-java/pull/6906))
* OTLP: Rename internal Marshaler#writeJsonToGenerator method to allow jackson runtimeOnly dependency
([#6896](https://github.com/open-telemetry/opentelemetry-java/pull/6896))
* OTLP: Fix repeated string serialization for JSON.
([#6888](https://github.com/open-telemetry/opentelemetry-java/pull/6888))
* OTLP: Fix missing unsafe available check
([#6920](https://github.com/open-telemetry/opentelemetry-java/pull/6920))
#### Extensions
* Declarative config: Don't require empty objects when referencing custom components
([#6891](https://github.com/open-telemetry/opentelemetry-java/pull/6891))
### Tooling
* Add javadoc boilerplate internal comment v2 for experimental classes
([#6886](https://github.com/open-telemetry/opentelemetry-java/pull/6886))
* Update develocity configuration
([#6903](https://github.com/open-telemetry/opentelemetry-java/pull/6903))
## Version 1.44.1 (2024-11-10)
### SDK
#### Traces
* Fix regression in event attributes
([#6865](https://github.com/open-telemetry/opentelemetry-java/pull/6865))
## Version 1.44.0 (2024-11-08)
### API
* Fix ConfigUtil#getString ConcurrentModificationException
([#6841](https://github.com/open-telemetry/opentelemetry-java/pull/6841))
### SDK
#### Traces
* Stabilize ExceptionEventData
([#6795](https://github.com/open-telemetry/opentelemetry-java/pull/6795))
#### Metrics
* Stabilize metric cardinality limits
([#6794](https://github.com/open-telemetry/opentelemetry-java/pull/6794))
* Refactor metrics internals to remove MeterSharedState
([#6845](https://github.com/open-telemetry/opentelemetry-java/pull/6845))
#### Exporters
* Add memory mode option to stdout exporters
([#6774](https://github.com/open-telemetry/opentelemetry-java/pull/6774))
* Log a warning if OTLP endpoint port is likely incorrect given the protocol
([#6813](https://github.com/open-telemetry/opentelemetry-java/pull/6813))
* Fix OTLP gRPC retry mechanism for unsuccessful HTTP responses
([#6829](https://github.com/open-telemetry/opentelemetry-java/pull/6829))
* Add ByteBuffer field type marshaling support
([#6686](https://github.com/open-telemetry/opentelemetry-java/pull/6686))
* Fix stdout exporter format by adding newline after each export
([#6848](https://github.com/open-telemetry/opentelemetry-java/pull/6848))
* Enable `reusuable_data` memory mode by default for `OtlpGrpc{Signal}Exporter`,
`OtlpHttp{Signal}Exporter`, `OtlpStdout{Signal}Exporter`, and `PrometheusHttpServer`
([#6799](https://github.com/open-telemetry/opentelemetry-java/pull/6799))
#### Extension
* Rebrand file configuration to declarative configuration in documentation
([#6812](https://github.com/open-telemetry/opentelemetry-java/pull/6812))
* Fix declarative config `file_format` validation
([#6786](https://github.com/open-telemetry/opentelemetry-java/pull/6786))
* Fix declarative config env substitution by disallowing '}' in default value
([#6793](https://github.com/open-telemetry/opentelemetry-java/pull/6793))
* Set declarative config default OTLP protocol to http/protobuf
([#6800](https://github.com/open-telemetry/opentelemetry-java/pull/6800))
* Stabilize autoconfigure disabling of resource keys via `otel.resource.disabled.keys`
([#6809](https://github.com/open-telemetry/opentelemetry-java/pull/6809))
### Tooling
* Run tests on Java 23
([#6825](https://github.com/open-telemetry/opentelemetry-java/pull/6825))
* Test Windows in CI
([#6824](https://github.com/open-telemetry/opentelemetry-java/pull/6824))
* Add error prone checks for internal javadoc and private constructors
([#6844](https://github.com/open-telemetry/opentelemetry-java/pull/6844))
## Version 1.43.0 (2024-10-11)
### API
* Add helper class to capture context using ScheduledExecutorService
([#6712](https://github.com/open-telemetry/opentelemetry-java/pull/6712))
* Adds Baggage.getEntry(String key)
([#6765](https://github.com/open-telemetry/opentelemetry-java/pull/6765))
#### Extensions
* Fix ottracepropagation for short span ids
([#6734](https://github.com/open-telemetry/opentelemetry-java/pull/6734))
### SDK
#### Metrics
* Optimize advice with FilteredAttributes
([#6633](https://github.com/open-telemetry/opentelemetry-java/pull/6633))
#### Exporters
* Add experimental stdout log, metric, trace exporters for printing records to stdout in standard
OTLP JSON format.
([#6675](https://github.com/open-telemetry/opentelemetry-java/pull/6675), [#6750](https://github.com/open-telemetry/opentelemetry-java/pull/6750))
* Add Marshalers for profiling signal type
([#6680](https://github.com/open-telemetry/opentelemetry-java/pull/6680))
#### Extensions
* Add `*Model` suffix to declarative config generated classes.
([#6721](https://github.com/open-telemetry/opentelemetry-java/pull/6721))
* Use autoconfigured ClassLoader to load declarative config
([#6725](https://github.com/open-telemetry/opentelemetry-java/pull/6725))
* Update declarative config to use opentelemetry-configuration v0.3.0
([#6733](https://github.com/open-telemetry/opentelemetry-java/pull/6733))
* Add `StructuredConfigProperties#getStructured` default method,
add `StructuredConfigProperties.empty()`
([#6759](https://github.com/open-telemetry/opentelemetry-java/pull/6759))
#### Testing
* Add context info about wrong span or trace.
([#6703](https://github.com/open-telemetry/opentelemetry-java/pull/6703))
## Version 1.42.1 (2024-09-10)
### API
* Revert `java-test-fixtures` plugin to remove test dependencies from `pom.xml`.
([#6695](https://github.com/open-telemetry/opentelemetry-java/pull/6695))
## Version 1.42.0 (2024-09-06)
### API
* BREAKING: Stabilize log support for AnyValue bodies. Rename `AnyValue` to `Value`, promote
from `opentelemetry-api-incubator` to `opentelemetry-api`, change package
from `io.opentelemetry.api.incubator.logs` to `io.opentelemetry.api.common`.
([#6591](https://github.com/open-telemetry/opentelemetry-java/pull/6591))
* Noop implementations detect when `opentelemetry-api-incubator` is present and return extended noop
implementations.
([#6617](https://github.com/open-telemetry/opentelemetry-java/pull/6617))%
### SDK
#### Traces
* Added experimental support for SpanProcessor OnEnding callback
([#6367](https://github.com/open-telemetry/opentelemetry-java/pull/6367))
* Remove final modifier from SdkTracer.tracerEnabled
([#6687](https://github.com/open-telemetry/opentelemetry-java/pull/6687))
#### Exporters
* Suppress zipkin exporter instrumentation
([#6552](https://github.com/open-telemetry/opentelemetry-java/pull/6552))
* OTLP exporters return status code exceptions via CompletableResultCode in GrpcExporter and
HttpExporter.
([#6645](https://github.com/open-telemetry/opentelemetry-java/pull/6645))
* Align GrpcSender contract with HttpSender
([#6658](https://github.com/open-telemetry/opentelemetry-java/pull/6658))
#### Extensions
* Add autoconfigure support for ns and us durations
([#6654](https://github.com/open-telemetry/opentelemetry-java/pull/6654))
* Add declarative configuration ComponentProvider support for resources
([#6625](https://github.com/open-telemetry/opentelemetry-java/pull/6625))
* Add declarative configuration ComponentProvider support for processors
([#6623](https://github.com/open-telemetry/opentelemetry-java/pull/6623))
* Add declarative configuration ComponentProvider support for samplers
([#6494](https://github.com/open-telemetry/opentelemetry-java/pull/6494))
* Add declarative configuration ComponentProvider support for propagators
([#6624](https://github.com/open-telemetry/opentelemetry-java/pull/6624))
* Add declarative configuration missing pieces
([#6677](https://github.com/open-telemetry/opentelemetry-java/pull/6677))
* Change jaeger remote sampler autoconfigure property from `pollingInterval` to `pollingIntervalMs`
to match spec.
([#6672](https://github.com/open-telemetry/opentelemetry-java/pull/6672))
#### Testing
* Add asserts for log record body fields
([#6509](https://github.com/open-telemetry/opentelemetry-java/pull/6509))
## Version 1.41.0 (2024-08-09)
### API
* Move experimental suppress instrumentation context key to api internal package
([#6546](https://github.com/open-telemetry/opentelemetry-java/pull/6546))
#### Incubator
* Fix bug in `ExtendedContextPropagators` preventing context extraction when case is incorrect.
([#6569](https://github.com/open-telemetry/opentelemetry-java/pull/6569))
### SDK
* Extend `CompletableResultCode` with `failExceptionally(Throwable)`.
([#6348](https://github.com/open-telemetry/opentelemetry-java/pull/6348))
#### Metrics
* Avoid allocations when experimental advice doesn't remove any attributes.
([#6629](https://github.com/open-telemetry/opentelemetry-java/pull/6629))
#### Exporter
* Enable retry by default for OTLP exporters.
([#6588](https://github.com/open-telemetry/opentelemetry-java/pull/6588))
* Retry ConnectException, add retry logging.
([#6614](https://github.com/open-telemetry/opentelemetry-java/pull/6614))
* Extend `PrometheusHttpServer` with ability to configure default aggregation as function of
instrument kind, including experimental env var support.
([#6541](https://github.com/open-telemetry/opentelemetry-java/pull/6541))
* Add exporter data model impl for profiling signal type.
([#6498](https://github.com/open-telemetry/opentelemetry-java/pull/6498))
* Add Marshalers for profiling signal type.
([#6565](https://github.com/open-telemetry/opentelemetry-java/pull/6565))
* Use generateCertificates() of CertificateFactory to process certificates.
([#6579](https://github.com/open-telemetry/opentelemetry-java/pull/6579))
#### Extensions
* Add file configuration ComponentProvider support for exporters.
([#6493](https://github.com/open-telemetry/opentelemetry-java/pull/6493))
* Remove nullable from file config Factory contract.
([#6612](https://github.com/open-telemetry/opentelemetry-java/pull/6612))
## Version 1.40.0 (2024-07-05)
### API
#### Incubator
* Narrow ExtendedSpanBuilder return types for chaining
([#6514](https://github.com/open-telemetry/opentelemetry-java/pull/6514))
* Add APIs to determine if tracer, logger, instruments are enabled
([#6502](https://github.com/open-telemetry/opentelemetry-java/pull/6502))
### SDK
#### Extensions
* Move autoconfigure docs to opentelemetry.io
([#6491](https://github.com/open-telemetry/opentelemetry-java/pull/6491))
## Version 1.39.0 (2024-06-07)
### API
#### Incubator
* BREAKING: Refactor ExtendedTracer, ExtendedSpanBuilder to reflect incubating API conventions
([#6497](https://github.com/open-telemetry/opentelemetry-java/pull/6497))
### SDK
#### Exporter
* BREAKING: Serve prometheus metrics only on `/metrics` by default. To restore the previous behavior
and serve metrics on all paths, override the default handler
as [demonstrated here](https://github.com/open-telemetry/opentelemetry-java/blob/main/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java#L251-L259).
([#6476](https://github.com/open-telemetry/opentelemetry-java/pull/6476))
* Make OTLP exporter memory mode API public
([#6469](https://github.com/open-telemetry/opentelemetry-java/pull/6469))
* Speed up OTLP string marshaling using sun.misc.Unsafe
([#6433](https://github.com/open-telemetry/opentelemetry-java/pull/6433))
* Add exporter data classes for experimental profiling signal type.
([#6374](https://github.com/open-telemetry/opentelemetry-java/pull/6374))
* Start prometheus http server with daemon thread
([#6472](https://github.com/open-telemetry/opentelemetry-java/pull/6472))
* Update the Prometheus metrics library and improve how units are included in metric names.
([#6473](https://github.com/open-telemetry/opentelemetry-java/pull/6473))
* Remove android animalsniffer check from prometheus exporter
([#6478](https://github.com/open-telemetry/opentelemetry-java/pull/6478))
#### Extensions
* Load file config YAML using core schema, ensure that env var substitution retains string types.
([#6436](https://github.com/open-telemetry/opentelemetry-java/pull/6436))
* Define dedicated file configuration SPI ComponentProvider
([#6457](https://github.com/open-telemetry/opentelemetry-java/pull/6457))
### Tooling
* Normalize timestamps and file ordering in jars, making the outputs reproducible
([#6471](https://github.com/open-telemetry/opentelemetry-java/pull/6471))
* GHA for generating the post-release pull request
([#6449](https://github.com/open-telemetry/opentelemetry-java/pull/6449))
## Version 1.38.0 (2024-05-10)
### API
* Stabilize synchronous gauge
([#6419](https://github.com/open-telemetry/opentelemetry-java/pull/6419))
#### Incubator
* Add put(AttributeKey<T>, T) overload to EventBuilder
([#6331](https://github.com/open-telemetry/opentelemetry-java/pull/6331))
#### Baggage
* Baggage filters space-only keys
([#6431](https://github.com/open-telemetry/opentelemetry-java/pull/6431))
### SDK
* Add experimental scope config to enable / disable scopes (i.e. meter, logger, tracer)
([#6375](https://github.com/open-telemetry/opentelemetry-java/pull/6375))
#### Traces
* Add ReadableSpan#getAttributes
([#6382](https://github.com/open-telemetry/opentelemetry-java/pull/6382))
* Use standard ArrayList size rather than max number of links for initial span links allocation
([#6252](https://github.com/open-telemetry/opentelemetry-java/pull/6252))
#### Metrics
* Use low precision Clock#now when computing timestamp for exemplars
([#6417](https://github.com/open-telemetry/opentelemetry-java/pull/6417))
* Update invalid instrument name log message now that forward slash `/` is valid
([#6343](https://github.com/open-telemetry/opentelemetry-java/pull/6343))
#### Exporters
* Introduce low allocation OTLP marshalers. If using autoconfigure, opt in
via `OTEL_JAVA_EXPERIMENTAL_EXPORTER_MEMORY_MODE=REUSABLE_DATA`.
* Low allocation OTLP logs marshaler
([#6429](https://github.com/open-telemetry/opentelemetry-java/pull/6429))
* Low allocation OTLP metrics marshaler
([#6422](https://github.com/open-telemetry/opentelemetry-java/pull/6422))
* Low allocation OTLP trace marshaler
([#6410](https://github.com/open-telemetry/opentelemetry-java/pull/6410))
* Add memory mode support to OTLP exporters
([#6430](https://github.com/open-telemetry/opentelemetry-java/pull/6430))
* Marshal span status description without allocation
([#6423](https://github.com/open-telemetry/opentelemetry-java/pull/6423))
* Add private constructors for stateless marshalers
([#6434](https://github.com/open-telemetry/opentelemetry-java/pull/6434))
* Mark opentelemetry-exporter-sender-jdk stable
([#6357](https://github.com/open-telemetry/opentelemetry-java/pull/6357))
* PrometheusHttpServer prevent concurrent reads when reusable memory mode
([#6371](https://github.com/open-telemetry/opentelemetry-java/pull/6371))
* Ignore TLS components (SSLContext, TrustManager, KeyManager) if plain HTTP protocol is used for
exporting
([#6329](https://github.com/open-telemetry/opentelemetry-java/pull/6329))
* Add is_remote_parent span flags to OTLP exported Spans and SpanLinks
([#6388](https://github.com/open-telemetry/opentelemetry-java/pull/6388))
* Add missing fields to OTLP metric exporters `toString()`
([#6402](https://github.com/open-telemetry/opentelemetry-java/pull/6402))
#### Extensions
* Rename otel.config.file to otel.experimental.config.file for autoconfigure
([#6396](https://github.com/open-telemetry/opentelemetry-java/pull/6396))
### OpenCensus Shim
* Fix opencensus shim spanBuilderWithRemoteParent behavior
([#6415](https://github.com/open-telemetry/opentelemetry-java/pull/6415))
### Tooling
* Add additional API incubator docs
([#6356](https://github.com/open-telemetry/opentelemetry-java/pull/6356))
* Run build on java 21
([#6370](https://github.com/open-telemetry/opentelemetry-java/pull/6370))
* Fix running tests with java 8 on macos
([#6411](https://github.com/open-telemetry/opentelemetry-java/pull/6411))
* Move away from deprecated gradle enterprise APIs
([#6363](https://github.com/open-telemetry/opentelemetry-java/pull/6363))
## Version 1.37.0 (2024-04-05)
**NOTICE:** This release contains a significant restructuring of the experimental event API and the API incubator artifact. Please read the notes in the `API -> Incubator` section carefully.
@ -847,7 +102,7 @@
have stopped being published. Jaeger
has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users
should export to jaeger
using OTLP
using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies)
instead.
### API
@ -931,7 +186,7 @@ instead.
and `opentelemetry-exporter-jaeger-thift`. Jaeger
has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users
should export to jaeger
using OTLP
using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies)
instead.
### API
@ -1368,7 +623,7 @@ The log bridge API / SDK are now stable! Some important notes:
of `otel.logs.exporter` from `none` to `otlp`.
NOTE: reminder that
the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/logs/bridge-api.md)
the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md)
is _not_ meant for end users. Log appenders use the API to bridge logs from existing log
frameworks (e.g. JUL, Log4j, SLf4J, Logback) into OpenTelemetry. Users configure the Log SDK to
dictate how logs are processed and exported.
@ -1436,7 +691,7 @@ merged into `opentelemetry-exporter-otlp`, `opentelemetry-sdk-logs-testing` will
into `opentelemetry-sdk-testing`, `opentelemetry-sdk-extension-autoconfigure` will enable `otlp`
log exporter by default (i.e. `otel.logs.exporter=otlp`). For more details, see tracking
issue [#5340](https://github.com/open-telemetry/opentelemetry-java/issues/5340). NOTE: reminder that
the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/logs/bridge-api.md)
the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md)
is _not_ meant for end users. Log appenders use the API to bridge logs from existing log
frameworks (e.g. JUL, Log4j, SLf4J, Logback) into OpenTelemetry. Users configure the Log SDK to
dictate how logs are processed and exported.
@ -1970,7 +1225,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/pull/4775):
[(#4775)](https://github.com/open-telemetry/opentelemetry-java/issues/4775):
* Fix handling of `none` in OTLP exporters.
* Add `JaegerGrpcSpanExporterBuilder#setCompression(String)`.
* Add `ZipkinSpanExporterBuilder#setCompression(String)`.
@ -1998,8 +1253,8 @@ log API component has been added for emitting events and for writing log appende
API is not a substitute for traditional log frameworks like Log4j, JUL, SLF4J, or Logback. While the
event portion of the API is intended for instrumentation authors and end users, the API for emitting
LogRecords is not.
See [LoggerProvider](./api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java)
and [Logger](./api/all/src/main/java/io/opentelemetry/api/logs/Logger.java) javadoc for more
See [LoggerProvider](./api/logs/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java)
and [Logger](./api/logs/src/main/java/io/opentelemetry/api/logs/Logger.java) javadoc for more
details.
### General
@ -2285,7 +1540,7 @@ details.
stable `opentelemetry-sdk-extension-autoconfigure-spi`.
* Autoconfigure now supports multiple values for `otel.metrics.exporter`.
* Autoconfigure now
supports [general attribute limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#attribute-limits),
supports [general attribute limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#attribute-limits),
applicable to span attributes, span event attributes, span link attributes, and log attributes.
* Autoconfigure now supports an experimental option to disable the SDK.
If `otel.experimental.sdk.enabled=true`, `AutoConfiguredOpenTelemetrySdk#getOpenTelemetrySdk()`
@ -2535,7 +1790,7 @@ should not be many. Thanks for bearing with us on this.
### General
* Examples moved
to [opentelemetry-java-examples](https://github.com/open-telemetry/opentelemetry-java-examples)
to [opentelemetry-java-docs](https://github.com/open-telemetry/opentelemetry-java-docs)
### SDK
@ -3845,7 +3100,7 @@ See the `opentelemetry-extension-kotlin` module for details.
#### Breaking changes
- There have been many updates to the semantic conventions constants. The constants are now auto-generated from the YAML specification files, so the names will now be consistent across languages. For more information, see the [YAML Model for Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/tree/main/model#yaml-model-for-semantic-conventions).
- There have been many updates to the semantic conventions constants. The constants are now auto-generated from the YAML specification files, so the names will now be consistent across languages. For more information, see the [YAML Model for Semantic Conventions](https://github.com/open-telemetry/opentelemetry-specification/tree/master/semantic_conventions).
- All API classes have been moved into the `io.opentelemetry.api.` prefix to support JPMS users.
- The API no longer uses the `grpc-context` as the context implementation. It now uses `io.opentelemetry.context.Context`. This is published in the `opentelemetry-context` artifact. Interactions with the context were mostly moved to static methods in the `Span` and `Baggage` interfaces.
- The Baggage API has been reworked to more closely match the specification. This includes the removal of the `BaggageManager`. Baggage is fully functional within the API, without needing to install an SDK.
@ -3876,7 +3131,7 @@ See the `opentelemetry-extension-kotlin` module for details.
#### Breaking changes
- `TraceConfig` configuration option names (environment variables and system properties) were renamed to match the OpenTelemetery Specification.
- `TraceConfig` configuration option names (environment variables and system properties) were renamed to match the OpenTelemetery Specification. For more information, see [TraceConfig](./QUICKSTART.md#TraceConfig).
- The Jaeger gRPC exporter was updated to match the OpenTelemetry Specification. The `message` log entry attribute has been renamed to `event` and a new `dropped attributes count` attribute was added. For more information, see the [Overview](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md).
- The `SpanData.getHasRemoteParent()` and `SpanData.getHasEnded()` methods were renamed to `hasRemoteParent()` and `hasEnded()`, respectively.
- The `IdsGenerator` interface has been renamed to `IdGenerator`, and all implementations and relevant factory methods were similarly renamed.

View File

@ -3,7 +3,7 @@
Welcome to OpenTelemetry Java repository!
Before you start - see OpenTelemetry general
[contributing](https://github.com/open-telemetry/community/blob/main/guides/contributor/README.md)
[contributing](https://github.com/open-telemetry/community/blob/main/CONTRIBUTING.md)
requirements and recommendations.
If you want to add new features or change behavior, please make sure your changes follow the
@ -93,7 +93,7 @@ Other repositories in the OpenTelemetry Java ecosystem include:
contains instrumentation.
* [opentelemetry-java-contrib](https://github.com/open-telemetry/opentelemetry-java-contrib)
contains extensions, prototypes, and instrumentation, including vendor specific components.
* [opentelemetry-java-examples](https://github.com/open-telemetry/opentelemetry-java-examples) contains
* [opentelemetry-java-docs](https://github.com/open-telemetry/opentelemetry-java-docs) contains
working code snippets demonstrating various concepts.
## Style guideline
@ -146,13 +146,6 @@ uses [google-java-format](https://github.com/google/google-java-format) library:
synchronized (lock) { ... }
}
```
* Don't
use [gradle test fixtures](https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures) (
i.e. `java-test-fixtures` plugin) to reuse code for internal testing. The test fixtures plugin has
side effects where test dependencies are added to the `pom.xml` and publishes an
extra `*-test-fixtures.jar` artifact which is unnecessary for internal testing. Instead, create a
new `*:testing-internal` module and omit the `otel.java-conventions`. For example,
see [/exporters/otlp/testing-internal](./exporters/otlp/testing-internal).
If you notice any practice being applied in the project consistently that isn't listed here, please
consider a pull request to add it.
@ -190,11 +183,6 @@ in the guide for exceptions to the Javadoc requirement.
* Our javadoc is available via [
javadoc.io}(https://javadoc.io/doc/io.opentelemetry/opentelemetry-api)
### SDK Configuration Documentation
All changes to the SDK configuration options or autoconfigure module should be documented on
[opentelemetry.io](https://opentelemetry.io/docs/languages/java/configuration/).
### AutoValue
* Use [AutoValue](https://github.com/google/auto/tree/master/value), when possible, for any new
@ -257,18 +245,13 @@ Example usage could be as follows:
}
```
Please confirm whether the local opentelemetry-java version is consistent with the
opentelemetry-java version declared in the project that relies on opentelemetry-java.
If it is inconsistent, `dependencySubstitution` may not take effect.
See [the Gradle documentation](https://docs.gradle.org/current/userguide/composite_builds.html#included_build_declaring_substitutions)
for more information.
4. If you now build your project, it will use the included build to supply the opentelemetry-java
artifacts, ignoring any version declarations. Use the prefix `:DIRECTORY:` to refer to
tasks/projects within the included build, where DIRECTORY is the name of the directory in the
included build (only the part after the last `/`).
5. Here are some issues and solutions ([discussions/6551](https://github.com/open-telemetry/opentelemetry-java/discussions/6551))
you may encounter that may be helpful to you.
### Updating the OTLP protobufs

519
README.md
View File

@ -1,25 +1,69 @@
# OpenTelemetry Java
[![Maven Central][maven-image]][maven-url]
[![Continuous Build][ci-image]][ci-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)
[![Maven Central][maven-image]][maven-url]
`opentelemetry-java` is the home of the Java implementation of the OpenTelemetry API for recording
telemetry, and SDK for managing telemetry recorded by the API.
## Project Status
See [opentelemetry.io Java Documentation](https://opentelemetry.io/docs/languages/java/intro/) for:
See [Java status on OpenTelemetry.io][otel-java-status].
* An overview of the OpenTelemetry Java ecosystem and key repositories
* Detailed documentation on the components published from this repository
* Review of instrumentation ecosystem, including OpenTelemetry Java agent
* End-to-end working code examples
* And more
## Getting Started
> [!IMPORTANT]
> We are currently seeking additional contributors! See [help wanted](#help-wanted) for details.
If you are looking for an all-in-one, easy-to-install **auto-instrumentation
javaagent**, see [opentelemetry-java-instrumentation][].
If you are looking for **examples** on how to use the OpenTelemetry API to
write your own **manual instrumentation**, or how to set up the OpenTelemetry
Java SDK, see [Manual instrumentation][]. Fully-functional examples
are available in [opentelemetry-java-docs][].
If you are looking for generated classes for
the [OpenTelemetry semantic conventions][opentelemetry-semantic-conventions],
see [semantic-conventions-java][opentelemetry-semantic-conventions-java].
For a general overview of OpenTelemetry, visit [opentelemetry.io][].
Would you like to get involved with the project? Read our [contributing guide](CONTRIBUTING.md). We welcome
contributions!
## Contacting us
We hold regular meetings. See details at [community page](https://github.com/open-telemetry/community#java-sdk).
We use [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-java/discussions)
for support or general questions. Feel free to drop us a line.
We are also present in the [`#otel-java`](https://cloud-native.slack.com/archives/C014L2KCTE3) channel in the [CNCF slack](https://slack.cncf.io/).
Please join us for more informal discussions.
To report a bug, or request a new feature,
please [open an issue](https://github.com/open-telemetry/opentelemetry-java/issues/new/choose).
## Overview
OpenTelemetry is the merging of OpenCensus and OpenTracing into a single project.
This project contains the following top level components:
* [OpenTelemetry API](api/):
* [stable apis](api/all) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage`.
* [context api](context/) The OpenTelemetry Context implementation.
* [incubating apis](api/incubator) incubating APIs, including `Events`.
* [extensions](extensions/) define additional API extensions not part of the core API, including propagators.
* [sdk](sdk/) defines the implementation of the OpenTelemetry API.
* [exporters](exporters/) trace, metric, and log exporters for the SDK.
* [sdk-extensions](sdk-extensions/) defines additional SDK extensions, which are not part of the core SDK.
* [OpenTracing shim](opentracing-shim/) defines a bridge layer from OpenTracing to the OpenTelemetry API.
* [OpenCensus shim](opencensus-shim/) defines a bridge layer from OpenCensus to the OpenTelemetry API.
This project publishes a lot of artifacts, listed in [releases](#releases).
[`opentelemetry-bom`](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-bom) (BOM =
Bill of Materials) is provided to assist with synchronizing versions of
dependencies. [`opentelemetry-bom-alpha`](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-bom-alpha)
provides the same function for unstable artifacts. See [published releases](#published-releases) for
instructions on using the BOMs.
We would love to hear from the larger community: please provide feedback proactively.
## Requirements
@ -31,134 +75,144 @@ details.
reasons, [library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring)
must be enabled.
See [contributing](#contributing) for details on building this project locally.
See [CONTRIBUTING.md](./CONTRIBUTING.md) for additional instructions for building this project for
development.
### Note about extensions
Both API and SDK extensions consist of various additional components which are excluded from the core artifacts
to keep them from growing too large.
We still aim to provide the same level of quality and guarantee for them as for the core components.
Please don't hesitate to use them if you find them useful.
## Project setup and contributing
Please refer to the [contribution guide](CONTRIBUTING.md) on how to set up for development and contribute!
## Published Releases
Published releases are available on maven central. We strongly recommend using our published BOM to keep all
dependency versions in sync.
### Maven
```xml
<project>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.36.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
</dependencies>
</project>
```
### Gradle
```groovy
dependencies {
implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0")
implementation('io.opentelemetry:opentelemetry-api')
}
```
Note that if you want to use any artifacts that have not fully stabilized yet (such as the [prometheus exporter](https://github.com/open-telemetry/opentelemetry-java/tree/main/exporters/prometheus), then you will need to add an entry for the Alpha BOM as well, e.g.
```groovy
dependencies {
implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0")
implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.36.0-alpha')
implementation('io.opentelemetry:opentelemetry-api')
implementation('io.opentelemetry:opentelemetry-exporter-prometheus')
implementation('io.opentelemetry:opentelemetry-sdk-extension-autoconfigure')
}
```
## Snapshots
Snapshots based out the `main` branch are available for `opentelemetry-api`, `opentelemetry-sdk` and the rest of the artifacts.
We strongly recommend using our published BOM to keep all dependency versions in sync.
### Maven
```xml
<project>
<repositories>
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.37.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
</dependencies>
</project>
```
### Gradle
```groovy
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
dependencies {
implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0-SNAPSHOT")
implementation('io.opentelemetry:opentelemetry-api')
}
```
Libraries will usually only need `opentelemetry-api`, while applications
will want to use the `opentelemetry-sdk` module which contains our standard implementation
of the APIs.
## Gradle composite builds
For opentelemetry-java developers that need to test the latest source code with another
project, composite builds can be used as an alternative to `publishToMavenLocal`. This
requires some setup which is explained [here](CONTRIBUTING.md#composing-builds).
## Releases
Releases are published to maven central. We
publish [minor releases monthly](RELEASING.md#release-cadence)
and [patch releases as needed](RELEASING.md#preparing-a-new-patch-release).
See the [VERSIONING.md](VERSIONING.md) document for our policies for releases and compatibility
guarantees.
See [releases](https://github.com/open-telemetry/opentelemetry-java/releases) for a listing of
released versions and notes (see also [changelog](CHANGELOG.md)).
Check out information about the [latest release](https://github.com/open-telemetry/opentelemetry-java/releases).
## Artifacts
See the project [milestones](https://github.com/open-telemetry/opentelemetry-java/milestones)
for details on upcoming releases. The dates and features described in issues
and milestones are estimates, and subject to change.
The artifacts published by this repository are summarized below in tables, organized in collapsible
sections by topic.
As discussed in [compatibility](#compatibility), artifact versions must be kept in sync, for which
we strongly recommend [using one of our BOMs][dependencies-and-boms].
<details>
<summary>Bill of Materials (BOMs)</summary>
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.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>
<summary>API</summary>
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.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>
<summary>API Extensions</summary>
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.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>
<summary>SDK</summary>
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.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>
<summary>SDK Exporters</summary>
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.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>
<summary>SDK Extensions</summary>
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.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>
<summary>Shims</summary>
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.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
To take a dependency, [include a BOM][dependencies-and-boms] and specify the dependency as follows,
replacing `{{artifact-id}}` with the value from the "Artifact ID" column
from [artifacts](#artifacts):
<details open>
<summary>Gradle</summary>
```groovy
implementation('io.opentelemetry:{{artifact-id}}')
```
</details>
<details>
<summary>Maven</summary>
The following tables describe the artifacts published by this project. To take a dependency, follow
the instructions in [Published Released](#published-releases) to include the BOM, and specify the
dependency as follows, replacing `{{artifact-id}}` with the value from the "Artifact ID" column:
```xml
<dependency>
@ -166,142 +220,125 @@ from [artifacts](#artifacts):
<artifactId>{{artifact-id}}</artifactId>
</dependency>
```
</details>
### Snapshots
Snapshots of the `main` branch are available as follows:
<details open>
<summary>Gradle</summary>
```groovy
repositories {
maven { url 'https://central.sonatype.com/repository/maven-snapshots/' }
}
dependencies {
implementation platform("io.opentelemetry:opentelemetry-bom:1.53.0-SNAPSHOT")
implementation('io.opentelemetry:opentelemetry-api')
}
implementation('io.opentelemetry:{{artifact-id}}')
```
</details>
<details>
<summary>Maven</summary>
### Bill of Material
```xml
<project>
<repositories>
<repository>
<id>sonatype-snapshot-repository</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.53.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
</dependencies>
</project>
```
</details>
| Component | Description | Artifact ID | Version | Javadoc |
|----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------|
| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | <!--VERSION_STABLE-->1.36.0<!--/VERSION_STABLE--> | N/A |
| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | <!--VERSION_UNSTABLE-->1.36.0-alpha<!--/VERSION_UNSTABLE--> | N/A |
## Compatibility
### API
Artifacts from this repository follow semantic versioning.
Stable artifacts (i.e. artifacts without `-alpha` version suffix) come with strong backwards
compatibility guarantees for public APIs.
| Component | Description | Artifact ID | Version | Javadoc |
|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | <!--VERSION_STABLE-->1.36.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` | TODO: add after first publish | TODO: add after first publish |
| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | <!--VERSION_STABLE-->1.36.0<!--/VERSION_STABLE--> | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |
Artifacts may depend on other artifacts from this repository, and may depend on internal APIs (i.e.
non-public APIs) which are subject to change across minor versions. Therefore, it's critical to keep
artifact versions in sync in order to avoid possible runtime exceptions. We strongly
recommend [using one of our BOMs][dependencies-and-boms] to assist in keeping artifacts in sync.
### API Extensions
See the [VERSIONING.md](VERSIONING.md) for complete details on compatibility policy.
| Component | Description | Artifact ID | Version | Javadoc |
|---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | <!--VERSION_STABLE-->1.36.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.36.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) |
## Contacting us
### SDK
We hold regular meetings. See details at [community page](https://github.com/open-telemetry/community#java-sdk).
| Component | Description | Artifact ID | Version | Javadoc |
|------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | <!--VERSION_STABLE-->1.36.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.36.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.36.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.36.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.36.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.36.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) |
To report a bug, or request a new feature,
please [open an issue](https://github.com/open-telemetry/opentelemetry-java/issues/new/choose).
### SDK Exporters
We use [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-java/discussions)
for support or general questions. Feel free to drop us a line.
| 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.36.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.36.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.36.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.36.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.36.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.36.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.36.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.36.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/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | <!--VERSION_UNSTABLE-->1.36.0-alpha<!--/VERSION_UNSTABLE--> | [![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.36.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) | |
We are also present in the [`#otel-java`](https://cloud-native.slack.com/archives/C014L2KCTE3) channel in the [CNCF slack](https://slack.cncf.io/).
Please join us for more informal discussions.
### SDK Extensions
| Component | Description | Artifact ID | Version | Javadoc |
|-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | <!--VERSION_STABLE-->1.36.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.36.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.36.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.36.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) |
### Shims
| Component | Description | Artifact ID | Version | Javadoc |
|----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | <!--VERSION_UNSTABLE-->1.36.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.36.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) |
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for:
See [CONTRIBUTING.md](CONTRIBUTING.md)
* Details on building locally
* Project scope
* Keys to successful PRs
* Guide to using gradle composite builds
Triagers:
### Maintainers
- [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana Labs
*Find more about the triager role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager).*
Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemetry/teams/java-approvers)):
- [Jason Plumb](https://github.com/breedx-splk), Splunk
- [Josh Suereth](https://github.com/jsuereth), Google
- [Trask Stalnaker](https://github.com/trask), Microsoft
*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).*
Maintainers ([@open-telemetry/java-maintainers](https://github.com/orgs/open-telemetry/teams/java-maintainers)):
- [Jack Berg](https://github.com/jack-berg), New Relic
- [John Watson](https://github.com/jkwatson), Verta.ai
For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).
### 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
For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).
### Triagers
- [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana Labs
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
Emeritus:
- Maintainer [Bogdan Drutu](https://github.com/BogdanDrutu)
- Maintainer [Carlos Alberto](https://github.com/carlosalberto)
- Approver [Mateusz Rzeszutek](https://github.com/mateuszrzeszutek)
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).
*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer).*
### Help wanted
We are currently resource constrained and are actively seeking new contributors interested in working towards [approver](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver) / [maintainer](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer) roles. In addition to the documentation for approver / maintainer roles and the [contributing](./CONTRIBUTING.md) guide, here are some additional notes on engaging:
- [Pull request](https://github.com/open-telemetry/opentelemetry-java/pulls) reviews are equally or more helpful than code contributions. Comments and approvals are valuable with or without a formal project role. They're also a great forcing function to explore a fairly complex codebase.
- Attending the [Java: SDK + Automatic Instrumentation](https://github.com/open-telemetry/community?tab=readme-ov-file#implementation-sigs) Special Interest Group (SIG) is a great way to get to know community members and learn about project priorities.
- Issues labeled [help wanted](https://github.com/open-telemetry/opentelemetry-java/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) are project priorities. Code contributions (or pull request reviews when a PR is linked) for these issues are particularly important.
- Triaging / responding to new issues and discussions is a great way to engage with the project.
### Thanks to all of our contributors!
### Thanks to all the people who have contributed
<a href="https://github.com/open-telemetry/opentelemetry-java/graphs/contributors">
<img alt="Repo contributors" src="https://contrib.rocks/image?repo=open-telemetry/opentelemetry-java" />
<img 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.sml.io/maven-central/io.opentelemetry/opentelemetry-api/badge.svg
[maven-url]: https://maven-badges.sml.io/maven-central/io.opentelemetry/opentelemetry-api
[Manual instrumentation]: https://opentelemetry.io/docs/java/manual_instrumentation/
[maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api/badge.svg
[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api
[opentelemetry-java-instrumentation]: https://github.com/open-telemetry/opentelemetry-java-instrumentation
[opentelemetry-java-docs]: https://github.com/open-telemetry/opentelemetry-java-docs
[opentelemetry-semantic-conventions]: https://opentelemetry.io/docs/specs/semconv/
[opentelemetry-semantic-conventions-java]: https://github.com/open-telemetry/semantic-conventions-java
[opentelemetry.io]: https://opentelemetry.io
[otel-java-status]: https://opentelemetry.io/docs/instrumentation/java/#status-and-releases

View File

@ -57,16 +57,23 @@ 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

View File

@ -18,7 +18,7 @@ changes are:
reordering parameters, adding a method to an interface or abstract class without adding a default
implementation.
- [ABI](https://wikipedia.org/wiki/Application_binary_interface) changes that could require code using the artifact to be recompiled, but not changed, e.g.,
- ABI changes that could require code using the artifact to be recompiled, but not changed, e.g.,
changing the return type of a method from `void` to non-`void`, changing a `class` to an `interface`.
The [JLS](https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html) has more information on
what constitutes compatible changes.
@ -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 | 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. |
| Android | 21+ (NOTE: [desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) is required. We stay up to date with the latest version of [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs).) | Artifacts using `otel.animalsniffer-conventions` plugin | Kept in sync with minimum requirements for [Google Play services](https://developers.google.com/android/guides/setup). Subject to change in minor version. |
| Kotlin | 1.6+ | Only applies to `opentelemetry-extension-kotlin` | Kept in sync with [minimum non-deprecated](https://kotlinlang.org/docs/gradle-compiler-options.html#attributes-common-to-jvm-and-js) version. Subject to change in minor versions. |
## API vs SDK

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, Common, or generic Java type.
* return only API, Context or generic Java type.
*/
@Test
void sdkImplementationOfApiClassesShouldReturnApiTypeOnly() {
@ -45,11 +45,7 @@ class SdkDesignTest {
.and(implementOrOverride())
.should()
.haveRawReturnType(
inPackage(
"io.opentelemetry.api..",
"io.opentelemetry.context..",
"io.opentelemetry.common..",
"java.."))
inPackage("io.opentelemetry.api..", "io.opentelemetry.context..", "java.."))
.orShould()
.haveRawReturnType("void");

View File

@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath)
configurations.add(generatedSignature)
dependencies {
signature("com.toasttab.android:gummy-bears-api-23:0.12.0@signature")
signature("com.toasttab.android:gummy-bears-api-21:0.8.0@signature")
signatureJar("com.android.tools:desugar_jdk_libs")
}

View File

@ -15,8 +15,6 @@ dependencies {
annotationProcessor("com.google.auto.value:auto-value")
testImplementation(project(":api:testing-internal"))
testImplementation("edu.berkeley.cs.jqf:jqf-fuzz")
testImplementation("com.google.guava:guava-testlib")
}

View File

@ -17,7 +17,6 @@ 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;
@ -117,21 +116,6 @@ 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

@ -99,23 +99,4 @@ public interface Baggage extends ImplicitContextKeyed {
* be set to not use an implicit parent, so any parent assignment must be done manually.
*/
BaggageBuilder toBuilder();
/**
* Returns the {@code BaggageEntry} associated with the given key.
*
* @param entryKey entry key to return the {@code BaggageEntry} for, or {@code null} if no {@code
* Entry} with the given {@code entryKey} is in this {@code Baggage}.
* @since 1.43.0
*/
@Nullable
default BaggageEntry getEntry(String entryKey) {
BaggageEntry[] result = new BaggageEntry[] {null};
forEach(
(key, entry) -> {
if (entryKey.equals(key)) {
result[0] = entry;
}
});
return result[0];
}
}

View File

@ -37,13 +37,6 @@ final class ImmutableBaggage extends ImmutableKeyValuePairs<String, BaggageEntry
return entry != null ? entry.getValue() : null;
}
// Overrides the default implementation to provide a more performant implementation.
@Nullable
@Override
public BaggageEntry getEntry(String entryKey) {
return get(entryKey);
}
@Override
public BaggageBuilder toBuilder() {
return new Builder(new ArrayList<>(data()));

View File

@ -13,6 +13,7 @@
* <p>Note that entries are independent of the tracing data that is propagated in the {@link
* io.opentelemetry.context.Context}, such as trace ID.
*/
// TODO: Add code examples.
@ParametersAreNonnullByDefault
package io.opentelemetry.api.baggage;

View File

@ -12,11 +12,11 @@ import javax.annotation.Nullable;
/**
* Implements single-pass Baggage parsing in accordance with https://w3c.github.io/baggage/ Key /
* value are restricted in accordance with https://www.ietf.org/rfc/rfc2616.txt.
* value are restricted in accordance with https://www.ietf.org/rfc/rfc2616.txt
*
* <p>Note: following aspects are not specified in RFC: - some invalid elements (key or value) -
* parser will include valid ones, disregard invalid - empty "value" is regarded as invalid - meta -
* anything besides element terminator (comma).
* anything besides element terminator (comma)
*/
class Parser {
@ -37,7 +37,7 @@ class Parser {
private boolean skipToNext;
Parser(String baggageHeader) {
public Parser(String baggageHeader) {
this.baggageHeader = baggageHeader;
reset(0);
}

View File

@ -17,7 +17,6 @@ import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.context.propagation.TextMapSetter;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
@ -96,34 +95,21 @@ public final class W3CBaggagePropagator implements TextMapPropagator {
return context;
}
return extractMulti(context, carrier, getter);
}
private static <C> Context extractMulti(
Context context, @Nullable C carrier, TextMapGetter<C> getter) {
Iterator<String> baggageHeaders = getter.getAll(carrier, FIELD);
if (baggageHeaders == null) {
String baggageHeader = getter.get(carrier, FIELD);
if (baggageHeader == null) {
return context;
}
if (baggageHeader.isEmpty()) {
return context;
}
boolean extracted = false;
BaggageBuilder baggageBuilder = Baggage.builder();
while (baggageHeaders.hasNext()) {
String header = baggageHeaders.next();
if (header.isEmpty()) {
continue;
}
try {
extractEntries(header, baggageBuilder);
extracted = true;
} catch (RuntimeException expected) {
// invalid baggage header, continue
}
try {
extractEntries(baggageHeader, baggageBuilder);
} catch (RuntimeException e) {
return context;
}
return extracted ? context.with(baggageBuilder.build()) : context;
return context.with(baggageBuilder.build());
}
private static void extractEntries(String baggageHeader, BaggageBuilder baggageBuilder) {
@ -141,7 +127,7 @@ public final class W3CBaggagePropagator implements TextMapPropagator {
* @return whether the name is valid.
*/
private static boolean isValidBaggageKey(String name) {
return name != null && !name.trim().isEmpty() && StringUtils.isPrintableString(name);
return name != null && !name.isEmpty() && StringUtils.isPrintableString(name);
}
/**

View File

@ -9,7 +9,6 @@ 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;
@ -38,7 +37,7 @@ class ArrayBackedAttributesBuilder implements AttributesBuilder {
}
@Override
public <T> AttributesBuilder put(AttributeKey<T> key, @Nullable T value) {
public <T> AttributesBuilder put(AttributeKey<T> key, T value) {
if (key == null || key.getKey().isEmpty() || value == null) {
return this;
}

View File

@ -26,11 +26,6 @@ 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,7 +18,6 @@ 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 {
@ -36,22 +35,18 @@ public interface AttributesBuilder {
// version.
<T> AttributesBuilder put(AttributeKey<Long> key, int 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 {@link AttributeKey} with associated value into this. */
<T> AttributesBuilder put(AttributeKey<T> key, T value);
/**
* Puts a String attribute into this if the value is non-null. Providing a null value does not
* remove or unset previously set values.
* Puts a String attribute into this.
*
* <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, @Nullable String value) {
default AttributesBuilder put(String key, String value) {
return put(stringKey(key), value);
}

View File

@ -1,26 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
/**
* Key-value pair of {@link String} key and {@link Value} value.
*
* @see Value#of(KeyValue...)
* @since 1.42.0
*/
public interface KeyValue {
/** Returns a {@link KeyValue} for the given {@code key} and {@code value}. */
static KeyValue of(String key, Value<?> value) {
return KeyValueImpl.create(key, value);
}
/** Returns the key. */
String getKey();
/** Returns the value. */
Value<?> getValue();
}

View File

@ -1,18 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import com.google.auto.value.AutoValue;
@AutoValue
abstract class KeyValueImpl implements KeyValue {
KeyValueImpl() {}
static KeyValueImpl create(String key, Value<?> value) {
return new AutoValue_KeyValueImpl(key, value);
}
}

View File

@ -1,75 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import static java.util.stream.Collectors.joining;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
final class KeyValueList implements Value<List<KeyValue>> {
private final List<KeyValue> value;
private KeyValueList(List<KeyValue> value) {
this.value = value;
}
static Value<List<KeyValue>> create(KeyValue... value) {
Objects.requireNonNull(value, "value must not be null");
List<KeyValue> list = new ArrayList<>(value.length);
list.addAll(Arrays.asList(value));
return new KeyValueList(Collections.unmodifiableList(list));
}
static Value<List<KeyValue>> createFromMap(Map<String, Value<?>> value) {
Objects.requireNonNull(value, "value must not be null");
KeyValue[] array =
value.entrySet().stream()
.map(entry -> KeyValue.of(entry.getKey(), entry.getValue()))
.toArray(KeyValue[]::new);
return create(array);
}
@Override
public ValueType getType() {
return ValueType.KEY_VALUE_LIST;
}
@Override
public List<KeyValue> getValue() {
return value;
}
@Override
public String asString() {
return value.stream()
.map(item -> item.getKey() + "=" + item.getValue().asString())
.collect(joining(", ", "[", "]"));
}
@Override
public String toString() {
return "KeyValueList{" + asString() + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
return (o instanceof Value) && Objects.equals(this.value, ((Value<?>) o).getValue());
}
@Override
public int hashCode() {
return value.hashCode();
}
}

View File

@ -1,118 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
/**
* Value mirrors the proto <a
* href="https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/common/v1/common.proto#L28">AnyValue</a>
* message type, and is used to model any type.
*
* <p>It can be used to represent:
*
* <ul>
* <li>Primitive values via {@link #of(long)}, {@link #of(String)}, {@link #of(boolean)}, {@link
* #of(double)}.
* <li>String-keyed maps (i.e. associative arrays, dictionaries) via {@link #of(KeyValue...)},
* {@link #of(Map)}. Note, because map values are type {@link Value}, maps can be nested
* within other maps.
* <li>Arrays (heterogeneous or homogenous) via {@link #of(Value[])}. Note, because array values
* are type {@link Value}, arrays can contain primitives, complex types like maps or arrays,
* or any combination.
* <li>Raw bytes via {@link #of(byte[])}
* </ul>
*
* <p>Currently, Value is only used as an argument for {@link
* io.opentelemetry.api.logs.LogRecordBuilder#setBody(Value)}.
*
* @param <T> the type. See {@link #getValue()} for description of types.
* @since 1.42.0
*/
public interface Value<T> {
/** Returns an {@link Value} for the {@link String} value. */
static Value<String> of(String value) {
return ValueString.create(value);
}
/** Returns an {@link Value} for the {@code boolean} value. */
static Value<Boolean> of(boolean value) {
return ValueBoolean.create(value);
}
/** Returns an {@link Value} for the {@code long} value. */
static Value<Long> of(long value) {
return ValueLong.create(value);
}
/** Returns an {@link Value} for the {@code double} value. */
static Value<Double> of(double value) {
return ValueDouble.create(value);
}
/** Returns an {@link Value} for the {@code byte[]} value. */
static Value<ByteBuffer> of(byte[] value) {
return ValueBytes.create(value);
}
/** Returns an {@link Value} for the array of {@link Value} values. */
static Value<List<Value<?>>> of(Value<?>... value) {
return ValueArray.create(value);
}
/** Returns an {@link Value} for the list of {@link Value} values. */
static Value<List<Value<?>>> of(List<Value<?>> value) {
return ValueArray.create(value);
}
/**
* Returns an {@link Value} for the array of {@link KeyValue} values. {@link KeyValue#getKey()}
* values should not repeat - duplicates may be dropped.
*/
static Value<List<KeyValue>> of(KeyValue... value) {
return KeyValueList.create(value);
}
/** Returns an {@link Value} for the {@link Map} of key, {@link Value}. */
static Value<List<KeyValue>> of(Map<String, Value<?>> value) {
return KeyValueList.createFromMap(value);
}
/** Returns the type of this {@link Value}. Useful for building switch statements. */
ValueType getType();
/**
* Returns the value for this {@link Value}.
*
* <p>The return type varies by {@link #getType()} as described below:
*
* <ul>
* <li>{@link ValueType#STRING} returns {@link String}
* <li>{@link ValueType#BOOLEAN} returns {@code boolean}
* <li>{@link ValueType#LONG} returns {@code long}
* <li>{@link ValueType#DOUBLE} returns {@code double}
* <li>{@link ValueType#ARRAY} returns {@link List} of {@link Value}
* <li>{@link ValueType#KEY_VALUE_LIST} returns {@link List} of {@link KeyValue}
* <li>{@link ValueType#BYTES} returns read only {@link ByteBuffer}. See {@link
* ByteBuffer#asReadOnlyBuffer()}.
* </ul>
*/
T getValue();
/**
* Return a string encoding of this {@link Value}. This is intended to be a fallback serialized
* representation in case there is no suitable encoding that can utilize {@link #getType()} /
* {@link #getValue()} to serialize specific types.
*
* <p>WARNING: No guarantees are made about the encoding of this string response. It MAY change in
* a future minor release. If you need a reliable string encoding, write your own serializer.
*/
// TODO(jack-berg): Should this be a JSON encoding?
String asString();
}

View File

@ -1,67 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import static java.util.stream.Collectors.joining;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
final class ValueArray implements Value<List<Value<?>>> {
private final List<Value<?>> value;
private ValueArray(List<Value<?>> value) {
this.value = value;
}
static Value<List<Value<?>>> create(Value<?>... value) {
Objects.requireNonNull(value, "value must not be null");
List<Value<?>> list = new ArrayList<>(value.length);
list.addAll(Arrays.asList(value));
return new ValueArray(Collections.unmodifiableList(list));
}
static Value<List<Value<?>>> create(List<Value<?>> value) {
return new ValueArray(Collections.unmodifiableList(value));
}
@Override
public ValueType getType() {
return ValueType.ARRAY;
}
@Override
public List<Value<?>> getValue() {
return value;
}
@Override
public String asString() {
return value.stream().map(Value::asString).collect(joining(", ", "[", "]"));
}
@Override
public String toString() {
return "ValueArray{" + asString() + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
return (o instanceof Value) && Objects.equals(this.value, ((Value<?>) o).getValue());
}
@Override
public int hashCode() {
return value.hashCode();
}
}

View File

@ -5,10 +5,8 @@
package io.opentelemetry.api.internal;
import java.util.ConcurrentModificationException;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import javax.annotation.Nullable;
/**
@ -21,17 +19,6 @@ public final class ConfigUtil {
private ConfigUtil() {}
/**
* Returns a copy of system properties which is safe to iterate over.
*
* <p>In java 8 and android environments, iterating through system properties may trigger {@link
* ConcurrentModificationException}. This method ensures callers can iterate safely without risk
* of exception. See https://github.com/open-telemetry/opentelemetry-java/issues/6732 for details.
*/
public static Properties safeSystemProperties() {
return (Properties) System.getProperties().clone();
}
/**
* Return the system property or environment variable for the {@code key}.
*
@ -46,9 +33,8 @@ public final class ConfigUtil {
*/
public static String getString(String key, String defaultValue) {
String normalizedKey = normalizePropertyKey(key);
String systemProperty =
safeSystemProperties().entrySet().stream()
System.getProperties().entrySet().stream()
.filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey().toString())))
.map(entry -> entry.getValue().toString())
.findFirst()

View File

@ -274,13 +274,4 @@ public abstract class ImmutableKeyValuePairs<K, V> {
sb.append("}");
return sb.toString();
}
/**
* Return the backing data array for these attributes. This is only exposed for internal use by
* opentelemetry authors. The contents of the array MUST NOT be modified.
*/
@SuppressWarnings("AvoidObjectArrays")
public Object[] getData() {
return data;
}
}

View File

@ -1,29 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.internal;
import java.lang.reflect.Method;
/**
* Incubating utilities.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class IncubatingUtil {
private IncubatingUtil() {}
@SuppressWarnings("unchecked")
public static <T> T incubatingApiIfAvailable(T stableApi, String incubatingClassName) {
try {
Class<?> incubatingClass = Class.forName(incubatingClassName);
Method getInstance = incubatingClass.getDeclaredMethod("getNoop");
return (T) getInstance.invoke(null);
} catch (Exception e) {
return stableApi;
}
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.internal;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import java.util.Objects;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class InstrumentationUtil {
private static final ContextKey<Boolean> SUPPRESS_INSTRUMENTATION_KEY =
ContextKey.named("suppress_instrumentation");
private InstrumentationUtil() {}
/**
* Adds a Context boolean key that will allow to identify HTTP calls coming from OTel exporters.
* The key later be checked by an automatic instrumentation to avoid tracing OTel exporter's
* calls.
*/
public static void suppressInstrumentation(Runnable runnable) {
Context.current().with(SUPPRESS_INSTRUMENTATION_KEY, true).wrap(runnable).run();
}
/**
* Checks if an automatic instrumentation should be suppressed with the provided Context.
*
* @return TRUE to suppress the automatic instrumentation, FALSE to continue with the
* instrumentation.
*/
public static boolean shouldSuppressInstrumentation(Context context) {
return Objects.equals(context.get(SUPPRESS_INSTRUMENTATION_KEY), true);
}
}

View File

@ -89,15 +89,10 @@ public final class OtelEncodingUtils {
/** Returns the {@code byte[]} decoded from the given hex {@link CharSequence}. */
public static byte[] bytesFromBase16(CharSequence value, int length) {
byte[] result = new byte[length / 2];
bytesFromBase16(value, length, result);
return result;
}
/** Fills {@code bytes} with bytes decoded from the given hex {@link CharSequence}. */
public static void bytesFromBase16(CharSequence value, int length, byte[] bytes) {
for (int i = 0; i < length; i += 2) {
bytes[i / 2] = byteFromBase16(value.charAt(i), value.charAt(i + 1));
result[i / 2] = byteFromBase16(value.charAt(i), value.charAt(i + 1));
}
return result;
}
/** Fills {@code dest} with the hex encoding of {@code bytes}. */

View File

@ -6,11 +6,9 @@
package io.opentelemetry.api.logs;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Value;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
class DefaultLogger implements Logger {
@ -73,12 +71,7 @@ class DefaultLogger implements Logger {
}
@Override
public LogRecordBuilder setBody(Value<?> body) {
return this;
}
@Override
public <T> LogRecordBuilder setAttribute(AttributeKey<T> key, @Nullable T value) {
public <T> LogRecordBuilder setAttribute(AttributeKey<T> key, T value) {
return this;
}

View File

@ -5,18 +5,11 @@
package io.opentelemetry.api.logs;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.doubleKey;
import static io.opentelemetry.api.common.AttributeKey.longKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.Value;
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}.
@ -73,23 +66,9 @@ public interface LogRecordBuilder {
/** Set the severity text. */
LogRecordBuilder setSeverityText(String severityText);
/**
* Set the body string.
*
* <p>Shorthand for calling {@link #setBody(Value)} with {@link Value#of(String)}.
*/
/** Set the body string. */
LogRecordBuilder setBody(String body);
/**
* Set the body {@link Value}.
*
* @since 1.42.0
*/
default LogRecordBuilder setBody(Value<?> body) {
setBody(body.asString());
return this;
}
/**
* Sets attributes. If the {@link LogRecordBuilder} previously contained a mapping for any of the
* keys, the old values are replaced by the specified values.
@ -104,111 +83,8 @@ public interface LogRecordBuilder {
return this;
}
/**
* 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;
}
/** Sets an attribute. */
<T> LogRecordBuilder setAttribute(AttributeKey<T> key, T value);
/** Emit the log record. */
void emit();

View File

@ -5,7 +5,6 @@
package io.opentelemetry.api.logs;
import io.opentelemetry.api.internal.IncubatingUtil;
import javax.annotation.concurrent.ThreadSafe;
/**
@ -44,8 +43,6 @@ public interface LoggerProvider {
/** Returns a no-op {@link LoggerProvider} which provides Loggers which do not record or emit. */
static LoggerProvider noop() {
return IncubatingUtil.incubatingApiIfAvailable(
DefaultLoggerProvider.getInstance(),
"io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider");
return DefaultLoggerProvider.getInstance();
}
}

View File

@ -320,10 +320,8 @@ class DefaultMeter implements Meter {
}
private static class NoopDoubleGaugeBuilder implements DoubleGaugeBuilder {
private static final ObservableDoubleGauge NOOP_OBSERVABLE_GAUGE =
new ObservableDoubleGauge() {};
private static final ObservableDoubleGauge NOOP = new ObservableDoubleGauge() {};
private static final LongGaugeBuilder NOOP_LONG_GAUGE_BUILDER = new NoopLongGaugeBuilder();
private static final NoopDoubleGauge NOOP_GAUGE = new NoopDoubleGauge();
@Override
public DoubleGaugeBuilder setDescription(String description) {
@ -342,34 +340,17 @@ class DefaultMeter implements Meter {
@Override
public ObservableDoubleGauge buildWithCallback(Consumer<ObservableDoubleMeasurement> callback) {
return NOOP_OBSERVABLE_GAUGE;
return NOOP;
}
@Override
public ObservableDoubleMeasurement buildObserver() {
return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT;
}
@Override
public DoubleGauge build() {
return NOOP_GAUGE;
}
}
private static class NoopDoubleGauge implements DoubleGauge {
@Override
public void set(double value) {}
@Override
public void set(double value, Attributes attributes) {}
@Override
public void set(double value, Attributes attributes, Context context) {}
}
private static class NoopLongGaugeBuilder implements LongGaugeBuilder {
private static final ObservableLongGauge NOOP_OBSERVABLE_GAUGE = new ObservableLongGauge() {};
private static final NoopLongGauge NOOP_GAUGE = new NoopLongGauge();
private static final ObservableLongGauge NOOP = new ObservableLongGauge() {};
@Override
public LongGaugeBuilder setDescription(String description) {
@ -383,29 +364,13 @@ class DefaultMeter implements Meter {
@Override
public ObservableLongGauge buildWithCallback(Consumer<ObservableLongMeasurement> callback) {
return NOOP_OBSERVABLE_GAUGE;
return NOOP;
}
@Override
public ObservableLongMeasurement buildObserver() {
return NOOP_OBSERVABLE_LONG_MEASUREMENT;
}
@Override
public LongGauge build() {
return NOOP_GAUGE;
}
}
private static class NoopLongGauge implements LongGauge {
@Override
public void set(long value) {}
@Override
public void set(long value, Attributes attributes) {}
@Override
public void set(long value, Attributes attributes, Context context) {}
}
private static class NoopObservableDoubleMeasurement implements ObservableDoubleMeasurement {

View File

@ -5,8 +5,6 @@
package io.opentelemetry.api.metrics;
import io.opentelemetry.api.internal.IncubatingUtil;
/** A {@link MeterProvider} that does nothing. */
class DefaultMeterProvider implements MeterProvider {
@Override
@ -14,10 +12,7 @@ class DefaultMeterProvider implements MeterProvider {
return BUILDER_INSTANCE;
}
private static final MeterProvider INSTANCE =
IncubatingUtil.incubatingApiIfAvailable(
new DefaultMeterProvider(),
"io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider");
private static final DefaultMeterProvider INSTANCE = new DefaultMeterProvider();
private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder();
static MeterProvider getInstance() {

View File

@ -65,21 +65,4 @@ public interface DoubleGaugeBuilder {
default ObservableDoubleMeasurement buildObserver() {
return DefaultMeter.getInstance().gaugeBuilder("noop").buildObserver();
}
/**
* Builds and returns a DoubleGauge instrument with the configuration.
*
* <p>NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users
* will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe
* the value of the gauge when metrics are collected.
*
* <p>If using the OpenTelemetry SDK, by default gauges use last value aggregation, such that only
* the value of the last recorded measurement is exported.
*
* @return The DoubleGauge instrument.
* @since 1.38.0
*/
default DoubleGauge build() {
return DefaultMeter.getInstance().gaugeBuilder("noop").build();
}
}

View File

@ -62,21 +62,4 @@ public interface LongGaugeBuilder {
default ObservableLongMeasurement buildObserver() {
return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().buildObserver();
}
/**
* Builds and returns a LongGauge instrument with the configuration.
*
* <p>NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users
* will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe
* the value of the gauge when metrics are collected.
*
* <p>If using the OpenTelemetry SDK, by default gauges use last value aggregation, such that only
* the value of the last recorded measurement is exported.
*
* @return The LongGauge instrument.
* @since 1.38.0
*/
default LongGauge build() {
return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().build();
}
}

View File

@ -65,7 +65,7 @@ public interface Meter {
* callbacks).
*
* @param name the name of the Counter. Instrument names must consist of 255 or fewer characters
* including alphanumeric, _, ., -, /, and start with a letter.
* including alphanumeric, _, ., -, and start with a letter.
* @return a builder for configuring a Counter instrument. Defaults to recording long values, but
* may be changed.
* @see <a
@ -81,7 +81,7 @@ public interface Meter {
* callbacks).
*
* @param name the name of the UpDownCounter. Instrument names must consist of 255 or fewer
* characters including alphanumeric, _, ., -, /, and start with a letter.
* characters including alphanumeric, _, ., -, and start with a letter.
* @return a builder for configuring an UpDownCounter instrument. Defaults to recording long
* values, but may be changed.
* @see <a
@ -94,7 +94,7 @@ public interface Meter {
* Constructs a Histogram instrument.
*
* @param name the name of the Histogram. Instrument names must consist of 255 or fewer characters
* including alphanumeric, _, ., -, /, and start with a letter.
* including alphanumeric, _, ., -, and start with a letter.
* @return a builder for configuring a Histogram synchronous instrument. Defaults to recording
* double values, but may be changed.
* @see <a
@ -107,7 +107,7 @@ public interface Meter {
* Constructs an Asynchronous Gauge instrument.
*
* @param name the name of the Gauge. Instrument names must consist of 255 or fewer characters
* including alphanumeric, _, ., -, /, and start with a letter.
* including alphanumeric, _, ., -, and start with a letter.
* @return a builder used for configuring a Gauge instrument. Defaults to recording double values,
* but may be changed.
* @see <a

View File

@ -5,16 +5,12 @@
package io.opentelemetry.api.trace;
import io.opentelemetry.api.internal.IncubatingUtil;
import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
class DefaultTracerProvider implements TracerProvider {
private static final TracerProvider INSTANCE =
IncubatingUtil.incubatingApiIfAvailable(
new DefaultTracerProvider(),
"io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider");
private static final TracerProvider INSTANCE = new DefaultTracerProvider();
static TracerProvider getInstance() {
return INSTANCE;

View File

@ -8,7 +8,6 @@ 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;
/**
@ -43,7 +42,7 @@ final class PropagatedSpan implements Span {
}
@Override
public Span setAttribute(String key, @Nullable String value) {
public Span setAttribute(String key, String value) {
return this;
}
@ -63,7 +62,7 @@ final class PropagatedSpan implements Span {
}
@Override
public <T> Span setAttribute(AttributeKey<T> key, @Nullable T value) {
public <T> Span setAttribute(AttributeKey<T> key, T value) {
return this;
}

View File

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

View File

@ -238,19 +238,6 @@ public interface SpanBuilder {
*/
<T> SpanBuilder setAttribute(AttributeKey<T> key, T value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @since 1.45.0
*/
default SpanBuilder setAttribute(AttributeKey<Long> key, int value) {
return setAttribute(key, (long) value);
}
/**
* Sets attributes to the {@link SpanBuilder}. If the {@link SpanBuilder} previously contained a
* mapping for any of the keys, the old values are replaced by the specified values.

View File

@ -18,6 +18,7 @@
* io.opentelemetry.context.Context} and between process using one of the wire propagation formats
* supported in the {@code opentelemetry.trace.propagation} package.
*/
// TODO: Add code examples.
@ParametersAreNonnullByDefault
package io.opentelemetry.api.trace;

View File

@ -5,25 +5,100 @@
package io.opentelemetry.api;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.testing.internal.AbstractOpenTelemetryTest;
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
class OpenTelemetryTest extends AbstractOpenTelemetryTest {
class OpenTelemetryTest {
@Override
protected TracerProvider getTracerProvider() {
return TracerProvider.noop();
@BeforeAll
static void beforeClass() {
GlobalOpenTelemetry.resetForTest();
}
@Override
protected MeterProvider getMeterProvider() {
return MeterProvider.noop();
@AfterEach
void after() {
GlobalOpenTelemetry.resetForTest();
}
@Override
protected LoggerProvider getLoggerProvider() {
return LoggerProvider.noop();
@Test
void testDefault() {
assertThat(OpenTelemetry.noop().getTracerProvider()).isSameAs(TracerProvider.noop());
assertThat(OpenTelemetry.noop().getPropagators()).isSameAs(ContextPropagators.noop());
assertThat(OpenTelemetry.noop().getMeterProvider()).isSameAs(MeterProvider.noop());
assertThat(OpenTelemetry.noop().getLogsBridge()).isSameAs(LoggerProvider.noop());
}
@Test
void propagating() {
ContextPropagators contextPropagators = mock(ContextPropagators.class);
OpenTelemetry openTelemetry = OpenTelemetry.propagating(contextPropagators);
assertThat(openTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop());
assertThat(openTelemetry.getMeterProvider()).isSameAs(MeterProvider.noop());
assertThat(openTelemetry.getLogsBridge()).isSameAs(LoggerProvider.noop());
assertThat(openTelemetry.getPropagators()).isSameAs(contextPropagators);
}
@Test
void testGlobalBeforeSet() {
assertThat(GlobalOpenTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop());
assertThat(GlobalOpenTelemetry.getTracerProvider())
.isSameAs(GlobalOpenTelemetry.getTracerProvider());
assertThat(GlobalOpenTelemetry.getPropagators()).isSameAs(GlobalOpenTelemetry.getPropagators());
}
@Test
void independentNonGlobalPropagators() {
ContextPropagators propagators1 = mock(ContextPropagators.class);
OpenTelemetry otel1 = OpenTelemetry.propagating(propagators1);
ContextPropagators propagators2 = mock(ContextPropagators.class);
OpenTelemetry otel2 = OpenTelemetry.propagating(propagators2);
assertThat(otel1.getPropagators()).isSameAs(propagators1);
assertThat(otel2.getPropagators()).isSameAs(propagators2);
}
@Test
void setThenSet() {
setOpenTelemetry();
assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop()))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("GlobalOpenTelemetry.set has already been called")
.hasStackTraceContaining("setOpenTelemetry");
}
@Test
void getThenSet() {
assertThat(getOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class);
assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop()))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("GlobalOpenTelemetry.set has already been called")
.hasStackTraceContaining("getOpenTelemetry");
}
@Test
void toString_noop_Valid() {
assertThat(OpenTelemetry.noop().toString())
.isEqualTo(
"DefaultOpenTelemetry{"
+ "propagators=DefaultContextPropagators{textMapPropagator=NoopTextMapPropagator}"
+ "}");
}
private static void setOpenTelemetry() {
GlobalOpenTelemetry.set(OpenTelemetry.noop());
}
private static OpenTelemetry getOpenTelemetry() {
return GlobalOpenTelemetry.get();
}
}

View File

@ -9,10 +9,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
import org.junit.jupiter.api.Test;
class BaggageTest {
@ -31,45 +27,4 @@ class BaggageTest {
assertThat(result.getEntryValue("foo")).isEqualTo("bar");
}
}
@Test
void getEntryDefault() {
BaggageEntryMetadata metadata = BaggageEntryMetadata.create("flib");
Map<String, BaggageEntry> result = new HashMap<>();
result.put("a", ImmutableEntry.create("b", metadata));
// Implementation that only implements asMap() which is used by getEntry()
Baggage baggage =
new Baggage() {
@Override
public Map<String, BaggageEntry> asMap() {
return result;
}
@Override
public int size() {
return 0;
}
@Override
public void forEach(BiConsumer<? super String, ? super BaggageEntry> consumer) {
result.forEach(consumer);
}
@Nullable
@Override
public String getEntryValue(String entryKey) {
return null;
}
@Override
public BaggageBuilder toBuilder() {
return null;
}
};
BaggageEntry entry = baggage.getEntry("a");
assertThat(entry.getValue()).isEqualTo("b");
assertThat(entry.getMetadata().getValue()).isEqualTo("flib");
}
}

View File

@ -9,8 +9,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import com.google.common.testing.EqualsTester;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import org.junit.jupiter.api.Test;
/**
@ -192,15 +190,4 @@ class ImmutableBaggageTest {
.addEqualityGroup(baggage2, baggage3)
.testEquals();
}
@Test
void getEntry() {
BaggageEntryMetadata metadata = BaggageEntryMetadata.create("flib");
try (Scope scope =
Context.root().with(Baggage.builder().put("a", "b", metadata).build()).makeCurrent()) {
Baggage result = Baggage.current();
assertThat(result.getEntry("a").getValue()).isEqualTo("b");
assertThat(result.getEntry("a").getMetadata().getValue()).isEqualTo("flib");
}
}
}

View File

@ -8,7 +8,6 @@ package io.opentelemetry.api.baggage.propagation;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageEntryMetadata;
@ -16,9 +15,7 @@ import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.junit.jupiter.api.Test;
@ -39,28 +36,6 @@ class W3CBaggagePropagatorTest {
}
};
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();
}
@Nullable
@Override
public String get(Map<String, List<String>> carrier, String key) {
return carrier.getOrDefault(key, Collections.emptyList()).stream()
.findFirst()
.orElse(null);
}
@Override
public Iterator<String> getAll(Map<String, List<String>> carrier, String key) {
List<String> values = carrier.get(key);
return values == null ? Collections.emptyIterator() : values.iterator();
}
};
@Test
void fields() {
assertThat(W3CBaggagePropagator.getInstance().fields()).containsExactly("baggage");
@ -446,101 +421,6 @@ class W3CBaggagePropagatorTest {
.isSameAs(context);
}
@Test
void extract_multiple_headers() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(),
ImmutableMap.of("baggage", ImmutableList.of("k1=v1", "k2=v2")),
multiGetter);
Baggage expectedBaggage = Baggage.builder().put("k1", "v1").put("k2", "v2").build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void extract_multiple_headers_duplicate_key() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(),
ImmutableMap.of("baggage", ImmutableList.of("k1=v1", "k1=v2")),
multiGetter);
Baggage expectedBaggage = Baggage.builder().put("k1", "v2").build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void extract_multiple_headers_mixed_duplicates_non_duplicates() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(),
ImmutableMap.of("baggage", ImmutableList.of("k1=v1,k2=v0", "k2=v2,k3=v3")),
multiGetter);
Baggage expectedBaggage =
Baggage.builder().put("k1", "v1").put("k2", "v2").put("k3", "v3").build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void extract_multiple_headers_all_empty() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(), ImmutableMap.of("baggage", ImmutableList.of("", "")), multiGetter);
Baggage expectedBaggage = Baggage.builder().build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void extract_multiple_headers_some_empty() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(), ImmutableMap.of("baggage", ImmutableList.of("", "k=v")), multiGetter);
Baggage expectedBaggage = Baggage.builder().put("k", "v").build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void extract_multiple_headers_all_invalid() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(),
ImmutableMap.of("baggage", ImmutableList.of("!@#$%^", "key=va%lue")),
multiGetter);
Baggage expectedBaggage = Baggage.builder().build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void extract_multiple_headers_some_invalid() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Context result =
propagator.extract(
Context.root(),
ImmutableMap.of("baggage", ImmutableList.of("k1=v1", "key=va%lue", "k2=v2")),
multiGetter);
Baggage expectedBaggage = Baggage.builder().put("k1", "v1").put("k2", "v2").build();
assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage);
}
@Test
void inject_noBaggage() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
@ -568,7 +448,6 @@ class W3CBaggagePropagatorTest {
.put("\2ab\3cd", "wacky key nonprintable")
.put(null, "null key")
.put("nullvalue", null)
.put(" ", "key is only space")
.build();
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
Map<String, String> carrier = new HashMap<>();

View File

@ -26,7 +26,6 @@ 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. */
@ -566,7 +565,7 @@ class AttributesTest {
}
@Override
public <T> AttributesBuilder put(AttributeKey<T> key, @Nullable T value) {
public <T> AttributesBuilder put(AttributeKey<T> key, T value) {
return null;
}

View File

@ -6,15 +6,7 @@
package io.opentelemetry.api.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.SetSystemProperty;
@ -64,45 +56,4 @@ class ConfigUtilTest {
assertThat(ConfigUtil.defaultIfNull("val1", "val2")).isEqualTo("val1");
assertThat(ConfigUtil.defaultIfNull(null, "val2")).isEqualTo("val2");
}
@Test
@SuppressWarnings("ReturnValueIgnored")
void systemPropertiesConcurrentAccess() throws ExecutionException, InterruptedException {
int threads = 4;
ExecutorService executor = Executors.newFixedThreadPool(threads);
try {
int cycles = 1000;
CountDownLatch latch = new CountDownLatch(1);
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < threads; i++) {
futures.add(
executor.submit(
() -> {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
for (int j = 0; j < cycles; j++) {
String property = "prop " + j;
System.setProperty(property, "a");
System.getProperties().remove(property);
}
}));
}
latch.countDown();
for (int i = 0; i < cycles; i++) {
assertThatCode(() -> ConfigUtil.getString("x", "y")).doesNotThrowAnyException();
}
for (Future<?> future : futures) {
future.get();
}
} finally {
executor.shutdownNow();
}
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.internal;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import io.opentelemetry.context.Context;
import org.junit.jupiter.api.Test;
class InstrumentationUtilTest {
@Test
void verifySuppressInstrumentation() {
// Should be false by default.
assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current()));
// Should be true inside the Runnable passed to InstrumentationUtil.suppressInstrumentation.
InstrumentationUtil.suppressInstrumentation(
() -> assertTrue(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())));
// Should be false after the runnable finishes.
assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current()));
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.logs;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import org.junit.jupiter.api.Test;
class DefaultLoggerProviderTest {
@Test
void noopLoggerProvider_doesNotThrow() {
LoggerProvider provider = LoggerProvider.noop();
assertThat(provider).isSameAs(DefaultLoggerProvider.getInstance());
assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException();
assertThatCode(
() ->
provider
.loggerBuilder("scope-name")
.setInstrumentationVersion("1.0")
.setSchemaUrl("http://schema.com")
.build())
.doesNotThrowAnyException();
assertThatCode(() -> provider.loggerBuilder("scope-name").build().logRecordBuilder())
.doesNotThrowAnyException();
}
}

View File

@ -5,17 +5,34 @@
package io.opentelemetry.api.logs;
import io.opentelemetry.api.testing.internal.AbstractDefaultLoggerTest;
import static org.assertj.core.api.Assertions.assertThatCode;
class DefaultLoggerTest extends AbstractDefaultLoggerTest {
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
@Override
protected LoggerProvider getLoggerProvider() {
return DefaultLoggerProvider.getInstance();
}
class DefaultLoggerTest {
@Override
protected Logger getLogger() {
return DefaultLogger.getInstance();
@Test
void buildAndEmit() {
assertThatCode(
() ->
DefaultLogger.getInstance()
.logRecordBuilder()
.setTimestamp(100, TimeUnit.SECONDS)
.setTimestamp(Instant.now())
.setObservedTimestamp(100, TimeUnit.SECONDS)
.setObservedTimestamp(Instant.now())
.setContext(Context.root())
.setSeverity(Severity.DEBUG)
.setSeverityText("debug")
.setBody("body")
.setAttribute(AttributeKey.stringKey("key1"), "value1")
.setAllAttributes(Attributes.builder().put("key2", "value2").build())
.emit())
.doesNotThrowAnyException();
}
}

View File

@ -1,215 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.logs;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import io.opentelemetry.api.common.KeyValue;
import io.opentelemetry.api.common.Value;
import io.opentelemetry.api.common.ValueType;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class ValueTest {
@Test
void value_OfString() {
assertThat(Value.of("foo"))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.STRING);
assertThat(value.getValue()).isEqualTo("foo");
assertThat(value).hasSameHashCodeAs(Value.of("foo"));
});
}
@Test
void value_OfBoolean() {
assertThat(Value.of(true))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.BOOLEAN);
assertThat(value.getValue()).isEqualTo(true);
assertThat(value).hasSameHashCodeAs(Value.of(true));
});
}
@Test
void value_OfLong() {
assertThat(Value.of(1L))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.LONG);
assertThat(value.getValue()).isEqualTo(1L);
assertThat(value).hasSameHashCodeAs(Value.of(1L));
});
}
@Test
void value_OfDouble() {
assertThat(Value.of(1.1))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.DOUBLE);
assertThat(value.getValue()).isEqualTo(1.1);
assertThat(value).hasSameHashCodeAs(Value.of(1.1));
});
}
@Test
void value_OfByteArray() {
assertThat(Value.of(new byte[] {'a', 'b'}))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.BYTES);
ByteBuffer buf = value.getValue();
// ValueBytes returns read only view of ByteBuffer
assertThatThrownBy(buf::array).isInstanceOf(ReadOnlyBufferException.class);
byte[] bytes = new byte[buf.remaining()];
buf.get(bytes);
assertThat(bytes).isEqualTo(new byte[] {'a', 'b'});
assertThat(value).hasSameHashCodeAs(Value.of(new byte[] {'a', 'b'}));
});
}
@Test
void value_OfvalueArray() {
assertThat(Value.of(Value.of(true), Value.of(1L)))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.ARRAY);
assertThat(value.getValue()).isEqualTo(Arrays.asList(Value.of(true), Value.of(1L)));
assertThat(value).hasSameHashCodeAs(Value.of(Value.of(true), Value.of(1L)));
});
}
@Test
@SuppressWarnings("DoubleBraceInitialization")
void value_OfKeyValueList() {
assertThat(Value.of(KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L))))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.KEY_VALUE_LIST);
assertThat(value.getValue())
.isEqualTo(
Arrays.asList(
KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L))));
assertThat(value)
.hasSameHashCodeAs(
Value.of(
KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L))));
});
assertThat(
Value.of(
new LinkedHashMap<String, Value<?>>() {
{
put("bool", Value.of(true));
put("long", Value.of(1L));
}
}))
.satisfies(
value -> {
assertThat(value.getType()).isEqualTo(ValueType.KEY_VALUE_LIST);
assertThat(value.getValue())
.isEqualTo(
Arrays.asList(
KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L))));
assertThat(value)
.hasSameHashCodeAs(
Value.of(
new LinkedHashMap<String, Value<?>>() {
{
put("bool", Value.of(true));
put("long", Value.of(1L));
}
}));
});
}
@Test
void value_NullsNotAllowed() {
assertThatThrownBy(() -> Value.of((String) null))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("value must not be null");
assertThatThrownBy(() -> Value.of((byte[]) null))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("value must not be null");
assertThatThrownBy(() -> Value.of((Value<?>[]) null))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("value must not be null");
assertThatThrownBy(() -> Value.of((KeyValue[]) null))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("value must not be null");
assertThatThrownBy(() -> Value.of((Map<String, Value<?>>) null))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("value must not be null");
}
@ParameterizedTest
@MethodSource("asStringArgs")
void asString(Value<?> value, String expectedAsString) {
assertThat(value.asString()).isEqualTo(expectedAsString);
}
@SuppressWarnings("DoubleBraceInitialization")
private static Stream<Arguments> asStringArgs() {
return Stream.of(
// primitives
arguments(Value.of("str"), "str"),
arguments(Value.of(true), "true"),
arguments(Value.of(1), "1"),
arguments(Value.of(1.1), "1.1"),
// heterogeneous array
arguments(
Value.of(Value.of("str"), Value.of(true), Value.of(1), Value.of(1.1)),
"[str, true, 1, 1.1]"),
// key value list from KeyValue array
arguments(
Value.of(KeyValue.of("key1", Value.of("val1")), KeyValue.of("key2", Value.of(2))),
"[key1=val1, key2=2]"),
// key value list from map
arguments(
Value.of(
new LinkedHashMap<String, Value<?>>() {
{
put("key1", Value.of("val1"));
put("key2", Value.of(2));
}
}),
"[key1=val1, key2=2]"),
// map of map
arguments(
Value.of(
Collections.singletonMap(
"child", Value.of(Collections.singletonMap("grandchild", Value.of("str"))))),
"[child=[grandchild=str]]"),
// bytes
arguments(Value.of("hello world".getBytes(StandardCharsets.UTF_8)), "aGVsbG8gd29ybGQ="));
}
@Test
void valueByteAsString() {
// TODO: add more test cases
String str = "hello world";
String base64Encoded = Value.of(str.getBytes(StandardCharsets.UTF_8)).asString();
byte[] decodedBytes = Base64.getDecoder().decode(base64Encoded);
assertThat(new String(decodedBytes, StandardCharsets.UTF_8)).isEqualTo(str);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.metrics;
import org.junit.jupiter.api.Test;
public class DefaultMeterProviderTest {
@Test
void noopMeterProvider_getDoesNotThrow() {
MeterProvider provider = MeterProvider.noop();
provider.get("user-instrumentation");
}
@Test
void noopMeterProvider_builderDoesNotThrow() {
MeterProvider provider = MeterProvider.noop();
provider.meterBuilder("user-instrumentation").build();
provider.meterBuilder("advanced-instrumetnation").setInstrumentationVersion("1.0").build();
provider.meterBuilder("schema-instrumentation").setSchemaUrl("myschema://url").build();
provider
.meterBuilder("schema-instrumentation")
.setInstrumentationVersion("1.0")
.setSchemaUrl("myschema://url")
.build();
}
}

View File

@ -5,17 +5,172 @@
package io.opentelemetry.api.metrics;
import io.opentelemetry.api.testing.internal.AbstractDefaultMeterTest;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
public class DefaultMeterTest extends AbstractDefaultMeterTest {
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import org.junit.jupiter.api.Test;
@Override
protected Meter getMeter() {
return DefaultMeter.getInstance();
@SuppressLogger()
public class DefaultMeterTest {
private static final Meter METER = DefaultMeter.getInstance();
@Test
void noopLongCounter_doesNotThrow() {
LongCounter counter =
METER.counterBuilder("size").setDescription("The size I'm measuring").setUnit("1").build();
counter.add(1);
counter.add(1, Attributes.of(stringKey("thing"), "car"));
counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current());
}
@Override
protected MeterProvider getMeterProvider() {
return DefaultMeterProvider.getInstance();
@Test
void noopDoubleCounter_doesNotThrow() {
DoubleCounter counter =
METER
.counterBuilder("size")
.ofDoubles()
.setDescription("The size I'm measuring")
.setUnit("1")
.build();
counter.add(1.2);
counter.add(2.5, Attributes.of(stringKey("thing"), "car"));
counter.add(2.5, Attributes.of(stringKey("thing"), "car"), Context.current());
}
@Test
void noopLongUpDownCounter_doesNotThrow() {
LongUpDownCounter counter =
METER
.upDownCounterBuilder("size")
.setDescription("The size I'm measuring")
.setUnit("1")
.build();
counter.add(-1);
counter.add(1, Attributes.of(stringKey("thing"), "car"));
counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current());
}
@Test
void noopDoubleUpDownCounter_doesNotThrow() {
DoubleUpDownCounter counter =
METER
.upDownCounterBuilder("size")
.ofDoubles()
.setDescription("The size I'm measuring")
.setUnit("1")
.build();
counter.add(-2e4);
counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"));
counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
}
@Test
void noopLongHistogram_doesNotThrow() {
LongHistogram histogram =
METER
.histogramBuilder("size")
.ofLongs()
.setDescription("The size I'm measuring")
.setUnit("1")
.build();
histogram.record(-1);
histogram.record(1, Attributes.of(stringKey("thing"), "car"));
histogram.record(1, Attributes.of(stringKey("thing"), "car"), Context.current());
}
@Test
void noopDoubleHistogram_doesNotThrow() {
DoubleHistogram histogram =
METER
.histogramBuilder("size")
.setDescription("The size I'm measuring")
.setUnit("1")
.build();
histogram.record(-2e4);
histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"));
histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
}
@Test
void noopObservableLongGauage_doesNotThrow() {
METER
.gaugeBuilder("temperature")
.ofLongs()
.setDescription("The current temperature")
.setUnit("C")
.buildWithCallback(
m -> {
m.record(1);
m.record(2, Attributes.of(stringKey("thing"), "engine"));
});
}
@Test
void noopObservableDoubleGauage_doesNotThrow() {
METER
.gaugeBuilder("temperature")
.setDescription("The current temperature")
.setUnit("C")
.buildWithCallback(
m -> {
m.record(1.0e1);
m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
});
}
@Test
void noopObservableLongCounter_doesNotThrow() {
METER
.counterBuilder("temperature")
.setDescription("The current temperature")
.setUnit("C")
.buildWithCallback(
m -> {
m.record(1);
m.record(2, Attributes.of(stringKey("thing"), "engine"));
});
}
@Test
void noopObservableDoubleCounter_doesNotThrow() {
METER
.counterBuilder("temperature")
.ofDoubles()
.setDescription("The current temperature")
.setUnit("C")
.buildWithCallback(
m -> {
m.record(1.0e1);
m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
});
}
@Test
void noopObservableLongUpDownCounter_doesNotThrow() {
METER
.upDownCounterBuilder("temperature")
.setDescription("The current temperature")
.setUnit("C")
.buildWithCallback(
m -> {
m.record(1);
m.record(2, Attributes.of(stringKey("thing"), "engine"));
});
}
@Test
void noopObservableDoubleUpDownCounter_doesNotThrow() {
METER
.upDownCounterBuilder("temperature")
.ofDoubles()
.setDescription("The current temperature")
.setUnit("C")
.buildWithCallback(
m -> {
m.record(1.0e1);
m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
});
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.trace;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
class DefaultTracerProviderTest {
@Test
void returnsDefaultTracer() {
assertThat(TracerProvider.noop().get("test")).isInstanceOf(DefaultTracer.class);
assertThat(TracerProvider.noop().get("test", "1.0")).isInstanceOf(DefaultTracer.class);
}
}

View File

@ -5,17 +5,89 @@
package io.opentelemetry.api.trace;
import io.opentelemetry.api.testing.internal.AbstractDefaultTracerTest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
class DefaultTracerTest extends AbstractDefaultTracerTest {
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import org.junit.jupiter.api.Test;
@Override
public Tracer getTracer() {
return DefaultTracer.getInstance();
/** Unit tests for {@link DefaultTracer}. */
// Need to suppress warnings for MustBeClosed because Android 14 does not support
// try-with-resources.
@SuppressWarnings("MustBeClosedChecker")
class DefaultTracerTest {
private static final Tracer defaultTracer = DefaultTracer.getInstance();
private static final String SPAN_NAME = "MySpanName";
private static final SpanContext spanContext =
SpanContext.create(
"00000000000000000000000000000061",
"0000000000000061",
TraceFlags.getDefault(),
TraceState.getDefault());
@Test
void defaultSpanBuilderWithName() {
assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getSpanContext().isValid())
.isFalse();
}
@Override
public TracerProvider getTracerProvider() {
return DefaultTracerProvider.getInstance();
@Test
void testSpanContextPropagationExplicitParent() {
Span span =
defaultTracer
.spanBuilder(SPAN_NAME)
.setParent(Context.root().with(Span.wrap(spanContext)))
.startSpan();
assertThat(span.getSpanContext()).isSameAs(spanContext);
}
@Test
void testSpanContextPropagation() {
Span parent = Span.wrap(spanContext);
Span span =
defaultTracer.spanBuilder(SPAN_NAME).setParent(Context.root().with(parent)).startSpan();
assertThat(span.getSpanContext()).isSameAs(spanContext);
}
@Test
void noSpanContextMakesInvalidSpans() {
Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
assertThat(span.getSpanContext()).isSameAs(SpanContext.getInvalid());
}
@Test
void testSpanContextPropagation_fromContext() {
Context context = Context.current().with(Span.wrap(spanContext));
Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).startSpan();
assertThat(span.getSpanContext()).isSameAs(spanContext);
}
@Test
void testSpanContextPropagation_fromContextAfterNoParent() {
Context context = Context.current().with(Span.wrap(spanContext));
Span span = defaultTracer.spanBuilder(SPAN_NAME).setNoParent().setParent(context).startSpan();
assertThat(span.getSpanContext()).isSameAs(spanContext);
}
@Test
void testSpanContextPropagation_fromContextThenNoParent() {
Context context = Context.current().with(Span.wrap(spanContext));
Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan();
assertThat(span.getSpanContext()).isEqualTo(SpanContext.getInvalid());
}
@Test
void addLink() {
Span span = Span.fromContext(Context.root());
assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException();
assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException();
assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException();
assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty()))
.doesNotThrowAnyException();
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.trace;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link SpanBuilder}. */
class SpanBuilderTest {
private final Tracer tracer = DefaultTracer.getInstance();
@Test
void doNotCrash_NoopImplementation() {
assertThatCode(
() -> {
SpanBuilder spanBuilder = tracer.spanBuilder(null);
spanBuilder.setSpanKind(null);
spanBuilder.setParent(null);
spanBuilder.setNoParent();
spanBuilder.addLink(null);
spanBuilder.addLink(null, Attributes.empty());
spanBuilder.addLink(SpanContext.getInvalid(), null);
spanBuilder.setAttribute((String) null, "foo");
spanBuilder.setAttribute("foo", null);
spanBuilder.setAttribute(null, 0L);
spanBuilder.setAttribute(null, 0.0);
spanBuilder.setAttribute(null, false);
spanBuilder.setAttribute((AttributeKey<String>) null, "foo");
spanBuilder.setAttribute(stringKey(null), "foo");
spanBuilder.setAttribute(stringKey(""), "foo");
spanBuilder.setAttribute(stringKey("foo"), null);
spanBuilder.setStartTimestamp(-1, TimeUnit.MILLISECONDS);
spanBuilder.setStartTimestamp(1, null);
spanBuilder.setParent(Context.root().with(Span.wrap(null)));
spanBuilder.setParent(Context.root());
spanBuilder.setNoParent();
spanBuilder.addLink(Span.getInvalid().getSpanContext());
spanBuilder.addLink(Span.getInvalid().getSpanContext(), Attributes.empty());
spanBuilder.setAttribute("key", "value");
spanBuilder.setAttribute("key", 12345L);
spanBuilder.setAttribute("key", .12345);
spanBuilder.setAttribute("key", true);
spanBuilder.setAttribute(stringKey("key"), "value");
spanBuilder.setAllAttributes(Attributes.of(stringKey("key"), "value"));
spanBuilder.setAllAttributes(Attributes.empty());
spanBuilder.setAllAttributes(null);
spanBuilder.setStartTimestamp(12345L, TimeUnit.NANOSECONDS);
spanBuilder.setStartTimestamp(Instant.EPOCH);
spanBuilder.setStartTimestamp(null);
assertThat(spanBuilder.startSpan().getSpanContext().isValid()).isFalse();
})
.doesNotThrowAnyException();
}
}

View File

@ -1,38 +1,167 @@
# API Incubator
# ExtendedTracer
Experimental APIs, including Event API, extended Log Bridge APIs, extended Metrics APIs, extended ContextPropagator APIs, and extended Trace APIs.
Utility methods to make it easier to use the OpenTelemetry tracer.
## Extended Log Bridge API
## Usage Examples
Features:
Here are some examples how the utility methods can help reduce boilerplate code.
* Check if logger is enabled before emitting logs to avoid unnecessary computation
* Add extended attributes to log records to encode complex data structures
### Tracing a function
See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java).
Before:
## Extended Metrics APIs
<!-- markdownlint-disable -->
```java
Span span = tracer.spanBuilder("reset_checkout").startSpan();
String transactionId;
try (Scope scope = span.makeCurrent()) {
transactionId = resetCheckout(cartId);
} catch (Throwable e) {
span.setStatus(StatusCode.ERROR);
span.recordException(e);
throw e; // or throw new RuntimeException(e) - depending on your error handling strategy
} finally {
span.end();
}
```
<!-- markdownlint-enable -->
Features:
After:
* Attributes advice
```java
import io.opentelemetry.extension.incubator.trace.ExtendedTracer;
See [ExtendedMetricsApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java).
ExtendedTracer extendedTracer = ExtendedTracer.create(tracer);
String transactionId = extendedTracer.spanBuilder("reset_checkout").startAndCall(() -> resetCheckout(cartId));
```
## Extended ContextPropagator APIs
If you want to set attributes on the span, you can use the `startAndCall` method on the span builder:
Features:
```java
import io.opentelemetry.extension.incubator.trace.ExtendedTracer;
* Check if instrument is enabled before recording measurements to avoid unnecessary computation
* Simplified injection / extraction of context
ExtendedTracer extendedTracer = ExtendedTracer.create(tracer);
String transactionId = extendedTracer.spanBuilder("reset_checkout")
.setAttribute("foo", "bar")
.startAndCall(() -> resetCheckout(cartId));
```
See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java).
Note:
## Extended Trace APIs
- Use `startAndRun` instead of `startAndCall` if the function returns `void` (both on the tracer and span builder).
- Exceptions are re-thrown without modification - see [Exception handling](#exception-handling)
for more details.
Features:
### Trace context propagation
* Check if tracer is enabled before starting spans to avoid unnecessary computation
* Utility methods to reduce boilerplace using span API, including extracting context, and wrapping runnables / callables with spans
Before:
See [ExtendedTraceApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java).
```java
Map<String, String> propagationHeaders = new HashMap<>();
openTelemetry
.getPropagators()
.getTextMapPropagator()
.inject(
Context.current(),
propagationHeaders,
(map, key, value) -> {
if (map != null) {
map.put(key, value);
}
});
// add propagationHeaders to request headers and call checkout service
```
<!-- markdownlint-disable -->
```java
// in checkout service: get request headers into a Map<String, String> requestHeaders
Map<String, String> requestHeaders = new HashMap<>();
String cartId = "cartId";
SpanBuilder spanBuilder = tracer.spanBuilder("checkout_cart");
TextMapGetter<Map<String, String>> TEXT_MAP_GETTER =
new TextMapGetter<Map<String, String>>() {
@Override
public Set<String> keys(Map<String, String> carrier) {
return carrier.keySet();
}
@Override
@Nullable
public String get(@Nullable Map<String, String> carrier, String key) {
return carrier == null ? null : carrier.get(key);
}
};
Map<String, String> normalizedTransport =
requestHeaders.entrySet().stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toLowerCase(Locale.ROOT), Map.Entry::getValue));
Context newContext = openTelemetry
.getPropagators()
.getTextMapPropagator()
.extract(Context.current(), normalizedTransport, TEXT_MAP_GETTER);
String transactionId;
try (Scope ignore = newContext.makeCurrent()) {
Span span = spanBuilder.setSpanKind(SERVER).startSpan();
try (Scope scope = span.makeCurrent()) {
transactionId = processCheckout(cartId);
} catch (Throwable e) {
span.setStatus(StatusCode.ERROR);
span.recordException(e);
throw e; // or throw new RuntimeException(e) - depending on your error handling strategy
} finally {
span.end();
}
}
```
<!-- markdownlint-enable -->
After:
```java
import io.opentelemetry.extension.incubator.propagation.ExtendedContextPropagators;
Map<String, String> propagationHeaders =
ExtendedContextPropagators.getTextMapPropagationContext(openTelemetry.getPropagators());
// add propagationHeaders to request headers and call checkout service
```
```java
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.extension.incubator.trace.ExtendedTracer;
// in checkout service: get request headers into a Map<String, String> requestHeaders
Map<String, String> requestHeaders = new HashMap<>();
String cartId = "cartId";
ExtendedTracer extendedTracer = ExtendedTracer.create(tracer);
String transactionId = extendedTracer.spanBuilder("checkout_cart")
.setSpanKind(SpanKind.SERVER)
.setParentFrom(openTelemetry.getPropagators(), requestHeaders)
.startAndCall(() -> processCheckout(cartId));
```
## Exception handling
`ExtendedTracer` re-throws exceptions without modification. This means you can
catch exceptions around `ExtendedTracer` calls and handle them as you would without `ExtendedTracer`.
When an exception is encountered during an `ExtendedTracer` call, the span is marked as error and
the exception is recorded.
If you want to customize this behaviour, e.g. to only record the exception, because you are
able to recover from the error, you can call the overloaded method of `startAndCall` or
`startAndRun` that takes an exception handler:
```java
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.extension.incubator.trace.ExtendedTracer;
ExtendedTracer extendedTracer = ExtendedTracer.create(tracer);
String transactionId = extendedTracer.spanBuilder("checkout_cart")
.startAndCall(() -> processCheckout(cartId), Span::recordException);
```

View File

@ -12,31 +12,8 @@ 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("io.opentelemetry.semconv:opentelemetry-semconv:1.21.0-alpha")
testImplementation(project(":sdk:testing"))
testImplementation(project(":api:testing-internal"))
testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating")
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

@ -1,86 +0,0 @@
/*
* 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

@ -1,84 +0,0 @@
/*
* 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

@ -1,100 +0,0 @@
/*
* 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

@ -1,26 +0,0 @@
/*
* 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

@ -1,103 +0,0 @@
/*
* 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

@ -1,233 +0,0 @@
/*
* 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

@ -1,37 +0,0 @@
/*
* 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

@ -1,22 +0,0 @@
/*
* 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

@ -1,235 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.incubator.config;
import static io.opentelemetry.api.internal.ConfigUtil.defaultIfNull;
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 declarative configuration data.
*
* <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
* sequences of mappings.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public interface DeclarativeConfigProperties {
/**
* 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 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 DeclarativeConfigException if the property is not a valid scalar string
*/
@Nullable
String getString(String name);
/**
* Returns a {@link String} configuration property.
*
* @return a {@link String} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar string
*/
default String getString(String name, String defaultValue) {
return defaultIfNull(getString(name), defaultValue);
}
/**
* Returns a {@link Boolean} configuration property. Implementations should use the same rules as
* {@link Boolean#parseBoolean(String)} for handling the values.
*
* @return null if the property has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar boolean
*/
@Nullable
Boolean getBoolean(String name);
/**
* Returns a {@link Boolean} configuration property.
*
* @return a {@link Boolean} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar boolean
*/
default boolean getBoolean(String name, boolean defaultValue) {
return defaultIfNull(getBoolean(name), defaultValue);
}
/**
* Returns a {@link Integer} configuration property.
*
* <p>If the underlying config property is {@link Long}, it is converted to {@link Integer} with
* {@link Long#intValue()} which may result in loss of precision.
*
* @return null if the property has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar integer
*/
@Nullable
Integer getInt(String name);
/**
* Returns a {@link Integer} configuration property.
*
* <p>If the underlying config property is {@link Long}, it is converted to {@link Integer} with
* {@link Long#intValue()} which may result in loss of precision.
*
* @return a {@link Integer} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar integer
*/
default int getInt(String name, int defaultValue) {
return defaultIfNull(getInt(name), defaultValue);
}
/**
* Returns a {@link Long} configuration property.
*
* @return null if the property has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar long
*/
@Nullable
Long getLong(String name);
/**
* Returns a {@link Long} configuration property.
*
* @return a {@link Long} configuration property or {@code defaultValue} if a property with {@code
* name} has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar long
*/
default long getLong(String name, long defaultValue) {
return defaultIfNull(getLong(name), defaultValue);
}
/**
* Returns a {@link Double} configuration property.
*
* @return null if the property has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar double
*/
@Nullable
Double getDouble(String name);
/**
* Returns a {@link Double} configuration property.
*
* @return a {@link Double} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws DeclarativeConfigException if the property is not a valid scalar double
*/
default double getDouble(String name, double defaultValue) {
return defaultIfNull(getDouble(name), defaultValue);
}
/**
* Returns a {@link List} configuration property. Empty values and values which do not map to the
* {@code scalarType} will be removed.
*
* @param name the property name
* @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or
* {@link Double}
* @return a {@link List} configuration property, or null if the property has not been configured
* @throws 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);
/**
* Returns a {@link List} configuration property. Entries which are not strings are converted to
* their string representation.
*
* @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 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 DeclarativeConfigProperties} configuration property.
*
* @return a map-valued configuration property, or {@code null} if {@code name} has not been
* configured
* @throws DeclarativeConfigException if the property is not a mapping
*/
@Nullable
DeclarativeConfigProperties getStructured(String name);
/**
* 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 DeclarativeConfigException if the property is not a mapping
*/
default DeclarativeConfigProperties getStructured(
String name, DeclarativeConfigProperties defaultValue) {
return defaultIfNull(getStructured(name), defaultValue);
}
/**
* 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 DeclarativeConfigException if the property is not a sequence of mappings
*/
@Nullable
List<DeclarativeConfigProperties> getStructuredList(String name);
/**
* 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 DeclarativeConfigException if the property is not a sequence of mappings
*/
default List<DeclarativeConfigProperties> getStructuredList(
String name, List<DeclarativeConfigProperties> defaultValue) {
return defaultIfNull(getStructuredList(name), defaultValue);
}
/**
* Returns a set of all configuration property keys.
*
* @return the configuration property keys
*/
Set<String> getPropertyKeys();
/** Return a {@link ComponentLoader} that should be used to load SPIs. */
ComponentLoader getComponentLoader();
}

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