Compare commits

..

1 Commits

Author SHA1 Message Date
OpenTelemetry Java Bot b7779be154
Prepare release 1.15.0 (#4522) 2022-06-10 10:58:49 -05:00
2820 changed files with 50515 additions and 105523 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,15 +11,17 @@ coverage:
status:
project:
default:
target: 89%
target: 90%
paths:
- "!opencensus-shim/"
- "!opentracing-shim/"
- "!sdk-extensions/zpages/"
unmaintained:
target: 80%
paths:
- "opencensus-shim/"
- "opentracing-shim/"
- "sdk-extensions/zpages/"
patch:
default:
target: 80%

View File

@ -3,7 +3,7 @@ charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
insert_final_newline = false
max_line_length = 100
tab_width = 2
ij_continuation_indent_size = 4

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

2
.github/CODEOWNERS vendored
View File

@ -2,4 +2,4 @@
# This file controls who is tagged for review for any given pull request.
# For anything not explicitly taken by someone else:
* @open-telemetry/java-approvers
* @anuraaga @jack-berg @jkwatson @jsuereth @kubawach @Oberon00

View File

@ -25,7 +25,7 @@ Version: (e.g., `v0.4.0`, `1eb551b`, etc)
How did you reference these artifacts? (excerpt from your `build.gradle`, `pom.xml`, etc)
**Environment**
Compiler: (e.g., "Temurin 17.0.7")
Compiler: (e.g., "AdoptOpenJDK 11.0.6")
OS: (e.g., "Ubuntu 20.04")
Runtime (if different from JDK above): (e.g., "Oracle JRE 8u251")
OS (if different from OS compiled on): (e.g., "Windows Server 2019")

6
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@ -1,85 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: [
'config:best-practices',
'helpers:pinGitHubActionDigestsToSemver',
],
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$/',
},
{
// junit-pioneer 2+ requires Java 11+
matchPackageNames: [
'org.junit-pioneer:junit-pioneer',
],
matchUpdateTypes: [
'major',
],
enabled: false,
},
{
// mockito 5+ requires Java 11+
matchUpdateTypes: [
'major',
],
enabled: false,
matchPackageNames: [
'org.mockito:{/,}**',
],
},
{
// jqf-fuzz version 1.8+ requires Java 11+
matchPackageNames: [
'edu.berkeley.cs.jqf:jqf-fuzz',
],
matchUpdateTypes: [
'major',
'minor',
],
enabled: false,
},
{
// pinned version for compatibility
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
}
],
}

View File

@ -1,24 +0,0 @@
# 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.
## 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`

View File

@ -1,34 +0,0 @@
#!/bin/bash -e
version=$("$(dirname "$0")/get-version.sh")
if [[ $version =~ ([0-9]+)\.([0-9]+)\.0 ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
else
echo "unexpected version: $version"
exit 1
fi
if [[ $minor == 0 ]]; then
prior_major=$((major - 1))
prior_minor=$(sed -n "s/^## Version $prior_major\.\([0-9]\+\)\..*/\1/p" CHANGELOG.md | head -1)
if [[ -z $prior_minor ]]; then
# assuming this is the first release
range=
else
range="v$prior_major.$prior_minor.0..HEAD"
fi
else
range="v$major.$((minor - 1)).0..HEAD"
fi
echo "## Unreleased"
echo
git log --reverse \
--perl-regexp \
--author='^(?!renovate\[bot\] )' \
--pretty=format:"* %s" \
"$range" \
| sed -E 's,\(#([0-9]+)\)$,\n ([#\1](https://github.com/open-telemetry/opentelemetry-java/pull/\1)),'

View File

@ -5,11 +5,6 @@
# this should be run on the release branch
# NOTE if you need to run this script locally, you will need to first:
# git fetch upstream main
# git push origin upstream/main:main
# export GITHUB_REPOSITORY=open-telemetry/opentelemetry-java
from_version=$1
# get the date of the first commit that was not in the from_version
@ -72,7 +67,7 @@ query($q: String!, $endCursor: String) {
}
}
' --jq '.data.search.edges.[].node.body' \
| grep -oE "#[0-9]{4,}$|#[0-9]{4,}[^0-9<]|$GITHUB_REPOSITORY/issues/[0-9]{4,}" \
| grep -oE "#[0-9]{4,}|$GITHUB_REPOSITORY/issues/[0-9]{4,}" \
| grep -oE "[0-9]{4,}" \
| xargs -I{} gh issue view {} --json 'author,url' --jq '[.author.login,.url]' \
| grep -v '/pull/' \
@ -84,7 +79,6 @@ echo $contributors1 $contributors2 \
| sort -uf \
| grep -v linux-foundation-easycla \
| grep -v github-actions \
| grep -v renovate \
| grep -v dependabot \
| grep -v codecov \
| grep -v otelbot \
| 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

@ -1,3 +1,3 @@
#!/bin/bash -e
grep -Eo "[0-9]+.[0-9]+.[0-9]+" version.gradle.kts
grep -Eo "[0-9]+.[0-9]+.0" version.gradle.kts

View File

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

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")/markdown-link-check-config.json" \
"$file"; then
break
elif [[ $i -eq $retry_count ]]; then
exit 1
fi
sleep 5
done
done

View File

@ -1,44 +0,0 @@
#!/bin/bash -e
# this script merges release notes for $VERSION into CHANGELOG.md
# the release date for $VERSION should be available in $RELEASE_DATE
# and the release notes for $VERSION should be available in /tmp/changelog-section.md
if [[ $VERSION =~ ^[0-9]+\.[0-9]+\.0 ]]; then
# this was not a patch release, so the version exists already in the CHANGELOG.md
# update the release date
sed -Ei "s/## Version $VERSION .*/## Version $VERSION ($RELEASE_DATE)/" CHANGELOG.md
# the entries are copied over from the release branch to support workflows
# where change log entries may be updated after preparing the release branch
{
# copy the portion above the release, up to and including the heading
sed -n "0,/^## Version $VERSION /p" CHANGELOG.md
# copy the release notes for $VERSION
cat /tmp/changelog-section.md
# copy the portion below the release
sed -n "0,/^## Version $VERSION /d;0,/^## Version /{/^## Version/!d};p" CHANGELOG.md
} > /tmp/CHANGELOG.md
# update the real CHANGELOG.md
cp /tmp/CHANGELOG.md CHANGELOG.md
else
# this was a patch release, so the version does not exist already in the CHANGELOG.md
{
# copy the portion above the top-most release, not including the heading
sed -n "0,/^## Version /{ /^## Version /!p }" CHANGELOG.md
# add the heading
echo "## Version $VERSION ($RELEASE_DATE)"
# copy the release notes for $VERSION
cat /tmp/changelog-section.md
# copy the portion starting from the top-most release
sed -n "/^## Version /,\$p" CHANGELOG.md
} > /tmp/CHANGELOG.md
# update the real CHANGELOG.md
cp /tmp/CHANGELOG.md CHANGELOG.md
fi

4
.github/scripts/set-git-user.sh vendored Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash -e
git config user.name opentelemetry-java-bot
git config user.email 97938252+opentelemetry-java-bot@users.noreply.github.com

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 +0,0 @@
#!/bin/bash -e
git config user.name otelbot
git config user.email 197425009+otelbot@users.noreply.github.com

View File

@ -6,49 +6,33 @@ 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: |
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x$ ]]; then
echo this workflow should only be run against release branches
exit 1
fi
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v3
with:
# history is needed to run git cherry-pick below
fetch-depth: 0
- 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: Set git user
run: .github/scripts/set-git-user.sh
- 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 }}
# not using the default GITHUB_TOKEN because pull requests generated by it do not run any workflows
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
run: |
commit=$(gh pr view $NUMBER --json mergeCommit --jq .mergeCommit.oid)
title=$(gh pr view $NUMBER --json title --jq .title)
url=$(gh pr view $NUMBER --json url --jq .url)
branch="otelbot/backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
branch="backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
git checkout -b $branch
git cherry-pick $commit
git push --set-upstream origin $branch
git push origin HEAD:$branch
gh pr create --title "[$GITHUB_REF_NAME] $title" \
--body "Clean cherry-pick of #$NUMBER to the \`$GITHUB_REF_NAME\` branch." \
--head $branch \
--base $GITHUB_REF_NAME

View File

@ -1,77 +0,0 @@
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
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
tag-version:
- v1.6.0
- v1.7.0
- v1.7.1
- v1.10.0
- v1.10.1
- v1.11.0
- v1.12.0
- v1.13.0
- v1.14.0
- v1.15.0
- v1.16.0
- v1.17.0
- v1.18.0
- v1.19.0
- v1.21.0
- v1.22.0
- v1.23.0
- v1.23.1
- v1.24.0
- v1.25.0
- v1.26.0
- v1.27.0
- v1.28.0
- v1.29.0
- v1.30.0
- v1.30.1
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ matrix.tag-version }}
- id: setup-java
name: Set up Java for build
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 jmh
run: ./gradlew jmhJar
- name: Run Benchmark
run: |
cd sdk/trace/build
java -jar libs/opentelemetry-sdk-trace-*-jmh.jar -rf json SpanBenchmark SpanPipelineBenchmark ExporterBenchmark
- name: Store benchmark results
uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4
with:
tool: 'jmh'
output-file-path: sdk/trace/build/jmh-result.json
gh-pages-branch: benchmarks
github-token: ${{ secrets.GITHUB_TOKEN }}
benchmark-data-dir-path: "benchmarks"
auto-push: true
ref: ${{ matrix.tag-version }}

View File

@ -1,46 +0,0 @@
name: Benchmark Main
on:
push:
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
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: setup-java
name: Set up Java for build
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 jmh
run: ./gradlew jmhJar
- name: Run Benchmark
run: |
cd sdk/trace/build
java -jar libs/opentelemetry-sdk-trace-*-jmh.jar -rf json SpanBenchmark SpanPipelineBenchmark ExporterBenchmark
- name: Store benchmark results
uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4
with:
tool: 'jmh'
output-file-path: sdk/trace/build/jmh-result.json
gh-pages-branch: benchmarks
github-token: ${{ secrets.GITHUB_TOKEN }}
benchmark-data-dir-path: "benchmarks"
auto-push: true

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@v3
- name: Login to GitHub package registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
uses: docker/login-action@v2
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@v3.0.0
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,99 +21,61 @@ jobs:
matrix:
os:
- macos-latest
- macos-13
- ubuntu-latest
- windows-latest
- ubuntu-20.04
test-java-version:
- 8
- 11
- 17
- 21
- 23
- 18
# Collect coverage on latest LTS
include:
- os: ubuntu-latest
test-java-version: 21
coverage: true
jmh-based-tests: true
# macos-latest drops support for java 8 temurin. Run java 8 on macos-13. Run java 11, 17, 21 on macos-latest.
exclude:
- os: macos-latest
test-java-version: 8
- os: macos-13
test-java-version: 11
- os: macos-13
- os: ubuntu-20.04
test-java-version: 17
- os: macos-13
test-java-version: 21
- os: macos-13
test-java-version: 23
coverage: true
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- 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@v3
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@v3
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/gradle-build-action@v2
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"
env:
# JMH-based tests run only if this environment variable is set to true
RUN_JMH_BASED_TESTS: ${{ matrix.jmh-based-tests }}
-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }},${{ steps.setup-java.outputs.path }}
- 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/') }}
run: |
# need to "git add" in case any generated files did not already exist
git add docs/apidiffs
if git diff --cached --quiet
then
echo "No diff detected."
else
echo "Diff detected - did you run './gradlew jApiCmp'?"
echo $(git diff --cached --name-only)
echo $(git diff --cached)
exit 1
fi
- uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
- uses: codecov/codecov-action@v3
if: ${{ matrix.coverage }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
- uses: actions/upload-artifact@v3
if: ${{ matrix.coverage }}
with:
name: coverage-report
path: all/build/reports/jacoco/test/html
markdown-link-check:
# release branches are excluded to avoid unnecessary maintenance
# release branches are excluded to avoid unnecessary maintenance if external links break
if: ${{ !startsWith(github.ref_name, 'release/') }}
uses: ./.github/workflows/reusable-markdown-link-check.yml
misspell-check:
# release branches are excluded to avoid unnecessary maintenance
# release branches are excluded to avoid unnecessary maintenance if new misspellings are added
# to the misspell dictionary
if: ${{ !startsWith(github.ref_name, 'release/') }}
uses: ./.github/workflows/reusable-misspell-check.yml
@ -127,75 +86,42 @@ jobs:
#
# and the name is updated when the steps below are skipped which makes what's happening clearer
# in the GitHub UI
#
# note: the condition below has to be written so that '' is last since it resolves to false
# and so would not short-circuit if used in the second-last position
name: publish-snapshots${{ (github.ref_name != 'main' || github.repository != 'open-telemetry/opentelemetry-java') && ' (skipped)' || '' }}
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-20.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- id: setup-java
name: Set up Java
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@v3
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/gradle-build-action@v2
# 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 }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
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
with:
java-version: ${{ matrix.test-graal-version }}
distribution: 'graalvm'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Running test
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
echo "JAVA_HOME: $JAVA_HOME"
java --version
native-image --version
./gradlew nativeTest
required-status-check:
# markdown-link-check is not required so pull requests are not blocked if external links break
# misspell-check is not required so pull requests are not blocked if the misspell dictionary is
# updated
needs:
- build
- build-graal
# markdown-link-check is not required so that pull requests will not be blocked if external
# links break
# similarly misspell-check is not required so that pull requests will not be blocked if new
# misspellings are added to the misspell dictionary
needs: build
runs-on: ubuntu-latest
if: always()
steps:
- if: |
needs.build.result != 'success' ||
needs.build-graal.result != 'success'
- if: needs.build.result != 'success'
run: exit 1

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

@ -0,0 +1,38 @@
name: CodeQL (daily)
on:
schedule:
- cron: '30 1 * * *'
workflow_dispatch:
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Java 17
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: java
- uses: gradle/gradle-build-action@v2
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@v2
open-issue-on-failure:
# open an issue on failure because it can be easy to miss CI failure notifications
needs: analyze
if: failure()
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@v2
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@v3
- uses: gradle/actions/wrapper-validation@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/wrapper-validation-action@v1.0.4

View File

@ -1,28 +0,0 @@
name: Issue management - remove needs feedback label
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
- name: Remove label
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue edit --remove-label "needs author feedback" $ISSUE_NUMBER

View File

@ -1,32 +0,0 @@
name: Issue management - run stale action
on:
schedule:
# 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
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 7
days-before-close: 7
only-labels: "needs author feedback"
stale-issue-message: >
This has been automatically marked as stale because it has been marked
as needing author feedback and has not had any activity for 7 days.
It will be closed if no further activity occurs within 7 days of this comment.
stale-pr-message: >
This has been automatically marked as stale because it has been marked
as needing author feedback and has not had any activity for 7 days.
It will be closed if no further activity occurs within 7 days of this comment.

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

@ -0,0 +1,36 @@
name: Merge change log to main
on:
workflow_dispatch:
jobs:
create-pull-request:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
# this workflow is run against the release branch (see usage of GITHUB_REF_NAME below)
# but it is creating a pull request against main
ref: main
# history is needed to run format-patch below
fetch-depth: 0
- name: Set git user
run: .github/scripts/set-git-user.sh
# this will fail if there have been conflicting change log updates introduced in main
- name: Create pull request against main
env:
# not using the default GITHUB_TOKEN because pull requests generated by it do not run any workflows
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
run: |
message="Merge change log updates from $GITHUB_REF_NAME"
body="Merge change log updates from \`$GITHUB_REF_NAME\`."
branch="merge-change-log-updates-from-${GITHUB_REF_NAME//\//-}"
git format-patch --stdout HEAD..origin/$GITHUB_REF_NAME CHANGELOG.md | git apply --3way
git commit -a -m "$message"
git push origin HEAD:$branch
gh pr create --title "$message" \
--body "$body" \
--head $branch \
--base main

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

@ -1,47 +0,0 @@
# the benefit of this over renovate is that this also analyzes transitive dependencies
# while renovate (at least currently) only analyzes top-level dependencies
name: OWASP dependency check (daily)
on:
schedule:
- cron: "30 1 * * *" # daily at 1:30 UTC
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
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 }}
- name: Upload report
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: javaagent/build/reports
workflow-notification:
permissions:
contents: read
issues: write
needs:
- analyze
if: always()
uses: ./.github/workflows/reusable-workflow-notification.yml
with:
success: ${{ needs.analyze.result == 'success' }}

View File

@ -2,32 +2,16 @@ name: Prepare patch release
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prepare-patch-release:
permissions:
contents: write # for git push to PR branch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: |
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x$ ]]; then
echo this workflow should only be run against release branches
exit 1
fi
if ! grep --quiet "^## Unreleased$" CHANGELOG.md; then
echo the change log is missing an \"Unreleased\" section
exit 1
fi
- uses: actions/checkout@v3
- name: Set environment variables
run: |
version=$(.github/scripts/get-version.sh)
if [[ $version =~ ^([0-9]+\.[0-9]+)\.([0-9]+)$ ]]; then
if [[ $version =~ ([0-9]+\.[0-9]+)\.([0-9]+) ]]; then
major_minor="${BASH_REMATCH[1]}"
patch="${BASH_REMATCH[2]}"
else
@ -37,33 +21,23 @@ jobs:
echo "VERSION=$major_minor.$((patch + 1))" >> $GITHUB_ENV
- name: Update version
run: .github/scripts/update-version.sh $VERSION
- name: Update the change log with the approximate release date
run: |
date=$(date "+%Y-%m-%d")
sed -Ei "s/^## Unreleased$/## Version $VERSION ($date)/" CHANGELOG.md
sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION/" version.gradle.kts
- 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: Set git user
run: .github/scripts/set-git-user.sh
- 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 }}
# not using the default GITHUB_TOKEN because pull requests generated by it do not run any workflows
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
run: |
message="Prepare release $VERSION"
branch="otelbot/prepare-release-${VERSION}"
branch="prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
git push --set-upstream origin $branch
git push origin HEAD:$branch
gh pr create --title "[$GITHUB_REF_NAME] $message" \
--body "$message." \
--head $branch \
--base $GITHUB_REF_NAME

View File

@ -2,46 +2,18 @@ name: Prepare release branch
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prereqs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Verify prerequisites
run: |
if [[ $GITHUB_REF_NAME != main ]]; then
echo this workflow should only be run against main
exit 1
fi
if ! grep --quiet "^## Unreleased$" CHANGELOG.md; then
echo the change log is missing an \"Unreleased\" section
exit 1
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@v3
- name: Create release branch
id: create-release-branch
run: |
version=$(.github/scripts/get-version.sh)
version=${version//-SNAPSHOT/}
if [[ $version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then
release_branch_name=$(echo $version | sed -E 's/([0-9]+)\.([0-9]+)\.0/release\/v\1.\2.x/')
else
echo "unexpected version: $version"
exit 1
fi
release_branch_name=$(echo $version | sed -E 's/([0-9]+)\.([0-9]+)\.0/release\/v\1.\2.x/')
git push origin HEAD:$release_branch_name
@ -49,90 +21,64 @@ jobs:
echo "RELEASE_BRANCH_NAME=$release_branch_name" >> $GITHUB_ENV
- name: Update version
run: sed -Ei "s/val snapshot = true/val snapshot = false/" version.gradle.kts
- name: Update the change log with the approximate release date
run: |
date=$(date "+%Y-%m-%d")
sed -Ei "s/^## Unreleased$/## Version $VERSION ($date)/" CHANGELOG.md
sed -Ei "s/val snapshot = true/val snapshot = false/" version.gradle.kts
- 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: Set git user
run: .github/scripts/set-git-user.sh
- 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 }}
# not using the default GITHUB_TOKEN because pull requests generated by it do not run any workflows
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
run: |
message="Prepare release $VERSION"
branch="otelbot/prepare-release-${VERSION}"
branch="prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
git push --set-upstream origin $branch
git push origin HEAD:$branch
gh pr create --title "[$RELEASE_BRANCH_NAME] $message" \
--body "$message." \
--head $branch \
--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@v3
- name: Set environment variables
run: |
version=$(.github/scripts/get-version.sh)
if [[ $version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then
if [[ $version =~ ([0-9]+)\.([0-9]+)\.0 ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
next_version="$major.$((minor + 1)).0"
else
echo "unexpected version: $version"
exit 1
fi
echo "NEXT_VERSION=${next_version}" >> $GITHUB_ENV
echo "VERSION=$version" >> $GITHUB_ENV
next_version="$major.$((minor + 1)).0"
echo "NEXT_VERSION=$next_version" >> $GITHUB_ENV
- name: Update version
run: .github/scripts/update-version.sh $NEXT_VERSION
- name: Update the change log on main
run: |
# the actual release date on main will be updated at the end of the release workflow
date=$(date "+%Y-%m-%d")
sed -Ei "s/^## Unreleased$/## Unreleased\n\n## Version $VERSION ($date)/" CHANGELOG.md
sed -Ei "s/[0-9]+\.[0-9]+\.[0-9]+/$NEXT_VERSION/" version.gradle.kts
- 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: Set git user
run: .github/scripts/set-git-user.sh
- name: Create pull request against main
env:
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ steps.otelbot-token.outputs.token }}
# not using the default GITHUB_TOKEN because pull requests generated by it do not run any workflows
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
run: |
message="Update version to $NEXT_VERSION"
body="Update version to \`$NEXT_VERSION\`."
branch="otelbot/update-version-to-${NEXT_VERSION}"
branch="update-version-to-${NEXT_VERSION}"
git checkout -b $branch
git commit -a -m "$message"
git push --set-upstream origin $branch
git push origin HEAD:$branch
gh pr create --title "$message" \
--body "$body" \
--head $branch \
--base main

View File

@ -2,36 +2,30 @@ name: Release
on:
workflow_dispatch:
permissions:
contents: read
jobs:
release:
permissions:
contents: write # for creating the release
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.create-github-release.outputs.version }}
prior-version: ${{ steps.create-github-release.outputs.prior-version }}
runs-on: ubuntu-20.04
steps:
- run: |
if [[ $GITHUB_REF_NAME != release/* ]]; then
echo this workflow should only be run against release branches
echo the release workflow should only be run against release branches
exit 1
fi
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v3
with:
# tags are needed for the generate-release-contributors.sh script
fetch-depth: 0
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
- uses: actions/setup-java@v3
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/gradle-build-action@v2
with:
arguments: assemble publishToSonatype closeAndReleaseSonatypeStagingRepository
env:
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }}
@ -41,7 +35,7 @@ jobs:
- name: Set environment variables
run: |
version=$(.github/scripts/get-version.sh)
if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
if [[ $version =~ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
patch="${BASH_REMATCH[3]}"
@ -63,159 +57,72 @@ jobs:
echo "VERSION=$version" >> $GITHUB_ENV
echo "PRIOR_VERSION=$prior_version" >> $GITHUB_ENV
# 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
with:
ref: main
- name: Check that change log update was merged to main
run: |
if [[ $VERSION == *.0 ]]; then
# not making a patch release
if ! grep --quiet "^## Version $VERSION " CHANGELOG.md; then
echo the pull request generated by prepare-release-branch.yml needs to be merged first
exit 1
fi
fi
# back to the release branch
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# tags are needed for the generate-release-contributors.sh script
fetch-depth: 0
- name: Generate release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# conditional blocks not indented because of the heredoc
if [[ $VERSION != *.0 ]]; then
cat > /tmp/release-notes.txt << EOF
if [[ $VERSION == *.0 ]]; then
cat > release-notes.txt << EOF
This release targets the OpenTelemetry SDK $VERSION.
EOF
else
cat > release-notes.txt << EOF
This is a patch release on the previous $PRIOR_VERSION release, fixing the issue(s) below.
EOF
fi
# CHANGELOG_SECTION.md is also used at the end of the release workflow
# for copying the change log updates to main
sed -n "0,/^## Version $VERSION /d;/^## Version /q;p" CHANGELOG.md \
> /tmp/CHANGELOG_SECTION.md
# the complex perl regex is needed because markdown docs render newlines as soft wraps
# while release notes render them as line breaks
perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g' /tmp/CHANGELOG_SECTION.md \
>> /tmp/release-notes.txt
sed -n "0,/^## Version $VERSION/d;/^## Version /q;p" CHANGELOG.md \
| perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g' \
>> release-notes.txt
# conditional block not indented because of the heredoc
if [[ $VERSION == *.0 ]]; then
cat >> /tmp/release-notes.txt << EOF
cat >> release-notes.txt << EOF
### 🙇 Thank you
This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:
EOF
.github/scripts/generate-release-contributors.sh v$PRIOR_VERSION >> /tmp/release-notes.txt
.github/scripts/generate-release-contributors.sh v$PRIOR_VERSION >> release-notes.txt
fi
- id: create-github-release
name: Create GitHub release
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create --target $GITHUB_REF_NAME \
--title "Version $VERSION" \
--notes-file /tmp/release-notes.txt \
--notes-file release-notes.txt \
--discussion-category announcements \
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
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
- name: Copy change log section from release branch
- name: Update the change log with the release date
env:
VERSION: ${{ needs.release.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
sed -n "0,/^## Version $VERSION /d;/^## Version /q;p" CHANGELOG.md \
> /tmp/changelog-section.md
date=$(gh release view v$VERSION --json publishedAt --jq .publishedAt | sed 's/T.*//')
sed -Ei "s/## Version $VERSION .*/## Version $VERSION ($date)/" CHANGELOG.md
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: main
- name: Set git user
run: .github/scripts/set-git-user.sh
- name: Merge change log to main
- name: Create pull request against the release branch
env:
VERSION: ${{ needs.release.outputs.version }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# not using the default GITHUB_TOKEN because pull requests generated by it do not run any workflows
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
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
message="Add the release date for $VERSION to the change log"
branch="add-release-date-for-${VERSION}"
- name: Wait for release to be available in maven central
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
until curl --silent \
--show-error \
--output /dev/null \
--head \
--fail \
https://repo1.maven.org/maven2/io/opentelemetry/opentelemetry-api/$VERSION/opentelemetry-api-$VERSION.jar
do
sleep 60
done
- name: Update apidiff baseline
env:
VERSION: ${{ needs.release.outputs.version }}
PRIOR_VERSION: ${{ needs.release.outputs.prior-version }}
run: |
./gradlew japicmp -PapiBaseVersion=$PRIOR_VERSION -PapiNewVersion=$VERSION
./gradlew --refresh-dependencies japicmp
git add docs/apidiffs
- name: Update versions in README.md
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
./gradlew updateVersionInDocs -Prelease.version=$VERSION
git add README.md
- name: Use CLA approved bot
run: .github/scripts/use-cla-approved-github-bot.sh
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- name: Create pull request against main
env:
VERSION: ${{ needs.release.outputs.version }}
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
GH_TOKEN: ${{ steps.otelbot-token.outputs.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}"
git checkout -b $branch
git commit -m "$message"
git push --set-upstream origin $branch
gh pr create --title "$message" \
--body "$body" \
--base main
git commit -a -m "$message"
git push origin HEAD:$branch
gh pr create --title "[$GITHUB_REF_NAME] $message" \
--body "$message." \
--head $branch \
--base $GITHUB_REF_NAME

View File

@ -3,22 +3,18 @@ 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@v3
- 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
run: npm install -g markdown-link-check
- 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,18 +3,15 @@ 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@v3
- name: Install misspell
run: |
curl -L -o install-misspell.sh https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh
curl -L -o ./install-misspell.sh https://git.io/misspell
sh ./install-misspell.sh
- name: Run misspell

View File

@ -1,24 +1,18 @@
name: Reusable - Open issue on workflow failure
name: Reusable - Open issue on 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@v3
- name: Open issue
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue create --title "$GITHUB_WORKFLOW #$GITHUB_RUN_NUMBER failed" \
--label Bug \
--label bug \
--body "See [$GITHUB_WORKFLOW #$GITHUB_RUN_NUMBER](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)."

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/

File diff suppressed because it is too large Load Diff

View File

@ -3,12 +3,12 @@
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
[OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification).
Otherwise, file an issue or submit a pull request (PR) to the specification repo first.
Otherwise file an issue or submit a PR to the specification repo first.
Make sure to review the projects [license](LICENSE) and sign the
[CNCF CLA](https://identity.linuxfoundation.org/projects/cncf). A signed CLA will be enforced by an
@ -16,7 +16,7 @@ automatic check once you submit a PR, but you can also sign it after opening you
## Requirements
Java 17 or higher is required to build the projects in this repository. The built artifacts can be
Java 11 or higher is required to build the projects in this repository. The built artifacts can be
used on Java 8 or higher.
## Building opentelemetry-java
@ -52,8 +52,7 @@ $ ./gradlew check
Note: this gradle task will potentially generate changes to files in
the `docs/apidiffs/current_vs_latest`
directory. Please make sure to include any changes to these files in your pull request (i.e.
add those files to your commits in the PR).
directory. Please make sure to include any changes to these files in your pull request.
## PR Review
@ -61,41 +60,6 @@ After you submit a PR, it will be reviewed by the project maintainers and approv
maintainers need to review a particular PR, but merging to the base branch is authorized to
restricted members (administrators).
### Draft PRs
Draft PRs are welcome, especially when exploring new ideas or experimenting with a hypothesis.
However, draft PRs may not receive the same degree of attention, feedback, or scrutiny unless
requested directly. In order to help keep the PR backlog maintainable, drafts older than 6 months
will be closed by the project maintainers. This should not be interpreted as a rejection. Closed
PRs may be reopened by the author when time or interest allows.
## Project Scope
`opentelemetry-java` is one of several repositories which comprise the OpenTelemetry Java ecosystem,
and contains the core components upon which instrumentation and extensions are built. In order to
prevent sprawl and maintain a high level of quality, we limit this repository's scope to components
which implement concepts defined in
the [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification),
with a few exceptions / comments:
* The [API incubator](./api/incubator) and [SDK incubator](./sdk-extensions/incubator)
contain prototypes which have been discussed in the specification
or [oteps](https://github.com/open-telemetry/oteps) and have a reasonable chance of becoming part
of the specification, subject to maintainers' discretion.
* Components like the [Kotlin Extension](./extensions/kotlin) are included which are required for
the API / SDK to function in key areas of the Java ecosystem. Inclusion is subject to maintainers'
discretion.
* As a general rule, components which implement semantic conventions belong elsewhere.
Other repositories in the OpenTelemetry Java ecosystem include:
* [opentelemetry-java-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation)
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
working code snippets demonstrating various concepts.
## Style guideline
We follow the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html). Our
@ -138,21 +102,6 @@ uses [google-java-format](https://github.com/google/google-java-format) library:
* Adding `toString()` overrides on classes is encouraged, but we only use `toString()` to provide
debugging assistance. The implementations of all `toString()` methods should be considered to be
unstable unless explicitly documented otherwise.
* Avoid synchronizing using a class's intrinsic lock. Instead, synchronize on a dedicated lock object. E.g:
```java
private final Object lock = new Object();
public void doSomething() {
synchronized (lock) { ... }
}
```
* 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 +139,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 +201,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

522
README.md
View File

@ -1,164 +1,202 @@
# OpenTelemetry Java
[![Maven Central][maven-image]][maven-url]
# OpenTelemetry for Java
[![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.
## Getting Started
See [opentelemetry.io Java Documentation](https://opentelemetry.io/docs/languages/java/intro/) for:
If you are looking for an all-in-one, easy-to-install **auto-instrumentation
javaagent**, see [opentelemetry-java-instrumentation][].
* 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
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][].
> [!IMPORTANT]
> We are currently seeking additional contributors! See [help wanted](#help-wanted) for details.
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` channel in the [CNCF slack](https://slack.cncf.io/).
Please join us for more informal discussions.
## 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/src/main/java/io/opentelemetry/api/) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage`
* [semantic conventions](semconv/) Generated code for the OpenTelemetry semantic conventions.
* [context api](context/src/main/java/io/opentelemetry/context/) The OpenTelemetry Context implementation.
* [extensions](extensions/) define additional API extensions, which are not part of the core API.
* [sdk](sdk/) defines the implementation of the OpenTelemetry API.
* [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.
* [Micrometer shim](micrometer1-shim/) defines a bridge layer from Micrometer 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
Unless otherwise noted, all published artifacts support Java 8 or higher.
See [language version compatibility](VERSIONING.md#language-version-compatibility) for complete
details.
**Android Disclaimer:** For compatibility
reasons, [library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring)
must be enabled.
**Android Disclaimer:** For compatibility reasons, [library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) must be enabled.
See [contributing](#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.14.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.14.0")
implementation('io.opentelemetry:opentelemetry-api')
}
```
Note that if you want to use any artifacts that have not fully stabilized yet (such as the [semantic conventions constants](https://github.com/open-telemetry/opentelemetry-java/tree/main/semconv) or the [SDK Autoconfigure Extension](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure)), 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.14.0")
implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.14.0-alpha')
implementation('io.opentelemetry:opentelemetry-api')
implementation('io.opentelemetry:opentelemetry-semconv')
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.15.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.15.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 +204,126 @@ 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 |
|----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|
| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
## Compatibility
### API
Artifacts from this repository follow semantic versioning.
| Component | Description | Artifact ID | Version |
|-----------------------------------|----------------------------------------------------------------|-------------------------|-------------------------------------------------------------|
| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Semantic Conventions](./semconv) | Generated code for OpenTelemetry semantic conventions | `opentelemetry-semconv` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
Stable artifacts (i.e. artifacts without `-alpha` version suffix) come with strong backwards
compatibility guarantees for public APIs.
### API Extensions
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.
| Component | Description | Artifact ID | Version |
|---------------------------------------------------------------|--------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|
| [Annotations Extension](./extensions/annotations) | Instrumentation annotations, used in conjunction with OpenTelemetry java agent | `opentelemetry-extension-annotations` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [AWS Extension](./extensions/aws) | AWS Xray propagator | `opentelemetry-extension-aws` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [Noop API Extension](./extensions/noop-api) | A noop OpenTelemetry implementation which ignores context | `opentelemetry-extension-noop-api` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
See the [VERSIONING.md](VERSIONING.md) for complete details on compatibility policy.
### SDK
## Contacting us
| Component | Description | Artifact ID | Version |
|----------------------------------------|--------------------------------------------------------|----------------------------------|-------------------------------------------------------------|
| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [SDK Logs Testing](./sdk/logs-testing) | Components for testing OpenTelemetry logs | `opentelemetry-sdk-logs-testing` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
We hold regular meetings. See details at [community page](https://github.com/open-telemetry/community#java-sdk).
### SDK Exporters
To report a bug, or request a new feature,
please [open an issue](https://github.com/open-telemetry/opentelemetry-java/issues/new/choose).
| Component | Description | Artifact ID | Version |
|-----------------------------------------------------|-------------------------------------------------------------------------------------|---------------------------------------|-------------------------------------------------------------|
| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including metrics and trace | `opentelemetry-exporter-otlp` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [OTLP Log Exporters](./exporters/otlp/logs) | OTLP gRPC & HTTP log exporters | `opentelemetry-exporter-otlp-logs` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter | `opentelemetry-exporter-jaeger` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter | `opentelemetry-exporter-jaeger-thift` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Jaeger Proto](./exporters/jaeger-proto) | Jaeger gRPC protobuf definitions (deprecated) | `opentelemetry-exporter-jaeger-proto` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Logging Exporter](./exporters/logging) | Logging exporters, includings metrics, traces, and logs | `opentelemetry-exporter-logging` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [OTLP Logging Exporter](./exporters/logging-otlp) | Logging exporters in OTLP protobuf JSON format, including metrics, traces, and logs | `opentelemetry-exporter-logging-otlp` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
We use [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-java/discussions)
for support or general questions. Feel free to drop us a line.
### SDK Extensions
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.
| Component | Description | Artifact ID | Version |
|-------------------------------------------------------------------------------|---------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|
| [SDK Autoconfigure Extension](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [SDK Resources Extension](./sdk-extensions/resources) | Resource providers, including container, host, os, and process | `opentelemetry-sdk-extension-resources` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [SDK AWS Extension](./sdk-extensions/aws) | AWS resource providers, including beanstalk, ec2, ecs, eks, and lambda | `opentelemetry-sdk-extension-aws` | <!--VERSION_STABLE-->1.14.0<!--/VERSION_STABLE--> |
| [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.14.0<!--/VERSION_STABLE--> |
| [SDK JFR Events Extension](./sdk-extensions/jfr-events) | SpanProcessor which records spans as JFR events | `opentelemetry-sdk-extension-jfr-events` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [SDK Metric Incubator Extension](./sdk-extensions/metric-incubator) | Metrics incubator, including YAML based view configuration | `opentelemetry-sdk-extension-metric-incubator` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [SDK Tracing Incubator Extension](./sdk-extensions/tracing-incubator) | Trace incubator, including leak detecting SpanProcessor | `opentelemetry-sdk-extension-tracing-incubator` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [SDK zPages Extension](./sdk-extensions/zpages) | SpanProcessor which exposes spans with zPages | `opentelemetry-sdk-extension-zpages` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
### Shims
| Component | Description | Artifact ID | Version |
|----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|
| [Micrometer Shim](./micrometer1-shim) | Bridge micrometer metrics into the OpenTelemetry metrics API | `opentelemetry-micrometer1-shim` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | <!--VERSION_UNSTABLE-->1.14.0-alpha<!--/VERSION_UNSTABLE--> |
## 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
Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemetry/teams/java-approvers)):
### 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
- [Christian Neumüller](https://github.com/Oberon00), Dynatrace
- [Jakub Wach](https://github.com/kubawach), 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).
*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).*
### Triagers
Maintainers ([@open-telemetry/java-maintainers](https://github.com/orgs/open-telemetry/teams/java-maintainers)):
- [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana Labs
- [Anuraag Agrawal](https://github.com/anuraaga), AWS
- [Jack Berg](https://github.com/jack-berg), New Relic
- [John Watson](https://github.com/jkwatson), Splunk
For more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).
Maintainers Emeritus:
### Emeritus
- [Bogdan Drutu](https://github.com/BogdanDrutu), Splunk
- [Carlos Alberto](https://github.com/carlosalberto), LightStep
- Maintainer [Bogdan Drutu](https://github.com/BogdanDrutu)
- Maintainer [Carlos Alberto](https://github.com/carlosalberto)
- Approver [Mateusz Rzeszutek](https://github.com/mateuszrzeszutek)
*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer).*
For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).
### Help wanted
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/Continuous%20Build/badge.svg
[ci-url]: https://github.com/open-telemetry/opentelemetry-java/actions?query=workflow%3Aci+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
[codecov-url]: https://codecov.io/gh/open-telemetry/opentelemetry-java/branch/main/
[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.io]: https://opentelemetry.io

View File

@ -6,33 +6,25 @@ directory. Additionally, ensure that appropriate `@since` annotations are added
the public APIs.
When preparing the change log, you can use
the [draft-change-log-entries.sh](./.github/scripts/draft-change-log-entries.sh) script to assist
with drafting. Alternatively,
use `git log upstream/v$MAJOR.$((MINOR-1)).x..upstream/v$MAJOR.$MINOR.x --graph --first-parent` or
the Github [compare tool](https://github.com/open-telemetry/opentelemetry-java/compare/) to view a
summary of all commits since last release as a reference.
## Release cadence
This repository roughly targets monthly minor releases from the `main` branch on the Friday after
the first Monday of the month.
`git log upstream/v$MAJOR.$((MINOR-1)).x..upstream/v$MAJOR.$MINOR.x --graph --first-parent`
or the Github [compare tool](https://github.com/open-telemetry/opentelemetry-java/compare/)
to view a summary of all commits since last release as a reference.
## Preparing a new major or minor release
* Close the release milestone if there is one.
* Merge a pull request to `main` updating the `CHANGELOG.md`.
* The heading for the unreleased entries should be `## Unreleased`.
* The heading for the release should include the release version but not the release date, e.g.
`## Version 1.9.0 (Unreleased)`.
* Run the [Prepare release branch workflow](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/prepare-release-branch.yml).
* Press the "Run workflow" button, and leave the default branch `main` selected.
* Review and merge the two pull requests that it creates
(one is targeted to the release branch and one is targeted to `main`).
* Review and merge the two pull requests that it creates
(one is targeted to the release branch and one is targeted to the `main` branch).
## Preparing a new patch release
All patch releases should include only bug-fixes, and must avoid adding/modifying the public APIs.
In general, patch releases are only made for regressions, security vulnerabilities, memory leaks
and deadlocks.
In general, patch releases are only made for regressions, memory leaks and deadlocks.
* Backport pull request(s) to the release branch.
* Run the [Backport workflow](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/backport.yml).
@ -41,56 +33,67 @@ and deadlocks.
then click the "Run workflow" button below that.
* Review and merge the backport pull request that it generates.
* Merge a pull request to the release branch updating the `CHANGELOG.md`.
* The heading for the unreleased entries should be `## Unreleased`.
* The heading for the release should include the release version but not the release date, e.g.
`## Version 1.9.1 (Unreleased)`.
* Run the [Prepare patch release workflow](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/prepare-patch-release.yml).
* Press the "Run workflow" button, then select the release branch from the dropdown list,
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
* Review and merge the pull request that it creates for updating the version.
* Review and merge the pull request that it creates.
## Making the release
* Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/release.yml).
* Press the "Run workflow" button, then select the release branch from the dropdown list,
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
* This workflow will publish the artifacts to maven central and will publish a GitHub release
with release notes based on the change log.
* 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.
Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/release.yml).
* Press the "Run workflow" button, then select the release branch from the dropdown list,
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
* This workflow will publish the artifacts to maven central and will publish a GitHub release
with release notes based on the change log.
* Review and merge the pull request that the release workflow creates against the release branch
which adds the release date to the change log.
## After the release
Run the [Merge change log to main workflow](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/merge-change-log-to-main.yml).
* Press the "Run workflow" button, then select the release branch from the dropdown list,
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
* This will create a pull request that merges the change log updates from the release branch
back to main.
* Review and merge the pull request that it creates.
* This workflow will fail if there have been conflicting change log updates introduced in main,
in which case you will need to merge the change log updates manually and send your own pull
request against main.
## 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 to mark the new release in README.md on the main branch.
Finally, update the [website docs][] to refer to the newly released version.
[website docs]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/java
## Credentials
The following credentials are required for building or publishing (and automatically set in Github Actions):
The following credentials are required for publishing (and automatically set in Circle CI):
* `GPG_PRIVATE_KEY` and `GPG_PASSWORD`: GPG private key and password for signing
- Note, currently only @anuraaga has this and we need to find a way to safely share secrets in the
OpenTelemetry project, for example with a password manager. In the worst case if you need to
release manually and cannot get a hold of it, you can generate a new key but don't forget to
upload the public key to keyservers.
* `GPG_PRIVATE_KEY` and `GPG_PASSWORD`: GPG private key and password for signing.
* `SONATYPE_USER` and `SONATYPE_KEY`: Sonatype username and password.
* Each maintainer will have their own set of Sonotype credentials with permission to publish to
the `io.opentelemetry` group prefix.
* [Register to publish](https://central.sonatype.org/register/central-portal/#and-publishing-is-easy)
and comment on [OSSRH-63768](https://issues.sonatype.org/browse/OSSRH-63768) with confirmation
from another maintainer.
* To obtain `SONATYPE_USER` and `SONATYPE_KEY` for your account, login
to [oss.sonatype.org](https://oss.sonatype.org/) and navigate to Profile -> User Token -> Access
User Token.
Additionally, credentials are stored with maintainers via
the [OpenTelemetry 1Password](https://opentelemetry.1password.com/signin) account. The following
defines the mapping from Github Action secret keys to 1Password keys:
| Github Actions Key | 1Password Key |
|--------------------|---------------|
| `GPG_PASSWORD` | `opentelemetry-java GPG_PASSWORD` |
| `GPG_PRIVATE_KEY` | `opentelemetry-java GPG_PRIVATE_KEY` |
## Releasing from the local setup

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.
@ -31,17 +31,6 @@ changes are:
Such changes will be avoided - if they must be made, the `MAJOR` version of the artifact will be
incremented.
A stable artifact may depend on an `-alpha` artifact, and expose classes, interfaces, enums, etc. of
the `-alpha` artifact as part of its public API. In these cases, the stable artifact will place
an [implementation](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation)
dependency (as opposed to an api dependency) on the `-alpha` artifact. In order to consume the
portions of the API related to the `-alpha` artifact, a user must place their own implementation
dependency on it. In adding the implementation dependency, the user has opted into to using
an `-alpha` artifact, and we reserve the right to change the portions of the API pertaining to
the `-alpha` artifact. This includes changing the names of methods, return types, argument types, etc.
We will use this technique sparingly and only when there is some significant reduction in friction
by including the `-alpha` artifact.
Backwards incompatible changes to `internal` packages are expected. Versions of published artifacts
are expected to be aligned by using BOMs we publish. We will always provide BOMs to allow alignment
of versions.
@ -50,31 +39,11 @@ Changes may be made that require changes to the an app's dependency declarations
incrementing the version on `MINOR` version updates. For example, code may be separated out to a
new artifact which requires adding the new artifact to dependency declarations.
On rare occasions we may deprecate an entire stable artifact, with the intent of stopping functional
changes or enhancements. In these situations we may stop publishing additional `MINOR` or `MAJOR`
versions of the artifact. However, if necessary, we'll publish security fixes via `PATCH` releases.
The API of the last published version will remain stable.
As a user, if you always depend on the latest version of the BOM for a given `MAJOR` version, and
you do not use classes in the `internal` package (which you MUST NOT do), you can be assured that
your app will always function and have access to the latest features of OpenTelemetry without needing
any changes to code.
## Language Version Compatibility
The artifacts published by this codebase are compatible with certain language levels of tooling in
the Java ecosystem. For example, all artifacts (except where otherwise noted) support Java language
level 8 or higher, and the many artifacts intended to be used in Android environments adhere to a
particular [Android API level](https://developer.android.com/tools/releases/build-tools). The
following table defines the minimum language levels we adhere to, and how each is considered with
respect to semantic versioning.
| Language | Minimum Version | Applicability | Semconv Notes |
|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java | 8+ | All artifacts, unless otherwise noted | Changing requires major version bump. |
| Android | 23+ (NOTE: [desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) is required. We stay up to date with the latest version of [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs).) | Artifacts using `otel.animalsniffer-conventions` plugin | Kept in sync with minimum requirements for [Google Play services](https://developers.google.com/android/guides/setup). Subject to change in minor version. |
| Kotlin | 1.8+ | Only applies to `opentelemetry-extension-kotlin` | Kept in sync with [minimum non-deprecated](https://kotlinlang.org/docs/gradle-compiler-options.html#attributes-common-to-jvm-and-js) version. Subject to change in minor versions. |
## API vs SDK
This codebase is broadly split into two large pieces, the OpenTelemetry API and the OpenTelemetry SDK,

View File

@ -8,9 +8,8 @@ otelJava.moduleName.set("io.opentelemetry.all")
tasks {
// We don't compile much here, just some API boundary tests. This project is mostly for
// aggregating jacoco reports and it doesn't work if this isn't at least as high as the
// highest supported Java version in any of our projects. All of our
// projects target Java 8 except :exporters:http-sender:jdk, which targets
// Java 11
// highest supported Java version in any of our projects. Most of our projects target
// Java 8, except for jfr-events.
withType(JavaCompile::class) {
options.release.set(11)
}
@ -23,11 +22,6 @@ tasks {
}
}
// Skip OWASP dependencyCheck task on test module
dependencyCheck {
skip = true
}
val testTasks = mutableListOf<Task>()
dependencies {
@ -44,7 +38,6 @@ dependencies {
}
}
}
testImplementation("com.tngtech.archunit:archunit-junit5")
}
@ -85,9 +78,15 @@ tasks.named<JacocoReport>("jacocoTestReport") {
// Exclude mrjar (jacoco complains), shaded, and generated code
!it.absolutePath.contains("META-INF/versions/") &&
!it.absolutePath.contains("/internal/shaded/") &&
!it.absolutePath.contains("io/opentelemetry/proto/") &&
!it.absolutePath.contains("io/opentelemetry/exporter/jaeger/proto/") &&
!it.absolutePath.contains("io/opentelemetry/exporter/jaeger/internal/protobuf/") &&
!it.absolutePath.contains("io/opentelemetry/sdk/extension/trace/jaeger/proto/") &&
!it.absolutePath.contains("AutoValue_")
},
!it.absolutePath.contains("io/opentelemetry/semconv/trace/attributes/") &&
!it.absolutePath.contains("AutoValue_") &&
// TODO(anuraaga): Remove exclusion after enabling coverage for jfr-events
!it.absolutePath.contains("io/opentelemetry/sdk/extension/jfr")
}
)
}
additionalSourceDirs(sourcesPath.incoming.artifactView { lenient(true) }.files)

View File

@ -6,17 +6,17 @@
package io.opentelemetry.all;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.base.Optional;
import com.tngtech.archunit.base.PackageMatcher;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.PackageMatcher;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
import com.tngtech.archunit.lang.syntax.elements.MethodsShouldConjunction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;
class SdkDesignTest {
@ -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");
@ -57,9 +53,9 @@ class SdkDesignTest {
}
static DescribedPredicate<? super JavaMethod> implementOrOverride() {
return new DescribedPredicate<JavaMethod>("implement or override a method") {
return new DescribedPredicate<>("implement or override a method") {
@Override
public boolean test(JavaMethod input) {
public boolean apply(JavaMethod input) {
List<JavaClass> params = input.getRawParameterTypes();
Class<?>[] paramsType = new Class<?>[params.size()];
for (int i = 0, n = params.size(); i < n; i++) {
@ -82,9 +78,9 @@ class SdkDesignTest {
}
static DescribedPredicate<? super JavaClass> inPackage(String... requiredPackages) {
return new DescribedPredicate<JavaClass>("are in " + Arrays.toString(requiredPackages)) {
return new DescribedPredicate<>("are in " + Arrays.toString(requiredPackages)) {
@Override
public boolean test(JavaClass member) {
public boolean apply(JavaClass member) {
for (String requiredPackage : requiredPackages) {
if (PackageMatcher.of(requiredPackage).matches(member.getPackageName())) {
return true;

View File

@ -0,0 +1,69 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.extension.noopapi;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
class NoopOpenTelemetryTest {
private static final SpanContext SPAN_CONTEXT =
SpanContext.create(
"00000000000000000000000000000061",
"0000000000000061",
TraceFlags.getDefault(),
TraceState.getDefault());
@Test
void contextNoOp() {
// Context.root() is not a no-op Context, so the default context is never root.
Context context = Context.current();
assertThat(context).isNotSameAs(Context.root());
// No allocations
assertThat(context.with(Span.wrap(SPAN_CONTEXT))).isSameAs(context);
assertThat(SPAN_CONTEXT.isValid()).isTrue();
try (Scope ignored = Context.current().with(Span.wrap(SPAN_CONTEXT)).makeCurrent()) {
// No context mounted, so always an invalid span.
assertThat(Span.fromContext(Context.current()).getSpanContext().isValid()).isFalse();
}
}
@Test
void tracerNoOp() {
SpanBuilder span1 = NoopOpenTelemetry.getInstance().getTracer("test").spanBuilder("test");
SpanBuilder span2 = NoopOpenTelemetry.getInstance().getTracer("test").spanBuilder("test");
// No allocations
assertThat(span1).isSameAs(span2);
// No crash
span1.setParent(Context.current());
span1.setNoParent();
span1.addLink(SPAN_CONTEXT);
span1.addLink(SPAN_CONTEXT, Attributes.empty());
span1.setAttribute("key", "value");
span1.setAttribute("key", 1L);
span1.setAttribute("key", 1.0);
span1.setAttribute("key", true);
span1.setAttribute(AttributeKey.stringKey("key"), "value");
span1.setSpanKind(SpanKind.CLIENT);
span1.setStartTimestamp(1, TimeUnit.DAYS);
// No allocations
assertThat(span1.startSpan()).isSameAs(Span.getInvalid());
}
}

View File

@ -1,52 +0,0 @@
import ru.vyarus.gradle.plugin.animalsniffer.info.SignatureInfoTask
import ru.vyarus.gradle.plugin.animalsniffer.signature.BuildSignatureTask
plugins {
id("otel.java-conventions")
id("ru.vyarus.animalsniffer")
}
description = "Build tool to generate the Animal Sniffer Android signature"
otelJava.moduleName.set("io.opentelemetry.internal.animalsniffer")
val signatureJar = configurations.create("signatureJar") {
isCanBeConsumed = false
isCanBeResolved = false
}
val signatureJarClasspath = configurations.create("signatureJarClasspath") {
isCanBeConsumed = false
isCanBeResolved = true
extendsFrom(signatureJar)
}
val generatedSignature = configurations.create("generatedSignature") {
isCanBeConsumed = true
isCanBeResolved = false
}
configurations.add(signatureJar)
configurations.add(signatureJarClasspath)
configurations.add(generatedSignature)
dependencies {
signature("com.toasttab.android:gummy-bears-api-23:0.12.0@signature")
signatureJar("com.android.tools:desugar_jdk_libs")
}
val signatureSimpleName = "android.signature"
val signatureBuilderTask = tasks.register("buildSignature", BuildSignatureTask::class.java) {
files(signatureJarClasspath) // All the jar files here will be added to the signature file.
signatures(configurations.signature) // We'll extend from the existing signatures added to this config.
outputName = signatureSimpleName // Name for the generated signature file.
}
// Exposing the "generatedSignature" consumable config to be used in other subprojects
artifacts {
add("generatedSignature", project.provider { File(signatureBuilderTask.get().outputs.files.singleFile, signatureSimpleName) }) {
builtBy(signatureBuilderTask)
}
}
// Utility task to show what's in the signature file
tasks.register("printSignature", SignatureInfoTask::class.java) {
signature = signatureBuilderTask.get().outputFiles
depth = 1
}

View File

@ -1,7 +1,22 @@
# OpenTelemetry API
#### API Misuse Logging
[![Javadocs][javadoc-image]][javadoc-url]
API misuse information is logged under logger named `io.opentelemetry.ApiUsageLogging`.
* The code in this module is the implementation of stable OpenTelemetry signals.
* Semantic Conventions for OpenTelemetry are in the `opentelemetry-semconv` module.
* The default implementation of the interfaces in this module is in the OpenTelemetry SDK module.
* The interfaces in this directory can be implemented to create alternative
implementations of the OpenTelemetry library.
To access, enable `FINEST` level logs.
[javadoc-image]: https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg
[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api
---
#### Running micro-benchmarks
From the root of the repo run `./gradlew clean :api:jmh` to run all the benchmarks
or run `./gradlew clean :api:jmh -PjmhIncludeSingleClass=<ClassNameHere>`
to run a specific benchmark class.
---
#### Logging API mis-use
Define `logging.level.io.opentelemetry.ApiUsageLogging=TRACE` to enable TRACE logging for invalid API calls.

View File

@ -15,13 +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")
}
tasks.test {
// Configure environment variable for ConfigUtilTest
environment("CONFIG_KEY", "environment")
}

View File

@ -25,30 +25,11 @@ public class AttributesBenchmark {
// pre-allocate the keys & values to remove one possible confounding factor
private static final List<AttributeKey<String>> keys = new ArrayList<>(10);
private static final List<String> values = new ArrayList<>(10);
private static final List<Attributes> attributes = new ArrayList<>();
static {
for (int i = 0; i < 10; i++) {
keys.add(AttributeKey.stringKey("key" + i));
values.add("value" + i);
AttributesBuilder builder = Attributes.builder();
for (int j = 0; j <= i; j++) {
builder.put(keys.get(j), values.get(j));
}
attributes.add(builder.build());
}
}
@Benchmark
@BenchmarkMode({Mode.AverageTime})
@Fork(1)
@Measurement(iterations = 15, time = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
@SuppressWarnings("ReturnValueIgnored")
public void computeHashCode() {
for (Attributes attributes : attributes) {
attributes.hashCode();
}
}

View File

@ -46,9 +46,4 @@ final class DefaultOpenTelemetry implements OpenTelemetry {
public ContextPropagators getPropagators() {
return propagators;
}
@Override
public String toString() {
return "DefaultOpenTelemetry{" + "propagators=" + propagators + "}";
}
}

View File

@ -5,9 +5,7 @@
package io.opentelemetry.api;
import io.opentelemetry.api.internal.ConfigUtil;
import io.opentelemetry.api.internal.GuardedBy;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterBuilder;
import io.opentelemetry.api.metrics.MeterProvider;
@ -17,7 +15,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;
@ -47,18 +44,12 @@ import javax.annotation.concurrent.ThreadSafe;
@SuppressWarnings("StaticAssignmentOfThrowable")
public final class GlobalOpenTelemetry {
private static final String GLOBAL_AUTOCONFIGURE_ENABLED_PROPERTY =
"otel.java.global-autoconfigure.enabled";
private static final Logger logger = Logger.getLogger(GlobalOpenTelemetry.class.getName());
private static final Object mutex = new Object();
@SuppressWarnings("NonFinalStaticField")
@Nullable
private static volatile ObfuscatedOpenTelemetry globalOpenTelemetry;
@Nullable private static volatile ObfuscatedOpenTelemetry globalOpenTelemetry;
@SuppressWarnings("NonFinalStaticField")
@GuardedBy("mutex")
@Nullable
private static Throwable setGlobalCaller;
@ -117,21 +108,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();
@ -243,29 +219,15 @@ public final class GlobalOpenTelemetry {
return null;
}
// If autoconfigure module is present but global autoconfigure disabled log a warning and return
boolean globalAutoconfigureEnabled =
Boolean.parseBoolean(ConfigUtil.getString(GLOBAL_AUTOCONFIGURE_ENABLED_PROPERTY, "false"));
if (!globalAutoconfigureEnabled) {
logger.log(
Level.INFO,
"AutoConfiguredOpenTelemetrySdk found on classpath but automatic configuration is disabled."
+ " To enable, run your JVM with -D"
+ GLOBAL_AUTOCONFIGURE_ENABLED_PROPERTY
+ "=true");
return null;
}
try {
Method initialize = openTelemetrySdkAutoConfiguration.getMethod("initialize");
Object autoConfiguredSdk = initialize.invoke(null);
Method getOpenTelemetrySdk =
openTelemetrySdkAutoConfiguration.getMethod("getOpenTelemetrySdk");
return new ObfuscatedOpenTelemetry(
(OpenTelemetry) getOpenTelemetrySdk.invoke(autoConfiguredSdk));
return (OpenTelemetry) getOpenTelemetrySdk.invoke(autoConfiguredSdk);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new IllegalStateException(
"AutoConfiguredOpenTelemetrySdk detected on classpath "
"OpenTelemetrySdkAutoConfiguration detected on classpath "
+ "but could not invoke initialize method. This is a bug in OpenTelemetry.",
e);
} catch (InvocationTargetException t) {
@ -301,11 +263,6 @@ public final class GlobalOpenTelemetry {
return delegate.getMeterProvider();
}
@Override
public LoggerProvider getLogsBridge() {
return delegate.getLogsBridge();
}
@Override
public ContextPropagators getPropagators() {
return delegate.getPropagators();

View File

@ -5,7 +5,6 @@
package io.opentelemetry.api;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterBuilder;
import io.opentelemetry.api.metrics.MeterProvider;
@ -103,7 +102,7 @@ public interface OpenTelemetry {
}
/**
* Creates a {@link MeterBuilder} for a named {@link Meter} instance.
* Creates a {@link MeterBuilder} for a named {@link Tracer} instance.
*
* @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as
* the instrumentation library, package, or fully qualified class name. Must not be null.
@ -114,19 +113,6 @@ public interface OpenTelemetry {
return getMeterProvider().meterBuilder(instrumentationScopeName);
}
/**
* Returns the {@link LoggerProvider} for bridging logs into OpenTelemetry.
*
* <p>The OpenTelemetry logs bridge API exists to enable bridging logs from other log frameworks
* (e.g. SLF4J, Log4j, JUL, Logback, etc) into OpenTelemetry and is <b>NOT</b> a replacement log
* API.
*
* @since 1.27.0
*/
default LoggerProvider getLogsBridge() {
return LoggerProvider.noop();
}
/** Returns the {@link ContextPropagators} for this {@link OpenTelemetry}. */
ContextPropagators getPropagators();
}

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

@ -6,7 +6,7 @@
package io.opentelemetry.api.baggage;
import com.google.auto.value.AutoValue;
import io.opentelemetry.api.internal.ApiUsageLogger;
import io.opentelemetry.api.internal.ValidationUtil;
import javax.annotation.concurrent.Immutable;
@Immutable
@ -25,7 +25,7 @@ abstract class ImmutableEntryMetadata implements BaggageEntryMetadata {
*/
static ImmutableEntryMetadata create(String metadata) {
if (metadata == null) {
ApiUsageLogger.log("metadata is null");
ValidationUtil.log("metadata is null");
return EMPTY;
}
return new AutoValue_ImmutableEntryMetadata(metadata);

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

@ -1,88 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.baggage.propagation;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Note: This class is based on code from Apache Commons Codec. It is comprised of code from these
* classes:
*
* <ul>
* <li><a
* href="https://github.com/apache/commons-codec/blob/482df6cabfb288acb6ab3e4a732fdb93aecfa7c2/src/main/java/org/apache/commons/codec/net/URLCodec.java">org.apache.commons.codec.net.URLCodec</a>
* <li><a
* href="https://github.com/apache/commons-codec/blob/482df6cabfb288acb6ab3e4a732fdb93aecfa7c2/src/main/java/org/apache/commons/codec/net/Utils.java">org.apache.commons.codec.net.Utils</a>
* </ul>
*
* <p>Implements baggage-octet decoding in accordance with th <a
* href="https://w3c.github.io/baggage/#definition">Baggage header content</a> specification. All
* US-ASCII characters excluding CTLs, whitespace, DQUOTE, comma, semicolon and backslash are
* encoded in `www-form-urlencoded` encoding scheme.
*/
class BaggageCodec {
private static final byte ESCAPE_CHAR = '%';
private static final int RADIX = 16;
private BaggageCodec() {}
/**
* Decodes an array of URL safe 7-bit characters into an array of original bytes. Escaped
* characters are converted back to their original representation.
*
* @param bytes array of URL safe characters
* @return array of original bytes
*/
private static byte[] decode(byte[] bytes) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
int b = bytes[i];
if (b == ESCAPE_CHAR) {
try {
int u = digit16(bytes[++i]);
int l = digit16(bytes[++i]);
buffer.write((char) ((u << 4) + l));
} catch (ArrayIndexOutOfBoundsException e) { // FIXME
throw new IllegalArgumentException("Invalid URL encoding: ", e);
}
} else {
buffer.write(b);
}
}
return buffer.toByteArray();
}
/**
* Decodes an array of URL safe 7-bit characters into an array of original bytes. Escaped
* characters are converted back to their original representation.
*
* @param value string of URL safe characters
* @param charset encoding of given string
* @return decoded value
*/
static String decode(String value, Charset charset) {
byte[] bytes = decode(value.getBytes(StandardCharsets.US_ASCII));
return new String(bytes, charset);
}
/**
* Returns the numeric value of the character {@code b} in radix 16.
*
* @param b The byte to be converted.
* @return The numeric value represented by the character in radix 16.
*/
private static int digit16(byte b) {
int i = Character.digit((char) b, RADIX);
if (i == -1) {
throw new IllegalArgumentException( // FIXME
"Invalid URL encoding: not a valid digit (radix " + RADIX + "): " + b);
}
return i;
}
}

View File

@ -7,16 +7,18 @@ package io.opentelemetry.api.baggage.propagation;
import io.opentelemetry.api.baggage.BaggageBuilder;
import io.opentelemetry.api.baggage.BaggageEntryMetadata;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
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 +39,7 @@ class Parser {
private boolean skipToNext;
Parser(String baggageHeader) {
public Parser(String baggageHeader) {
this.baggageHeader = baggageHeader;
reset(0);
}
@ -62,8 +64,6 @@ class Parser {
} else {
skipToNext = true;
}
} else if (state == State.VALUE) {
skipToNext = !value.tryNextChar(current, i);
}
break;
}
@ -146,7 +146,11 @@ class Parser {
if (value == null) {
return null;
}
return BaggageCodec.decode(value, StandardCharsets.UTF_8);
try {
return URLDecoder.decode(value, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**

View File

@ -18,8 +18,9 @@
* the License.
*/
package io.opentelemetry.api.internal;
package io.opentelemetry.api.baggage.propagation;
import io.opentelemetry.api.internal.TemporaryBuffers;
import javax.annotation.CheckForNull;
/**
@ -58,13 +59,10 @@ import javax.annotation.CheckForNull;
* <p><b>Note:</b> This escaper produces <a
* href="https://url.spec.whatwg.org/#percent-encode">uppercase</a> hexadecimal sequences.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*
* @author David Beaumont
* @since 15.0
*/
public final class PercentEscaper {
final class PercentEscaper {
/** The amount of padding (chars) to use when growing the escape buffer. */
private static final int DEST_PAD = 32;
@ -88,7 +86,7 @@ public final class PercentEscaper {
private static final boolean[] safeOctets = createSafeOctets(SAFE_CHARS);
/** The default {@link PercentEscaper} which will *not* replace spaces with plus signs. */
public static PercentEscaper create() {
static PercentEscaper create() {
return new PercentEscaper();
}
@ -111,7 +109,7 @@ public final class PercentEscaper {
}
/** Escape the provided String, using percent-style URL Encoding. */
public String escape(String s) {
String escape(String s) {
int slen = s.length();
for (int index = 0; index < slen; index++) {
char c = s.charAt(index);

View File

@ -10,14 +10,12 @@ import static java.util.Collections.singletonList;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageBuilder;
import io.opentelemetry.api.baggage.BaggageEntry;
import io.opentelemetry.api.internal.PercentEscaper;
import io.opentelemetry.api.internal.StringUtils;
import io.opentelemetry.context.Context;
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 +94,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 +126,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);
}
/**
@ -153,9 +138,4 @@ public final class W3CBaggagePropagator implements TextMapPropagator {
private static boolean isValidBaggageValue(String value) {
return value != null;
}
@Override
public String toString() {
return "W3CBaggagePropagator";
}
}

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

@ -1,54 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.util.Objects;
final class ValueBoolean implements Value<Boolean> {
private final boolean value;
private ValueBoolean(boolean value) {
this.value = value;
}
static Value<Boolean> create(boolean value) {
return new ValueBoolean(value);
}
@Override
public ValueType getType() {
return ValueType.BOOLEAN;
}
@Override
public Boolean getValue() {
return value;
}
@Override
public String asString() {
return String.valueOf(value);
}
@Override
public String toString() {
return "ValueBoolean{" + 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 Boolean.hashCode(value);
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Base64;
import java.util.Objects;
final class ValueBytes implements Value<ByteBuffer> {
private final byte[] raw;
private ValueBytes(byte[] value) {
this.raw = value;
}
static Value<ByteBuffer> create(byte[] value) {
Objects.requireNonNull(value, "value must not be null");
return new ValueBytes(Arrays.copyOf(value, value.length));
}
@Override
public ValueType getType() {
return ValueType.BYTES;
}
@Override
public ByteBuffer getValue() {
return ByteBuffer.wrap(raw).asReadOnlyBuffer();
}
@Override
public String asString() {
return Base64.getEncoder().encodeToString(raw);
}
@Override
public String toString() {
return "ValueBytes{" + asString() + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
return (o instanceof ValueBytes) && Arrays.equals(this.raw, ((ValueBytes) o).raw);
}
@Override
public int hashCode() {
return Arrays.hashCode(raw);
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.util.Objects;
final class ValueDouble implements Value<Double> {
private final double value;
private ValueDouble(double value) {
this.value = value;
}
static Value<Double> create(double value) {
return new ValueDouble(value);
}
@Override
public ValueType getType() {
return ValueType.DOUBLE;
}
@Override
public Double getValue() {
return value;
}
@Override
public String asString() {
return String.valueOf(value);
}
@Override
public String toString() {
return "ValueDouble{" + 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 Double.hashCode(value);
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.util.Objects;
final class ValueLong implements Value<Long> {
private final long value;
private ValueLong(long value) {
this.value = value;
}
static Value<Long> create(long value) {
return new ValueLong(value);
}
@Override
public ValueType getType() {
return ValueType.LONG;
}
@Override
public Long getValue() {
return value;
}
@Override
public String asString() {
return String.valueOf(value);
}
@Override
public String toString() {
return "ValueLong{" + 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 Long.hashCode(value);
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.util.Objects;
final class ValueString implements Value<String> {
private final String value;
private ValueString(String value) {
this.value = value;
}
static Value<String> create(String value) {
Objects.requireNonNull(value, "value must not be null");
return new ValueString(value);
}
@Override
public ValueType getType() {
return ValueType.STRING;
}
@Override
public String getValue() {
return value;
}
@Override
public String asString() {
return value;
}
@Override
public String toString() {
return "ValueString{" + value + "}";
}
@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,23 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
/**
* AnyValue type options, mirroring <a
* href="https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/common/v1/common.proto#L31">AnyValue#value
* options</a>.
*
* @since 1.42.0
*/
public enum ValueType {
STRING,
BOOLEAN,
LONG,
DOUBLE,
ARRAY,
KEY_VALUE_LIST,
BYTES
}

View File

@ -1,42 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.internal;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Helper for API misuse logging.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public final class ApiUsageLogger {
private static final Logger API_USAGE_LOGGER = Logger.getLogger(ApiUsageLogger.class.getName());
/**
* Log the {@code message} to the {@link #API_USAGE_LOGGER API Usage Logger}.
*
* <p>Log at {@link Level#FINEST} and include a stack trace.
*/
public static void log(String message) {
log(message, Level.FINEST);
}
/**
* Log the {@code message} to the {@link #API_USAGE_LOGGER API Usage Logger}.
*
* <p>Log includes a stack trace.
*/
public static void log(String message, Level level) {
if (API_USAGE_LOGGER.isLoggable(level)) {
API_USAGE_LOGGER.log(level, message, new AssertionError());
}
}
private ApiUsageLogger() {}
}

View File

@ -1,82 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
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;
/**
* Configuration utilities.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
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}.
*
* <p>Normalize the {@code key} using {@link #normalizePropertyKey(String)}. Match to system
* property keys also normalized with {@link #normalizePropertyKey(String)}. Match to environment
* variable keys normalized with {@link #normalizeEnvironmentVariableKey(String)}. System
* properties take priority over environment variables.
*
* @param key the property key
* @return the system property if not null, or the environment variable if not null, or {@code
* defaultValue}
*/
public static String getString(String key, String defaultValue) {
String normalizedKey = normalizePropertyKey(key);
String systemProperty =
safeSystemProperties().entrySet().stream()
.filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey().toString())))
.map(entry -> entry.getValue().toString())
.findFirst()
.orElse(null);
if (systemProperty != null) {
return systemProperty;
}
return System.getenv().entrySet().stream()
.filter(entry -> normalizedKey.equals(normalizeEnvironmentVariableKey(entry.getKey())))
.map(Map.Entry::getValue)
.findFirst()
.orElse(defaultValue);
}
/**
* Normalize an environment variable key by converting to lower case and replacing "_" with ".".
*/
public static String normalizeEnvironmentVariableKey(String key) {
return key.toLowerCase(Locale.ROOT).replace("_", ".");
}
/** Normalize a property key by converting to lower case and replacing "-" with ".". */
public static String normalizePropertyKey(String key) {
return key.toLowerCase(Locale.ROOT).replace("-", ".");
}
/** Returns defaultValue if value is null, otherwise value. This is an internal method. */
public static <T> T defaultIfNull(@Nullable T value, T defaultValue) {
return value == null ? defaultValue : value;
}
}

View File

@ -32,7 +32,6 @@ import javax.annotation.concurrent.Immutable;
@Immutable
public abstract class ImmutableKeyValuePairs<K, V> {
private final Object[] data;
private int hashcode;
/**
* Stores the raw object data directly. Does not do any de-duping or sorting. If you use this
@ -212,12 +211,6 @@ public abstract class ImmutableKeyValuePairs<K, V> {
// Skip entries with null value, we do it here because we want them to overwrite and remove
// entries with same key that we already added.
if (value == null) {
// When the value is null, there are two cases:
// 1. next key is the same as the current one, it may cause ArrayIndexOutOfBoundsException,
// so we reset the previous key to null to avoid this
// 2. next key is different than the current one; In this case, whether the previous key is
// null or not will have no impact.
previousKey = null;
continue;
}
previousKey = key;
@ -248,13 +241,9 @@ public abstract class ImmutableKeyValuePairs<K, V> {
@Override
public int hashCode() {
int result = hashcode;
if (result == 0) {
result = 1;
result *= 1000003;
result ^= Arrays.hashCode(data);
hashcode = result;
}
int result = 1;
result *= 1000003;
result ^= Arrays.hashCode(data);
return result;
}
@ -274,13 +263,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

@ -54,8 +54,6 @@ public abstract class ImmutableSpanContext implements SpanContext {
* @param traceFlags the trace flags of the {@code SpanContext}.
* @param traceState the trace state for the {@code SpanContext}.
* @param remote the remote flag for the {@code SpanContext}.
* @param skipIdValidation pass true to skip validation of trace ID and span ID as an optimization
* in cases where they are known to have been already validated.
* @return a new {@code SpanContext} with the given identifiers and options.
*/
public static SpanContext create(

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

@ -0,0 +1,105 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.internal;
import java.nio.charset.StandardCharsets;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
/**
* General internal validation utility methods.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public final class ValidationUtil {
public static final String API_USAGE_LOGGER_NAME = "io.opentelemetry.ApiUsageLogging";
private static final Logger API_USAGE_LOGGER = Logger.getLogger(API_USAGE_LOGGER_NAME);
/**
* Instrument names MUST conform to the following syntax.
*
* <ul>
* <li>They are not null or empty strings.
* <li>They are case-insensitive, ASCII strings.
* <li>The first character must be an alphabetic character.
* <li>Subsequent characters must belong to the alphanumeric characters, '_', '.', and '-'.
* <li>They can have a maximum length of 63 characters.
* </ul>
*/
private static final Pattern VALID_INSTRUMENT_NAME_PATTERN =
Pattern.compile("([A-Za-z]){1}([A-Za-z0-9\\_\\-\\.]){0,62}");
/**
* Log the {@code message} to the {@link #API_USAGE_LOGGER_NAME API Usage Logger}.
*
* <p>Log at {@link Level#FINEST} and include a stack trace.
*/
public static void log(String message) {
log(message, Level.FINEST);
}
/**
* Log the {@code message} to the {@link #API_USAGE_LOGGER_NAME API Usage Logger}.
*
* <p>Log includes a stack trace.
*/
public static void log(String message, Level level) {
API_USAGE_LOGGER.log(level, message, new AssertionError());
}
/** Check if the instrument name is valid. If invalid, log a warning. */
public static boolean checkValidInstrumentName(String name) {
return checkValidInstrumentName(name, "");
}
/**
* Check if the instrument name is valid. If invalid, log a warning with the {@code logSuffix}
* appended.
*/
public static boolean checkValidInstrumentName(String name, String logSuffix) {
if (name != null && VALID_INSTRUMENT_NAME_PATTERN.matcher(name).matches()) {
return true;
}
log(
"Instrument name \""
+ name
+ "\" is invalid, returning noop instrument. Instrument names must consist of 63 or fewer characters including alphanumeric, _, ., -, and start with a letter."
+ logSuffix,
Level.WARNING);
return false;
}
/** Check if the instrument unit is valid. If invalid, log a warning. */
public static boolean checkValidInstrumentUnit(String unit) {
return checkValidInstrumentUnit(unit, "");
}
/**
* Check if the instrument unit is valid. If invalid, log a warning with the {@code logSuffix}
* appended.
*/
public static boolean checkValidInstrumentUnit(String unit, String logSuffix) {
if (unit != null
&& !unit.equals("")
&& unit.length() < 64
&& StandardCharsets.US_ASCII.newEncoder().canEncode(unit)) {
return true;
}
log(
"Unit \""
+ unit
+ "\" is invalid. Instrument unit must be 63 or fewer ASCII characters."
+ logSuffix,
Level.WARNING);
return false;
}
private ValidationUtil() {}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
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 {
private static final Logger INSTANCE = new DefaultLogger();
private static final LogRecordBuilder NOOP_LOG_RECORD_BUILDER = new NoopLogRecordBuilder();
private DefaultLogger() {}
static Logger getInstance() {
return INSTANCE;
}
@Override
public LogRecordBuilder logRecordBuilder() {
return NOOP_LOG_RECORD_BUILDER;
}
private static final class NoopLogRecordBuilder implements LogRecordBuilder {
private NoopLogRecordBuilder() {}
@Override
public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
return this;
}
@Override
public LogRecordBuilder setTimestamp(Instant instant) {
return this;
}
@Override
public LogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) {
return this;
}
@Override
public LogRecordBuilder setObservedTimestamp(Instant instant) {
return this;
}
@Override
public LogRecordBuilder setContext(Context context) {
return this;
}
@Override
public LogRecordBuilder setSeverity(Severity severity) {
return this;
}
@Override
public LogRecordBuilder setSeverityText(String severityText) {
return this;
}
@Override
public LogRecordBuilder setBody(String body) {
return this;
}
@Override
public LogRecordBuilder setBody(Value<?> body) {
return this;
}
@Override
public <T> LogRecordBuilder setAttribute(AttributeKey<T> key, @Nullable T value) {
return this;
}
@Override
public void emit() {}
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.logs;
class DefaultLoggerProvider implements LoggerProvider {
private static final LoggerProvider INSTANCE = new DefaultLoggerProvider();
private static final LoggerBuilder NOOP_BUILDER = new NoopLoggerBuilder();
private DefaultLoggerProvider() {}
static LoggerProvider getInstance() {
return INSTANCE;
}
@Override
public LoggerBuilder loggerBuilder(String instrumentationScopeName) {
return NOOP_BUILDER;
}
private static class NoopLoggerBuilder implements LoggerBuilder {
@Override
public LoggerBuilder setSchemaUrl(String schemaUrl) {
return this;
}
@Override
public LoggerBuilder setInstrumentationVersion(String instrumentationVersion) {
return this;
}
@Override
public Logger build() {
return DefaultLogger.getInstance();
}
}
}

View File

@ -1,215 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
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}.
*
* <p>Obtain a {@link Logger#logRecordBuilder()}, add properties using the setters, and emit the log
* record by calling {@link #emit()}.
*
* @since 1.27.0
*/
public interface LogRecordBuilder {
/**
* Set the epoch {@code timestamp}, using the timestamp and unit.
*
* <p>The {@code timestamp} is the time at which the log record occurred. If unset, it will be set
* to the current time when {@link #emit()} is called.
*/
LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit);
/**
* Set the epoch {@code timestamp}, using the instant.
*
* <p>The {@code timestamp} is the time at which the log record occurred. If unset, it will be set
* to the current time when {@link #emit()} is called.
*/
LogRecordBuilder setTimestamp(Instant instant);
/**
* Set the epoch {@code observedTimestamp}, using the timestamp and unit.
*
* <p>The {@code observedTimestamp} is the time at which the log record was observed. If unset, it
* will be set to the {@code timestamp}. {@code observedTimestamp} may be different from {@code
* timestamp} if logs are being processed asynchronously (e.g. from a file or on a different
* thread).
*/
LogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit);
/**
* Set the {@code observedTimestamp}, using the instant.
*
* <p>The {@code observedTimestamp} is the time at which the log record was observed. If unset, it
* will be set to the {@code timestamp}. {@code observedTimestamp} may be different from {@code
* timestamp} if logs are being processed asynchronously (e.g. from a file or on a different
* thread).
*/
LogRecordBuilder setObservedTimestamp(Instant instant);
/** Set the context. */
LogRecordBuilder setContext(Context context);
/** Set the severity. */
LogRecordBuilder setSeverity(Severity severity);
/** Set the severity text. */
LogRecordBuilder setSeverityText(String severityText);
/**
* Set the body string.
*
* <p>Shorthand for calling {@link #setBody(Value)} with {@link Value#of(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.
*/
@SuppressWarnings("unchecked")
default LogRecordBuilder setAllAttributes(Attributes attributes) {
if (attributes == null || attributes.isEmpty()) {
return this;
}
attributes.forEach(
(attributeKey, value) -> setAttribute((AttributeKey<Object>) attributeKey, value));
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;
}
/** Emit the log record. */
void emit();
}

View File

@ -1,36 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.logs;
import javax.annotation.concurrent.ThreadSafe;
/**
* A {@link Logger} is the entry point into a log pipeline.
*
* <p>Obtain a {@link #logRecordBuilder()}, add properties using the setters, and emit it via {@link
* LogRecordBuilder#emit()}.
*
* <p>The OpenTelemetry logs bridge API exists to enable bridging logs from other log frameworks
* (e.g. SLF4J, Log4j, JUL, Logback, etc) into OpenTelemetry and is <b>NOT</b> a replacement log
* API.
*
* @since 1.27.0
*/
@ThreadSafe
public interface Logger {
/**
* Return a {@link LogRecordBuilder} to emit a log record.
*
* <p><b>IMPORTANT:</b> this should be used to write appenders to bridge logs from logging
* frameworks (e.g. SLF4J, Log4j, JUL, Logback, etc). It is <b>NOT</b> a replacement for an
* application logging framework, and should not be used by application developers.
*
* <p>Build the log record using the {@link LogRecordBuilder} setters, and emit via {@link
* LogRecordBuilder#emit()}.
*/
LogRecordBuilder logRecordBuilder();
}

View File

@ -1,43 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.logs;
/**
* Builder class for creating {@link Logger} instances.
*
* <p>{@link Logger}s are identified by their scope name, version, and schema URL. These identifying
* fields, along with attributes, combine to form the instrumentation scope, which is attached to
* all log records produced by the {@link Logger}.
*
* @since 1.27.0
*/
public interface LoggerBuilder {
/**
* Set the scope schema URL of the resulting {@link Logger}. Schema URL is part of {@link Logger}
* identity.
*
* @param schemaUrl The schema URL.
* @return this
*/
LoggerBuilder setSchemaUrl(String schemaUrl);
/**
* Sets the instrumentation scope version of the resulting {@link Logger}. Version is part of
* {@link Logger} identity.
*
* @param instrumentationScopeVersion The instrumentation scope version.
* @return this
*/
LoggerBuilder setInstrumentationVersion(String instrumentationScopeVersion);
/**
* Gets or creates a {@link Logger} instance.
*
* @return a {@link Logger} instance configured with the provided options.
*/
Logger build();
}

View File

@ -1,51 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.logs;
import io.opentelemetry.api.internal.IncubatingUtil;
import javax.annotation.concurrent.ThreadSafe;
/**
* A registry for creating scoped {@link Logger}s. The name <i>Provider</i> is for consistency with
* other languages and it is <b>NOT</b> loaded using reflection.
*
* <p>The OpenTelemetry logs bridge API exists to enable bridging logs from other log frameworks
* (e.g. SLF4J, Log4j, JUL, Logback, etc) into OpenTelemetry and is <b>NOT</b> a replacement log
* API.
*
* @since 1.27.0
* @see Logger
*/
@ThreadSafe
public interface LoggerProvider {
/**
* Gets or creates a named Logger instance.
*
* @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as
* the instrumentation library, package, or fully qualified class name. Must not be null.
* @return a Logger instance.
*/
default Logger get(String instrumentationScopeName) {
return loggerBuilder(instrumentationScopeName).build();
}
/**
* Creates a LoggerBuilder for a named Logger instance.
*
* @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as
* the instrumentation library, package, or fully qualified class name. Must not be null.
* @return a LoggerBuilder instance.
*/
LoggerBuilder loggerBuilder(String instrumentationScopeName);
/** 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");
}
}

View File

@ -1,17 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
/**
* API for writing log appenders.
*
* <p>The OpenTelemetry logging API exists to enable the creation of log appenders, which bridge
* logs from other log frameworks (e.g. SLF4J, Log4j, JUL, Logback, etc) into OpenTelemetry via
* {@link io.opentelemetry.api.logs.Logger#logRecordBuilder()}. It is <b>NOT</b> a replacement log
* framework.
*/
@ParametersAreNonnullByDefault
package io.opentelemetry.api.logs;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -6,6 +6,7 @@
package io.opentelemetry.api.metrics;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.internal.ValidationUtil;
import io.opentelemetry.context.Context;
import java.util.function.Consumer;
import javax.annotation.concurrent.ThreadSafe;
@ -38,21 +39,25 @@ class DefaultMeter implements Meter {
@Override
public LongCounterBuilder counterBuilder(String name) {
ValidationUtil.checkValidInstrumentName(name);
return NOOP_LONG_COUNTER_BUILDER;
}
@Override
public LongUpDownCounterBuilder upDownCounterBuilder(String name) {
ValidationUtil.checkValidInstrumentName(name);
return NOOP_LONG_UP_DOWN_COUNTER_BUILDER;
}
@Override
public DoubleHistogramBuilder histogramBuilder(String name) {
ValidationUtil.checkValidInstrumentName(name);
return NOOP_DOUBLE_HISTOGRAM_BUILDER;
}
@Override
public DoubleGaugeBuilder gaugeBuilder(String name) {
ValidationUtil.checkValidInstrumentName(name);
return NOOP_DOUBLE_GAUGE_BUILDER;
}
@ -102,6 +107,7 @@ class DefaultMeter implements Meter {
@Override
public LongCounterBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -138,6 +144,7 @@ class DefaultMeter implements Meter {
@Override
public DoubleCounterBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -194,6 +201,7 @@ class DefaultMeter implements Meter {
@Override
public LongUpDownCounterBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -232,6 +240,7 @@ class DefaultMeter implements Meter {
@Override
public DoubleUpDownCounterBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -286,6 +295,7 @@ class DefaultMeter implements Meter {
@Override
public DoubleHistogramBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -310,6 +320,7 @@ class DefaultMeter implements Meter {
@Override
public LongHistogramBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -320,10 +331,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) {
@ -332,6 +341,7 @@ class DefaultMeter implements Meter {
@Override
public DoubleGaugeBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@ -342,34 +352,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) {
@ -378,34 +371,19 @@ class DefaultMeter implements Meter {
@Override
public LongGaugeBuilder setUnit(String unit) {
ValidationUtil.checkValidInstrumentUnit(unit);
return this;
}
@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

@ -1,42 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.metrics;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import javax.annotation.concurrent.ThreadSafe;
/**
* A gauge instrument that synchronously records {@code double} values.
*
* @since 1.38.0
*/
@ThreadSafe
public interface DoubleGauge {
/**
* Set the gauge value.
*
* @param value The current gauge value.
*/
void set(double value);
/**
* Records a value with a set of attributes.
*
* @param value The current gauge value.
* @param attributes A set of attributes to associate with the value.
*/
void set(double value, Attributes attributes);
/**
* Records a value with a set of attributes.
*
* @param value The current gauge value.
* @param attributes A set of attributes to associate with the value.
* @param context The explicit context to associate with this measurement.
*/
void set(double value, Attributes attributes, Context context);
}

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

@ -5,8 +5,6 @@
package io.opentelemetry.api.metrics;
import java.util.List;
/**
* Builder class for {@link DoubleHistogram}.
*
@ -34,20 +32,6 @@ public interface DoubleHistogramBuilder {
*/
DoubleHistogramBuilder setUnit(String unit);
/**
* Set the explicit bucket buckets boundaries advice, which suggests the recommended set of
* explicit bucket boundaries for this histogram.
*
* @param bucketBoundaries The explicit bucket boundaries advice.
* @see <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-advisory-parameter-explicitbucketboundaries">Explicit
* bucket boundaries advisory parameter</a>
* @since 1.32.0
*/
default DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(List<Double> bucketBoundaries) {
return this;
}
/** Sets the Counter for recording {@code long} values. */
LongHistogramBuilder ofLongs();

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