Compare commits

...

No commits in common. "main" and "v1.0.3" have entirely different histories.
main ... v1.0.3

1487 changed files with 1045 additions and 223998 deletions

64
.eslintrc.js Normal file
View File

@ -0,0 +1,64 @@
module.exports = {
"env": {
"mocha": true,
"commonjs": true,
"shared-node-browser": true
},
plugins: [
"@typescript-eslint",
"header"
],
extends: [
"./node_modules/gts",
],
parser: "@typescript-eslint/parser",
parserOptions: {
"project": [
"./tsconfig.json"
]
},
ignorePatterns: [
'build',
],
rules: {
"@typescript-eslint/no-this-alias": "off",
"eqeqeq": [
"error",
"smart"
],
"prefer-rest-params": "off",
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "memberLike",
"modifiers": ["private", "protected"],
"format": ["camelCase"],
"leadingUnderscore": "require"
}
],
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "args": "after-used" }],
"@typescript-eslint/no-inferrable-types": ["error", { ignoreProperties: true }],
"arrow-parens": ["error", "as-needed"],
"prettier/prettier": ["error", { "singleQuote": true, "arrowParens": "avoid" }],
"prefer-spread": "off",
"node/no-deprecated-api": ["warn"],
"header/header": [2, "block", [{
pattern: / \* Copyright The OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm,
template:
`\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n `
}]]
},
overrides: [
{
"files": ["test/**/*.ts"],
"rules": {
"no-empty": "off",
"@typescript-eslint/ban-ts-ignore": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-var-requires": "off"
}
}
]
}

2
.github/CODEOWNERS vendored
View File

@ -12,4 +12,4 @@
# https://help.github.com/en/articles/about-code-owners
#
* @open-telemetry/javascript-approvers
* @dyladan @mayurkale22 @OlivierAlbertini @vmarchaud @markwolff @obecny @mwear @naseemkullah @legendecas @Flarna @johnbley @MSNev @Rauno56

View File

@ -1,139 +0,0 @@
name: Bug Report
description: File a bug report
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
> [!IMPORTANT]
> **Please read all parts of this form carefully.** By following the instructions carefully, you ensure that we
> can get started fixing your bug, instead of being stuck at trying to reproduce your issue. Please provide
> all requested information, even if you think it does not apply to your problem.
>
> **If you use a third-party package that re-distributes OpenTelemetry, open the bug ticket with that third party unless you can provide steps to reproduce this with pure OpenTelemetry.**
> Digging into third-party distributions of OpenTelemetry is not in scope for this project.
Before filing a bug, please be sure you have searched through [existing open bugs](https://github.com/open-telemetry/opentelemetry-js/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug)
to see if this bug has already been filed.
- type: markdown
attributes:
value: |
## Bug Reproduction
- type: textarea
attributes:
label: What happened?
description: |
> [!IMPORTANT]
> **Please provide as much detail as you reasonably can.**
> We all know the complexities of developing with JavaScript/TypeScript. **Be specific** about your setup and **DO NOT** assume that the person handling your bug report knows how to use your specific combination of tooling. Always provide build instructions and config files.
value: |
## Steps to Reproduce
<!--
The most effective way to solve a bug is to provide a link to a reproducer repository. It is extremely difficult to exactly reproduce problems
and doing so can take multiple hours for us. You know your tooling and setup and we know OpenTelemetry JavaScript internals.
Let's help each other! :)
-->
## Expected Result
## Actual Result
## Additional Details
<!--
Anything you can think of that will help us reproduce and understand your problem:
- details about the behavior of the bug
- code to reproduce, if not provided via a repository above (including setting up any frameworks you may be using, we likely don't use the same tech-stack that you're using on the daily)
- which tooling you use and how you're using it
- config files for your tooling (typescript, bundlers, ...)
- how you run your code (example: `node -r otel.js ./index.js`).
- which module type you are you using (`module` or `commonjs`)
-->
validations:
required: true
- type: textarea
attributes:
label: OpenTelemetry Setup Code
description: |
Please provide the code you use to set up OpenTelemetry.
If you use `@opentelemetry/auto-instrumentations-node/register`, please state so here.
You may omit this step if you have provided a reproducer repository.
placeholder: | # This comes from our README.md
// otel.js
'use strict'
const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
// configure the SDK to export telemetry data to the console
// enable all auto-instrumentations from the meta package
const traceExporter = new ConsoleSpanExporter();
const sdk = new opentelemetry.NodeSDK({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'my-service',
}),
traceExporter,
instrumentations: [getNodeAutoInstrumentations()]
});
// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()
.then(() => console.log('Tracing initialized'))
.catch((error) => console.log('Error initializing tracing', error));
// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
sdk.shutdown()
.then(() => console.log('Tracing terminated'))
.catch((error) => console.log('Error terminating tracing', error))
.finally(() => process.exit(0));
});
render: "JavaScript"
- type: textarea
attributes:
label: package.json
description: |
Please provide your the full package.json needed to reproduce the issue.
You may omit this step if you provided a reproducer repository.
render: "JSON"
placeholder: |
{
"name": "my-app",
"scripts": {
"start": "node -r otel.js app.js"
},
"dependencies": {
"@opentelemetry/api": "^1.3.0",
"@opentelemetry/sdk-trace-base": "~1.3.1",
...
}
}
- type: textarea
attributes:
label: Relevant log output
description: |
Please copy and paste any relevant log output.
render: shell
- type: markdown
attributes:
value: |
## System Details
System Details help us when we cannot reproduce your problem with the information provided above. Sometimes bugs only surface on specific platforms and runtime versions.
- type: textarea
attributes:
label: Operating System and Version
placeholder: Ubuntu 24.04, Windows 11 Build 26100.2033, macOS 15.0.1
validations:
required: false
- type: textarea
attributes:
label: Runtime and Version
placeholder: Node.js v20.12.1, Node.js v18.18.2, Firefox 130, Chrome 132, ...
validations:
required: false

View File

@ -1,12 +0,0 @@
---
name: Discussion
about: Ask a question or bring up points of consideration
labels: discussion
---
<!--
**NB:** Before opening a discussion here, please consider whether it is JS specific, or if it should be considered in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first.
-->
- [ ] This only affects the JavaScript OpenTelemetry library
- [ ] This may affect other libraries, but I would like to get opinions here first

View File

@ -1,23 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
labels: feature-request
---
**NB:** Before opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first.
### Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
### Describe the solution you'd like
A clear and concise description of what you want to happen.
### Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
### Additional context
Add any other context or screenshots about the feature request here.

View File

@ -1,29 +0,0 @@
---
name: Suggest Instrumentation
about: Suggest instrumentation for a module or framework
labels: instrumentation
---
<!--
**NB:** Before opening an instrumentation support request against this repo, consider whether the instrumentation should reside in the [contrib repository](https://github.com/open-telemetry/opentelemetry-js-contrib).
You are welcome to try out the [instrumentation api](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/instrumentation-guide.md) to build your own instrumentation. If you do try out the instrumentation api, please let us know if you have any questions/feedback.
-->
### Is it applicable for Node or Browser or both
### Do you expect this plugin to be commonly used
Weekly Downloads:
### What version of plugin are you interested in using
Versions:
### Additional context
<!--
Add any other context or screenshots about the plugin request here.
-->
#### Is there a reference you could point for the well-defined lifecycle methods**

View File

@ -1,43 +0,0 @@
<!--
We appreciate your contribution to the OpenTelemetry project! 👋🎉
Before creating a pull request, please make sure:
- Your PR is solving one problem
- Please provide enough information so that others can review your pull request
- You have read the guide for contributing
- See https://github.com/open-telemetry/opentelemetry-js/blob/main/CONTRIBUTING.md
- You signed all your commits (otherwise we won't be able to merge the PR)
- See https://github.com/open-telemetry/community/blob/main/guides/contributor#sign-the-cla
- You added unit tests for the new functionality
- You mention in the PR description which issue it is addressing, e.g. "Fixes #xxx". This will auto-close
the issue that your PR fixes (if such)
-->
## Which problem is this PR solving?
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
## Short description of the changes
## Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
## How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
- [ ] Test A
## Checklist:
- [ ] Followed the style guidelines of this project
- [ ] Unit tests have been added
- [ ] Documentation has been updated

View File

@ -1,45 +0,0 @@
# Repository settings
This document describes any changes that have been made to the
settings for this repository beyond the [OpenTelemetry default repository
settings](https://github.com/open-telemetry/community/blob/main/docs/how-to-configure-new-repository.md#repository-settings).
## General
No changes
## Collaborators and Teams
- There is currently no `javascript-triagers` role
- `javascript-maintainers` has `Admin` permission
## Branches
## Branch protection rules
### `main`
- Uncheck "Restrict who can push to matching branches"
- Check "Require merge queue"
- Build concurrency: 5
- Minimum pull requests to merge: 1 or after 5 minutes
- Maximum pull requests to merge: 5
- Check "Only merge non-failing pull requests"
- Status check timeout: 60 minutes
### `dependabot/**/**`
There is currently not an explicit rule for this branch pattern.
Our dependencies are managed by a bot which creates PRs from a fork.
### `gh-pages`
This is a special branch which we use to publish the automatically generated docs.
It is exempt from most protections.
- "Allow force pushes from everyone" (requires write permission)
## Pages
- Source: Deploy from a branch
- Branch: `gh-pages` `/ (root)`

View File

@ -1,55 +0,0 @@
name: Benchmark Tests
on:
push:
branches: [ main ]
permissions:
contents: read
jobs:
benchmark-tests:
permissions:
contents: write # required for pushing benchmark results to gh-pages
strategy:
fail-fast: false
matrix:
node_version:
- "22"
runs-on: equinix-bare-metal
timeout-minutes: 10
env:
NPM_CONFIG_UNSAFE_PERM: true
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: ${{ matrix.node_version }}
- run: npm install -g npm@latest
- name: Bootstrap
run: npm ci
- name: Build 🔧
run: npm run compile
- name: Benchmark tests
run: |
npm run test:bench
find . -name .benchmark-results.txt -exec cat {} + > combined_benchmarks.txt
- name: Store benchmark results
uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'benchmarkjs'
output-file-path: combined_benchmarks.txt
gh-pages-branch: gh-pages
github-token: ${{ secrets.GITHUB_TOKEN }}
benchmark-data-dir-path: "benchmarks"
auto-push: true

View File

@ -1,36 +0,0 @@
# This action requires that any PR targeting the main and next branch should touch at
# least one CHANGELOG file. If a CHANGELOG entry is not required, add the "Skip
# Changelog" label to disable this action.
name: changelog
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
branches:
- main
- next
permissions:
contents: read
jobs:
changelog:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'dependencies') && !contains(github.event.pull_request.labels.*.name, 'Skip Changelog')}}
steps:
- uses: actions/checkout@v4
- name: Check for CHANGELOG changes
run: |
# Only the latest commit of the feature branch is available
# automatically. To diff with the base branch, we need to
# fetch that too (and we only need its latest commit).
git fetch origin ${{ github.base_ref }} --depth=1
if [[ $(git diff --name-only FETCH_HEAD | grep CHANGELOG) ]]
then
echo "A CHANGELOG was modified. Looks good!"
else
echo "No CHANGELOG was modified."
echo "Please add a CHANGELOG entry, or add the \"Skip Changelog\" label if not required."
false
fi

View File

@ -1,27 +0,0 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 6 * * 1'
permissions:
contents: read
jobs:
stale:
permissions:
issues: write # required for closing stale issues
pull-requests: write # required for closing stale PRs
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
days-before-stale: 60
days-before-close: 14
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.'
close-issue-message: 'This issue was closed because it has been stale for 14 days with no activity.'
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.'
close-pr-message: 'This PR was closed because it has been stale for 14 days with no activity.'
stale-issue-label: stale
stale-pr-label: stale
exempt-issue-labels: never-stale,bug
exempt-pr-labels: never-stale,bug

View File

@ -1,32 +1,34 @@
name: "CodeQL Analysis"
name: "CodeQL"
on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
permissions:
contents: read
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: '30 1 * * *'
jobs:
CodeQL-Build:
permissions:
security-events: write
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v1
with:
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v1

View File

@ -1,65 +0,0 @@
name: Create or Update Release PR
on:
workflow_dispatch:
inputs:
release_type:
type: choice
description: Release type
options:
- patch
- minor
release_scope:
type: choice
description: Release Scope
options:
- experimental # all packages in experimental/packages
- sdk # all SDK packages, experimental and stable, excluding semantic conventions
- all # all release packages, including API, excluding semconv
- semconv # only semantic convention package
permissions:
contents: read
jobs:
create-or-update-release-pr:
runs-on: ubuntu-latest
steps:
- name: Fork
run: gh repo fork open-telemetry/opentelemetry-js
env:
GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v4
with:
repository: opentelemetrybot/opentelemetry-js
ref: main
token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
- name: Sync with upstream
run: |
git remote show origin
git remote add upstream https://github.com/open-telemetry/opentelemetry-js.git
git fetch upstream
git reset --hard upstream/main
git push origin main --force
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: package-lock.json
node-version: 22
- run: npm install -g npm@latest
- run: npm ci
- name: Create/Update Release PR
run: |
git config user.name opentelemetrybot
git config user.email 107717825+opentelemetrybot@users.noreply.github.com
npm run github:create_or_update_release_pr
env:
GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
RELEASE_SCOPE: ${{ github.event.inputs.release_scope }}
RELEASE_KIND: ${{ github.event.inputs.release_scope }}:${{ github.event.inputs.release_type }}
RELEASE_PR_REMOTE: origin
RELEASE_PR_OWNER: opentelemetrybot

View File

@ -4,40 +4,24 @@ on:
release:
types: [published]
permissions:
contents: read
jobs:
build-and-deploy:
permissions:
contents: write # required for deploying documentation to gh-pages
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout 🛎️
uses: actions/checkout@v2
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: '22'
- name: Install root dependencies
run: npm install --ignore-scripts
- name: Install and Build 🔧
- name: Build 🔧
run: |
npm ci
npm run compile
npm run docs
- name: Build Docs
run: npm run docs
env:
NODE_OPTIONS: --max-old-space-size=6144
- name: Deploy Documentation 🚀
uses: JamesIves/github-pages-deploy-action@releases/v4
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
branch: gh-pages # The branch the action should deploy to.
folder: docs # The folder the action should deploy.
# ensure we don't override benchmark data
clean-exclude: |
benchmarks/**
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: docs/out # The folder the action should deploy.

View File

@ -1,76 +0,0 @@
name: E2E Tests
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
e2e-tests:
strategy:
fail-fast: false
matrix:
node_version:
- "18.19.0"
- "18"
- "20.6.0"
- "20"
- "22"
- "23"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: ${{ matrix.node_version }}
# npm@11.0.0 drops support for Node.js v18
# Install the latest npm compatible with this version of Node.js
# - npm@11.1.0 supports: {"node":"^20.17.0 || >=22.9.0"}
- run: npm install -g npm@"<11.0.0"
if: ${{
matrix.node_version == '18.19.0' ||
matrix.node_version == '18' ||
matrix.node_version == '20.6.0'
}}
- run: npm install -g npm@latest
if: ${{
matrix.node_version == '20' ||
matrix.node_version == '22' ||
matrix.node_version == '23'
}}
- name: Bootstrap
run: npm ci
- name: Build 🔧
run: npm run compile
- name: Install collector
run: |
curl -sSL -o otelcol-contrib.tar.gz https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.126.0/otelcol-contrib_0.126.0_linux_amd64.tar.gz
tar -xzf otelcol-contrib.tar.gz
working-directory: e2e-tests
- name: run collector in background
run: |
./otelcol-contrib --config collector-config.yaml &
working-directory: e2e-tests
- name: Export telemetry to collector
run: npm run export-telemetry
working-directory: e2e-tests
- name: stop collector
run: pkill -f otelcol-contrib
working-directory: e2e-tests
- name: Print output
run: cat collector-output.json
working-directory: e2e-tests
- name: verify exported telemetry
run: npm run verify
working-directory: e2e-tests

View File

@ -1,20 +0,0 @@
name: FOSSA scanning
on:
push:
branches:
- main
permissions:
contents: read
jobs:
fossa:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0
with:
api-key: ${{secrets.FOSSA_API_KEY}}
team: OpenTelemetry

37
.github/workflows/lint.yaml vendored Normal file
View File

@ -0,0 +1,37 @@
name: Lint
on:
push:
branches:
- main
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Lint markdown files
uses: docker://avtodev/markdown-lint:v1
with:
args: "./**/*.md -i ./CHANGELOG.md"
- name: Install dependencies
run: npm install
- name: Build 🔧
run: npm run compile
- name: Lint
run: npm run lint
- name: Check for Circular Dependencies
run: npm run cycle-check
- name: Generate Documentation 📜
run: npm run docs
- name: Test Docs
run: npm run docs:test

View File

@ -1,39 +0,0 @@
name: Lint
on:
push:
branches:
- main
pull_request:
merge_group:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: '22'
- name: Bootstrap
run: npm ci
- name: Lint
run: |
npm run lint
npm run lint:examples
- name: Lint doc files
run: |
npm run compile
NODE_OPTIONS=--max-old-space-size=6144 npm run docs
npm run docs:test

View File

@ -1,47 +0,0 @@
name: OSSF Scorecard
on:
push:
branches:
- main
schedule:
- cron: "44 18 * * 6" # once a week
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@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
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@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: results.sarif

View File

@ -1,30 +0,0 @@
name: Ensure API Peer Dependency
on:
push:
branches:
- main
pull_request:
merge_group:
permissions:
contents: read
jobs:
peer-api-check:
runs-on: ubuntu-latest
container:
image: node:22
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install lerna
run: npm install -g lerna@6.6.2
- name: Install semver
run: npm install -g semver
- name: Check API dependency semantics
working-directory: packages
run: lerna run peer-api-check

View File

@ -1,44 +0,0 @@
name: Publish packages to NPM
on:
workflow_dispatch:
permissions:
contents: read
jobs:
release-to-npm:
runs-on: ubuntu-latest
permissions:
# needed for NPM provenance
id-token: write
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
registry-url: 'https://registry.npmjs.org'
- run: npm ci
# NOTE: in the past, we've had situations where the compiled files were missing as the `prepublishOnly` script was
# missing in some packages. `npx lerna publish` *should* also run compile, but this is intended as a safeguard
# when that does not happen for whatever reason.
- run: npm run compile
- name: Publish to npm
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
NPM_CONFIG_PROVENANCE: true
# NOTE: using --concurrency 1 to reduce the likelihood of a race when publishing,
# which happens when the npm registry is not fully consistent yet. This can cause the publishing of a package to be
# rejected because dependencies are not available yet. `lerna` does ensure that this is not the case locally
# (packages are in-fact published in the correct order), but the race on the registry still applies.
# If this happens, run the workflow again - there should be enough time for everything to settle until this workflow
# attempts to publish again.
run: npx lerna publish --concurrency 1 from-package --no-push --no-private --no-git-tag-version --no-verify-access --dist-tag=latest --yes

33
.github/workflows/release-please.yml vendored Normal file
View File

@ -0,0 +1,33 @@
on:
push:
branches:
- main
name: release-please
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: GoogleCloudPlatform/release-please-action@v2
id: release
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: node
package-name: "@opentelemetry/api"
# The logic below handles the npm publication:
- uses: actions/checkout@v2
# these if statements ensure that a publication only occurs when
# a new release is created:
if: ${{ steps.release.outputs.release_created }}
- uses: actions/setup-node@v1
with:
node-version: 14
registry-url: 'https://registry.npmjs.org'
if: ${{ steps.release.outputs.release_created }}
- run: npm install
if: ${{ steps.release.outputs.release_created }}
- run: npm run compile
if: ${{ steps.release.outputs.release_created }}
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
if: ${{ steps.release.outputs.release_created }}

View File

@ -1,79 +0,0 @@
name: SBOM
on:
release:
types: [published]
permissions: read-all
jobs:
generate-sboms:
runs-on: ubuntu-latest
env:
NPM_CONFIG_UNSAFE_PERM: true
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g npm@latest
- name: Bootstrap
run: npm ci
- name: Generate SBOM for core packages
if: ${{ ! startsWith(github.ref, 'refs/tags/experimental') && ! startsWith(github.ref, 'refs/tags/api') }}
run: |
for dir in $(find packages -mindepth 1 -maxdepth 1 -type d)
do
dir_name=$(basename "$dir")
echo "Generating SBOM for $dir_name"
npm sbom --sbom-format=spdx --legacy-peer-deps --workspace ${dir} > "opentelemetry-js_${dir_name}.spdx.json"
done
- name: Generate SBOM for the API package
if: startsWith(github.ref, 'refs/tags/api/')
run: |
npm sbom --sbom-format=spdx --legacy-peer-deps --workspace api > opentelemetry-js_api.spdx.json
- name: Generate SBOMs for experimental packages
if: startsWith(github.ref, 'refs/tags/experimental/')
run: |
for dir in $(find experimental/packages -mindepth 1 -maxdepth 1 -type d)
do
dir_name=$(basename "$dir")
echo "Generating SBOM for $dir_name"
npm sbom --sbom-format=spdx --legacy-peer-deps --workspace ${dir} > "opentelemetry-js_${dir_name}.spdx.json"
done
- name: Zip all SBOM files
run: |
zip sbom.zip *.spdx.json
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: SBOM.zip
path: ./sbom.zip
add-release-artifact:
needs: generate-sboms
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download artifact from generate-sboms
uses: actions/download-artifact@v4
with:
name: SBOM.zip
- name: Upload release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./sbom.zip
asset_name: SBOM.zip
asset_content_type: application/zip

View File

@ -1,44 +0,0 @@
name: Survey on Merged PR by Non-Member
on:
pull_request_target:
types: [closed]
permissions:
contents: read
env:
PR_NUM: ${{ github.event.pull_request.number }}
SURVEY_URL: https://docs.google.com/forms/d/e/1FAIpQLSf2FfCsW-DimeWzdQgfl0KDzT2UEAqu69_f7F2BVPSxVae1cQ/viewform?entry.1540511742=open-telemetry/opentelemetry-js
jobs:
comment-on-pr:
name: Add survey to PR if author is not a member
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
if: github.event.pull_request.merged == true
steps:
- uses: actions/checkout@v4
- name: Check if user is a member of the org
id: check-membership
run: |
USERNAME=$(jq -r '.pull_request.user.login' "$GITHUB_EVENT_PATH")
ORG="${{ github.repository_owner }}"
STATUS=$(gh api "orgs/$ORG/members/$USERNAME" --silent && echo "true" || echo "false")
if [[ "$STATUS" == "true" ]]; then
echo "MEMBER_FOUND=true" >> $GITHUB_ENV
else
echo "MEMBER_FOUND=false" >> $GITHUB_ENV
fi
env:
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
- name: Add comment to PR if author is not a member
if: env.MEMBER_FOUND == 'false'
run: |
USERNAME=$(jq -r '.pull_request.user.login' "$GITHUB_EVENT_PATH")
gh pr comment ${PR_NUM} --repo open-telemetry/opentelemetry-js --body "Thank you for your contribution @${USERNAME}! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this [survey](${SURVEY_URL})."
env:
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}

54
.github/workflows/test.yaml vendored Normal file
View File

@ -0,0 +1,54 @@
name: Unit Tests
on:
push:
branches:
- main
pull_request:
jobs:
unit-test:
strategy:
fail-fast: false
matrix:
container: ["node:8", "node:10", "node:12", "node:14", "node:16"]
runs-on: ubuntu-latest
container:
image: ${{ matrix.container }}
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install Dependencies
run: npm install
- name: Compile 🔧
run: npm run compile
- name: Unit tests
run: npm run test
- name: Report Coverage
run: npm run codecov
if: ${{ matrix.container == 'node:14' }}
browser-tests:
runs-on: ubuntu-latest
container:
image: circleci/node:12-browsers
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Permission Setup
run: sudo chmod -R 777 /github /__w
- name: Install Dependencies
run: npm install
- name: Compile 🔧
run: npm run compile
- name: Unit tests
run: npm run test:browser
- name: Report Coverage
run: npm run codecov:browser

View File

@ -1,160 +0,0 @@
name: Unit Tests
on:
push:
branches:
- main
pull_request:
merge_group:
permissions:
contents: read
jobs:
node-tests:
strategy:
fail-fast: false
matrix:
node_version:
- "18.19.0"
- "18"
- "20.6.0"
- "20"
- "22"
- "23"
- "24"
runs-on: ubuntu-latest
env:
NPM_CONFIG_UNSAFE_PERM: true
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: ${{ matrix.node_version }}
# npm@11.0.0 drops support for Node.js v18
# Install the latest npm compatible with this version of Node.js
# - npm@11.1.0 supports: {"node":"^20.17.0 || >=22.9.0"}
- run: npm install -g npm@"<11.0.0"
if: ${{
matrix.node_version == '18.19.0' ||
matrix.node_version == '18' ||
matrix.node_version == '20.6.0'
}}
- run: npm install -g npm@latest
if: ${{
matrix.node_version == '20' ||
matrix.node_version == '22' ||
matrix.node_version == '23' ||
matrix.node_version == '24'
}}
- name: Bootstrap
run: npm ci
- name: Build 🔧
run: npm run compile
- run: npm test
if: ${{ matrix.node_version != '23' && matrix.node_version != '24' }}
# Node.js >= 23 type stripping conflicts with mocha usage of ts-node.
# See https://github.com/open-telemetry/opentelemetry-js/issues/5415
- run: npm test
env:
NODE_OPTIONS: '--no-experimental-strip-types'
if: ${{ matrix.node_version == '23' || matrix.node_version == '24' }}
- name: Report Coverage
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
verbose: true
node-windows-tests:
runs-on: windows-latest
env:
NPM_CONFIG_UNSAFE_PERM: true
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: '22'
- run: npm install -g npm@latest
- name: Bootstrap
run: npm ci
- name: Build 🔧
run: |
npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"
npm run compile
- name: Unit tests
run: npm run test
browser-tests:
runs-on: ubuntu-latest
env:
NPM_CONFIG_UNSAFE_PERM: true
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: 22
- name: Bootstrap
run: npm ci
- name: Build 🔧
run: npm run compile
- name: Unit tests
run: npm run test:browser
- name: Report Coverage
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
verbose: true
webworker-tests:
runs-on: ubuntu-latest
env:
NPM_CONFIG_UNSAFE_PERM: true
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: 22
- name: Bootstrap
run: npm ci
- name: Build 🔧
run: npm run compile
- name: Unit tests
run: npm run test:webworker
- name: Report Coverage
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
verbose: true

View File

@ -1,38 +0,0 @@
name: W3C Trace Context Integration Test
on:
push:
branches:
- main
pull_request:
merge_group:
permissions:
contents: read
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: 18
- name: Install and Bootstrap 🔧
run: npm ci
- name: Generate version.ts files
run: npm run version:update
- name: Build 🔧
run: npm run compile
working-directory: ./integration-tests/propagation-validation-server
- name: Run W3C Test harness
run: ./integration-tests/tracecontext-integration-test.sh

18
.gitignore vendored
View File

@ -1,6 +1,5 @@
# version.ts file is automatically generated at compile time
version.ts
# version.ts file is autogenerated at compile time
src/version.ts
# Logs
logs
@ -8,8 +7,6 @@ logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Filter Logs singal files
!experimental/examples/logs
# Runtime data
pids
@ -66,9 +63,10 @@ typings/
# lock files
yarn.lock
package-lock.json
# docs files
docs
# generated gh-pages files
docs/out
.nyc_output
@ -88,9 +86,3 @@ package.json.lerna_backup
#IDEA
.idea
*.iml
# non-aggregated benchmark results
.benchmark-results.txt
# release notes for release creation
.tmp/

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "experimental/packages/otlp-transformer/protos"]
path = experimental/packages/otlp-transformer/protos
url = https://github.com/open-telemetry/opentelemetry-proto.git

View File

@ -1,15 +0,0 @@
// https://github.com/DavidAnson/markdownlint-cli2#markdownlint-cli2jsonc
{
"config": {
// https://github.com/DavidAnson/markdownlint/blob/main/README.md#rules--aliases
"MD013": false,
"MD024": false,
"MD033": false,
"MD041": false,
"MD026": false,
"MD004": { "style": "dash" } // ul-style
},
"gitignore": true,
"noBanner": true,
"noProgress": true
}

7
.markdownlint.json Normal file
View File

@ -0,0 +1,7 @@
{
"MD013": false,
"MD024": false,
"MD033": false,
"MD041": false,
"MD026": false
}

View File

@ -1 +0,0 @@
require: 'ts-node/register'

1
.npmrc
View File

@ -1 +0,0 @@
lockfile-version=2

20
.nycrc
View File

@ -1,20 +0,0 @@
{
"produceSourceMap": false,
"extension": [
".ts"
],
"reporter": ["text", "json"],
"exclude": [
"**/*.d.ts",
"build/**/*.*",
"src/index.ts",
"src/platform/**/index.ts",
"src/version.ts",
"test/**/*.*",
".eslintrc.js",
"karma.conf.js",
"webpack/*.js",
"src/generated/**"
],
"all": true
}

File diff suppressed because it is too large Load Diff

View File

@ -1,324 +0,0 @@
# Contributing Guide
We'd love your help!
- [Development Quick Start](#development-quick-start)
- [Pull Request Merge Guidelines](#pull-request-merge-guidelines)
- [General Merge Requirements](#general-merge-requirements)
- [Report a bug or requesting feature](#report-a-bug-or-requesting-feature)
- [How to contribute](#how-to-contribute)
- [Before you start](#before-you-start)
- [Conventional commit](#conventional-commit)
- [Changelog](#changelog)
- [Fork](#fork)
- [Development](#development)
- [Tools used](#tools-used)
- [Install dependencies](#install-dependencies)
- [Compile modules](#compile-modules)
- [Running tests](#running-tests)
- [Linting](#linting)
- [Generating docs](#generating-docs)
- [Adding a package](#adding-a-package)
- [Platform conditional exports](#platform-conditional-exports)
## Development Quick Start
To get the project started quickly, you can follow these steps. For more
detailed instructions, see [development](#development) below.
```sh
git clone https://github.com/open-telemetry/opentelemetry-js.git
cd opentelemetry-js
npm ci
npm run compile
npm run test
```
## Pull Request Merge Guidelines
Most pull requests MAY be merged by an approver OR a maintainer provided they meet the following [General Merge Requirements](#general-merge-requirements).
All requirements are at the discretion of the maintainers.
Maintainers MAY merge pull requests which have not strictly met these requirements.
Maintainers MAY close, block, or put on hold pull requests even if they have strictly met these requirements.
It is generally expected that a maintainer ([@open-telemetry/javascript-maintainers](https://github.com/orgs/open-telemetry/teams/javascript-maintainers)) should review and merge major changes.
Some examples include, but are not limited to:
- API changes
- Breaking changes
- New modules
- Changes which affect runtime support
- New features which are not required by the specification
If a PR has not been interacted with by a reviewer within one week, please ping the approvers ([@open-telemetry/javascript-approvers](https://github.com/orgs/open-telemetry/teams/javascript-approvers)).
### General Merge Requirements
- No “changes requested” reviews by approvers, maintainers, technical committee members, or subject matter experts
- No unresolved conversations
- Approved by at least one maintainer OR by at least one approver who is not the approver merging the pull request
- A pull request for small (simple typo, URL, update docs, or grammatical fix) changes may be approved and merged by the same approver
- For plugins, exporters, and propagators approval of the original code module author, or a contributor who has done extensive work on the module, is preferred but not required
- New or changed functionality is tested by unit tests
- New or changed functionality is documented if appropriate
- Substantial changes should not be merged within 24 hours of opening in order to allow reviewers from all time zones to have a chance to review
If all of the above requirements are met and there are no unresolved discussions, a pull request may be merged by either a maintainer or an approver.
## Report a bug or requesting feature
Reporting bugs is an important contribution. Please make sure to include:
- expected and actual behavior.
- Node version that application is running.
- OpenTelemetry version that application is using.
- if possible - repro application and steps to reproduce.
## How to contribute
### Before you start
Please read project contribution
[guide](https://github.com/open-telemetry/community/blob/main/guides/contributor)
for general practices for OpenTelemetry project.
#### Conventional commit
The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of. This convention dovetails with SemVer, by describing the features, fixes, and breaking changes made in commit messages. You can see examples [here](https://www.conventionalcommits.org/en/v1.0.0-beta.4/#examples).
It is recommended to have your commit messages follow the Conventional Commits specification, with possible types listed in [.commitlint.rc.yml](.commitlintrc.yml). Here an example that uses the recommended format: `git commit -s -am "chore(opentelemetry-core): update deps"`
### Changelog
An entry into `CHANGELOG.md` or `experimental/CHANGELOG.md` is required for the following reasons:
- Changes made to the behaviour of the component
- Changes to the configuration
- Changes to default settings
- New components being added
It is reasonable to omit an entry to the changelog under these circumstances:
- Updating test to remove flakiness or improve coverage
- Updates to the CI/CD process
If there is some uncertainty with regards to if a changelog entry is needed, the recommendation is to create an entry to in the event that the change is important to the project consumers.
If a change does not require a changelog entry, the label `"Skip Changelog"` may be applied.
Pull requests with the `dependencies` label will be skipped by the changelog CI check.
If the change affects the overall project and not any individual package, it should usually go in the main changelog.
Changelog entries should be in the following format:
```md
* feat(subject): pull request title here #{pull request number} @{author github handle}
```
Subject should describe the area of the project that was changed as descriptively as is possible in a short space.
For example, this may be the package name if a single package was updated or just `metrics` if both the metrics API and SDK are affected.
### Fork
In the interest of keeping this repository clean and manageable, you should work from a fork. To create a fork, click the 'Fork' button at the top of the repository, then clone the fork locally using `git clone git@github.com:USERNAME/opentelemetry-js.git`.
You should also add this repository as an "upstream" repo to your local copy, in order to keep it up to date. You can add this as a remote like so:
```sh
git remote add upstream https://github.com/open-telemetry/opentelemetry-js.git
#verify that the upstream exists
git remote -v
```
To update your fork, fetch the upstream repo's branches and commits, then merge your main with upstream's main:
```sh
git fetch upstream
git checkout main
git merge upstream/main
```
Remember to always work in a branch of your local copy, as you might otherwise have to contend with conflicts in main.
Please also see [GitHub workflow](https://github.com/open-telemetry/community/blob/main/guides/contributor/processes.md#github-workflow) section of general project contributing guide.
## Development
### Tools used
- [NPM](https://npmjs.com)
- [TypeScript](https://www.typescriptlang.org/)
- [lerna](https://github.com/lerna/lerna) to manage dependencies, compilations, and links between packages. Most lerna commands should be run by calling the provided npm scripts.
- [MochaJS](https://mochajs.org/) for tests
- [eslint](https://eslint.org/)
Most of the commands needed for development are accessed as [npm scripts](https://docs.npmjs.com/cli/v6/using-npm/scripts). It is recommended that you use the provided npm scripts instead of using `lerna run` in most cases.
### Install dependencies
This will install all dependencies for the root project and all modules managed by `npm workspaces`.
```sh
npm ci
```
### Compile modules
All modules are managed as a composite typescript project using [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html). This means that a breaking change in one module will be reflected in compilations of its dependent modules automatically.
DO NOT use lerna to compile all modules unless you know what you are doing because this will cause a new typescript process to be spawned for every module in the project.
```sh
# Build all modules
npm run compile
# Remove compiled output
npm run clean
```
These commands can also be run for specific packages instead of the whole project, which can speed up compilations while developing.
**NOTE**: To run commands in specific packages (compile, lint, etc), please ensure you are using at least `7.x`
version of `npm`.
```sh
# Build a single module and all of its dependencies
cd packages/opentelemetry-module-name
npm run compile
```
Finally, builds can be run continuously as files change using the `watch` npm script.
```sh
# Build all modules
npm run watch
# Build a single module and all of its dependencies
cd packages/opentelemetry-module-name
npm run watch
```
#### TypeScript version & update policy
TypeScript version used to compile the pacakges is `v5.0.4`. If you plan to use any of the packages from this
repository to make your own application or package instrumentation make sure to use same version or higher.
<!-- Ref: https://github.com/open-telemetry/opentelemetry-js/pull/5145#issuecomment-2518263890 -->
As update policy OpenTelemetry JS will follow DefinitelyType's [support policy for TypeScript](https://github.com/DefinitelyTyped/DefinitelyTyped#support-window)
which sets a support window of 2 years.
### Running tests
Similar to compilations, tests can be run from the root to run all tests or from a single module to run only the tests for that module.
```sh
# Test all modules
npm test
# Test a single module
cd packages/opentelemetry-module-name
npm test
```
To run the unit tests continuously in watch mode while developing, use:
```sh
# Run test in watch mode
npm run tdd
```
Packages that are expected to run in the browser have browser specific tests:
```sh
# Run browser-specific test
npm run test:browser
# Run web worker test
npm run test:webworker
```
### Linting
This project uses `eslint` to lint source code. Just like tests and compilation, linting can be done for all packages or only a single package.
```sh
# Lint all modules
npm run lint
# Lint a single module
cd packages/opentelemetry-module-name
npm run lint
```
There is also a script which will automatically fix many linting errors.
```sh
# Lint all modules, fixing errors
npm run lint:fix
# Lint a single module, fixing errors
cd packages/opentelemetry-module-name
npm run lint:fix
```
The default lint command will check majority of files, including Markdown files (such as README.md files), but you
also have the option to check just the Markdown files with:
```sh
npm run lint:markdown
npm run lint:markdown:fix # can automatically fix some Markdown rules
```
The default command doesn't check the examples folder. To lint just the examples, use the script:
```sh
npm run lint:examples
npm run lint:examples:fix # can automatically fix some errors
```
### Generating docs
We use [typedoc](https://www.npmjs.com/package/typedoc) to generate the api documentation.
To generate the docs, use:
```sh
# Generate docs in the root 'docs' directory
npm run docs
```
The document will be available under `docs` path.
### Adding a package
To add a new package, copy `packages/template` to your new package directory and modify the `package.json` file to reflect your desired package settings. If the package will not support browser, the `karma.conf` and `tsconifg.esm.json` files may be deleted. If the package will support es5 targets, the reference to `tsconfig.base.json` in `tsconfig.json` should be changed to `tsconfig.es5.json`.
After adding the package, run `npm install` from the root of the project. This will update the `tsconfig.json` project references automatically and install all dependencies in your new package. For packages supporting browser, file `tsconfig.esm.json` needs to be manually updated to include reference to ES modules build.
### Platform conditional exports
Universal packages are packages that can be used in both web browsers and
Node.js environment. These packages may be implemented on top of different
platform APIs to achieve the same goal. Like accessing the _global_ reference,
we have different preferred ways to do it:
- In Node.js, we access the _global_ reference with `globalThis` or `global`:
```js
/// packages/opentelemetry-core/src/platform/node/globalThis.ts
export const _globalThis = typeof globalThis === 'object' ? globalThis : global;
```
- In web browser, we access the _global_ reference with the following definition:
```js
/// packages/opentelemetry-core/src/platform/browser/globalThis.ts
export const _globalThis: typeof globalThis =
typeof globalThis === 'object' ? globalThis :
typeof self === 'object' ? self :
typeof window === 'object' ? window :
typeof global === 'object' ? global :
{} as typeof globalThis;
```
Even though the implementation may differ, the exported names must be aligned.
It can be confusing if exported names present in one environment but not in the
others.

438
README.md
View File

@ -2,403 +2,145 @@
---
<p align="center">
<strong>
<a href="https://opentelemetry.io/docs/languages/js/getting-started/">Getting Started</a>
<a href="https://open-telemetry.github.io/opentelemetry-js-api">API Documentation<a/>
&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://open-telemetry.github.io/opentelemetry-js">API and SDK Reference</a>
<a href="https://github.com/open-telemetry/opentelemetry-js/discussions">Getting In Touch (GitHub Discussions)<a/>
</strong>
</p>
<p align="center">
<a href="https://github.com/open-telemetry/opentelemetry-js/releases">
<img alt="GitHub release (latest by date including pre-releases)" src="https://img.shields.io/github/v/release/open-telemetry/opentelemetry-js?include_prereleases&style=for-the-badge">
<a href="https://github.com/open-telemetry/opentelemetry-js-api/releases">
<img alt="GitHub release (latest by date including pre-releases)" src="https://img.shields.io/github/v/release/open-telemetry/opentelemetry-js-api?include_prereleases&style=for-the-badge">
</a>
<a href="https://codecov.io/gh/open-telemetry/opentelemetry-js/branch/main/">
<img alt="Codecov Status" src="https://img.shields.io/codecov/c/github/open-telemetry/opentelemetry-js?style=for-the-badge">
<a href="https://codecov.io/gh/open-telemetry/opentelemetry-js-api/branch/main/">
<img alt="Codecov Status" src="https://img.shields.io/codecov/c/github/open-telemetry/opentelemetry-js-api?style=for-the-badge">
</a>
<a href="https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE">
<a href="https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE">
<img alt="license" src="https://img.shields.io/badge/license-Apache_2.0-green.svg?style=for-the-badge">
</a>
<br/>
<a href="https://github.com/open-telemetry/opentelemetry-js/actions">
<img alt="Build Status" src="https://github.com/open-telemetry/opentelemetry-js/actions/workflows/unit-test.yml/badge.svg?style=shield">
<a href="https://github.com/open-telemetry/opentelemetry-js-api/actions/workflows/docs.yaml">
<img alt="Build Status" src="https://github.com/open-telemetry/opentelemetry-js-api/actions/workflows/test.yaml/badge.svg?branch=main">
</a>
<a href="https://github.com/open-telemetry/opentelemetry-js-api/actions/workflows/test.yaml?query=branch%3Amain">
<img alt="Build Status" src="https://github.com/open-telemetry/opentelemetry-js-api/actions/workflows/docs.yaml/badge.svg">
</a>
<img alt="Beta" src="https://img.shields.io/badge/status-beta-informational?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACQAAAAAQAAAJAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABigAwAEAAAAAQAAABgAAAAA8A2UOAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAABK5JREFUSA2dVm1sFEUYfmd2b/f2Pkqghn5eEQWKrRgjpkYgpoRCLC0oxV5apAiGUDEpJvwxEQ2raWPU+Kf8INU/RtEedwTCR9tYPloxGNJYTTQUwYqJ1aNpaLH3sXu3t7vjvFevpSqt7eSyM+/czvM8877PzB3APBoLgoDLsNePF56LBwqa07EKlDGg84CcWsI4CEbhNnDpAd951lXE2NkiNknCCTLv4HtzZuvPm1C/IKv4oDNXqNDHragety2XVzjECZsJARuBMyRzJrh1O0gQwLXuxofxsPSj4hG8fMLQo7bl9JJD8XZfC1E5yWFOMtd07dvX5kDwg6+2++Chq8txHGtfPoAp0gOFmhYoNFkHjn2TNUmrwRdna7W1QSkU8hvbGk4uThLrapaiLA2E6QY4u/lS9ItHfvJkxYsTMVtnAJLipYIWtVrcdX+8+b8IVnPl/R81prbuPZ1jpYw+0aEUGSkdFsgyBIaFTXCm6nyaxMtJ4n+TeDhJzGqZtQZcuYDgqDwDbqb0JF9oRpIG1Oea3bC1Y6N3x/WV8Zh83emhCs++hlaghDw+8w5UlYKq2lU7Pl8IkvS9KDqXmKmEwdMppVPKwGSEilmyAwJhRwWcq7wYC6z4wZ1rrEoMWxecdOjZWXeAQClBcYDN3NwVwD9pGwqUSyQgclcmxpNJqCuwLmDh3WtvPqXdlt+6Oz70HPGDNSNBee/EOen+rGbEFqDENBPDbtdCp0ukPANmzO0QQJYUpyS5IJJI3Hqt4maS+EB3199ozm8EDU/6fVNU2dQpdx3ZnKzeFXyaUTiasEV/gZMzJMjr3Z+WvAdQ+hs/zw9savimxUntDSaBdZ2f+Idbm1rlNY8esFffBit9HtK5/MejsrJVxikOXlb1Ukir2X+Rbdkd1KG2Ixfn2Ql4JRmELnYK9mEM8G36fAA3xEQ89fxXihC8q+sAKi9jhHxNqagY2hiaYgRCm0f0QP7H4Fp11LSXiuBY2aYFlh0DeDIVVFUJQn5rCnpiNI2gvLxHnASn9DIVHJJlm5rXvQAGEo4zvKq2w5G1NxENN7jrft1oxMdekETjxdH2Z3x+VTVYsPb+O0C/9/auN6v2hNZw5b2UOmSbG5/rkC3LBA+1PdxFxORjxpQ81GcxKc+ybVjEBvUJvaGJ7p7n5A5KSwe4AzkasA+crmzFtowoIVTiLjANm8GDsrWW35ScI3JY8Urv83tnkF8JR0yLvEt2hO/0qNyy3Jb3YKeHeHeLeOuVLRpNF+pkf85OW7/zJxWdXsbsKBUk2TC0BCPwMq5Q/CPvaJFkNS/1l1qUPe+uH3oD59erYGI/Y4sce6KaXYElAIOLt+0O3t2+/xJDF1XvOlWGC1W1B8VMszbGfOvT5qaRRAIFK3BCO164nZ0uYLH2YjNN8thXS2v2BK9gTfD7jHVxzHr4roOlEvYYz9QIz+Vl/sLDXInsctFsXjqIRnO2ZO387lxmIboLDZCJ59KLFliNIgh9ipt6tLg9SihpRPDO1ia5byw7de1aCQmF5geOQtK509rzfdwxaKOIq+73AvwCC5/5fcV4vo3+3LpMdtWHh0ywsJC/ZGoCb8/9D8F/ifgLLl8S8QWfU8cAAAAASUVORK5CYII=">
</p>
<p align="center">
<strong>
<a href="https://github.com/open-telemetry/opentelemetry-js/blob/main/CONTRIBUTING.md">Contributing</a>
&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://github.com/open-telemetry/opentelemetry-js/tree/main/examples">Examples</a>
</strong>
</p>
---
## About this project
# OpenTelemetry API for JavaScript
This is the JavaScript version of [OpenTelemetry](https://opentelemetry.io/), a framework for collecting traces, metrics, and logs from applications.
[![NPM Published Version][npm-img]][npm-url]
[![dependencies][dependencies-image]][dependencies-url]
[![devDependencies][devDependencies-image]][devDependencies-url]
## Quick Start
This package provides everything needed to interact with the OpenTelemetry API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser.
**Much of OpenTelemetry JS documentation is written assuming the compiled application is run as CommonJS.**
For more details on ECMAScript Modules vs CommonJS, refer to [esm-support](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md).
The methods in this package perform no operations by default. This means they can be safely called by a library or end-user application whether there is an SDK registered or not. In order to generate and export telemetry data, you will also need an SDK such as the [OpenTelemetry JS SDK][opentelemetry-js].
The following describes how to set up tracing for a basic web application.
For more detailed documentation, see the website at <https://opentelemetry.io/docs/instrumentation/js/>.
## Tracing Quick Start
### Installation
### You Will Need
Dependencies with the `latest` tag on NPM should be compatible with each other.
See the [version compatibility matrix](#package-version-compatibility) below for more information.
- An application you wish to instrument
- [OpenTelemetry JS SDK][opentelemetry-js]
- Node.js >=8.5.0 (14+ is preferred) or an ECMAScript 5+ compatible browser
```shell
npm install --save @opentelemetry/api
npm install --save @opentelemetry/sdk-node
npm install --save @opentelemetry/auto-instrumentations-node
**Note:** ECMAScript 5+ compatibility is for this package only. Please refer to the documentation for the SDK you are using to determine its minimum ECMAScript version.
**Note for library authors:** Only your end users will need an OpenTelemetry SDK. If you wish to support OpenTelemetry in your library, you only need to use the OpenTelemetry API. For more information, please read the [tracing documentation][docs-tracing].
### Install Dependencies
```sh
npm install @opentelemetry/api @opentelemetry/tracing
```
**Note:** `auto-instrumentations-node` is a meta package from [opentelemetry-js-contrib](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/metapackages/auto-instrumentations-node) that provides a simple way to initialize multiple Node.js instrumentations.
### Trace Your Application
### Set up Tracing
In order to get started with tracing, you will need to first register an SDK. The SDK you are using may provide a convenience method which calls the registration methods for you, but if you would like to call them directly they are documented here: [sdk registration methods][docs-sdk-registration].
```js
// tracing.js
Once you have registered an SDK, you can start and end spans. A simple example of basic SDK registration and tracing a simple operation is below. The example should export spans to the console once per second. For more information, see the [tracing documentation][docs-tracing].
'use strict'
```javascript
const { trace } = require("@opentelemetry/api");
const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require("@opentelemetry/tracing");
const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
// Create and register an SDK
const provider = new BasicTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
trace.setGlobalTracerProvider(provider);
// configure the SDK to export telemetry data to the console
// enable all auto-instrumentations from the meta package
const traceExporter = new ConsoleSpanExporter();
const sdk = new opentelemetry.NodeSDK({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'my-service',
}),
traceExporter,
instrumentations: [getNodeAutoInstrumentations()]
});
// Acquire a tracer from the global tracer provider which will be used to trace the application
const name = 'my-application-name';
const version = '0.1.0';
const tracer = trace.getTracer(name, version);
// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start();
// Trace your application by creating spans
async function operation() {
const span = tracer.startSpan("do operation");
// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
sdk.shutdown()
.then(() => console.log('Tracing terminated'))
.catch((error) => console.log('Error terminating tracing', error))
.finally(() => process.exit(0));
});
// mock some work by sleeping 1 second
await new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
})
span.end();
}
async function main() {
while (true) {
await operation();
}
}
main();
```
### Run Your Application
## Version Compatibility
```shell
node -r ./tracing.js app.js
```
Because the npm installer and node module resolution algorithm could potentially allow two or more copies of any given package to exist within the same `node_modules` structure, the OpenTelemetry API takes advantage of a variable on the `global` object to store the global API. When an API method in the API package is called, it checks if this `global` API exists and proxies calls to it if and only if it is a compatible API version. This means if a package has a dependency on an OpenTelemetry API version which is not compatible with the API used by the end user, the package will receive a no-op implementation of the API.
The above example will emit auto-instrumented telemetry about your Node.js application to the console. For a more in-depth example, see the [Getting Started Guide](https://opentelemetry.io/docs/languages/js/getting-started/). For more information about automatic instrumentation see [@opentelemetry/sdk-trace-node][otel-node], which provides auto-instrumentation for Node.js applications. If the automatic instrumentation does not suit your needs, or you would like to create manual traces, see [@opentelemetry/sdk-trace-base][otel-tracing]
## Upgrade Guidelines
## Library Author
### 0.21.0 to 1.0.0
If you are a library author looking to build OpenTelemetry into your library, please see [the documentation][docs]. As a library author, it is important that you only depend on properties and methods published on the public API. If you use any properties or methods from the SDK that are not officially a part of the public API, your library may break if an application owner uses a different SDK implementation.
No breaking changes
## Supported Runtimes
### 0.20.0 to 0.21.0
| Platform Version | Supported |
| ------------------- | --------------------------------------------- |
| Node.JS `v22` | :heavy_check_mark: |
| Node.JS `v20` | :heavy_check_mark: |
| Node.JS `v18` | :heavy_check_mark: |
| Older Node Versions | See [Node Support](#node-support) |
| Web Browsers | See [Browser Support](#browser-support) below |
- [#78](https://github.com/open-telemetry/opentelemetry-js-api/issues/78) `api.context.bind` arguments reversed and `context` is now a required argument.
- [#46](https://github.com/open-telemetry/opentelemetry-js-api/issues/46) Noop classes and singletons are no longer exported. To create a noop span it is recommended to use `api.trace.wrapSpanContext` with `INVALID_SPAN_CONTEXT` instead of using the `NOOP_TRACER`.
### Node Support
### 1.0.0-rc.3 to 0.20.0
Only Node.js Active or Maintenance LTS versions are supported.
Previous versions of node *may* work, but they are not tested by OpenTelemetry and they are not guaranteed to work.
### Browser Support
> [!IMPORTANT]
> Client instrumentation for the browser is **experimental** and mostly **unspecified**. If you are interested in
> helping out, get in touch with the [Client Instrumentation SIG][client-instrumentation-sig].
Rather than define versions of specific browsers / runtimes, OpenTelemetry sets the minimum supported version based on the
underlying language features used.
The current minumum language feature support is set as [ECMAScript 2022](https://262.ecma-international.org/13.0/) that are available
in all modern browsers / runtimes.
This means that if you are targeting or your end-users are using a browser / runtime that does not support ES2022, you will need
to transpile the code and provide any necessary polyfills for the missing features to ensure compatibility with your target
environments. Any support issues that arise from using a browser or runtime that does not support ES2022 will be closed as "won't fix".
This minimum support level is subject to change as the project evolves and as the underlying language features evolve.
## TypeScript Support
OpenTelemetry JavaScript is built with TypeScript `v5.0.4`. If you have a TypeScript project (app, library, instrumentation, etc.)
that depends on it, we recommend using same or higher version to compile the project.
OpenTelemetry JavaScript will follows DefinitelyType's [support policy for TypeScript](https://github.com/DefinitelyTyped/DefinitelyTyped#support-window) which sets a support window of 2 years. Support for TypeScript versions older than 2 years will be dropped in minor releases of OpenTelemetry JavaScript.
## Package Version Compatibility
OpenTelemetry is released as a set of distinct packages in 3 categories: API, stable SDK, and experimental.
The API is located at [/api](/api/), the stable SDK packages are in the [/packages](/packages/) directory, and the experimental packages are listed in the [/experimental/packages](/experimental/packages/) directory.
There may also be API packages for experimental signals in the experimental directory.
All stable packages are released with the same version, and all experimental packages are released with the same version.
The below table describes which versions of each set of packages are expected to work together.
| Stable Packages | Experimental Packages |
|-----------------|-----------------------|
| 2.0.x | 0.200.x |
| 1.30.x | 0.57.x |
| 1.29.x | 0.56.x |
| 1.28.x | 0.55.x |
| 1.27.x | 0.54.x |
| 1.25.x | 0.52.x |
<details>
<summary>Older version compatibility matrix</summary>
<table>
<tr><th>Stable Packages</th> <th>Experimental Packages</th></tr>
<tr><td>1.24.x</td> <td>0.51.x</td></tr>
<tr><td>1.23.x</td> <td>0.50.x</td></tr>
<tr><td>1.22.x</td> <td>0.49.x</td></tr>
<tr><td>1.21.x</td> <td>0.48.x</td></tr>
<tr><td>1.20.x</td> <td>0.47.x</td></tr>
<tr><td>1.19.x</td> <td>0.46.x</td></tr>
<tr><td>1.18.x</td> <td>0.45.x</td></tr>
<tr><td>1.17.x</td> <td>0.43.x, 0.44.x</td></tr>
<tr><td>1.16.x</td> <td>0.42.x</td></tr>
<tr><td>1.15.x</td> <td>0.41.x</td></tr>
<tr><td>1.14.x</td> <td>0.40.x</td></tr>
<tr><td>1.13.x</td> <td>0.39.x</td></tr>
<tr><td>1.12.x</td> <td>0.38.x</td></tr>
<tr><td>1.11.x</td> <td>0.37.x</td></tr>
<tr><td>1.10.x</td> <td>0.36.x</td></tr>
<tr><td>1.9.x</td> <td>0.35.x</td></tr>
<tr><td>1.8.x (this and later versions require API >=1.3.0 for metrics)</td><td>0.34.x</td></tr>
<tr><td>1.7.x</td> <td>0.33.x</td></tr>
<tr><td>1.6.x</td> <td>0.32.x</td></tr>
<tr><td>1.5.x</td> <td>0.31.x</td></tr>
<tr><td>1.4.x</td> <td>0.30.x</td></tr>
<tr><td>1.3.x</td> <td>0.29.x</td></tr>
<tr><td>1.2.x</td> <td>0.29.x</td></tr>
<tr><td>1.1.x</td> <td>0.28.x</td></tr>
<tr><td>1.0.x</td> <td>0.27.x</td></tr>
<tr><td>1.0.x (this and later versions require API >=1.0.0 for traces)</td><td>0.26.x</td></tr>
</table>
</details>
## Versioning
The current version for each package can be found in the respective `package.json` file for that module. For additional details see the [versioning and stability][spec-versioning] document in the specification.
## Feature Status
| Signal | API Status | SDK Status |
| ------- | ----------- | ----------- |
| Tracing | Stable | Stable |
| Metrics | Stable | Stable |
| Logs | Development | Development |
For a more detailed breakdown of feature support see the [specification compliance matrix][compliance-matrix].
## Contributing
We'd love your help!. Use tags [up-for-grabs][up-for-grabs-issues] and
[good first issue][good-first-issues] to get started with the project. For
instructions to build and make changes to this project, see the
[CONTRIBUTING][CONTRIBUTING] guide.
We have a weekly SIG meeting! See the [community page](https://github.com/open-telemetry/community#javascript-sdk) for meeting details and notes.
### Maintainers
- [Amir Blum](https://github.com/blumamir), Odigos
- [Chengzhong Wu](https://github.com/legendecas), Bloomberg
- [Daniel Dyla](https://github.com/dyladan), Dynatrace
- [Jamie Danielson](https://github.com/JamieDanielson), Honeycomb
- [Marc Pichler](https://github.com/pichlermarc), Dynatrace
- [Trent Mick](https://github.com/trentm), Elastic
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
- [David Luna](https://github.com/david-luna), Elastic
- [Hector Hernandez](https://github.com/hectorhdzg), Microsoft
- [Martin Kuba](https://github.com/martinkuba), Lightstep
- [Marylia Gutierrez](https://github.com/maryliag), Grafana Labs
- [Matthew Wear](https://github.com/mwear), LightStep
- [Neville Wylie](https://github.com/MSNev), Microsoft
- [Purvi Kanal](https://github.com/pkanal), Honeycomb
- [Svetlana Brennan](https://github.com/svetlanabrennan), New Relic
For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).
### Triagers
Members of this team have triager permissions for opentelemetry-js.git and opentelemetry-js-contrib.git.
- [Jackson Weber](https://github.com/JacksonWeber), Microsoft
For more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).
### Contrib Triagers
Members of this team have triager permissions for opentelemetry-js-contrib.git.
Typically, members of this are [component owners](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/.github/component_owners.yml) of one or more packages in the contrib repo.
- [Aaron Abbott](https://github.com/aabmass), Google
- [Abhinav Mathur](https://github.com/abhee11), AppDynamics
- [Bartlomiej Obecny](https://github.com/obecny)
- [Daniel Li](https://github.com/d4nyll)
- [Florencia Acosta](https://github.com/facostaembrace), Embrace
- [Jackson Weber](https://github.com/JacksonWeber), Microsoft
- [Jaryk](https://github.com/Ugzuzg), Volvo Cars
- [Jonathan Lee](https://github.com/jj22ee)
- [Jonathan Munz](https://github.com/jpmunz), Embrace
- [kirrg001](https://github.com/kirrg001), Instana
- [MartenH](https://github.com/mhennoch), Splunk
- [Mike Goldsmith](https://github.com/MikeGoldsmith), Honeycomb
- [Motti](https://github.com/mottibec)
- [Punya Biswal](https://github.com/punya), Google
- [Siim Kallas](https://github.com/seemk), Splunk
- [t2t2](https://github.com/t2t2), Splunk
- [Trivikram Kamat](https://github.com/trivikr), AWS
For more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).
### Emeriti
- [Bartlomiej Obecny](https://github.com/obecny), Maintainer
- [Brandon Gonzalez](https://github.com/bg451), Approver
- [Daniel Khan](https://github.com/dkhan), Maintainer
- [Gerhard Stöbich](https://github.com/Flarna), Approver
- [Haddas Bronfman](https://github.com/haddasbronfman), Approver
- [John Bley](https://github.com/johnbley), Approver
- [Mark Wolff](https://github.com/markwolff), Approver
- [Mayur Kale](https://github.com/mayurkale22), Maintainer
- [Naseem K. Ullah](https://github.com/naseemkullah), Approver
- [Olivier Albertini](https://github.com/OlivierAlbertini), Approver
- [Rauno Viskus](https://github.com/rauno56), Maintainer
- [Roch Devost](https://github.com/rochdev), Approver
- [Valentin Marchaud](https://github.com/vmarchaud), 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).
### Thanks to all of our contributors!
<a href="https://github.com/open-telemetry/opentelemetry-js/graphs/contributors">
<img alt="Repo contributors" src="https://contrib.rocks/image?repo=open-telemetry/opentelemetry-js" />
</a>
## Packages
### API
| Package | Description |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [@opentelemetry/api][otel-api] | This package provides TypeScript interfaces, enums and no-op implementations for the OpenTelemetry core trace and metrics model. It is intended for use both on the server and in the browser. |
| [@opentelemetry/core][otel-core] | This package provides default and no-op implementations of the OpenTelemetry api for trace and metrics. It's intended for use both on the server and in the browser. |
### Implementation / SDKs
| Package | Description |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [@opentelemetry/sdk-trace-base][otel-tracing] | This module provides a full control over instrumentation and span creation. It doesn't load [`async_hooks`](https://nodejs.org/api/async_hooks.html) or any instrumentation by default. It is intended for use both on the server and in the browser. |
| [@opentelemetry/sdk-metrics][otel-metrics] | This module provides instruments and meters for reporting of time series data. |
| [@opentelemetry/sdk-trace-node][otel-node] | This module provides automatic tracing for Node.js applications. It is intended for use on the server only. |
| [@opentelemetry/sdk-trace-web][otel-web] | This module provides automated instrumentation and tracing for Web applications. It is intended for use in the browser only. |
### Compatible Exporters
OpenTelemetry is vendor-agnostic and can upload data to any backend with various exporter implementations. Even though, OpenTelemetry provides support for many backends, vendors/users can also implement their own exporters for proprietary and unofficially supported backends.
See the [OpenTelemetry registry](https://opentelemetry.io/registry/?language=js&component=exporter#) for a list of exporters available.
### Instrumentations
OpenTelemetry can collect tracing data automatically using instrumentations.
To request automatic tracing support for a module not on this list, please [file an issue](https://github.com/open-telemetry/opentelemetry-js/issues). Alternatively, Vendor/Users can [write an instrumentation yourself](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/instrumentation-guide.md).
Currently, OpenTelemetry supports automatic tracing for:
#### Node Instrumentations
##### Core
- [@opentelemetry/instrumentation-grpc][otel-instrumentation-grpc]
- [@opentelemetry/instrumentation-http][otel-instrumentation-http]
##### Contrib
These instrumentations are hosted at <https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node>
#### Web Instrumentations
##### Core
- [@opentelemetry/instrumentation-xml-http-request][otel-instrumentation-xml-http-request]
- [@opentelemetry/instrumentation-fetch][otel-instrumentation-fetch]
##### Contrib
These instrumentations are hosted at <https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/web>
### Shims
| Package | Description |
| -------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| [@opentelemetry/shim-opentracing][otel-shim-opentracing] | OpenTracing shim allows existing OpenTracing instrumentation to report to OpenTelemetry |
- Removing `TimedEvent` which was not part of spec
- `HttpBaggage` renamed to `HttpBaggagePropagator`
- [#45](https://github.com/open-telemetry/opentelemetry-js-api/pull/45) `Span#context` renamed to `Span#spanContext`
- [#47](https://github.com/open-telemetry/opentelemetry-js-api/pull/47) `getSpan`/`setSpan`/`getSpanContext`/`setSpanContext` moved to `trace` namespace
- [#55](https://github.com/open-telemetry/opentelemetry-js-api/pull/55) `getBaggage`/`setBaggage`/`createBaggage` moved to `propagation` namespace
## Useful links
- [Upgrade to SDK 2.x guide](./doc/upgrade-to-2.x.md)
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
- For more about OpenTelemetry JavaScript: <https://github.com/open-telemetry/opentelemetry-js>
- For help or feedback on this project, join us in [GitHub Discussions][discussions-url]
## License
Apache 2.0 - See [LICENSE][license-url] for more information.
[opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE
[up-for-grabs-issues]: https://github.com/open-telemetry/OpenTelemetry-js/issues?q=is%3Aissue+is%3Aopen+label%3Aup-for-grabs
[good-first-issues]: https://github.com/open-telemetry/OpenTelemetry-js/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22
[client-instrumentation-sig]: https://docs.google.com/document/d/16Vsdh-DM72AfMg_FIt9yT9ExEWF4A_vRbQ3jRNBe09w/edit
[docs]: https://open-telemetry.github.io/opentelemetry-js
[compliance-matrix]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md
[CONTRIBUTING]: https://github.com/open-telemetry/opentelemetry-js/blob/main/CONTRIBUTING.md
[otel-metrics]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics
[otel-node]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node
[otel-instrumentation-fetch]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch
[otel-instrumentation-grpc]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-grpc
[otel-instrumentation-http]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http
[otel-instrumentation-xml-http-request]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-xml-http-request
[otel-shim-opentracing]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing
[otel-tracing]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-base
[otel-web]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web
[otel-api]: https://github.com/open-telemetry/opentelemetry-js/tree/main/api
[otel-core]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core
[spec-versioning]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md
[license-url]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
[dependencies-image]: https://status.david-dm.org/gh/open-telemetry/opentelemetry-js-api.svg
[dependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js-api
[devDependencies-image]: https://status.david-dm.org/gh/open-telemetry/opentelemetry-js-api.svg?type=dev
[devDependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js-api?type=dev
[npm-url]: https://www.npmjs.com/package/@opentelemetry/api
[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi.svg
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/tracing.md
[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/sdk-registration.md

View File

@ -1 +0,0 @@
build

View File

@ -1,8 +0,0 @@
module.exports = {
"env": {
"mocha": true,
"commonjs": true,
"shared-node-browser": true
},
...require('../eslint.base.js')
}

View File

@ -1,295 +0,0 @@
<!-- markdownlint-disable MD004 -->
# CHANGELOG
All notable changes to this project will be documented in this file.
## Unreleased
### :boom: Breaking Change
### :rocket: (Enhancement)
* feat(api): improve isValidSpanId, isValidTraceId performance [#5714](https://github.com/open-telemetry/opentelemetry-js/pull/5714) @seemk
* feat(diag): change types in `DiagComponentLogger` from `any` to `unknown`[#5478](https://github.com/open-telemetry/opentelemetry-js/pull/5478) @loganrosen
### :bug: (Bug Fix)
### :books: (Refine Doc)
### :house: (Internal)
* refactor(api): remove "export *" in favor of explicit named exports [#4880](https://github.com/open-telemetry/opentelemetry-js/pull/4880) @robbkidd
* chore: enable tsconfig isolatedModules [#5697](https://github.com/open-telemetry/opentelemetry-js/pull/5697) @legendecas
## 1.9.0
### :rocket: (Enhancement)
* feat(metrics): added synchronous gauge [#4528](https://github.com/open-telemetry/opentelemetry-js/pull/4528) @clintonb
* feat(api): allow adding span links after span creation [#4536](https://github.com/open-telemetry/opentelemetry-js/pull/4536) @seemk
* This change is non-breaking for end-users, but breaking for Trace SDK implmentations in accordance with the [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/a03382ada8afa9415266a84dafac0510ec8c160f/specification/upgrading.md?plain=1#L97-L122) as new features need to be implemented.
* feat: support node 22 [#4666](https://github.com/open-telemetry/opentelemetry-js/pull/4666) @dyladan
## 1.8.0
### :rocket: (Enhancement)
* feat(api): add SugaredTracer for functions not defined in the spec
### :bug: (Bug Fix)
* fix(api): fix unreachable @opentelemetry/api/experimental entry [#4446](https://github.com/open-telemetry/opentelemetry-js/pull/4446) @legendecas
## 1.7.0
### :rocket: (Enhancement)
* feat(metrics): prototype experimental advice support [#3876](https://github.com/open-telemetry/opentelemetry-js/pull/3876) @legendecas
* feat(api): publish api esnext target [#4231](https://github.com/open-telemetry/opentelemetry-js/pull/4231) @legendecas
## 1.6.0
### :bug: (Bug Fix)
* Revert "feat(api): add attributes argument to recordException API [#4071](https://github.com/open-telemetry/opentelemetry-js/pull/4071)"
* This feature was an unintentional breaking change introduced with 1.5.0
## 1.5.0
### :rocket: (Enhancement)
* feat(api): add attributes argument to recordException API [#4071](https://github.com/open-telemetry/opentelemetry-js/pull/4071)
## 1.4.1
### :bug: (Bug Fix)
* fix(metrics): export `MetricsAPI` type [#3535](https://github.com/open-telemetry/opentelemetry-js/pull/3535)
* fix(api): rename `LoggerOptions` to `DiagLoggerOptions` [#3641](https://github.com/open-telemetry/opentelemetry-js/pull/3641)
* fix(api): export `DiagLoggerOptions` type [#3639](https://github.com/open-telemetry/opentelemetry-js/pull/3639)
## 1.4.0
### :rocket: (Enhancement)
* feat(api): add `getActiveBaggage` API [#3385](https://github.com/open-telemetry/opentelemetry-js/pull/3385)
* feat(api): add optional `droppedAttributesCount` property in the `Link` interface [#3576](https://github.com/open-telemetry/opentelemetry-js/pull/3576) @mohitk05
### :bug: (Bug Fix)
* fix(api): deprecate MetricAttributes and MetricAttributeValue [#3406](https://github.com/open-telemetry/opentelemetry-js/pull/3406) @blumamir
* fix(api): use active context as default in NoopTracer [#3476](https://github.com/open-telemetry/opentelemetry-js/pull/3476) @flarna
* fix(api): declare this parameter type in observable callbacks [#3497](https://github.com/open-telemetry/opentelemetry-js/pull/3497) @legendecas
### :house: (Internal)
* test(api): disable module concatenation in tree-shaking test [#3409](https://github.com/open-telemetry/opentelemetry-js/pull/3409) @legendecas
## [1.3.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.2.0...v1.3.0)
* feat(api): merge api-metrics into api [#3374](https://github.com/open-telemetry/opentelemetry-js/pull/3374) @legendecas
* Optionally suppress warning about logger being overwritten ([#3366](https://www.github.com/open-telemetry/opentelemetry-js-api/pull/3366))
## [1.2.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.1.0...v1.2.0) (2022-08-09)
### Features
* Add getActiveSpan to trace API ([#163](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/163)) ([17ccb3a](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/17ccb3a4e385bc5769ded6fc742c9782a93244a5))
* deprecate Sampler ([#166](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/166)) ([313b2e2](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/313b2e2225f246a6a9518ec4da6942f7d61babce))
## [1.1.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.0.4...v1.1.0) (2022-01-25)
### Features
* add tracestate implementation to api ([#147](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/147)) ([82842c7](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/82842c7097614e6ece99e73838ac5e94ff5460b7))
* define common attributes type ([#142](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/142)) ([ae9bead](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/ae9bead17750d35dec4b63cfae098087666abc85))
* **trace:** add optional schema url to TracerProvider.getTracer ([#129](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/129)) ([aa65fc6](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/aa65fc66809d45090d6e4951c265386d17ccc6f6))
### Bug Fixes
* export tracer options ([#154](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/154)) ([b125324](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/b125324438fb2f24eb80c7c6673afc8cfc99575e))
## [1.0.4](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.0.3...v1.0.4) (2021-12-18)
### Bug Fixes
* align globalThis fallbacks with otel-core ([#126](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/126)) ([3507de7](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/3507de7c3b95396696657c021953b0b24a63a029))
## [1.0.3](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.0.2...v1.0.3) (2021-08-30)
### Bug Fixes
* remove all circular dependencies ([#119](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/119)) ([a8083e8](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/a8083e84b23227828745da80fd5fe512357dd34b))
## 1.0.2
### :bug: Bug Fix
* [#105](https://github.com/open-telemetry/opentelemetry-js-api/pull/105) fix: set delegate after successful registration ([@Flarna](https://github.com/Flarna))
* [#94](https://github.com/open-telemetry/opentelemetry-js-api/pull/94) fix: enforce strict equality on prerelease versions ([@dyladan](https://github.com/dyladan))
### :memo: Documentation
* [#106](https://github.com/open-telemetry/opentelemetry-js-api/pull/106) docs: fix crash in README example ([@trentm](https://github.com/trentm))
* [#101](https://github.com/open-telemetry/opentelemetry-js-api/pull/101) docs: Format example for tracer.startActiveSpan ([@ad-m](https://github.com/ad-m))
* [#99](https://github.com/open-telemetry/opentelemetry-js-api/pull/99) chore: fix link to API docs ([@dyladan](https://github.com/dyladan))
### :house: Internal
* [#109](https://github.com/open-telemetry/opentelemetry-js-api/pull/109) internal: add missing approvers from core ([@dyladan](https://github.com/dyladan))
* [#103](https://github.com/open-telemetry/opentelemetry-js-api/pull/103) chore: reuse NoopTracer in ProxyTracer ([@Flarna](https://github.com/Flarna))
### Committers: 4
* Adam Dobrawy ([@ad-m](https://github.com/ad-m))
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
* Gerhard Stöbich ([@Flarna](https://github.com/Flarna))
* Trent Mick ([@trentm](https://github.com/trentm))
## 1.0.1
### :bug: Bug Fix
* [#96](https://github.com/open-telemetry/opentelemetry-js-api/pull/96) chore: remove circular dependency ([@dyladan](https://github.com/dyladan))
### Committers: 1
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
## 1.0.0
### :memo: Documentation
* [#89](https://github.com/open-telemetry/opentelemetry-js-api/pull/89) chore: update upgrade guidelines ([@dyladan](https://github.com/dyladan))
### :house: Internal
* [#90](https://github.com/open-telemetry/opentelemetry-js-api/pull/90) chore: enable typescript 4.3 noImplicitOverride option ([@Flarna](https://github.com/Flarna))
### Committers: 2
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
* Gerhard Stöbich ([@Flarna](https://github.com/Flarna))
## 0.21.0
### :boom: Breaking Change
* [#78](https://github.com/open-telemetry/opentelemetry-js-api/pull/78) feat: unify signatures of `with` and `bind` ([@Rauno56](https://github.com/Rauno56))
* [#46](https://github.com/open-telemetry/opentelemetry-js-api/pull/46) chore: do not export singletons ([@dyladan](https://github.com/dyladan))
### :rocket: Enhancement
* [#81](https://github.com/open-telemetry/opentelemetry-js-api/pull/81) chore: function overloads implementation of startActiveSpan in noop t… ([@naseemkullah](https://github.com/naseemkullah))
### :house: Internal
* [#84](https://github.com/open-telemetry/opentelemetry-js-api/pull/84) chore: remove unused backwards compatibility folder ([@Flarna](https://github.com/Flarna))
* [#85](https://github.com/open-telemetry/opentelemetry-js-api/pull/85) chore: add node:16 to the test matrix ([@Rauno56](https://github.com/Rauno56))
* [#63](https://github.com/open-telemetry/opentelemetry-js-api/pull/63) feat: debug log global registrations and logger overwrites ([@Rauno56](https://github.com/Rauno56))
* [#75](https://github.com/open-telemetry/opentelemetry-js-api/pull/75) Add CodeQL Security Scan ([@xukaren](https://github.com/xukaren))
* [#79](https://github.com/open-telemetry/opentelemetry-js-api/pull/79) chore: fix eslint config ([@Rauno56](https://github.com/Rauno56))
### Committers: 5
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
* Gerhard Stöbich ([@Flarna](https://github.com/Flarna))
* Karen Xu ([@xukaren](https://github.com/xukaren))
* Naseem ([@naseemkullah](https://github.com/naseemkullah))
* Rauno Viskus ([@Rauno56](https://github.com/Rauno56))
## 0.20.0
### :rocket: Enhancement
* [#69](https://github.com/open-telemetry/opentelemetry-js-api/pull/69) feat(context): add utils method to remove keys from context ([@vmarchaud](https://github.com/vmarchaud))
* [#71](https://github.com/open-telemetry/opentelemetry-js-api/pull/71) chore: export baggage ([@dyladan](https://github.com/dyladan))
### Committers: 2
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
* Valentin Marchaud ([@vmarchaud](https://github.com/vmarchaud))
## 0.19.0
### :boom: Breaking Change
* [#55](https://github.com/open-telemetry/opentelemetry-js-api/pull/55) chore: move baggage methods in propagation namespace ([@vmarchaud](https://github.com/vmarchaud))
* [#65](https://github.com/open-telemetry/opentelemetry-js-api/pull/65) chore: remove suppress instrumentation ([@dyladan](https://github.com/dyladan))
* [#60](https://github.com/open-telemetry/opentelemetry-js-api/pull/60) chore: removing timed event ([@obecny](https://github.com/obecny))
* [#58](https://github.com/open-telemetry/opentelemetry-js-api/pull/58) chore: use spancontext for link ([@dyladan](https://github.com/dyladan))
* [#47](https://github.com/open-telemetry/opentelemetry-js-api/pull/47) chore: move span method for context in trace API #40 ([@vmarchaud](https://github.com/vmarchaud))
* [#45](https://github.com/open-telemetry/opentelemetry-js-api/pull/45) chore: rename `span#context()` to `span#spanContext` ([@dyladan](https://github.com/dyladan))
* [#43](https://github.com/open-telemetry/opentelemetry-js-api/pull/43) chore: renaming noop span to non recording span ([@obecny](https://github.com/obecny))
* [#32](https://github.com/open-telemetry/opentelemetry-js-api/pull/32) feat!: return boolean success value from setGlobalXXX methods ([@dyladan](https://github.com/dyladan))
### :rocket: Enhancement
* [#62](https://github.com/open-telemetry/opentelemetry-js-api/pull/62) chore: adding component logger ([@obecny](https://github.com/obecny))
* [#54](https://github.com/open-telemetry/opentelemetry-js-api/pull/54) feat: add tracer.startActiveSpan() ([@naseemkullah](https://github.com/naseemkullah))
* [#58](https://github.com/open-telemetry/opentelemetry-js-api/pull/58) chore: use spancontext for link ([@dyladan](https://github.com/dyladan))
* [#51](https://github.com/open-telemetry/opentelemetry-js-api/pull/51) feat: add function to wrap SpanContext in NonRecordingSpan #49 ([@dyladan](https://github.com/dyladan))
### :memo: Documentation
* [#64](https://github.com/open-telemetry/opentelemetry-js-api/pull/64) chore: document the reason for symbol.for ([@dyladan](https://github.com/dyladan))
* [#44](https://github.com/open-telemetry/opentelemetry-js-api/pull/44) chore: updating readme headline and fixing links ([@obecny](https://github.com/obecny))
### Committers: 6
* Bartlomiej Obecny ([@obecny](https://github.com/obecny))
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
* Gerhard Stöbich ([@Flarna](https://github.com/Flarna))
* Naseem ([@naseemkullah](https://github.com/naseemkullah))
* Valentin Marchaud ([@vmarchaud](https://github.com/vmarchaud))
* t2t2 ([@t2t2](https://github.com/t2t2))
## 1.0.0-rc.0
### :memo: Documentation
* [#20](https://github.com/open-telemetry/opentelemetry-js-api/pull/20) docs: document latest manual tracing ([@dyladan](https://github.com/dyladan))
* [#18](https://github.com/open-telemetry/opentelemetry-js-api/pull/18) chore: deploy docs on a release ([@dyladan](https://github.com/dyladan))
* [#19](https://github.com/open-telemetry/opentelemetry-js-api/pull/19) docs: fix readme links ([@dyladan](https://github.com/dyladan))
### Committers: 1
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
## 0.18.1
### :bug: Bug Fix
* [#16](https://github.com/open-telemetry/opentelemetry-js-api/pull/16) fix: Reverse the direction of the semver check ([@dyladan](https://github.com/dyladan))
### Committers: 1
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
## v0.18.0
### :boom: Breaking Change
* [#9](https://github.com/open-telemetry/opentelemetry-js-api/pull/9) chore: refactor diag logger ([@dyladan](https://github.com/dyladan))
### :rocket: Enhancement
* [#10](https://github.com/open-telemetry/opentelemetry-js-api/pull/10) Use semver to determine API compatibility ([@dyladan](https://github.com/dyladan))
### :house: Internal
* [#12](https://github.com/open-telemetry/opentelemetry-js-api/pull/12) chore: don't disable rule eqeqeq ([@Flarna](https://github.com/Flarna))
* [#8](https://github.com/open-telemetry/opentelemetry-js-api/pull/8) chore: remove nycrc in favor of tsconfig reporting ([@dyladan](https://github.com/dyladan))
* [#3](https://github.com/open-telemetry/opentelemetry-js-api/pull/3) chore: add test workflow ([@dyladan](https://github.com/dyladan))
* [#4](https://github.com/open-telemetry/opentelemetry-js-api/pull/4) chore: remove package lock ([@dyladan](https://github.com/dyladan))
* [#2](https://github.com/open-telemetry/opentelemetry-js-api/pull/2) chore: add lint workflow ([@dyladan](https://github.com/dyladan))
### Committers: 2
* Daniel Dyla ([@dyladan](https://github.com/dyladan))
* Gerhard Stöbich ([@Flarna](https://github.com/Flarna))
## v0.17.0
Versions previous to `0.18.0` were developed in another repository.
To see previous changelog entries see the [CHANGELOG.md](https://github.com/open-telemetry/opentelemetry-js/blob/main/CHANGELOG.md).

View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,117 +0,0 @@
# OpenTelemetry API for JavaScript
<p align="center">
<strong>
<a href="https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api.html">API Reference</a>
&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://opentelemetry.io/docs/instrumentation/js/">Documentation</a>
</br>
<a href="https://github.com/open-telemetry/opentelemetry-js/releases">
<img alt="NPM Release" src="https://img.shields.io/npm/v/@opentelemetry/api?color=brightgreen&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACQAAAAAQAAAJAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABigAwAEAAAAAQAAABgAAAAA8A2UOAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAABK5JREFUSA2dVm1sFEUYfmd2b%2Ff2Pkqghn5eEQWKrRgjpkYgpoRCLC0oxV5apAiGUDEpJvwxEQ2raWPU%2BKf8INU%2FRtEedwTCR9tYPloxGNJYTTQUwYqJ1aNpaLH3sXu3t7vjvFevpSqt7eSyM%2B%2FczvM8877PzB3APBoLgoDLsNePF56LBwqa07EKlDGg84CcWsI4CEbhNnDpAd951lXE2NkiNknCCTLv4HtzZuvPm1C%2FIKv4oDNXqNDHragety2XVzjECZsJARuBMyRzJrh1O0gQwLXuxofxsPSj4hG8fMLQo7bl9JJD8XZfC1E5yWFOMtd07dvX5kDwg6%2B2%2B%2BChq8txHGtfPoAp0gOFmhYoNFkHjn2TNUmrwRdna7W1QSkU8hvbGk4uThLrapaiLA2E6QY4u%2FlS9ItHfvJkxYsTMVtnAJLipYIWtVrcdX%2B8%2Bb8IVnPl%2FR81prbuPZ1jpYw%2B0aEUGSkdFsgyBIaFTXCm6nyaxMtJ4n%2BTeDhJzGqZtQZcuYDgqDwDbqb0JF9oRpIG1Oea3bC1Y6N3x%2FWV8Zh83emhCs%2B%2BhlaghDw%2B8w5UlYKq2lU7Pl8IkvS9KDqXmKmEwdMppVPKwGSEilmyAwJhRwWcq7wYC6z4wZ1rrEoMWxecdOjZWXeAQClBcYDN3NwVwD9pGwqUSyQgclcmxpNJqCuwLmDh3WtvPqXdlt%2B6Oz70HPGDNSNBee%2FEOen%2BrGbEFqDENBPDbtdCp0ukPANmzO0QQJYUpyS5IJJI3Hqt4maS%2BEB3199ozm8EDU%2F6fVNU2dQpdx3ZnKzeFXyaUTiasEV%2FgZMzJMjr3Z%2BWvAdQ%2Bhs%2Fzw9savimxUntDSaBdZ2f%2BIdbm1rlNY8esFffBit9HtK5%2FMejsrJVxikOXlb1Ukir2X%2BRbdkd1KG2Ixfn2Ql4JRmELnYK9mEM8G36fAA3xEQ89fxXihC8q%2BsAKi9jhHxNqagY2hiaYgRCm0f0QP7H4Fp11LSXiuBY2aYFlh0DeDIVVFUJQn5rCnpiNI2gvLxHnASn9DIVHJJlm5rXvQAGEo4zvKq2w5G1NxENN7jrft1oxMdekETjxdH2Z3x%2BVTVYsPb%2BO0C%2F9%2FauN6v2hNZw5b2UOmSbG5%2FrkC3LBA%2B1PdxFxORjxpQ81GcxKc%2BybVjEBvUJvaGJ7p7n5A5KSwe4AzkasA%2BcrmzFtowoIVTiLjANm8GDsrWW35ScI3JY8Urv83tnkF8JR0yLvEt2hO%2F0qNyy3Jb3YKeHeHeLeOuVLRpNF%2Bpkf85OW7%2FzJxWdXsbsKBUk2TC0BCPwMq5Q%2FCPvaJFkNS%2F1l1qUPe%2BuH3oD59erYGI%2FY4sce6KaXYElAIOLt%2B0O3t2%2B%2FxJDF1XvOlWGC1W1B8VMszbGfOvT5qaRRAIFK3BCO164nZ0uYLH2YjNN8thXS2v2BK9gTfD7jHVxzHr4roOlEvYYz9QIz%2BVl%2FsLDXInsctFsXjqIRnO2ZO387lxmIboLDZCJ59KLFliNIgh9ipt6tLg9SihpRPDO1ia5byw7de1aCQmF5geOQtK509rzfdwxaKOIq%2B73AvwCC5%2F5fcV4vo3%2B3LpMdtWHh0ywsJC%2FZGoCb8%2F9D8F%2FifgLLl8S8QWfU8cAAAAASUVORK5CYII%3D">
</a>
</strong>
</p>
This package provides everything needed to interact with the OpenTelemetry API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser.
The methods in this package perform no operations by default. This means they can be safely called by a library or end-user application whether there is an SDK registered or not. In order to generate and export telemetry data, you will also need an SDK such as the [OpenTelemetry JS SDK][opentelemetry-js].
## Tracing Quick Start
### You Will Need
- An application you wish to instrument
- [OpenTelemetry JS SDK][opentelemetry-js]
- Node.js >=8.5.0 (14+ is preferred) or an ECMAScript 5+ compatible browser
**Note:** ECMAScript 5+ compatibility is for this package only. Please refer to the documentation for the SDK you are using to determine its minimum ECMAScript version.
**Note for library authors:** Only your end users will need an OpenTelemetry SDK. If you wish to support OpenTelemetry in your library, you only need to use the OpenTelemetry API. For more information, please read the [tracing documentation][docs-tracing].
### Install Dependencies
```sh
npm install @opentelemetry/api @opentelemetry/sdk-trace-base
```
### Trace Your Application
In order to get started with tracing, you will need to first register an SDK. The SDK you are using may provide a convenience method which calls the registration methods for you, but if you would like to call them directly they are documented here: [SDK registration methods][docs-sdk-registration].
Once you have registered an SDK, you can start and end spans. A simple example of basic SDK registration and tracing a simple operation is below. The example should export spans to the console once per second. For more information, see the [tracing documentation][docs-tracing].
```javascript
const { trace } = require("@opentelemetry/api");
const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require("@opentelemetry/sdk-trace-base");
// Create and register an SDK
const provider = new BasicTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]
});
trace.setGlobalTracerProvider(provider);
// Acquire a tracer from the global tracer provider which will be used to trace the application
const name = 'my-application-name';
const version = '0.1.0';
const tracer = trace.getTracer(name, version);
// Trace your application by creating spans
async function operation() {
const span = tracer.startSpan("do operation");
// mock some work by sleeping 1 second
await new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
})
span.end();
}
async function main() {
while (true) {
await operation();
}
}
main();
```
## Version Compatibility
Because the npm installer and node module resolution algorithm could potentially allow two or more copies of any given package to exist within the same `node_modules` structure, the OpenTelemetry API takes advantage of a variable on the `global` object to store the global API. When an API method in the API package is called, it checks if this `global` API exists and proxies calls to it if and only if it is a compatible API version. This means if a package has a dependency on an OpenTelemetry API version which is not compatible with the API used by the end user, the package will receive a no-op implementation of the API.
## Upgrade Guidelines
### 0.21.0 to 1.0.0
No breaking changes
### 0.20.0 to 0.21.0
- [#78](https://github.com/open-telemetry/opentelemetry-js-api/issues/78) `api.context.bind` arguments reversed and `context` is now a required argument.
- [#46](https://github.com/open-telemetry/opentelemetry-js-api/issues/46) Noop classes and singletons are no longer exported. To create a noop span it is recommended to use `api.trace.wrapSpanContext` with `INVALID_SPAN_CONTEXT` instead of using the `NOOP_TRACER`.
### 1.0.0-rc.3 to 0.20.0
- Removing `TimedEvent` which was not part of spec
- `HttpBaggage` renamed to `HttpBaggagePropagator`
- [#45](https://github.com/open-telemetry/opentelemetry-js-api/pull/45) `Span#context` renamed to `Span#spanContext`
- [#47](https://github.com/open-telemetry/opentelemetry-js-api/pull/47) `getSpan`/`setSpan`/`getSpanContext`/`setSpanContext` moved to `trace` namespace
- [#55](https://github.com/open-telemetry/opentelemetry-js-api/pull/55) `getBaggage`/`setBaggage`/`createBaggage` moved to `propagation` namespace
## Useful links
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
- For more about OpenTelemetry JavaScript: <https://github.com/open-telemetry/opentelemetry-js>
- For help or feedback on this project, join us in [GitHub Discussions][discussions-url]
## License
Apache 2.0 - See [LICENSE][license-url] for more information.
[opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/api/LICENSE
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/tracing.md
[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/sdk-registration.md

View File

@ -1,24 +0,0 @@
/*!
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const karmaWebpackConfig = require('../karma.webpack');
const karmaBaseConfig = require('../karma.base');
module.exports = (config) => {
config.set(Object.assign({}, karmaBaseConfig, {
webpack: karmaWebpackConfig,
}))
};

View File

@ -1,24 +0,0 @@
/*!
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const karmaWebpackConfig = require('../karma.webpack');
const karmaBaseConfig = require('../karma.worker');
module.exports = (config) => {
config.set(Object.assign({}, karmaBaseConfig, {
webpack: karmaWebpackConfig,
}))
};

View File

@ -1,103 +0,0 @@
{
"name": "@opentelemetry/api",
"version": "1.9.0",
"description": "Public API for OpenTelemetry",
"main": "build/src/index.js",
"module": "build/esm/index.js",
"esnext": "build/esnext/index.js",
"types": "build/src/index.d.ts",
"browser": {
"./src/platform/index.ts": "./src/platform/browser/index.ts",
"./build/esm/platform/index.js": "./build/esm/platform/browser/index.js",
"./build/esnext/platform/index.js": "./build/esnext/platform/browser/index.js",
"./build/src/platform/index.js": "./build/src/platform/browser/index.js"
},
"exports": {
".": {
"module": "./build/esm/index.js",
"esnext": "./build/esnext/index.js",
"types": "./build/src/index.d.ts",
"default": "./build/src/index.js"
},
"./experimental": {
"module": "./build/esm/experimental/index.js",
"esnext": "./build/esnext/experimental/index.js",
"types": "./build/src/experimental/index.d.ts",
"default": "./build/src/experimental/index.js"
}
},
"repository": "open-telemetry/opentelemetry-js",
"scripts": {
"clean": "tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"precompile": "cross-var lerna run version --scope $npm_package_name --include-dependencies",
"compile": "tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"lint:fix": "eslint . --ext .ts --fix",
"lint": "eslint . --ext .ts",
"test:browser": "karma start --single-run",
"test": "nyc mocha 'test/**/*.test.ts'",
"test:webworker": "karma start karma.worker.js --single-run",
"cycle-check": "dpdm --exit-code circular:1 src/index.ts",
"version": "node ../scripts/version-update.js",
"prewatch": "npm run precompile",
"watch": "tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"peer-api-check": "node ../scripts/peer-api-check.js"
},
"keywords": [
"opentelemetry",
"nodejs",
"browser",
"tracing",
"profiling",
"stats",
"monitoring"
],
"author": "OpenTelemetry Authors",
"license": "Apache-2.0",
"engines": {
"node": ">=8.0.0"
},
"files": [
"build/esm/**/*.js",
"build/esm/**/*.js.map",
"build/esm/**/*.d.ts",
"build/esnext/**/*.js",
"build/esnext/**/*.js.map",
"build/esnext/**/*.d.ts",
"build/src/**/*.js",
"build/src/**/*.js.map",
"build/src/**/*.d.ts",
"LICENSE",
"README.md"
],
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@types/mocha": "10.0.10",
"@types/node": "^8.10.66",
"@types/sinon": "17.0.4",
"@types/webpack": "5.28.5",
"@types/webpack-env": "1.16.3",
"babel-plugin-istanbul": "7.0.0",
"cross-var": "1.1.0",
"dpdm": "3.13.1",
"karma": "6.4.4",
"karma-chrome-launcher": "3.1.0",
"karma-coverage": "2.2.1",
"karma-mocha": "2.0.1",
"karma-mocha-webworker": "1.3.0",
"karma-spec-reporter": "0.0.36",
"karma-webpack": "5.0.1",
"lerna": "6.6.2",
"memfs": "3.5.3",
"mocha": "11.1.0",
"nyc": "17.1.0",
"sinon": "18.0.1",
"ts-loader": "9.5.2",
"typescript": "5.0.4",
"unionfs": "4.5.4",
"webpack": "5.99.9"
},
"homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/api",
"sideEffects": false
}

View File

@ -1,77 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Meter, MeterOptions } from '../metrics/Meter';
import { MeterProvider } from '../metrics/MeterProvider';
import { NOOP_METER_PROVIDER } from '../metrics/NoopMeterProvider';
import {
getGlobal,
registerGlobal,
unregisterGlobal,
} from '../internal/global-utils';
import { DiagAPI } from './diag';
const API_NAME = 'metrics';
/**
* Singleton object which represents the entry point to the OpenTelemetry Metrics API
*/
export class MetricsAPI {
private static _instance?: MetricsAPI;
/** Empty private constructor prevents end users from constructing a new instance of the API */
private constructor() {}
/** Get the singleton instance of the Metrics API */
public static getInstance(): MetricsAPI {
if (!this._instance) {
this._instance = new MetricsAPI();
}
return this._instance;
}
/**
* Set the current global meter provider.
* Returns true if the meter provider was successfully registered, else false.
*/
public setGlobalMeterProvider(provider: MeterProvider): boolean {
return registerGlobal(API_NAME, provider, DiagAPI.instance());
}
/**
* Returns the global meter provider.
*/
public getMeterProvider(): MeterProvider {
return getGlobal(API_NAME) || NOOP_METER_PROVIDER;
}
/**
* Returns a meter from the global meter provider.
*/
public getMeter(
name: string,
version?: string,
options?: MeterOptions
): Meter {
return this.getMeterProvider().getMeter(name, version, options);
}
/** Remove the global meter provider */
public disable(): void {
unregisterGlobal(API_NAME, DiagAPI.instance());
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Defines High-Resolution Time.
*
* The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970.
* The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds.
* For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150.
* The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds:
* HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210.
* The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds:
* HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000.
* This is represented in HrTime format as [1609504210, 150000000].
*
* @since 1.0.0
*/
export type HrTime = [number, number];
/**
* Defines TimeInput.
*
* hrtime, epoch milliseconds, performance.now() or Date
*
* @since 1.0.0
*/
export type TimeInput = HrTime | number | Date;

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Split module-level variable definition into separate files to allow
// tree-shaking on each api instance.
import { ContextAPI } from './api/context';
/**
* Entrypoint for context API
* @since 1.0.0
*/
export const context = ContextAPI.getInstance();

View File

@ -1,28 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Split module-level variable definition into separate files to allow
// tree-shaking on each api instance.
import { DiagAPI } from './api/diag';
/**
* Entrypoint for Diag API.
* Defines Diagnostic handler used for internal diagnostic logging operations.
* The default provides a Noop DiagLogger implementation which may be changed via the
* diag.setLogger(logger: DiagLogger) function.
*
* @since 1.0.0
*/
export const diag = DiagAPI.instance();

View File

@ -1,23 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Any exports here may change at any time and without warning
* @module @opentelemetry/api/experimental
*/
export { wrapTracer, SugaredTracer } from './trace/SugaredTracer';
export type { SugaredSpanOptions } from './trace/SugaredOptions';

View File

@ -1,29 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Span, SpanOptions } from '../../';
/**
* Options needed for span creation
*/
export interface SugaredSpanOptions extends SpanOptions {
/**
* function to overwrite default exception behavior to record the exception. No exceptions should be thrown in the function.
* @param e Error which triggered this exception
* @param span current span from context
*/
onException?: (e: Error, span: Span) => void;
}

View File

@ -1,215 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SugaredSpanOptions } from './SugaredOptions';
import { context, Context, Span, SpanStatusCode, Tracer } from '../../';
const defaultOnException = (e: Error, span: Span) => {
span.recordException(e);
span.setStatus({
code: SpanStatusCode.ERROR,
});
};
/**
* return a new SugaredTracer created from the supplied one
* @param tracer
*/
export function wrapTracer(tracer: Tracer): SugaredTracer {
return new SugaredTracer(tracer);
}
export class SugaredTracer implements Tracer {
private readonly _tracer: Tracer;
constructor(tracer: Tracer) {
this._tracer = tracer;
this.startSpan = tracer.startSpan.bind(this._tracer);
this.startActiveSpan = tracer.startActiveSpan.bind(this._tracer);
}
startActiveSpan: Tracer['startActiveSpan'];
startSpan: Tracer['startSpan'];
/**
* Starts a new {@link Span} and calls the given function passing it the
* created span as first argument.
* Additionally, the new span gets set in context and this context is activated
* for the duration of the function call.
* The span will be closed after the function has executed.
* If an exception occurs, it is recorded, the status is set to ERROR and the exception is rethrown.
*
* @param name The name of the span
* @param [options] SugaredSpanOptions used for span creation
* @param [context] Context to use to extract parent
* @param fn function called in the context of the span and receives the newly created span as an argument
* @returns return value of fn
* @example
* const something = tracer.withActiveSpan('op', span => {
* // do some work
* });
* @example
* const something = await tracer.withActiveSpan('op', span => {
* // do some async work
* });
*/
withActiveSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
fn: F
): ReturnType<F>;
withActiveSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
options: SugaredSpanOptions,
fn: F
): ReturnType<F>;
withActiveSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
options: SugaredSpanOptions,
context: Context,
fn: F
): ReturnType<F>;
withActiveSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
arg2: F | SugaredSpanOptions,
arg3?: F | Context,
arg4?: F
): ReturnType<F> {
const { opts, ctx, fn } = massageParams(arg2, arg3, arg4);
return this._tracer.startActiveSpan(name, opts, ctx, (span: Span) =>
handleFn(span, opts, fn)
) as ReturnType<F>;
}
/**
* Starts a new {@link Span} and ends it after execution of fn without setting it on context.
* The span will be closed after the function has executed.
* If an exception occurs, it is recorded, the status is et to ERROR and rethrown.
*
* This method does NOT modify the current Context.
*
* @param name The name of the span
* @param [options] SugaredSpanOptions used for span creation
* @param [context] Context to use to extract parent
* @param fn function called in the context of the span and receives the newly created span as an argument
* @returns Span The newly created span
* @example
* const something = tracer.withSpan('op', span => {
* // do some work
* });
* @example
* const something = await tracer.withSpan('op', span => {
* // do some async work
* });
*/
withSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
fn: F
): ReturnType<F>;
withSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
options: SugaredSpanOptions,
fn: F
): ReturnType<F>;
withSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
options: SugaredSpanOptions,
context: Context,
fn: F
): ReturnType<F>;
withSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
options: SugaredSpanOptions,
context: Context,
fn: F
): ReturnType<F>;
withSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
arg2: SugaredSpanOptions | F,
arg3?: Context | F,
arg4?: F
): ReturnType<F> {
const { opts, ctx, fn } = massageParams(arg2, arg3, arg4);
const span = this._tracer.startSpan(name, opts, ctx);
return handleFn(span, opts, fn) as ReturnType<F>;
}
}
/**
* Massages parameters of withSpan and withActiveSpan to allow signature overwrites
* @param arg
* @param arg2
* @param arg3
*/
function massageParams<F extends (span: Span) => ReturnType<F>>(
arg: F | SugaredSpanOptions,
arg2?: F | Context,
arg3?: F
) {
let opts: SugaredSpanOptions | undefined;
let ctx: Context | undefined;
let fn: F;
if (!arg2 && !arg3) {
fn = arg as F;
} else if (!arg3) {
opts = arg as SugaredSpanOptions;
fn = arg2 as F;
} else {
opts = arg as SugaredSpanOptions;
ctx = arg2 as Context;
fn = arg3 as F;
}
opts = opts ?? {};
ctx = ctx ?? context.active();
return { opts, ctx, fn };
}
/**
* Executes fn, returns results and runs onException in the case of exception to allow overwriting of error handling
* @param span
* @param opts
* @param fn
*/
function handleFn<F extends (span: Span) => ReturnType<F>>(
span: Span,
opts: SugaredSpanOptions,
fn: F
): ReturnType<F> {
const onException = opts.onException ?? defaultOnException;
const errorHandler = (e: Error) => {
onException(e, span);
span.end();
throw e;
};
try {
const ret = fn(span) as Promise<ReturnType<F>>;
// if fn is an async function, attach a recordException and spanEnd callback to the promise
if (typeof ret?.then === 'function') {
return ret.then(val => {
span.end();
return val;
}, errorHandler) as ReturnType<F>;
}
span.end();
return ret as ReturnType<F>;
} catch (e) {
// add throw to signal the compiler that this will throw in the inner scope
throw errorHandler(e);
}
}

View File

@ -1,133 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @module @opentelemetry/api
*/
export type {
BaggageEntry,
BaggageEntryMetadata,
Baggage,
} from './baggage/types';
export { baggageEntryMetadataFromString } from './baggage/utils';
export type { Exception } from './common/Exception';
export type { HrTime, TimeInput } from './common/Time';
export type { Attributes, AttributeValue } from './common/Attributes';
// Context APIs
export { createContextKey, ROOT_CONTEXT } from './context/context';
export type { Context, ContextManager } from './context/types';
export type { ContextAPI } from './api/context';
// Diag APIs
export { DiagConsoleLogger } from './diag/consoleLogger';
export { DiagLogLevel } from './diag/types';
export type {
DiagLogFunction,
DiagLogger,
ComponentLoggerOptions,
DiagLoggerOptions,
} from './diag/types';
export type { DiagAPI } from './api/diag';
// Metrics APIs
export { createNoopMeter } from './metrics/NoopMeter';
export type { MeterOptions, Meter } from './metrics/Meter';
export type { MeterProvider } from './metrics/MeterProvider';
export { ValueType } from './metrics/Metric';
export type {
Counter,
Gauge,
Histogram,
MetricOptions,
Observable,
ObservableCounter,
ObservableGauge,
ObservableUpDownCounter,
UpDownCounter,
BatchObservableCallback,
MetricAdvice,
MetricAttributes,
MetricAttributeValue,
ObservableCallback,
} from './metrics/Metric';
export type {
BatchObservableResult,
ObservableResult,
} from './metrics/ObservableResult';
export type { MetricsAPI } from './api/metrics';
// Propagation APIs
export {
defaultTextMapGetter,
defaultTextMapSetter,
} from './propagation/TextMapPropagator';
export type {
TextMapPropagator,
TextMapSetter,
TextMapGetter,
} from './propagation/TextMapPropagator';
export type { PropagationAPI } from './api/propagation';
// Trace APIs
export type { SpanAttributes, SpanAttributeValue } from './trace/attributes';
export type { Link } from './trace/link';
export { ProxyTracer, type TracerDelegator } from './trace/ProxyTracer';
export { ProxyTracerProvider } from './trace/ProxyTracerProvider';
export type { Sampler } from './trace/Sampler';
export { SamplingDecision, type SamplingResult } from './trace/SamplingResult';
export type { SpanContext } from './trace/span_context';
export { SpanKind } from './trace/span_kind';
export type { Span } from './trace/span';
export type { SpanOptions } from './trace/SpanOptions';
export { type SpanStatus, SpanStatusCode } from './trace/status';
export { TraceFlags } from './trace/trace_flags';
export type { TraceState } from './trace/trace_state';
export { createTraceState } from './trace/internal/utils';
export type { TracerProvider } from './trace/tracer_provider';
export type { Tracer } from './trace/tracer';
export type { TracerOptions } from './trace/tracer_options';
export {
isSpanContextValid,
isValidTraceId,
isValidSpanId,
} from './trace/spancontext-utils';
export {
INVALID_SPANID,
INVALID_TRACEID,
INVALID_SPAN_CONTEXT,
} from './trace/invalid-span-constants';
export type { TraceAPI } from './api/trace';
// Split module-level variable definition into separate files to allow
// tree-shaking on each api instance.
import { context } from './context-api';
import { diag } from './diag-api';
import { metrics } from './metrics-api';
import { propagation } from './propagation-api';
import { trace } from './trace-api';
// Named export.
export { context, diag, metrics, propagation, trace };
// Default export.
export default {
context,
diag,
metrics,
propagation,
trace,
};

View File

@ -1,25 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Split module-level variable definition into separate files to allow
// tree-shaking on each api instance.
import { MetricsAPI } from './api/metrics';
/**
* Entrypoint for metrics API
*
* @since 1.3.0
*/
export const metrics = MetricsAPI.getInstance();

View File

@ -1,190 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
BatchObservableCallback,
Counter,
Gauge,
Histogram,
MetricAttributes,
MetricOptions,
Observable,
ObservableCounter,
ObservableGauge,
ObservableUpDownCounter,
UpDownCounter,
} from './Metric';
/**
* An interface describes additional metadata of a meter.
*
* @since 1.3.0
*/
export interface MeterOptions {
/**
* The schemaUrl of the meter or instrumentation library
*/
schemaUrl?: string;
}
/**
* An interface to allow the recording metrics.
*
* {@link Metric}s are used for recording pre-defined aggregation (`Counter`),
* or raw values (`Histogram`) in which the aggregation and attributes
* for the exported metric are deferred.
*
* @since 1.3.0
*/
export interface Meter {
/**
* Creates and returns a new `Gauge`.
* @param name the name of the metric.
* @param [options] the metric options.
*/
createGauge<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): Gauge<AttributesTypes>;
/**
* Creates and returns a new `Histogram`.
* @param name the name of the metric.
* @param [options] the metric options.
*/
createHistogram<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): Histogram<AttributesTypes>;
/**
* Creates a new `Counter` metric. Generally, this kind of metric when the
* value is a quantity, the sum is of primary interest, and the event count
* and value distribution are not of primary interest.
* @param name the name of the metric.
* @param [options] the metric options.
*/
createCounter<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): Counter<AttributesTypes>;
/**
* Creates a new `UpDownCounter` metric. UpDownCounter is a synchronous
* instrument and very similar to Counter except that Add(increment)
* supports negative increments. It is generally useful for capturing changes
* in an amount of resources used, or any quantity that rises and falls
* during a request.
* Example uses for UpDownCounter:
* <ol>
* <li> count the number of active requests. </li>
* <li> count memory in use by instrumenting new and delete. </li>
* <li> count queue size by instrumenting enqueue and dequeue. </li>
* <li> count semaphore up and down operations. </li>
* </ol>
*
* @param name the name of the metric.
* @param [options] the metric options.
*/
createUpDownCounter<
AttributesTypes extends MetricAttributes = MetricAttributes,
>(
name: string,
options?: MetricOptions
): UpDownCounter<AttributesTypes>;
/**
* Creates a new `ObservableGauge` metric.
*
* The callback SHOULD be safe to be invoked concurrently.
*
* @param name the name of the metric.
* @param [options] the metric options.
*/
createObservableGauge<
AttributesTypes extends MetricAttributes = MetricAttributes,
>(
name: string,
options?: MetricOptions
): ObservableGauge<AttributesTypes>;
/**
* Creates a new `ObservableCounter` metric.
*
* The callback SHOULD be safe to be invoked concurrently.
*
* @param name the name of the metric.
* @param [options] the metric options.
*/
createObservableCounter<
AttributesTypes extends MetricAttributes = MetricAttributes,
>(
name: string,
options?: MetricOptions
): ObservableCounter<AttributesTypes>;
/**
* Creates a new `ObservableUpDownCounter` metric.
*
* The callback SHOULD be safe to be invoked concurrently.
*
* @param name the name of the metric.
* @param [options] the metric options.
*/
createObservableUpDownCounter<
AttributesTypes extends MetricAttributes = MetricAttributes,
>(
name: string,
options?: MetricOptions
): ObservableUpDownCounter<AttributesTypes>;
/**
* Sets up a function that will be called whenever a metric collection is
* initiated.
*
* If the function is already in the list of callbacks for this Observable,
* the function is not added a second time.
*
* Only the associated observables can be observed in the callback.
* Measurements of observables that are not associated observed in the
* callback are dropped.
*
* @param callback the batch observable callback
* @param observables the observables associated with this batch observable callback
*/
addBatchObservableCallback<
AttributesTypes extends MetricAttributes = MetricAttributes,
>(
callback: BatchObservableCallback<AttributesTypes>,
observables: Observable<AttributesTypes>[]
): void;
/**
* Removes a callback previously registered with {@link Meter.addBatchObservableCallback}.
*
* The callback to be removed is identified using a combination of the callback itself,
* and the set of the observables associated with it.
*
* @param callback the batch observable callback
* @param observables the observables associated with this batch observable callback
*/
removeBatchObservableCallback<
AttributesTypes extends MetricAttributes = MetricAttributes,
>(
callback: BatchObservableCallback<AttributesTypes>,
observables: Observable<AttributesTypes>[]
): void;
}

View File

@ -1,35 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Meter, MeterOptions } from './Meter';
/**
* A registry for creating named {@link Meter}s.
*
* @since 1.3.0
*/
export interface MeterProvider {
/**
* Returns a Meter, creating one if one with the given name, version, and
* schemaUrl pair is not already created.
*
* @param name The name of the meter or instrumentation library.
* @param version The version of the meter or instrumentation library.
* @param options The options of the meter or instrumentation library.
* @returns Meter A Meter with the given name and version
*/
getMeter(name: string, version?: string, options?: MeterOptions): Meter;
}

View File

@ -1,209 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Attributes, AttributeValue } from '../common/Attributes';
import { Context } from '../context/types';
import { BatchObservableResult, ObservableResult } from './ObservableResult';
/**
* Advisory options influencing aggregation configuration parameters.
*
* @since 1.7.0
* @experimental
*/
export interface MetricAdvice {
/**
* Hint the explicit bucket boundaries for SDK if the metric is been
* aggregated with a HistogramAggregator.
*/
explicitBucketBoundaries?: number[];
}
/**
* Options needed for metric creation
*
* @since 1.3.0
*/
export interface MetricOptions {
/**
* The description of the Metric.
* @default ''
*/
description?: string;
/**
* The unit of the Metric values.
* @default ''
*/
unit?: string;
/**
* Indicates the type of the recorded value.
* @default {@link ValueType.DOUBLE}
*/
valueType?: ValueType;
/**
* The advice influencing aggregation configuration parameters.
* @experimental
* @since 1.7.0
*/
advice?: MetricAdvice;
}
/**
* The Type of value. It describes how the data is reported.
*
* @since 1.3.0
*/
export enum ValueType {
INT,
DOUBLE,
}
/**
* Counter is the most common synchronous instrument. This instrument supports
* an `Add(increment)` function for reporting a sum, and is restricted to
* non-negative increments. The default aggregation is Sum, as for any additive
* instrument.
*
* Example uses for Counter:
* <ol>
* <li> count the number of bytes received. </li>
* <li> count the number of requests completed. </li>
* <li> count the number of accounts created. </li>
* <li> count the number of checkpoints run. </li>
* <li> count the number of 5xx errors. </li>
* <ol>
*
* @since 1.3.0
*/
export interface Counter<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Increment value of counter by the input. Inputs must not be negative.
*/
add(value: number, attributes?: AttributesTypes, context?: Context): void;
}
/**
* @since 1.3.0
*/
export interface UpDownCounter<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Increment value of counter by the input. Inputs may be negative.
*/
add(value: number, attributes?: AttributesTypes, context?: Context): void;
}
/**
* @since 1.9.0
*/
export interface Gauge<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Records a measurement.
*/
record(value: number, attributes?: AttributesTypes, context?: Context): void;
}
/**
* @since 1.3.0
*/
export interface Histogram<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Records a measurement. Value of the measurement must not be negative.
*/
record(value: number, attributes?: AttributesTypes, context?: Context): void;
}
/**
* @deprecated please use {@link Attributes}
* @since 1.3.0
*/
export type MetricAttributes = Attributes;
/**
* @deprecated please use {@link AttributeValue}
* @since 1.3.0
*/
export type MetricAttributeValue = AttributeValue;
/**
* The observable callback for Observable instruments.
*
* @since 1.3.0
*/
export type ObservableCallback<
AttributesTypes extends MetricAttributes = MetricAttributes,
> = (
observableResult: ObservableResult<AttributesTypes>
) => void | Promise<void>;
/**
* The observable callback for a batch of Observable instruments.
*
* @since 1.3.0
*/
export type BatchObservableCallback<
AttributesTypes extends MetricAttributes = MetricAttributes,
> = (
observableResult: BatchObservableResult<AttributesTypes>
) => void | Promise<void>;
/**
* @since 1.3.0
*/
export interface Observable<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Sets up a function that will be called whenever a metric collection is initiated.
*
* If the function is already in the list of callbacks for this Observable, the function is not added a second time.
*/
addCallback(callback: ObservableCallback<AttributesTypes>): void;
/**
* Removes a callback previously registered with {@link Observable.addCallback}.
*/
removeCallback(callback: ObservableCallback<AttributesTypes>): void;
}
/**
* @since 1.3.0
*/
export type ObservableCounter<
AttributesTypes extends MetricAttributes = MetricAttributes,
> = Observable<AttributesTypes>;
/**
* @since 1.3.0
*/
export type ObservableUpDownCounter<
AttributesTypes extends MetricAttributes = MetricAttributes,
> = Observable<AttributesTypes>;
/**
* @since 1.3.0
*/
export type ObservableGauge<
AttributesTypes extends MetricAttributes = MetricAttributes,
> = Observable<AttributesTypes>;

View File

@ -1,172 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Meter } from './Meter';
import {
BatchObservableCallback,
Counter,
Gauge,
Histogram,
MetricAttributes,
MetricOptions,
Observable,
ObservableCallback,
ObservableCounter,
ObservableGauge,
ObservableUpDownCounter,
UpDownCounter,
} from './Metric';
/**
* NoopMeter is a noop implementation of the {@link Meter} interface. It reuses
* constant NoopMetrics for all of its methods.
*/
export class NoopMeter implements Meter {
constructor() {}
/**
* @see {@link Meter.createGauge}
*/
createGauge(_name: string, _options?: MetricOptions): Gauge {
return NOOP_GAUGE_METRIC;
}
/**
* @see {@link Meter.createHistogram}
*/
createHistogram(_name: string, _options?: MetricOptions): Histogram {
return NOOP_HISTOGRAM_METRIC;
}
/**
* @see {@link Meter.createCounter}
*/
createCounter(_name: string, _options?: MetricOptions): Counter {
return NOOP_COUNTER_METRIC;
}
/**
* @see {@link Meter.createUpDownCounter}
*/
createUpDownCounter(_name: string, _options?: MetricOptions): UpDownCounter {
return NOOP_UP_DOWN_COUNTER_METRIC;
}
/**
* @see {@link Meter.createObservableGauge}
*/
createObservableGauge(
_name: string,
_options?: MetricOptions
): ObservableGauge {
return NOOP_OBSERVABLE_GAUGE_METRIC;
}
/**
* @see {@link Meter.createObservableCounter}
*/
createObservableCounter(
_name: string,
_options?: MetricOptions
): ObservableCounter {
return NOOP_OBSERVABLE_COUNTER_METRIC;
}
/**
* @see {@link Meter.createObservableUpDownCounter}
*/
createObservableUpDownCounter(
_name: string,
_options?: MetricOptions
): ObservableUpDownCounter {
return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC;
}
/**
* @see {@link Meter.addBatchObservableCallback}
*/
addBatchObservableCallback(
_callback: BatchObservableCallback,
_observables: Observable[]
): void {}
/**
* @see {@link Meter.removeBatchObservableCallback}
*/
removeBatchObservableCallback(_callback: BatchObservableCallback): void {}
}
export class NoopMetric {}
export class NoopCounterMetric extends NoopMetric implements Counter {
add(_value: number, _attributes: MetricAttributes): void {}
}
export class NoopUpDownCounterMetric
extends NoopMetric
implements UpDownCounter
{
add(_value: number, _attributes: MetricAttributes): void {}
}
export class NoopGaugeMetric extends NoopMetric implements Gauge {
record(_value: number, _attributes: MetricAttributes): void {}
}
export class NoopHistogramMetric extends NoopMetric implements Histogram {
record(_value: number, _attributes: MetricAttributes): void {}
}
export class NoopObservableMetric {
addCallback(_callback: ObservableCallback) {}
removeCallback(_callback: ObservableCallback) {}
}
export class NoopObservableCounterMetric
extends NoopObservableMetric
implements ObservableCounter {}
export class NoopObservableGaugeMetric
extends NoopObservableMetric
implements ObservableGauge {}
export class NoopObservableUpDownCounterMetric
extends NoopObservableMetric
implements ObservableUpDownCounter {}
export const NOOP_METER = new NoopMeter();
// Synchronous instruments
export const NOOP_COUNTER_METRIC = new NoopCounterMetric();
export const NOOP_GAUGE_METRIC = new NoopGaugeMetric();
export const NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric();
export const NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric();
// Asynchronous instruments
export const NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric();
export const NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric();
export const NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC =
new NoopObservableUpDownCounterMetric();
/**
* Create a no-op Meter
*
* @since 1.3.0
*/
export function createNoopMeter(): Meter {
return NOOP_METER;
}

View File

@ -1,31 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Meter, MeterOptions } from './Meter';
import { MeterProvider } from './MeterProvider';
import { NOOP_METER } from './NoopMeter';
/**
* An implementation of the {@link MeterProvider} which returns an impotent Meter
* for all calls to `getMeter`
*/
export class NoopMeterProvider implements MeterProvider {
getMeter(_name: string, _version?: string, _options?: MeterOptions): Meter {
return NOOP_METER;
}
}
export const NOOP_METER_PROVIDER = new NoopMeterProvider();

View File

@ -1,63 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { MetricAttributes, Observable } from './Metric';
/**
* Interface that is being used in callback function for Observable Metric.
*
* @since 1.3.0
*/
export interface ObservableResult<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Observe a measurement of the value associated with the given attributes.
*
* @param value The value to be observed.
* @param attributes The attributes associated with the value. If more than
* one values associated with the same attributes values, SDK may pick the
* last one or simply drop the entire observable result.
*/
observe(
this: ObservableResult<AttributesTypes>,
value: number,
attributes?: AttributesTypes
): void;
}
/**
* Interface that is being used in batch observable callback function.
*/
export interface BatchObservableResult<
AttributesTypes extends MetricAttributes = MetricAttributes,
> {
/**
* Observe a measurement of the value associated with the given attributes.
*
* @param metric The observable metric to be observed.
* @param value The value to be observed.
* @param attributes The attributes associated with the value. If more than
* one values associated with the same attributes values, SDK may pick the
* last one or simply drop the entire observable result.
*/
observe(
this: BatchObservableResult<AttributesTypes>,
metric: Observable<AttributesTypes>,
value: number,
attributes?: AttributesTypes
): void;
}

View File

@ -1,38 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Updates to this file should also be replicated to @opentelemetry/core too.
/**
* - globalThis (New standard)
* - self (Will return the current window instance for supported browsers)
* - window (fallback for older browser implementations)
* - global (NodeJS implementation)
* - <object> (When all else fails)
*/
/** only globals that common to node and browsers are allowed */
// eslint-disable-next-line node/no-unsupported-features/es-builtins, no-undef
export const _globalThis: typeof globalThis =
typeof globalThis === 'object'
? globalThis
: typeof self === 'object'
? self
: typeof window === 'object'
? window
: typeof global === 'object'
? (global as unknown as typeof globalThis)
: ({} as typeof globalThis);

View File

@ -1,17 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { _globalThis } from './globalThis';

View File

@ -1,17 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { _globalThis } from './globalThis';

View File

@ -1,25 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Split module-level variable definition into separate files to allow
// tree-shaking on each api instance.
import { PropagationAPI } from './api/propagation';
/**
* Entrypoint for propagation API
*
* @since 1.0.0
*/
export const propagation = PropagationAPI.getInstance();

View File

@ -1,26 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Split module-level variable definition into separate files to allow
// tree-shaking on each api instance.
import { TraceAPI } from './api/trace';
/**
* Entrypoint for trace API
*
* @since 1.0.0
*/
export const trace = TraceAPI.getInstance();

View File

@ -1,29 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Attributes, AttributeValue } from '../common/Attributes';
/**
* @deprecated please use {@link Attributes}
* @since 1.0.0
*/
export type SpanAttributes = Attributes;
/**
* @deprecated please use {@link AttributeValue}
* @since 1.0.0
*/
export type SpanAttributeValue = AttributeValue;

View File

@ -1,110 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TraceState } from '../trace_state';
import { validateKey, validateValue } from './tracestate-validators';
const MAX_TRACE_STATE_ITEMS = 32;
const MAX_TRACE_STATE_LEN = 512;
const LIST_MEMBERS_SEPARATOR = ',';
const LIST_MEMBER_KEY_VALUE_SPLITTER = '=';
/**
* TraceState must be a class and not a simple object type because of the spec
* requirement (https://www.w3.org/TR/trace-context/#tracestate-field).
*
* Here is the list of allowed mutations:
* - New key-value pair should be added into the beginning of the list
* - The value of any key can be updated. Modified keys MUST be moved to the
* beginning of the list.
*/
export class TraceStateImpl implements TraceState {
private _internalState: Map<string, string> = new Map();
constructor(rawTraceState?: string) {
if (rawTraceState) this._parse(rawTraceState);
}
set(key: string, value: string): TraceStateImpl {
// TODO: Benchmark the different approaches(map vs list) and
// use the faster one.
const traceState = this._clone();
if (traceState._internalState.has(key)) {
traceState._internalState.delete(key);
}
traceState._internalState.set(key, value);
return traceState;
}
unset(key: string): TraceStateImpl {
const traceState = this._clone();
traceState._internalState.delete(key);
return traceState;
}
get(key: string): string | undefined {
return this._internalState.get(key);
}
serialize(): string {
return this._keys()
.reduce((agg: string[], key) => {
agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key));
return agg;
}, [])
.join(LIST_MEMBERS_SEPARATOR);
}
private _parse(rawTraceState: string) {
if (rawTraceState.length > MAX_TRACE_STATE_LEN) return;
this._internalState = rawTraceState
.split(LIST_MEMBERS_SEPARATOR)
.reverse() // Store in reverse so new keys (.set(...)) will be placed at the beginning
.reduce((agg: Map<string, string>, part: string) => {
const listMember = part.trim(); // Optional Whitespace (OWS) handling
const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER);
if (i !== -1) {
const key = listMember.slice(0, i);
const value = listMember.slice(i + 1, part.length);
if (validateKey(key) && validateValue(value)) {
agg.set(key, value);
} else {
// TODO: Consider to add warning log
}
}
return agg;
}, new Map());
// Because of the reverse() requirement, trunc must be done after map is created
if (this._internalState.size > MAX_TRACE_STATE_ITEMS) {
this._internalState = new Map(
Array.from(this._internalState.entries())
.reverse() // Use reverse same as original tracestate parse chain
.slice(0, MAX_TRACE_STATE_ITEMS)
);
}
}
private _keys(): string[] {
return Array.from(this._internalState.keys()).reverse();
}
private _clone(): TraceStateImpl {
const traceState = new TraceStateImpl();
traceState._internalState = new Map(this._internalState);
return traceState;
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const VALID_KEY_CHAR_RANGE = '[_0-9a-z-*/]';
const VALID_KEY = `[a-z]${VALID_KEY_CHAR_RANGE}{0,255}`;
const VALID_VENDOR_KEY = `[a-z0-9]${VALID_KEY_CHAR_RANGE}{0,240}@[a-z]${VALID_KEY_CHAR_RANGE}{0,13}`;
const VALID_KEY_REGEX = new RegExp(`^(?:${VALID_KEY}|${VALID_VENDOR_KEY})$`);
const VALID_VALUE_BASE_REGEX = /^[ -~]{0,255}[!-~]$/;
const INVALID_VALUE_COMMA_EQUAL_REGEX = /,|=/;
/**
* Key is opaque string up to 256 characters printable. It MUST begin with a
* lowercase letter, and can only contain lowercase letters a-z, digits 0-9,
* underscores _, dashes -, asterisks *, and forward slashes /.
* For multi-tenant vendor scenarios, an at sign (@) can be used to prefix the
* vendor name. Vendors SHOULD set the tenant ID at the beginning of the key.
* see https://www.w3.org/TR/trace-context/#key
*/
export function validateKey(key: string): boolean {
return VALID_KEY_REGEX.test(key);
}
/**
* Value is opaque string up to 256 characters printable ASCII RFC0020
* characters (i.e., the range 0x20 to 0x7E) except comma , and =.
*/
export function validateValue(value: string): boolean {
return (
VALID_VALUE_BASE_REGEX.test(value) &&
!INVALID_VALUE_COMMA_EQUAL_REGEX.test(value)
);
}

View File

@ -1,25 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TraceState } from '../trace_state';
import { TraceStateImpl } from './tracestate-impl';
/**
* @since 1.1.0
*/
export function createTraceState(rawTraceState?: string): TraceState {
return new TraceStateImpl(rawTraceState);
}

View File

@ -1,27 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* An interface describes additional metadata of a tracer.
*
* @since 1.3.0
*/
export interface TracerOptions {
/**
* The schemaUrl of the tracer or instrumentation library
*/
schemaUrl?: string;
}

View File

@ -1,157 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { wrapTracer } from '../../../../src/experimental';
import * as assert from 'assert';
import { NoopTracerProvider } from '../../../../src/trace/NoopTracerProvider';
import { NoopTracer } from '../../../../src/trace/NoopTracer';
import { Span } from '../../../../src';
import { Context, context, SpanOptions } from '../../../../src';
describe('SugaredTracer', function () {
class TestTracer extends NoopTracer {
public calls: IArguments[] = [];
override startActiveSpan<F extends (span: Span) => ReturnType<F>>(
name: string,
arg2?: SpanOptions,
arg3?: Context,
arg4?: F
): ReturnType<F> | undefined {
this.calls.push(arguments);
return super.startActiveSpan(name, arg2, arg3, arg4 as F);
}
override startSpan(
name: string,
options?: SpanOptions,
_context: Context = context.active()
): Span {
this.calls.push(arguments);
return super.startSpan(name, options, _context);
}
}
class TestTracerProvider extends NoopTracerProvider {
override getTracer() {
return new TestTracer();
}
}
const tracer = new TestTracerProvider().getTracer();
const sugaredTracer = wrapTracer(tracer);
afterEach(() => {
tracer.calls = [];
});
describe('wrapTracer()', function () {
it('still provides standard tracer functions', function () {
assert.ok(
typeof sugaredTracer.startSpan === 'function',
'startSpan is missing'
);
assert.ok(
typeof sugaredTracer.startActiveSpan === 'function',
'startActiveSpan is missing'
);
});
});
describe('withActiveSpan()', function () {
it('proxies value with minimal args', function () {
const result = sugaredTracer.withActiveSpan('test', span => {
return 'result';
});
assert.strictEqual(result, 'result', 'Unexpected result');
assert.strictEqual(tracer.calls.length, 2); // ensure that startActiveSpan and startSpan is called
});
it('proxies value with context', function () {
const result = sugaredTracer.withActiveSpan(
'test',
{ onException: e => e },
span => {
return 'result';
}
);
assert.strictEqual(result, 'result', 'Unexpected result');
assert.strictEqual(tracer.calls.length, 2); // ensure that startActiveSpan and startSpan is called
});
it('proxies value with context', function () {
const result = sugaredTracer.withActiveSpan(
'test',
{ onException: e => e },
context.active(),
span => {
return 'result';
}
);
assert.strictEqual(result, 'result', 'Unexpected result');
assert.strictEqual(tracer.calls.length, 2); // ensure that startActiveSpan and startSpan is called
});
it('returns promise if wrapped function returns promise', async function () {
const result = sugaredTracer.withActiveSpan('test', span => {
return Promise.resolve('result');
});
assert.ok(typeof result.then == 'function');
assert.strictEqual(await result, 'result', 'Unexpected result');
});
it('returns void', function () {
const result = sugaredTracer.withActiveSpan('test', (span: Span) => {
return;
});
assert.strictEqual(result, undefined);
});
});
describe('withSpan()', function () {
it('proxies value', function () {
const result = sugaredTracer.withSpan('test', span => {
return 'result';
});
assert.strictEqual(result, 'result', 'Unexpected result');
});
it('returns promise if wrapped function returns promise', async function () {
const result = sugaredTracer.withSpan('test', span => {
return Promise.resolve('result');
});
assert.ok(typeof result.then == 'function');
assert.strictEqual(await result, 'result', 'Unexpected result');
});
it('returns void', function () {
const result = sugaredTracer.withSpan('test', (span: Span) => {
return;
});
assert.strictEqual(result, undefined);
});
});
});

View File

@ -1,109 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Counter, UpDownCounter, Histogram } from '../../../src';
describe('Metric', function () {
describe('Counter', function () {
it('enable not to define any type', function () {
const counter: Counter = {
add(_value: number, _attribute: unknown) {},
};
counter.add(1, { 'some-attribute': 'value' });
});
it('enable to use with type', function () {
type Attributes = {
'some-attribute': string;
};
const counter: Counter<Attributes> = {
add(_value: number, _attribute: Attributes) {},
};
counter.add(1, { 'some-attribute': 'value' });
});
it('disable wrong attributes by typing', function () {
type Attributes = {
'some-attribute': string;
};
const counter: Counter<Attributes> = {
add(_value: number, _attribute: Attributes) {},
};
// @ts-expect-error Expecting the type of Attributes
counter.add(1, { 'another-attribute': 'value' });
});
});
describe('UpDownCounter', function () {
it('enable not to define any type', function () {
const counter: UpDownCounter = {
add(_value: number, _attribute: unknown) {},
};
counter.add(1, { 'some-attribute': 'value' });
});
it('enable to use with type', function () {
type Attributes = {
'some-attribute': string;
};
const counter: UpDownCounter<Attributes> = {
add(_value: number, _attribute: Attributes) {},
};
counter.add(1, { 'some-attribute': 'value' });
});
it('disable wrong attributes by typing', function () {
type Attributes = {
'some-attribute': string;
};
const counter: UpDownCounter<Attributes> = {
add(_value: number, _attribute: Attributes) {},
};
// @ts-expect-error Expecting the type of Attributes
counter.add(1, { 'another-attribute': 'value' });
});
});
describe('Histogram', function () {
it('enable not to define any type', function () {
const counter: Histogram = {
record(_value: number, _attribute: unknown) {},
};
counter.record(1, { 'some-attribute': 'value' });
});
it('enable to use with type', function () {
type Attributes = {
'some-attribute': string;
};
const counter: Histogram<Attributes> = {
record(_value: number, _attribute: Attributes) {},
};
counter.record(1, { 'some-attribute': 'value' });
});
it('disable wrong attributes by typing', function () {
type Attributes = {
'some-attribute': string;
};
const counter: Histogram<Attributes> = {
record(_value: number, _attribute: Attributes) {},
};
// @ts-expect-error Expecting the type of Attributes
counter.record(1, { 'another-attribute': 'value' });
});
});
});

View File

@ -1,162 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'assert';
import {
NoopMeter,
NOOP_COUNTER_METRIC,
NOOP_HISTOGRAM_METRIC,
NOOP_OBSERVABLE_COUNTER_METRIC,
NOOP_OBSERVABLE_GAUGE_METRIC,
NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC,
NOOP_UP_DOWN_COUNTER_METRIC,
createNoopMeter,
NOOP_GAUGE_METRIC,
} from '../../../src/metrics/NoopMeter';
import { NoopMeterProvider } from '../../../src/metrics/NoopMeterProvider';
const attributes = {};
const options = {
component: 'tests',
description: 'the testing package',
};
describe('NoopMeter', function () {
it('constructor should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
assert.ok(meter instanceof NoopMeter);
});
it('counter should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const counter = meter.createCounter('some-name');
// ensure NoopMetric does not crash.
counter.add(1, attributes);
// ensure the correct noop const is returned
assert.strictEqual(counter, NOOP_COUNTER_METRIC);
const counterWithOptions = meter.createCounter('some-name', options);
assert.strictEqual(counterWithOptions, NOOP_COUNTER_METRIC);
});
it('histogram should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const histogram = meter.createHistogram('some-name');
histogram.record(1, attributes);
// ensure the correct noop const is returned
assert.strictEqual(histogram, NOOP_HISTOGRAM_METRIC);
const histogramWithOptions = meter.createHistogram('some-name', options);
assert.strictEqual(histogramWithOptions, NOOP_HISTOGRAM_METRIC);
});
it('up down counter should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const upDownCounter = meter.createUpDownCounter('some-name');
upDownCounter.add(1, attributes);
// ensure the correct noop const is returned
assert.strictEqual(upDownCounter, NOOP_UP_DOWN_COUNTER_METRIC);
const upDownCounterWithOptions = meter.createUpDownCounter(
'some-name',
options
);
assert.strictEqual(upDownCounterWithOptions, NOOP_UP_DOWN_COUNTER_METRIC);
});
it('observable counter should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const observableCounter = meter.createObservableCounter('some-name');
observableCounter.addCallback(() => {});
// ensure the correct noop const is returned
assert.strictEqual(observableCounter, NOOP_OBSERVABLE_COUNTER_METRIC);
const observableCounterWithOptions = meter.createObservableCounter(
'some-name',
options
);
assert.strictEqual(
observableCounterWithOptions,
NOOP_OBSERVABLE_COUNTER_METRIC
);
});
it('observable gauge should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const observableGauge = meter.createObservableGauge('some-name');
observableGauge.addCallback(() => {});
// ensure the correct noop const is returned
assert.strictEqual(observableGauge, NOOP_OBSERVABLE_GAUGE_METRIC);
const observableGaugeWithOptions = meter.createObservableGauge(
'some-name',
options
);
assert.strictEqual(
observableGaugeWithOptions,
NOOP_OBSERVABLE_GAUGE_METRIC
);
});
it('gauge should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const observableGauge = meter.createGauge('some-name');
// ensure the correct noop const is returned
assert.strictEqual(observableGauge, NOOP_GAUGE_METRIC);
const gaugeWithOptions = meter.createGauge('some-name', options);
assert.strictEqual(gaugeWithOptions, NOOP_GAUGE_METRIC);
});
it('observable up down counter should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
const observableUpDownCounter =
meter.createObservableUpDownCounter('some-name');
observableUpDownCounter.addCallback(() => {});
// ensure the correct noop const is returned
assert.strictEqual(
observableUpDownCounter,
NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC
);
const observableUpDownCounterWithOptions =
meter.createObservableUpDownCounter('some-name', options);
assert.strictEqual(
observableUpDownCounterWithOptions,
NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC
);
});
it('batch callback should not crash', function () {
const meter = new NoopMeterProvider().getMeter('test-noop');
meter.addBatchObservableCallback(() => {}, []);
meter.removeBatchObservableCallback(() => {}, []);
});
});
describe('createNoopMeter', function () {
it('should return NoopMeter', function () {
assert.ok(createNoopMeter() instanceof NoopMeter);
});
});

View File

@ -1,35 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'assert';
import { NoopTracer } from '../../../src/trace/NoopTracer';
import { NoopTracerProvider } from '../../../src/trace/NoopTracerProvider';
describe('NoopTracerProvider', function () {
it('should not crash', function () {
const tracerProvider = new NoopTracerProvider();
assert.ok(tracerProvider.getTracer('tracer-name') instanceof NoopTracer);
assert.ok(
tracerProvider.getTracer('tracer-name', 'v1') instanceof NoopTracer
);
assert.ok(
tracerProvider.getTracer('tracer-name', 'v1', {
schemaUrl: 'https://opentelemetry.io/schemas/1.7.0',
}) instanceof NoopTracer
);
});
});

View File

@ -1,95 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'assert';
import {
validateKey,
validateValue,
} from '../../../src/trace/internal/tracestate-validators';
describe('validators', function () {
describe('validateKey', function () {
const validKeysTestCases = [
'abcdefghijklmnopqrstuvwxyz0123456789-_*/',
'baz-',
'baz_',
'baz*',
'baz*bar',
'baz/',
'tracestate',
'fw529a3039@dt',
'6cab5bb-29a@dt',
];
validKeysTestCases.forEach(testCase =>
it(`returns true when key contains valid chars ${testCase}`, function () {
assert.ok(validateKey(testCase), `${testCase} should be valid`);
})
);
const invalidKeysTestCases = [
'1_key',
'kEy_1',
'k'.repeat(257),
'key,',
'TrAcEsTaTE',
'TRACESTATE',
'',
'6num',
];
invalidKeysTestCases.forEach(testCase =>
it(`returns true when key contains invalid chars ${testCase}`, function () {
assert.ok(!validateKey(testCase), `${testCase} should be invalid`);
})
);
});
describe('validateValue', function () {
const validValuesTestCases = [
'first second',
'baz*',
'baz$',
'baz@',
'first-second',
'baz~bar',
'test-v1:120',
'-second',
'first.second',
'TrAcEsTaTE',
'TRACESTATE',
];
validValuesTestCases.forEach(testCase =>
it(`returns true when value contains valid chars ${testCase}`, function () {
assert.ok(validateValue(testCase));
})
);
const invalidValuesTestCases = [
'my_value=5',
'first,second',
'first ',
'k'.repeat(257),
',baz',
'baz,',
'baz=',
'',
];
invalidValuesTestCases.forEach(testCase =>
it(`returns true when value contains invalid chars ${testCase}`, function () {
assert.ok(!validateValue(testCase));
})
);
});
});

View File

@ -1,139 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'assert';
import { createTraceState } from '../../../src/trace/internal/utils';
import { TraceStateImpl } from '../../../src/trace/internal/tracestate-impl';
describe('TraceState', function () {
describe('.serialize()', function () {
it('returns serialize string', function () {
const state = createTraceState('a=1,b=2');
assert.deepStrictEqual(state.serialize(), 'a=1,b=2');
});
it('must create a createTraceState and move updated keys to the front', function () {
const orgState = createTraceState('a=1,b=2');
const state = orgState.set('b', '3');
assert.deepStrictEqual(orgState.serialize(), 'a=1,b=2');
assert.deepStrictEqual(state.serialize(), 'b=3,a=1');
});
it('must create a createTraceState and add new keys to the front', function () {
let state = createTraceState().set('vendorname1', 'opaqueValue1');
assert.deepStrictEqual(state.serialize(), 'vendorname1=opaqueValue1');
state = state.set('vendorname2', 'opaqueValue2');
assert.deepStrictEqual(
state.serialize(),
'vendorname2=opaqueValue2,vendorname1=opaqueValue1'
);
});
it('must create a createTraceState and unset the entries', function () {
const orgState = createTraceState('c=4,b=3,a=1');
let state = orgState.unset('b');
assert.deepStrictEqual(state.serialize(), 'c=4,a=1');
state = state.unset('c').unset('A');
assert.deepStrictEqual(state.serialize(), 'a=1');
assert.strictEqual(orgState.serialize(), 'c=4,b=3,a=1');
});
});
describe('.parse()', function () {
it('must successfully parse valid state value', function () {
const state = createTraceState(
'vendorname2=opaqueValue2,vendorname1=opaqueValue1'
);
assert.deepStrictEqual(state.get('vendorname1'), 'opaqueValue1');
assert.deepStrictEqual(state.get('vendorname2'), 'opaqueValue2');
assert.deepStrictEqual(
state.serialize(),
'vendorname2=opaqueValue2,vendorname1=opaqueValue1'
);
});
it('must drop states when the items are too long', function () {
const state = createTraceState('a=' + 'b'.repeat(512));
assert.deepStrictEqual(state.get('a'), undefined);
assert.deepStrictEqual(state.serialize(), '');
});
it('must drop states which cannot be parsed', function () {
const state = createTraceState('a=1,b,c=3');
assert.deepStrictEqual(state.get('a'), '1');
assert.deepStrictEqual(state.get('b'), undefined);
assert.deepStrictEqual(state.get('c'), '3');
assert.deepStrictEqual(state.serialize(), 'a=1,c=3');
});
it('must skip states that only have a single value with an equal sign', function () {
const state = createTraceState('a=1=');
assert.deepStrictEqual(state.get('a'), undefined);
});
it('must successfully parse valid state keys', function () {
const state = createTraceState('a-b=1,c/d=2,p*q=3,x_y=4');
assert.deepStrictEqual(state.get('a-b'), '1');
assert.deepStrictEqual(state.get('c/d'), '2');
assert.deepStrictEqual(state.get('p*q'), '3');
assert.deepStrictEqual(state.get('x_y'), '4');
});
it('must successfully parse valid state value with spaces in between', function () {
const state = createTraceState('a=1,foo=bar baz');
assert.deepStrictEqual(state.get('foo'), 'bar baz');
assert.deepStrictEqual(state.serialize(), 'a=1,foo=bar baz');
});
it('must truncate states with too many items', function () {
const state = createTraceState(
new Array(33)
.fill(0)
.map((_: null, num: number) => `a${num}=${num}`)
.join(',')
) as TraceStateImpl;
assert.deepStrictEqual(state['_keys']().length, 32);
assert.deepStrictEqual(state.get('a0'), '0');
assert.deepStrictEqual(state.get('a31'), '31');
assert.deepStrictEqual(
state.get('a32'),
undefined,
'should truncate from the tail'
);
});
it('should not count invalid items towards max limit', function () {
const tracestate = new Array(32)
.fill(0)
.map((_: null, num: number) => `a${num}=${num}`)
.concat('invalid.suffix.key=1'); // add invalid key to beginning
tracestate.unshift('invalid.prefix.key=1');
tracestate.splice(15, 0, 'invalid.middle.key.a=1');
tracestate.splice(15, 0, 'invalid.middle.key.b=2');
tracestate.splice(15, 0, 'invalid.middle.key.c=3');
const state = createTraceState(tracestate.join(',')) as TraceStateImpl;
assert.deepStrictEqual(state['_keys']().length, 32);
assert.deepStrictEqual(state.get('a0'), '0');
assert.deepStrictEqual(state.get('a31'), '31');
assert.deepStrictEqual(state.get('invalid.middle.key.a'), undefined);
assert.deepStrictEqual(state.get('invalid.middle.key.b'), undefined);
assert.deepStrictEqual(state.get('invalid.middle.key.c'), undefined);
});
});
});

View File

@ -1,19 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
const testsContext = require.context('./common', true);
testsContext.keys().forEach(testsContext);
}

View File

@ -1,19 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
const testsContext = require.context('./common', true);
testsContext.keys().forEach(testsContext);
}

View File

@ -1,127 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'assert';
import { webpack, Stats } from 'webpack';
import * as path from 'path';
import { IFS, Union } from 'unionfs';
import { fs as mfs } from 'memfs';
import * as realFs from 'fs';
/**
* Verify that tree-shaking can be properly applied on the @opentelemetry/api package.
* Unused optional apis should be able to be removed from the final bundle.
*
* Webpack doesn't run in node 8 because it requires BigInt. Since we are testing
* build tooling here, we can safely skip tooling we know can't run anyway.
*/
describe('tree-shaking', function () {
const allowedAPIs = ['ContextAPI', 'DiagAPI'];
const testAPIs = [
{
name: 'MetricsAPI',
export: 'metrics',
},
{
name: 'PropagationAPI',
export: 'propagation',
},
{
name: 'TraceAPI',
export: 'trace',
},
];
const APIMatcher = /(?:class|function) (\w+API)/g;
const sourceCodePath = path.join(__dirname, 'test.js');
const outputPath = path.join(__dirname, 'output');
const outputFilename = path.join(outputPath, 'bundle.js');
afterEach(function () {
try {
mfs.unlinkSync(outputFilename);
} catch {
/** ignore */
}
});
for (const testAPI of testAPIs) {
it(`verify ${testAPI.name}`, async function () {
if (parseInt(process.versions.node.split('.')[0], 10) < 10) {
this.skip();
}
const sourceCode = `
import { ${testAPI.export} } from '../../';
console.log(${testAPI.export});
`;
mfs.mkdirpSync(path.dirname(sourceCodePath));
mfs.writeFileSync(sourceCodePath, sourceCode, { encoding: 'utf8' });
const compiler = webpack({
entry: sourceCodePath,
output: {
filename: 'bundle.js',
path: outputPath,
},
mode: 'production',
optimization: {
// disable minimization so that we can inspect the output easily.
minimize: false,
// disable module concatenation so that variable names will not be mangled.
concatenateModules: false,
},
});
const fs = new Union();
fs.use(mfs as any).use(realFs as unknown as IFS);
// direct webpack to use unionfs for file input
// needs workaround from https://github.com/webpack/webpack/issues/18242#issuecomment-2018116985 since webpack 5.91.0
compiler.inputFileSystem = fs as any as typeof compiler.inputFileSystem;
// direct webpack to output to memoryfs rather than to disk
compiler.outputFileSystem = {
...mfs,
join: path.join,
} as any;
const stats = await new Promise<Stats>((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {
return reject(err);
}
resolve(stats!);
});
});
assert.deepStrictEqual(stats.compilation.errors, []);
assert.deepStrictEqual(stats.compilation.warnings, []);
const outputFile = mfs.readFileSync(outputFilename, 'utf8') as string;
const matches = new Set();
let match;
do {
match = APIMatcher.exec(outputFile);
if (match) {
matches.add(match[1]);
}
} while (match);
// Remove allowed apis from checking list.
allowedAPIs.forEach(it => matches.delete(it));
assert.deepStrictEqual(Array.from(matches), [testAPI.name]);
}).timeout(5000);
}
});

View File

@ -1,17 +0,0 @@
{
"extends": "../tsconfig.base.esm.json",
"compilerOptions": {
"lib": [
"es2017",
"dom"
],
"outDir": "build/esm",
"rootDir": "src",
"target": "es2017",
"tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo"
},
"include": [
"src/**/*.ts"
],
"references": []
}

View File

@ -1,17 +0,0 @@
{
"extends": "../tsconfig.base.esnext.json",
"compilerOptions": {
"lib": [
"es2017",
"dom"
],
"outDir": "build/esnext",
"rootDir": "src",
"target": "es2017",
"tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo"
},
"include": [
"src/**/*.ts"
],
"references": []
}

View File

@ -1,18 +0,0 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"lib": [
"es2017",
"dom"
],
"outDir": "build",
"rootDir": ".",
"target": "es2017"
},
"files": [],
"include": [
"src/**/*.ts",
"test/**/*.ts"
],
"references": []
}

View File

@ -1,6 +0,0 @@
{
"entryPoints": [
"src/index.ts",
"src/experimental/index.ts"
]
}

View File

@ -1,15 +0,0 @@
codecov:
notify:
require_ci_to_pass: no
comment:
layout: "header, changes, diff, files"
behavior: default
coverage:
status:
patch:
default:
target: 80%
project:
default:
target: auto
threshold: 1%

View File

@ -1,53 +0,0 @@
# Performance Benchmark Testing Guide
Benchmark tests are intended to measure performance of small units of code.
It is recommended that operations that have a high impact on the performance of the SDK (or potential for) are accompanied by a benchmark test. This helps end-users understand the performance trend over time, and it also helps maintainers catch performance regressions.
Benchmark tests are run automatically with every merge to main, and the results are available at <https://open-telemetry.github.io/opentelemetry-js/benchmarks>.
## Running benchmark tests
Performance benchmark tests can be run from the root for all modules or from a single module directory only for that module:
``` bash
# benchmark all modules
npm run test:bench
# benchmark a single module
cd packages/opentelemetry-sdk-trace-base
npm run test:bench
```
## Adding a benchmark test
Unlike unit tests, benchmark tests should be written in plain JavaScript (not Typescript).
Add a new test file in folder `test/performance/benchmark` using the following as a template:
``` javascript
const Benchmark = require('benchmark');
const suite = new Benchmark.Suite();
suite.on('cycle', event => {
console.log(String(event.target));
});
suite.add('new benchmark test', function() {
// write code to test ...
});
suite.run();
```
## Automatically running benchmark tests
If you want your test to run automatically with every merge to main (to track trend over time), register the new test file by requiring it in `test/performance/benchmark/index.js`.
Add the `test:bench` script in package.json, if the module does not contain it already.
``` json
"test:bench": "node test/performance/benchmark/index.js | tee .benchmark-results.txt"
```

View File

@ -1,49 +0,0 @@
# OpenTelemetry Bug Triage
This procedure describes the steps project maintainers and approvers should take to triage a bug report.
Bugs should be created using the [Bug Report](https://github.com/open-telemetry/opentelemetry-js/issues/new?template=bug_report.yaml) issue template.
This template automatically applies the `bug` and `triage` labels.
## Gather Required Information
The first step is to ensure the bug report is unique and complete.
If the bug report is not unique, leave a comment with a link to the existing bug and close the issue.
If the bug report is not complete, leave a comment requesting additional details and apply the `information-requested` label.
When the user provides additional details, remove the `information-requested` label and repeat this step.
## Categorize
Once a bug report is complete, we can determine if it is truly a bug or not.
A bug is defined as code that does not work the way it was intended to work when written.
A change required by specification may not be a bug if the code is working as intended.
If a bug report is determined not to be a bug, remove the `bug` label and apply the appropriate labels as follows:
- `documentation` feature is working as intended but documentation is incorrect or incomplete
- `feature-request` new feature request which is not required by the specification, but is allowable by specification rules
- `spec-feature` change required by the specification which adds a new feature or extends an existing feature with new functionality
- `spec-inconsistency` an existing feature incorrectly or incompletely implements the specification - may or may not also be a bug
## Prioritize
For bugs and specification required changes, apply a priority label as follows.
Each bug should have only a single priority label which is the highest priority that applies.
For example, a bug which satisfies the conditions for both `p2` and `p3` labels should only receive the `p2` label.
- `p1` bugs which cause problems in end-user applications such as crashes, data inconsistencies, or memory leaks which grow unbounded
- `p2` bugs and specification inconsistencies which cause telemetry to be incorrectly or incompletely reported
- `p3` bugs which cause problems in end-user applications not related to correctness such as performance issues or high memory use
- `p4` bugs and specification inconsistencies which do not fall into any of the above categories
## Schedule
The final step is to determine a reasonable timeline for a bug to be fixed.
`p1` and `p2` issues should be fixed as quickly as possible.
These bugs should be either immediately assigned to the appropriate person, or added to the agenda for the next SIG meeting where they will be assigned.
`p3` and `p4` issues may be addressed less urgently than `p1` and `p2` issues.
If they are not urgent the `up-for-grabs`, `good-first-issue`, or other similar labels may be applied as appropriate.
## Triage Complete
The final step is to remove the `triage` label.
This indicates that all above steps have been taken and an issue is ready to be worked on.

View File

@ -1,31 +0,0 @@
# OpenTelemetry Dependencies
This section refers to `"dependencies"` and `"devDependencies"` entries in `package.json` file.
> [!IMPORTANT]
> Not all libraries follow [Semantic Versioning](https://semver.org/). Even those who do might occasionally introduce breaking changes due to human errors. Exceptions to the guidelines in this document MAY be granted by Approvers or Maintainers to work around this.
## Development Dependencies
`"devDependencies"` SHOULD be pinned to reduce the risk of autobreaking the build. Since we cannot use the `package-lock.json` file (because the libraries are distributed without it), control over the version our contributors will get is limited. By using pinned versions, we prevent potential disruptions caused by unpinned versions.
**Example:** `^1.2.3` might inadvertently lead to version `1.2.6` which includes unintended breaking changes).
> [!NOTE]
> As this approach might leave our project with outdated tooling, we adopt `renovate-bot`. This automated dependency update tool proactively opens pull requests upon the release of new patch/minor/major versions. The complete configuration for renovate-bot can be found in [renovate.json](../../renovate.json) file.
## @opentelemetry/* dependencies
All packages from the `@opentelemetry/` namespace MUST have the same pinned version, as these dependencies are automatically updated on each release by lerna.
**Example:** all packages under `packages/` should consistently maintain the same version, as should those under `experimental/packages/`.
An exception is granted for dependencies on `@opentelemetry/api`, which, if used by the package SHOULD NOT be included as a `dependency`. `@opentelemetry/api` SHOULD be included as a `peerDependency` instead. The version range of the `peerDependency` SHOULD reflect the minimum supported, and SHOULD NOT allow versions greater than the latest released minor version.
## Third-Party Library Dependencies
Packages categorized as third-party and listed under the `"dependencies"` section (e.g., @grpc/grpc-js, @grpc/proto-loader, etc.) should remain unpinned and utilize the caret (`^`) symbol. This approach offers several advantages:
- Our users could get bug fixes of those 3rd-party packages easily, without waiting for us to update our library.
- In cases where multiple packages have dependencies on different versions of the same package, npm will opt for the most recent version, saving space and preventing potential disruptions.
It's important to acknowledge that this approach does expose users to potential breaking changes arising from either human error or libraries that do not strictly follow to semver conventions. This trade-off is an inherent aspect of this approach.

View File

@ -1,14 +0,0 @@
# Maintaining npm workspaces dependencies
This documents the caveats on maintaining npm workspaces dependencies.
## Karma
Packages with executables are hoisted in workspaces. In this case, `karma` and
its plugins are not installed in the same `node_modules` folder, which leads to
a condition that `karma` can not find the plugins necessary to run the tests.
To alleviate this, karma and its plugins are listed as root dependencies as
well.
Relevant issue: [[RFC] Add nohoist option for workspaces](https://github.com/npm/rfcs/issues/287)

View File

@ -1,49 +0,0 @@
# Releasing
This document is aimed at Maintainers and describes how to release a new version of the packages contained in this repository.
We aim to eventually automate this process as much as possible.
## 1. Create a release PR
1. Go to the [Release PR Workflow](https://github.com/open-telemetry/opentelemetry-js/actions/workflows/create-or-update-release-pr.yml)
2. Click "Run workflow"
3. For `Release Type`, select if you want to create a release PR for a new `minor` or `patch` version.
4. For `Release Scope`, select if you want to release
- `experimental` (all packages under `./experimental/packages`)
- `sdk` (all packages under `./packages/` and `./experimental/packages`)
- `all` (all packages under `./api/`, `./packages/` and `./experimental/packages`; excludes `./semantic-conventions/`)
- `semconv` (the single semconv package at `./semantic-conventions/`)
> [!TIP]
> If there was a commit to `main`, after PR creation simply run the workflow again before merging it.
> Re-running it will update the PR with the contents from `main` and will update the PR body too.
## 2. Review and merge the release PR
1. Review the PR generated via the workflow (it will be titled `chore: prepare next release` and opened by the @opentelemetrybot user)
2. Once approved, merge the PR
## 3. Publish to NPM
> [!IMPORTANT]
> This step will publish anything that's on `main` IF AND ONLY IF the version has been bumped. If the version for a package
> has not been bumped, it will not publish a new version of the package.
1. Go to the [NPM publish workflow](https://github.com/open-telemetry/opentelemetry-js/actions/workflows/publish-to-npm.yml)
2. Click "Run workflow" (from main)
1. In rare cases not all packages are published due to a race when publishing, if you suspect this to
be the case, re-run the workflow: there should be enough time from 1.
## 4. Create GitHub Releases
1. Check out the commit created by merging the release PR
2. Run
- `npm run _github:draft_release:experimental`, if you published an `all`, `sdk` or `experimental` release
- `npm run _github:draft_release:stable`, if you published an `all` or `sdk` release
- `npm run _github:draft_release:semconv`, if you published a `semconv` release
- `npm run _github:draft_release:api` if you published an `all` release
3. Verify that the contents of the created draft releases (title, changelog, selected commit)
4. Publish the releases
- uncheck `Set as a pre-release` for all releases
- uncheck `Set as the latest release` for all releases except for the `stable` SDK release. This will ensure that the
`stable` SDK release consistently shows up as latest under `Releases` when navigating to the project page.

View File

@ -1,37 +0,0 @@
# OpenTelemetry JS Style Guide
This guide is meant to be a supplement to the linting rules.
It is not exhaustive, nor should the suggestions in this guide be considered hard rules.
Suggestions for changes and additions to this doc are welcome and this doc should not be considered to be set in stone.
There may be code written before this guide which does not follow the suggestions in this guide.
That code is not required to be updated, but maybe a good starting place for new contributors getting used to the codebase.
## Test coverage
In general, all changes should be tested.
New features generally require tests to be added and bugfixes require tests to ensure there are no regressions.
## Linting
The lint check must pass in order for a PR to be merged.
In some cases, it may be acceptable to disable a linting rule for a specific line or file.
It may also be acceptable in some cases to modify the linting rules themselves if a sufficient argument is made that the rule should be changed.
## `null` and `undefined` should be treated the same
In general, null and undefined should be treated the same.
In case of the rare exception where `null` is used to mean something different than `undefined` it should be documented clearly in the jsdocs.
- Prefer `undefined` instead of `null` in most cases
- Prefer `value == null` instead of `value == null || value == undefined`
## Prefer `===` over `==`
`===`/`!==` should be preferred over `==` and `!=`.
An exception to this is when checking for `null`/`undefined` when it is preferred to use `== null` in order to treat `null` and `undefined` the same.
## Prefer options objects to long lists of optional positional parameters
For functions/methods/constructors with optional parameters, the parameters should be passed as an options object.
This allows options to be added later without changing the function signature and avoids long lists of arguments.
Required arguments should be at the start of the arguments list.

View File

@ -1,21 +0,0 @@
# Web API Usages Guidance
The packages of OpenTelemetry that targeting web platforms should be compatible
with the following web environments:
- [Browsing Context](https://developer.mozilla.org/en-US/docs/Glossary/Browsing_context),
- [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Functions_and_classes_available_to_workers).
As such, the usage of Web API that depends on APIs like [`window`],
[`document`] and [`navigator`] is discouraged.
If the use of the browsing context API is necessary, like adding `onload`
listeners, an alternative code path for Web Worker environment should also be
supported.
It is an exception to above guidance if the package is instrumenting the
browsing context only.
[`window`]: https://developer.mozilla.org/en-US/docs/Web/API/window
[`document`]: https://developer.mozilla.org/en-US/docs/Web/API/Document
[`navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Navigator

View File

@ -1,131 +0,0 @@
# ECMAScript Modules vs. CommonJS
Node.js uses a different module loader for ECMAScript Modules (ESM) vs. CommonJS (CJS).
To verify whether your application is ESM or CJS, refer to [Node.js docs for Determining Module System](https://nodejs.org/api/packages.html#determining-module-system).
An `.mjs` extension or `type:module` in the built app's `package.json` indicates the app is ESM.
**Much of OpenTelemetry JS documentation is written assuming the compiled application is run as CJS.**
ESM support is ongoing; a few adjustments are needed for configuration and startup commands.
For more explanation about CJS and ESM, see the [Node.js docs](https://nodejs.org/api/modules.html#enabling).
## TypeScript
Many TypeScript projects today are written using ESM syntax, regardless of how they are compiled.
In the `tsconfig.json`, there is an option to compile to ESM or CJS.
If the compiled code is ESM, those import statements will remain the same (e.g. `import { foo } from 'bar';`).
If the compiled code is CJS, those import statements will become `require()` statements (e.g. `const { foo } = require('bar');`)
## Initializing the SDK
Instrumentation setup and configuration must be run before your application code.
If the SDK is initialized in a separate file (recommended), ensure it is imported first in application startup, or use the `--require` or `--import` flag during startup to preload the module.
For CJS, the `NODE_OPTIONS` for the startup command should include `--require ./telemetry.js`.
For ESM, minimum Node.js version of `18.19.0` is required.
The `NODE_OPTIONS` for the startup command should include `--import ./telemetry.js`.
## Instrumentation Hook Required for ESM
If your application is written in JavaScript as ESM, or compiled to ESM from TypeScript, then a loader hook is required to properly patch instrumentation.
The custom hook for ESM instrumentation is `--experimental-loader=@opentelemetry/instrumentation/hook.mjs`.
This flag must be passed to the `node` binary, which is often done as a startup command and/or in the `NODE_OPTIONS` environment variable.
### Additional Notes on Experimental Loaders
Though the OpenTelemetry loader currently relies on `import-in-the-middle`, direct usage of `import-in-the-middle/hook.mjs` may cease to work in the future.
The only currently supported loader hook is `@opentelemetry/instrumentation/hook.mjs`.
**Note:** Eventually the recommendation for how to setup OpenTelemetry for usage with ESM will change to no longer require `--experimental-loader=@opentelemetry/instrumentation/hook.mjs`.
Instead the bootstrap code (in `./telemetry.js`) will use Node.js's newer `module.register(...)`.
Refer to this [issue](https://github.com/open-telemetry/opentelemetry-js/issues/4933) for details.
Because of ongoing issues with loaders running TypeScript code as ESM in development environments, results may vary.
To use `ts-node` to run the uncompiled TypeScript code, the module must be CJS.
To use `tsx` to run the uncompiled TypeScript code as ESM, the `--import` flag must be used.
## Using the Zero Code Option with `auto-instrumentations-node`
The `auto-instrumentations-node` package contains a `register` entry-point that can be used with `--require` or `--import` to setup and start the SDK easily, without application code changes.
For ESM, the package also requires the usage of the loader hook.
Startup command for CJS:
```sh
node --require @opentelemetry/auto-instrumentations-node/register app.js
```
Startup command for ESM:
```sh
node --experimental-loader=@opentelemetry/instrumentation/hook.mjs --import @opentelemetry/auto-instrumentations-node/register app.js
```
## Examples
### Example Written in JavaScript as CJS
```javascript
/*telemetry.cjs*/
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const sdk = new NodeSDK({
traceExporter: new ConsoleSpanExporter(),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
```
Startup command:
```sh
node --require ./telemetry.cjs app.js
```
### Example Written in JavaScript as ESM or TypeScript
```typescript
/*telemetry.ts | telemetry.mjs*/
import { NodeSDK } from '@opentelemetry/sdk-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
const sdk = new NodeSDK({
traceExporter: new ConsoleSpanExporter(),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
```
Startup command for compiled CJS:
```sh
node --require ./telemetry.js app.js
```
Startup command for compiled ESM:
```sh
node --experimental-loader=@opentelemetry/instrumentation/hook.mjs --import ./telemetry.js app.js
```
### ESM Options for Different Versions of Node.js
The entire startup command should include the following `NODE_OPTIONS`:
| Node.js Version | NODE_OPTIONS |
| ----------------- | ----------------------------------------------------------------------------------------- |
| 16.x | `--require ./telemetry.cjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` |
| >=18.1.0 <18.19.0 | `--require ./telemetry.cjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` |
| ^18.19.0 | `--import ./telemetry.mjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` |
| 20.x | `--import ./telemetry.mjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` |
| 22.x | `--import ./telemetry.mjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` |

View File

@ -1,88 +0,0 @@
# Exporter Developer Guide
An exporter sends traces and metrics to any backend that is capable of consuming them. With OpenTelemetry, you can easily add and remove any exporter without requiring changes to your application code.
We provide support for several open source backends and vendors out-of-the-box like Zipkin, Jaeger, and Prometheus, but OpenTelemetry exporters follow a public interface which can be implemented by anyone. This document describes the process for developers to create their own exporter if the provided ones do not meet their needs.
A typical package layout:
```text
opentelemetry-exporter-myexporter
├── src
│ └── index.ts
│ └── transform.ts
│ └── types.ts
│ └── my-trace-exporter.ts
│ └── my-metric-exporter.ts
└── test
└── transform.test.ts
└── my-trace-exporter.test.ts
└── my-metric-exporter.test.ts
```
## Traces
The `SpanExporter` interface defines which methods the protocol-specific trace/span exporters must implement so that they can be plugged into OpenTelemetry SDK. Span exporters must follow these rules:
1. Implement the `SpanExporter` interface.
2. Expect to only receive spans which have been sampled.
3. Expect to only receive spans which are ended.
4. Do not throw exceptions.
5. Do not modify received spans.
6. Do not implement queuing or batching logic because this is handled by Span Processors.
The current `SpanExporter` interface contains 2 methods:
- `export`: Exports a batch of spans. In this method, youll process and translate `ReadableSpan` Data into the data that your trace backend accepts, and send them to your tracing backend.
- `shutdown`: Shuts down the exporter. This is an opportunity for exporter to do any cleanup required. `Shutdown` should be called only once for each Exporter instance. After the call to `Shutdown` subsequent calls to Export are not allowed and should return `FailedNotRetryable` error.
Please refer to the [Zipkin Exporter][zipkin-exporter] or [Jaeger Exporter][jaeger-exporter] for more comprehensive examples.
## Metrics
Metrics can be exported with two distinct patterns:
- Push model exporting, like periodically push metrics to the backend.
- Pull model exporting, like Prometheus pulling metrics from the application.
### Push model exporting
The `PushMetricExporter` defines the interface that protocol-specific exporters must implement so that they can be plugged into OpenTelemetry SDK and support sending of metrics data with `PeriodicMetricReader`.
The current `PushMetricExporter` interface defines 3 required methods:
- `export`: Exports a batch of telemetry data. In this method youll process and translate `ResourceMetrics` into the data that your metric backend accepts.
- `shutdown`: Shuts down the exporter. This is an opportunity for exporter to do any cleanup required. `Shutdown` should be called only once for each Exporter instance.
- `forceFlush`: Ensure that the export of any metrics the exporter has received is completed before the returned promise is settled.
The `PushMetricExporter` interface can also implement following methods to provide a preference on metric configuration:
- `selectAggregationTemporality`: Select the preferred `AggregationTemporality` for the given `InstrumentType` for this exporter.
- `selectAggregation`: Select the preferred `Aggregation` for the given `InstrumentType` for this exporter.
Please refer to the [OTLP Exporter][otlp-exporter] for more comprehensive examples.
### Pull model exporting
The pulling model exporting requires the export pipeline proactively initiate metric collections. Such exporting pipeline must be modeled as a `MetricReader`.
The abstract class `MetricReader` defines the interface that protocol-specific readers must implement so that they can be plugged into OpenTelemetry SDK and support pulling of metrics data.
The current `MetricReader` interface defines 2 required methods:
- `onShutdown`: Shuts down the reader. This is an opportunity for reader to do any cleanup required. `Shutdown` should be called only once for each reader instance.
- `onForceFlush`: Ensure that the export of any metrics the reader has received is completed before the returned promise is settled.
A `MetricReader` can initiate a metric collection request with `MetricReader.collect()` method. The `MetricReader.collect()` returns a promise that settles with a `CollectionResult`, containing the `ResourceMetrics` record and a series of reasons for possibly failed asynchronous metric instrument collection. The `ResourceMetrics` record can be processed and translated into the data that your metric backend accepts.
Please refer to the [Prometheus Exporter][prometheus-exporter] for more comprehensive examples.
[zipkin-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-exporter-zipkin
[jaeger-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-exporter-jaeger
[otlp-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc
[prometheus-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-exporter-prometheus

View File

@ -1,28 +0,0 @@
# Frequently Asked Questions
This FAQ has bits of advice and workarounds for common problems.
## I'm using Jest and get import errors when I run my test suite
Test suite failures of the form:
``` text
Cannot find module @opentelemetry/foo/bar from @opentelemetry/...
```
but package `@opentelemetry/foo` is installed may occur with Jest < v29.4.
This is because older versions of `jest-resolve` cannot find the nested module
imports used by some OpenTelemetry packages since version 0.56 and higher.
See [#5618](https://github.com/open-telemetry/opentelemetry-js/issues/5618)
Either upgrade to a newer version of Jest to resolve the issue, or use this
workaround for older versions of Jest by adding a `moduleNameMapper` rule.
Add this line to your `jest.config.js`:
``` javascript
module.exports = {
moduleNameMapper: {
'^@opentelemetry/([^/]+)/(.+)$': '<rootDir>/node_modules/@opentelemetry/$1/build/src/index-$2',
}
}
```

View File

@ -1,11 +0,0 @@
# Instrumentation Developer Guide
A detailed explained guide how to instrument a package is available at [instrumentation package][base-instrumentation]
For more comprehensive examples please refer to the [HTTP instrumentation][http-instrumentation] or [gRPC instrumentation][grpc-instrumentation] for node
and [XMLHttpRequest instrumentation][xhr-instrumentation] for web.
[base-instrumentation]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation
[http-instrumentation]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-http/src/http.ts#L59
[grpc-instrumentation]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-grpc/src/instrumentation.ts#L28
[xhr-instrumentation]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L71

View File

@ -1,563 +0,0 @@
# Metrics
This quick start is for end users of OpenTelemetry who wish to manually measure their applications. If you wish to automatically instrument your application, see the automatic instrumentation documentation for the SDK you wish to use.
For a high-level overview of OpenTelemetry metrics in general and definitions of some common terms, you can refer to the [OpenTelemetry Specification Overview][spec-overview]
_Metrics API Specification: <https://github.com/open-telemetry/opentelemetry-specification/blob/v1.14.0/specification/metrics/api.md>_
_Metrics API Reference: <https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api._opentelemetry_api.MetricsAPI.html>_
- [Getting Started](#getting-started)
- [Acquiring a Meter](#acquiring-a-meter)
- [Create a metric instrument](#create-a-metric-instrument)
- [Describing a instrument measurement](#describing-a-instrument-measurement)
- [Metric Attributes](#metric-attributes)
- [Semantic Conventions](#semantic-conventions)
- [Configuring metric views](#configuring-metric-views)
- [Configuring explicit bucket sizes for the Histogram instrument](#configuring-explicit-bucket-sizes-for-the-histogram-instrument)
- [Dropping instrument from being exported](#dropping-instrument-from-being-exported)
- [Customizing the metric attributes of instrument](#customizing-the-metric-attributes-of-instrument)
- [Exporting measurements](#exporting-measurements)
- [Exporting measurements to Prometheus](#exporting-measurements-to-prometheus)
- [Exporting measurements to OpenTelemetry Protocol](#exporting-measurements-to-opentelemetry-protocol)
## Getting Started
In this page, you'll learn how to setup OpenTelemetry JS to export metrics from an HTTP server with Fastify. If you're not using Fastify, that's fine -- this guide will also work with Express, etc.
### Installation
To begin, set up an environment in a new directory:
```bash
mkdir otel-getting-started
cd otel-getting-started
npm init -y
```
Now install Fastify and OpenTelemetry:
```bash
npm install fastify @opentelemetry/sdk-node @opentelemetry/exporter-prometheus @opentelemetry/auto-instrumentations-node
```
The `@opentelemetry/sdk-node` and `@opentelemetry/auto-instrumentations-node` will install all the
necessary packages to start with OpenTelemetry including instrumentation for a wide variety of popular
packages, such as `http`, `fetch` etc. The package `@opentelemetry/exporter-prometheus` is installed
to export our collected metrics to Prometheus.
### Create the sample HTTP Server
Create a file `app.js`:
```javaScript
const api = require('@opentelemetry/api')
const opentelemetry = require("@opentelemetry/sdk-node");
const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus");
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
const prometheusExporter = new PrometheusExporter();
const sdk = new opentelemetry.NodeSDK({
// Optional - If omitted, the metrics SDK will not be initialized
metricReader: prometheusExporter,
// Optional - you can use the metapackage or load each instrumentation individually
instrumentations: [getNodeAutoInstrumentations()],
// See the Configuration section below for additional configuration options
});
// You can optionally detect resources asynchronously from the environment.
// Detected resources are merged with the resources provided in the SDK configuration.
sdk.start();
// Resources have been detected and SDK is started
console.log(`SDK started`)
// Start the http server
const fastify = require('fastify')({
logger: true
})
fastify.get('/', function (request, reply) {
reply.send({ hello: 'world' })
})
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
console.log(`Server is now listening on ${address}`)
})
// You can also use the shutdown method to gracefully shut down the SDK before process shutdown
// or on some operating system signal.
const process = require("process");
process.on("SIGTERM", () => {
sdk
.shutdown()
.then(
() => console.log("SDK shut down successfully"),
(err) => console.log("Error shutting down SDK", err)
)
.finally(() => process.exit(0));
});
```
In the above example we are initializing the Node SDK to enable the Metrics SDK
and configure it to export the metrics in Prometheus format by registering the
`PrometheusExporter`.
You can now run the instrument application and it will run the HTTP server on
port 3000 with command:
```bash
node app.js
```
Now when accessing the HTTP server via <http://localhost:3000> you will
see the following:
```json
{"hello":"world"}
```
### Add manual instrumentation
Automatic instrumentation is powerful but it doesn't capture what's going on in
your application. For that you'll need to write some manual instrumentation. Below
we will show you how you can count the number of times a HTTP endpoint has been
accessed.
#### Counting number of incoming http requests
First, modify `app.js` to include code that initializes a meter and uses it to
create a counter instrument which counts the number of times the `/` http endpoint
has been requested.
```javaScript
const api = require('@opentelemetry/api')
const opentelemetry = require("@opentelemetry/sdk-node");
const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus");
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
const prometheusExporter = new PrometheusExporter();
const sdk = new opentelemetry.NodeSDK({
// Optional - If omitted, the metrics SDK will not be initialized
metricReader: prometheusExporter,
// Optional - you can use the metapackage or load each instrumentation individually
instrumentations: [getNodeAutoInstrumentations()],
// See the Configuration section below for additional configuration options
});
// You can optionally detect resources asynchronously from the environment.
// Detected resources are merged with the resources provided in the SDK configuration.
sdk.start();
// Resources have been detected and SDK is started
console.log(`SDK started`)
// Create Meter with the name `http-server`
const appMeter = api.metrics.getMeter('http-server')
// Use the created Meter to create a counter instrument
const numberOfRequests = appMeter.createCounter('request-counter')
// Start the http server
const fastify = require('fastify')({
logger: true
})
fastify.get('/', function (request, reply) {
// Increase the counter by 1 each time the `/` endpoint is requested
numberOfRequests.add(1)
reply.send({ hello: 'world' })
})
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
console.log(`Server is now listening on ${address}`)
})
// You can also use the shutdown method to gracefully shut down the SDK before process shutdown
// or on some operating system signal.
const process = require("process");
process.on("SIGTERM", () => {
sdk
.shutdown()
.then(
() => console.log("SDK shut down successfully"),
(err) => console.log("Error shutting down SDK", err)
)
.finally(() => process.exit(0));
});
```
Now run the application again:
```bash
node app.js
```
When you navigate to <http://localhost:3000>, the counter instrument will be increased
each time the page is accessed. If you want to see the exporter instruments, you
can access via the dedicates metrics endpoint for Prometheus by accessing:
<http://localhost:9464/metrics> the contents will look similar to:
```text
# HELP request_counter_total description missing
# TYPE request_counter_total counter
request_counter_total 6 1666624810428
```
In the above example output you can that one instrument is available with the
name `request_counter_total`:
```text
request_counter_total 6 1666624810428
```
The postfixed `_total` get automatically to the instrument name for each counter instrument
when the measurements are getting exported in the Prometheus format. In the above
example you see that we accessed our `/` endpoint six times.
## Acquiring a Meter
In OpenTelemetry, Instruments that allow for measurement operations are acquired through a _meter_. You can get a meter by calling [`getMeter`](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.MeterProvider.html#getmeter) on the global meter provider. `getMeter` takes the name and version of the application or library acquiring the meter, and provides a meter which can be used to create instruments.
```typescript
import { metrics } from '@opentelemetry/api';
const meter = metrics.getMeter("my-application", "0.1.0");
```
## Create a metric instrument
In OpenTelemetry, all _metrics_ are composed of [`Instruments`](https://open-telemetry.github.io/opentelemetry-js/enums/_opentelemetry_sdk-metrics.InstrumentType.html). An instrument is responsible for reporting measurements,
there are four types of instruments that can be created:
- Counter, a synchronous instrument which supports non-negative increments
- Asynchronous Counter, a asynchronous instrument which supports non-negative increments
- Histogram, a synchronous instrument which supports arbitrary values that are statistically meaningful, such as histograms, summaries or percentile
- Asynchronous Gauge, an asynchronous instrument which supports non-additive values, such as room temperature
- UpDownCounter, a synchronous instrument which supports increments and decrements, such as number of active requests
- Asynchronous UpDownCounter, an asynchronous instrument which supports increments and decrements
You can create a Counter instrument by calling [`Meter#createCounter`](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Meter.html#createcounter). The only required argument to `createCounter` is the _instrument name_, which should describe the item that is being measurement.
```typescript
const counter = meter.createCounter("events.counter");
// increase the counter
counter.add(1);
```
Most of the time, instruments will be used to measure operations in your application. The following example shows what it might look like to manually measure a function's duration.
```typescript
async function myTask() {
const histogram = meter.createHistogram("task.duration");
const startTime = new Date().getTime()
try {
// Wait for five seconds before continuing code execution
await setTimeout(5_000)
} catch (err) {
} finally {
const endTime = new Date().getTime()
const executionTime = endTime - startTime
// Record the duration of the task operation
histogram.record(executionTime)
}
}
await myTask()
```
## Describing a instrument measurement
Using attributes, kind, and the related [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/metrics.md), we can more accurately describe the measurement in a way our metrics backend will more easily understand. The following example uses these mechanisms, which are described below, for recording a measurement
of a HTTP request.
Each metric instruments allows to associate a description, unit of measure, and the value type.
The description of a metric instrument can expose up in the metrics backend, the unit or value type
can be used to information about the record measurement itself.
```typescript
async function myTask() {
const httpServerDuration = meter.createHistogram("my.http.server.request.duration", {
description: 'HTTP server request duration',
unit: 's',
valueType: ValueType.DOUBLE
});
const startTime = new Date().getTime()
try {
// Wait for five seconds before continuing code execution
await setTimeout(5_000)
} catch (err) {
} finally {
const endTime = new Date().getTime()
const executionTime = (endTime - startTime) / 1000
httpServerDuration.record(executionTime, {
[ATTR_HTTP_REQUEST_METHOD]: 'POST',
[ATTR_HTTP_RESPONSE_STATUS_CODE]: '200',
[ATTR_URL_SCHEME]: 'https',
})
}
}
await myTask()
```
In the above example we are recording a measurement of roughly 5000ms and associate
three metric attributes with this measurement. Metrics backends can show these metric
attributes. In Prometheus the metric attributes would become labels and can be used
as part of queries, and allow search queries, such as what's the 90% percentile of
all successful POST requests.
### Metric Attributes
While name and measurement are the minimum required to record a metric measurement,
most of the time they will not be enough information on their own to effectively observe
an application. To solve this, OpenTelemetry uses _Metric Attributes_. Metric attributes are object with
string keys and string values which add more context to the measurement.
For example, when you are measuring the number of inflight requests, you might want to be able to count
the number of POST, or GET requests. You can add the a metric attribute for `http.method` to allow more
flexibility when leveraging your metric measurement like in Grafana dashboards.
### Semantic Conventions
One problem with metrics names and attributes is recognizing, categorizing, and analyzing them in your metrics backend. Between different applications, libraries, and metrics backends there might be different names and expected values for various attributes. For example, your application may use `http.status` to describe the HTTP status code, but a library you use may use `http.status_code`. In order to solve this problem, OpenTelemetry uses a library of semantic conventions which describe the name and attributes which should be used for specific types of metrics.
The use of semantic conventions is always recommended where applicable, but they are merely conventions. For example, you may find that some name other than the name suggested by the semantic conventions more accurately describes your metric, you may decide not to include a metric attribute which is suggested by semantic conventions for privacy reasons, or you may wish to add a custom attribute which isn't covered by semantic conventions. All of these cases are fine, but please keep in mind that if you stray from the semantic conventions, the categorization of metrics in your metrics backend may be affected.
_See the current metrics semantic conventions in the OpenTelemetry Specification repository: <https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/metrics.md>_
[spec-overview]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md
## Configuring metric views
A [Metric View](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view) provides the ability to customize the metrics that are exposed by the
Metrics SDK. Metric Views allows you to do:
- Customize which Metric Attributes are reported on metrics
- Customize which instruments get processed/ignored
- Change the aggregation of a metric
- Define explicit bucket sizes to Histogram instruments
The Metric view requires the instrument selection query, and the configuration
for the resulting metric. The first step is select to the metrics to whom the View
is relevant, the second step is to configure the customizations for the the selected
metrics.
A Metric View can be added to a `MeterProvider` like so
````typescript
new MeterProvider({
views: [{
name: 'metric-view', // optionally, give the view a unique name
// select instruments with a specific name
instrumentName: 'http.server.duration',
}]
});
````
In the above example a View is created which select instruments with the name `http.server.duration` other options to select instruments are:
- By Instrument Type: use `instrumentType` to select instruments of the given type
- By Meter: use `meterName` to select meters with the given name
- By Meter Version: use `meterVersion` to select meters with the given version
- By Meter Schema URL: use `meterSchemaUrl` to select meters with given schema url
The `instrumentName` has support for wildcards, so you can select all instruments
using `*` or select all instruments starting with 'http.' by using `http.*`.
_Note_: The Views can only be defined when the `MeterProvider` instance gets
instantiated. A proposal is submitted to ease the ability to define Metrics Views:
<https://github.com/open-telemetry/oteps/issues/209>
### Configuring explicit bucket sizes for the Histogram instrument
The Histogram instrument has a predefined set of bucket sizes defined which might not
suit all your needs. The bucket sizes can be overridden by configuring a different
aggregation for the Histogram instrument. The `ExplicitBucketHistogramAggregation`
should be used to define the bucket sizes for the Histogram instrument.
Below an example is given how you can define explicit buckets for a histogram.
```typescript
// Create an instance of the metric provider
const meterProvider = new MeterProvider({
views: [
// Define view for the histogram metric
{
aggregation: {
type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM,
options: {
boundaries: [0, 1, 5, 10, 15, 20, 25, 30],
}
},
// Note, the instrumentName is the same as the name that has been passed for
// the Meter#createHistogram function
instrumentName: 'http.server.duration',
instrumentType: InstrumentType.HISTOGRAM,
}
]
});
// Create histogram metric
const httpServerDuration = meter.createHistogram('my.http.server.request.duration', {
description: 'HTTP server request duration',
unit: 's',
valueType: ValueType.DOUBLE
});
// Record measurement for histogram
httpServerDuration.record(50, {
[ATTR_HTTP_REQUEST_METHOD]: 'POST',
[ATTR_HTTP_RESPONSE_STATUS_CODE]: '200',
[ATTR_URL_SCHEME]: 'https',
});
```
### Dropping instrument from being exported
In some circumstances you don't want specific metrics to be exported by OpenTelemetry,
for example, you might be using custom instrumentations or third-party packages that
define their own metrics you are not interested in.
In such cases you can define a view which drops the instruments you are
not interested in. For example, you can drop instruments of a specific meter or
instruments with a specific name:
The following view drops all instruments that are associated with a meter named `pubsub`:
```typescript
{
aggregation: { type: AggregationType.DROP },
meterName: 'pubsub',
}
```
Alternatively, you can also drop instruments with a specific instrument name,
for example, all instruments of which the name starts with `http`:
```typescript
{
aggregation: { type: AggregationType.DROP },
instrumentName: 'http*',
}
```
### Customizing the metric attributes of instrument
If you want to limit the Metric Attributes that get exported in measurements of
an instrument, you can create a Metric View which defines which attributes should
be exported. Attributes that are missing in the list will not be exported.
In the example below will drop all attributes except attribute `environment` for
all instruments.
```typescript
{
// only export the attribute 'environment'
attributeKeys: ['environment'],
// apply the view to all instruments
instrumentName: '*',
}
```
## Exporting measurements
After you have instrumented your application with metrics, you also need to make
sure that the metrics get collected by your metrics backend. The most common formats
that are used are Prometheus and OTLP.
The latter is the [OpenTelemetry protocol format](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md)
which is supported by the OpenTelemetry Collector. The former is based on the [OpenMetrics
format](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md) can be consumed by Prometheus and Thanos or other OpenMetrics compatible
backends.
_Note_: Both OpenTelemetry JavaScript and OpenTelemetry Collector support
exporters for different formats, such as [Cloud Monitoring](https://github.com/GoogleCloudPlatform/opentelemetry-operations-js/tree/master/packages/opentelemetry-cloud-monitoring-exporter).
## Exporting measurements to Prometheus
If you want to export your metrics to Prometheus you need to initialize OpenTelemetry
to use the Prometheus exporter `PrometheusExporter` which is included in the
`@opentelemetry/exporter-prometheus`-package.
```typescript
const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus');
const { MeterProvider } = require('@opentelemetry/sdk-metrics');
// Add your port to the Prometheus options
const options = { port: 9464 };
const exporter = new PrometheusExporter(options);
// Creates MeterProvider and installs the exporter as a MetricReader
const meterProvider = new MeterProvider({
readers: [exporter],
});
const meter = meterProvider.getMeter('example-prometheus');
// Now, start recording data
const counter = meter.createCounter('metric_name', {
description: 'Example of a counter'
});
counter.add(10, { pid: process.pid });
```
In the above example the instantiated `PrometheusExporter` is configured to expose
a new http server on port 9464. You can now access the metrics at the endpoint
<http://localhost:9464/metrics>. This is the URL that can be scraped by Prometheus so it can consumed the metrics collected by OpenTelemetry in your application.
More information about Prometheus and how to configure can be found at:
[Prometheus Scraping Config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)
For a fully functioning code example for using this exporter, please have a look
at: <https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/examples/prometheus>
## Exporting measurements to OpenTelemetry Protocol
OpenTelemetry JavaScript comes with three different kinds of exporters that export
the OTLP protocol, a) [over HTTP](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http), b) [over GRPC](https://www.npmjs.com/package/@opentelemetry/exporter-metrics-otlp-grpc), c) [over Protobuf](https://www.npmjs.com/package/@opentelemetry/exporter-metrics-otlp-proto).
The example below shows how you can configure OpenTelemetry JavaScript to use
the OTLP exporter using http/protobuf.
```typescript
const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-proto');
const collectorOptions = {
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics
concurrencyLimit: 1, // an optional limit on pending requests
};
const exporter = new OTLPMetricExporter(collectorOptions);
const meterProvider = new MeterProvider({
readers: [
new PeriodicExportingMetricReader({
exporter,
exportIntervalMillis: 1000,
}),
],
});
// Now, start recording data
const meter = meterProvider.getMeter('example-meter');
const counter = meter.createCounter('metric_name');
counter.add(10, { 'key': 'value' });
```
For a fully functioning code example for using this exporter, please have a look
at: <https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/otlp-exporter-node>

View File

@ -1,92 +0,0 @@
# Propagation
Span context fields like trace id, span id, trace flags, and baggages need to be send to the downstream services
in order to properly associate downstream created spans with the current span.
This is commonly achieved with HTTP headers, RPC metadata, with well-known formats like:
- [W3C Trace Context][]: Supported with [W3CTraceContextPropagator][].
- [B3][]: Supported with [B3Propagator][].
- Jaeger: Supported with [JaegerPropagator][].
If none of the above formats meet your needs, you can implement your own propagator.
## Implement your own propagator
To implement a propagator, you need to define a class implementing the `TextMapPropagator` interface.
```ts
import {
Context,
isSpanContextValid,
isValidSpanId,
isValidTraceId,
TextMapGetter,
TextMapPropagator,
TextMapSetter,
TraceFlags,
trace,
} from '@opentelemetry/api';
import { isTracingSuppressed } from '@opentelemetry/core';
// Example header, the content format can be `<trace-id>:<span-id>`
const MyHeader = 'my-header';
export class MyPropagator implements TextMapPropagator {
// Inject the header to the outgoing request.
inject(context: Context, carrier: unknown, setter: TextMapSetter): void {
const spanContext = trace.getSpanContext(context);
// Skip if the current span context is not valid or suppressed.
if (
!spanContext ||
!isSpanContextValid(spanContext) ||
isTracingSuppressed(context)
) {
return;
}
const value = `${spanContext.traceId}:${spanContext.spanId}`;
setter.set(carrier, MyHeader, value);
// You can set more header fields as you need.
}
// Extract the header from the incoming request.
extract(context: Context, carrier: unknown, getter: TextMapGetter): Context {
const headers = getter.get(carrier, MyHeader);
const header = Array.isArray(headers) ? headers[0] : headers;
if (typeof header !== 'string') return context;
const [traceId, spanId] = header.split(':');
// Skip if the traceId or spanId is invalid.
if (!isValidTraceId(traceId) || !isValidSpanId(spanId)) return context;
return trace.setSpanContext(context, {
traceId,
spanId,
isRemote: true,
traceFlags: TraceFlags.SAMPLED,
});
}
fields(): string[] {
return [MyHeader];
}
}
```
With the propagator defined, you can set it as the global propagator, so that all instrumentations
can make use of it.
```ts
const api = require('@opentelemetry/api');
const { MyPropagator } = require('./my-propagator');
api.propagation.setGlobalPropagator(new MyPropagator());
```
[B3]: https://github.com/openzipkin/b3-propagation
[B3Propagator]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-b3
[JaegerPropagator]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-jaeger
[W3C Trace Context]: https://www.w3.org/TR/trace-context/
[W3CTraceContextPropagator]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core#w3ctracecontextpropagator-propagator

View File

@ -1,641 +0,0 @@
# Upgrade to OpenTelemetry JS SDK 2.x
In late February 2025, the OpenTelemetry JavaScript project released the first versions of "JS SDK 2.x" packages, which include a number of *breaking changes*. This document shows how to migrate to the new 2.x. For the most part, this document *only covers breaking changes*. Refer to the full changelogs for these releases here:
- [CHANGELOG for stable SDK packages](https://github.com/open-telemetry/opentelemetry-js/blob/main/CHANGELOG.md)
- [CHANGELOG for experimental SDK packages](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/CHANGELOG.md)
<!-- TODO: update these changelog links to the 2.0.0 and 0.200.0 anchors when we have a final release. -->
Per [OpenTelemetry guidelines](https://opentelemetry.io/docs/specs/otel/versioning-and-stability/#sdk-support), the 1.x versions of stable SDK packages will be supported for one year from the 2.0.0 release.
If you have any questions about the 2.x changes, please ask! You can reach the OTel JS community on the [#otel-js](https://cloud-native.slack.com/archives/C01NL1GRPQR) channel of the [CNCF Slack](https://slack.cncf.io/), [open a Discussion issue](https://github.com/open-telemetry/opentelemetry-js/issues/new?template=discussion.md) on the repository, or join the weekly [OTel JS SIG zoom call](https://docs.google.com/document/d/1tCyoQK49WVcE-x8oryZOTTToFm7sIeUhxFPm9g-qL1k/edit).
## What is JS SDK 2.x?
"JS SDK 2.x" encompasses new releases of the `@opentelemetry/*` JavaScript packages published from the [opentelemetry-js.git](https://github.com/open-telemetry/opentelemetry-js) repository, except the API and semantic-conventions packages &mdash; categories 3 and 4 in the groupings below. The package versions for this new major will be `>=2.0.0` for the stable and `>=0.200.0` for the unstable packages. (The jump to `0.200.x` was intentional, to hopefully help signal that these packages are in the "2.x generation".)
If your usage of OpenTelemetry does not *directly* use these packages, then you most likely will not need to change your code to migrate. You still need to be aware of the new minimum versions of Node.js, TypeScript, and ES that are supported.
<details>
<summary>Categories of OpenTelemetry JS packages</summary>
The OpenTelemetry JS SIG is responsible for numerous packages, all published to npm under the `@opentelemetry/` org, and developed in two git repositories: [opentelemetry-js.git](https://github.com/open-telemetry/opentelemetry-js) (sometimes called the "core" repo) and [opentelemetry-js-contrib.git](https://github.com/open-telemetry/opentelemetry-js-contrib) (the "contrib" repo). For the sake of this document, these packages can be grouped into these categories:
1. The [API](../api/) (`@opentelemetry/api`). The API is versioned independently of all other packages. Its version is *not* being changed as part of "JS SDK 2.x".
2. The [Semantic Conventions](../semantic-conventions/) (`@opentelemetry/semantic-conventions`). This package follows the [versioning](https://github.com/open-telemetry/semantic-conventions/releases) of the language-independent Semantic Conventions. It is *not* being changed as part of "JS SDK 2.x".
3. [Stable packages from opentelemetry-js.git](../packages/). These are packages that have reached "1.x". These packages are all versioned together, and are at version "1.30.0" at the time of writing.
4. [Unstable packages from opentelemetry-js.git](../experimental/packages/). These are packages deemed still experimental. They are all at "0.x" versions. These packages are all versioned together, and are at version "0.57.0" at the time of writing.
5. All packages from opentelemetry-js-contrib.git. These packages are all versioned independently. These packages are not considered part of the "JS SDK 2.0" release. However, eventually they will update to use JS SDK 2.x releases.
"JS SDK 2.x" refers to categories 3 and 4.
</details>
<details>
<summary>The full set of "JS SDK 2.x" packages</summary>
| Package | Version |
| ------- | ------- |
| @opentelemetry/context-async-hooks | 2.0.0 |
| @opentelemetry/context-zone | 2.0.0 |
| @opentelemetry/context-zone-peer-dep | 2.0.0 |
| @opentelemetry/core | 2.0.0 |
| @opentelemetry/exporter-jaeger | 2.0.0 |
| @opentelemetry/exporter-zipkin | 2.0.0 |
| @opentelemetry/propagator-b3 | 2.0.0 |
| @opentelemetry/propagator-jaeger | 2.0.0 |
| @opentelemetry/resources | 2.0.0 |
| @opentelemetry/sdk-metrics | 2.0.0 |
| @opentelemetry/sdk-trace-base | 2.0.0 |
| @opentelemetry/sdk-trace-node | 2.0.0 |
| @opentelemetry/sdk-trace-web | 2.0.0 |
| @opentelemetry/shim-opentracing | 2.0.0 |
| @opentelemetry/api-events | 0.200.0 |
| @opentelemetry/api-logs | 0.200.0 |
| @opentelemetry/exporter-logs-otlp-grpc | 0.200.0 |
| @opentelemetry/exporter-logs-otlp-http | 0.200.0 |
| @opentelemetry/exporter-logs-otlp-proto | 0.200.0 |
| @opentelemetry/exporter-metrics-otlp-grpc | 0.200.0 |
| @opentelemetry/exporter-metrics-otlp-http | 0.200.0 |
| @opentelemetry/exporter-metrics-otlp-proto | 0.200.0 |
| @opentelemetry/exporter-prometheus | 0.200.0 |
| @opentelemetry/exporter-trace-otlp-grpc | 0.200.0 |
| @opentelemetry/exporter-trace-otlp-http | 0.200.0 |
| @opentelemetry/exporter-trace-otlp-proto | 0.200.0 |
| @opentelemetry/instrumentation | 0.200.0 |
| @opentelemetry/instrumentation-fetch | 0.200.0 |
| @opentelemetry/instrumentation-grpc | 0.200.0 |
| @opentelemetry/instrumentation-http | 0.200.0 |
| @opentelemetry/instrumentation-xml-http-request | 0.200.0 |
| @opentelemetry/opentelemetry-browser-detector | 0.200.0 |
| @opentelemetry/otlp-exporter-base | 0.200.0 |
| @opentelemetry/otlp-grpc-exporter-base | 0.200.0 |
| @opentelemetry/otlp-transformer | 0.200.0 |
| @opentelemetry/sampler-jaeger-remote | 0.200.0 |
| @opentelemetry/sdk-events | 0.200.0 |
| @opentelemetry/sdk-logs | 0.200.0 |
| @opentelemetry/sdk-node | 0.200.0 |
| @opentelemetry/shim-opencensus | 0.200.0 |
| @opentelemetry/web-common | 0.200.0 |
</details>
## 💥 Node.js supported versions
The **minimum supported Node.js has been raised to `^18.19.0 || >=20.6.0`**. This means that support for Node.js 14 and 16 has been dropped.
> [!NOTE]
>
> - The minimum supported Node.js versions for `@opentelemetry/api` (Node.js v8) and `@opentelemetry/semantic-conventions` (Node.js v14) are *not* changing as part of "JS SDK 2.x".
> - The particular minimum *minor* versions of Node.js 18 and 20 were selected to include support for Node.js's `--import` flag and `module.register()` API. It is expected that this will provide a smoother experience for improved automatic ES module instrumentation.
>
> Related issues and PRs:
> [#5395](https://github.com/open-telemetry/opentelemetry-js/issues/5395)
## 💥 TypeScript supported versions
The **minimum supported TypeScript version has been raised to 5.0.4**.
As well, going forward all packages published from this repository will **drop support for old versions of `typescript` in minor releases**. We will only drop support for versions that are older than 2 years.
Important: Both of these changes (typescript@5.0.4, dropping old TypeScript versions in minor releases) **also apply to the `@opentelemetry/api` and `@opentelemetry/semantic-conventions` packages**, even though those two packages aren't otherwise considered part of the "JS SDK 2.x" update.
> [!NOTE]
> Related issues and PRs:
> [#5145](https://github.com/open-telemetry/opentelemetry-js/pull/5145)
## 💥 ES2022 compilation target
The **compilation target for transpiled TypeScript has been raised to ES2022** (from ES2017) for all packages (except `@opentelemetry/api`, `@opentelemetry/api-logs`, `@opentelemetry/api-events`, and `@opentelemetry/semantic-conventions`).
For Browser usage, this drops support for any browser versions that do not support ES2022 features.
For Node.js usage, this already follows from the new minimum supported Node.js versions mentioned above.
> [!NOTE]
> Related issues and PRs:
> [#5393](https://github.com/open-telemetry/opentelemetry-js/issues/5393)
> [#5456](https://github.com/open-telemetry/opentelemetry-js/pull/5456)
## 💥 Drop `window.OTEL_*` support in browsers
For browser users, support for `window.OTEL_*` environment variable configuration (previous handled by the `envDetector`) has been dropped. OpenTelemetry bootstrap code for the browser should be configured via code.
> [!NOTE]
> Related issues and PRs:
> [#5217](https://github.com/open-telemetry/opentelemetry-js/issues/5217)
> [#5455](https://github.com/open-telemetry/opentelemetry-js/pull/5455)
> [#5472](https://github.com/open-telemetry/opentelemetry-js/pull/5472)
> [#5465](https://github.com/open-telemetry/opentelemetry-js/pull/5465)
> [#5473](https://github.com/open-telemetry/opentelemetry-js/pull/5473)
## 💥 `@opentelemetry/resources` API changes
Perhaps the most likely API change you will need to update for is from the `@opentelemetry/resources` package.
<br/>
The `Resource` *class* is no longer exported; instead use new utility functions.
- Creating a resource: `new Resource(...)` -> `resourceFromAttributes(...)`
- Getting the default resource: `Resource.default()` -> `defaultResource()`
- Getting an empty resource: `Resource.empty()` or `Resource.EMPTY` -> `emptyResource()`
- TypeScript interface for a resource: `IResource` -> `Resource`
```ts
// Before
import { Resource } from '@opentelemetry/resources';
new Resource({ ... }); // Create a resource
Resource.default(); // Get a resource with the default attributes
Resource.empty(); // Get an empty resource
// After
import { resourceFromAttributes, defaultResource, emptyResource } from '@opentelemetry/resources';
resourceFromAttributes({ ... });
defaultResource();
emptyResource();
```
<br/>
"Sync" and async resource detectors have been unified. For example, where before there were both `hostDetector` and `hostDetectorSync`, now there is only `hostDetector` which may be used in all cases.
- `envDetectorSync` -> `envDetector`
- `hostDetectorSync` -> `hostDetector`
- `osDetectorSync` -> `osDetector`
- `processDetectorSync` -> `processDetector`
- `serviceInstanceIdDetectorSync` -> `serviceInstanceIdDetector`
- `detectResourcesSync` -> `detectResources`
<br/>
The `browserDetector` and `browserDetectorSync` exports were dropped. This resource detector was long ago replaced by the (semantic-conventions-compliant) browser detector in the separate `@opentelemetry/opentelemetry-browser-detector` package.
- `browserDetector` or `browserDetectorSync` -> `import { browserDetector } from '@opentelemetry/opentelemetry-browser-detector'`
<br/>
As mentioned above, support for `window.OTEL_*` environment variable configuration in browsers has been dropped. This means that the `envDetector` in browsers is now a no-op.
- `envDetector` in a browser -> manually create a resource with the API
<br/>
In TypeScript code, the `ResourceAttributes` type was replaced with the `Attributes` type from the 'api' package. Though unlikely, it is possible this could be a breaking change because it raised the minimum `peerDependencies` entry for `@opentelemetry/api` from `1.0.0` to `1.3.0`.
- type `ResourceAttributes` -> `import type { Attributes } from '@opentelemetry/api';`
<br/>
If you maintain an *implementation* of a resource detector, i.e. if you have a class that `implements DetectorSync` (or the deprecated `Detector`) interface from `@opentelemetry/resources`, then please see the [section below for implementors of resource detectors](#-opentelemetryresources-changes-for-implementors-of-resource-detectors).
- `class ... implements DetectorSync` -> see section below for implementation changes
> [!NOTE]
>
> - In general, the OTel JS packages are trending away from exporting *classes* because that results in exporting types with internal details that inhibit later refactoring. See [#5283](https://github.com/open-telemetry/opentelemetry-js/issues/5283) for details.
> - The unification of sync and async resource detectors simplified the API, clarified the behavior for merging results from multiple detectors, and laid the groundwork for supporting OpenTelemetry *Entities* in the future. See [#5350](https://github.com/open-telemetry/opentelemetry-js/pull/5350) for details.
>
> Related issues and PRs:
> [#5421](https://github.com/open-telemetry/opentelemetry-js/pull/5421)
> [#5467](https://github.com/open-telemetry/opentelemetry-js/pull/5467)
> [#5350](https://github.com/open-telemetry/opentelemetry-js/pull/5350)
> [#5420](https://github.com/open-telemetry/opentelemetry-js/issues/5420)
> [#5217](https://github.com/open-telemetry/opentelemetry-js/issues/5217)
> [#5016](https://github.com/open-telemetry/opentelemetry-js/issues/5016)
## 💥 `@opentelemetry/core` API changes
The environment variable utilities have changed to no longer have one large load and parse of all possible `OTEL_*` environment variables. Instead there are `get{Type}FromEnv()` utilities to handle the various [specified OpenTelemetry SDK environment variable types](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#configuration-types).
The caller should now handle default values. The authority for default values is the [OpenTelemetry Environment Variable Spec](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration). The previously used defaults in the 1.x code can be seen [here](https://github.com/open-telemetry/opentelemetry-js/blob/e9d3c71918635d490b6a9ac9f8259265b38394d0/packages/opentelemetry-core/src/utils/environment.ts#L154-L239).
- `getEnv().OTEL_FOO` -> `get{Type}FromEnv('OTEL_FOO') ?? defaultValue`
- `getStringFromEnv()`
- `getNumberFromEnv()`
- `getBooleanFromEnv()`
- `getStringListFromEnv()`
- `diagLogLevelFromString()` for reading `OTEL_LOG_LEVEL`
- `getEnvWithoutDefaults().OTEL_FOO` -> `get{Type}FromEnv('OTEL_FOO')`
- The following have been removed without replacement:
- `DEFAULT_ENVIRONMENT`
- `ENVIRONMENT`
- `RAW_ENVIRONMENT`
- `parseEnvironment`
For example:
```ts
// Before
import { getEnv, getEnvWithoutDefaults } from '@opentelemetry/core';
const flavor = getEnv().OTEL_EXPORTER_OTLP_PROTOCOL;
const limit = getEnv().OTEL_BSP_MAX_QUEUE_SIZE;
const level = getEnv().OTEL_LOG_LEVEL;
// After
import { getStringFromEnv, getNumberFromEnv, diagLogLevelFromString } from '@opentelemetry/core';
const flavor = getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? 'http/protobuf';
const limit = getNumberFromEnv('OTEL_BSP_MAX_QUEUE_SIZE') ?? 2048;
const level = diagLogLevelFromString(getStringFromEnv('OTEL_LOG_LEVEL'));
```
<br/>
A number of deprecated, obsolete, unused, and accidentally exported functions and variables have been removed from the `core` package. (If there is a replacement, it is mentioned with `-> ...`.)
- `IdGenerator` and `RandomIdGenerator` (deprecated)
- type `InstrumentationLibrary` (deprecated) -> type `InstrumentationScope`
- `AlwaysOnSampler` (deprecated) -> moved to `@opentelemetry/sdk-trace-base`
- `AlwaysOffSampler` (deprecated) -> moved to `@opentelemetry/sdk-trace-base`
- `ParentBasedSampler` (deprecated) -> moved to `@opentelemetry/sdk-trace-base`
- `TraceIdRatioSampler` (deprecated) -> moved to `@opentelemetry/sdk-trace-base`
- `TracesSamplerValues` (was only used internally)
- `VERSION`
- `isWrapped` -> use `isWrapped` from `@opentelemetry/instrumentation`
- `ShimWrapped` -> use `ShimWrapped` from `@opentelemetry/instrumentation`
- `hexToBase64`
- `hexToBinary`
- `baggageUtils.getKeyPairs` (unintentionally exported)
- `baggageUtils.serializeKeyPairs` (unintentionally exported)
- `baggageUtils.parseKeyPairsIntoRecord` -> `parseKeyPairsIntoRecord`
- `baggageUtils.parsePairKeyValue` (unintentionally exported)
- `TimeOriginLegacy`
- `isAttributeKey` (unintentionally exported)
- `DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT` -> use `Infinity`
- `DEFAULT_ATTRIBUTE_VALUE_COUNT_LIMIT` -> use `128`
- `DEFAULT_SPAN_ATTRIBUTE_PER_EVENT_COUNT_LIMIT` -> use `128`
- `DEFAULT_SPAN_ATTRIBUTE_PER_LINK_COUNT_LIMIT` -> use `128`
<br/>
> [!NOTE]
>
> - The `getEnv()` et al API changes avoid a problem of requiring an update to
> `@opentelemetry/core` for any added `OTEL_*` envvars, including in unstable
> packages and packages maintained in the separate contrib repository.
> See [#5443](https://github.com/open-telemetry/opentelemetry-js/pull/5443).
>
> Related issues and PRs:
> [#5443](https://github.com/open-telemetry/opentelemetry-js/pull/5443)
> [#5481](https://github.com/open-telemetry/opentelemetry-js/pull/5481)
> [#5475](https://github.com/open-telemetry/opentelemetry-js/pull/5475)
> [#5309](https://github.com/open-telemetry/opentelemetry-js/pull/5309)
> [#5308](https://github.com/open-telemetry/opentelemetry-js/pull/5308)
> [#5316](https://github.com/open-telemetry/opentelemetry-js/pull/5316)
> [#5406](https://github.com/open-telemetry/opentelemetry-js/pull/5406)
> [#5444](https://github.com/open-telemetry/opentelemetry-js/pull/5444)
> [#5504](https://github.com/open-telemetry/opentelemetry-js/pull/5504)
## 💥 Tracing SDK API changes
This section describes API changes in the set of packages that implement the tracing SDK: `@opentelemetry/sdk-trace-base`, `@opentelemetry/sdk-trace-node`, `@opentelemetry/sdk-trace-web`.
Tracing was the first signal to have an SDK. Over time, and as the Metrics and Logs SDKs were added, the API design separating functionality between the `{Tracer,Meter,Logs}Provider`s APIs and the higher level `NodeSDK` (in `@opentelemetry/sdk-node`) improved. The Tracing SDK was left with some cruft that is being removed in JS SDK 2.0. (See [#5290](https://github.com/open-telemetry/opentelemetry-js/issues/5290) for motivation.)
- removed `BasicTracerProvider#addSpanProcessor(...)` -> use constructor options to the TracerProvider class
- made `BasicTracerProvider#getActiveSpanProcessor()` private
- made `BasicTracerProvider#resource` private
- `BasicTracerProvider` and `NodeTracerProvider` will no longer use the `OTEL_TRACES_EXPORTER` envvar to create exporters -> This functionality already resides in `NodeSDK` (from `@opentelemetry/sdk-node`).
- `BasicTracerProvider` and `NodeTracerProvider` will no longer use the `OTEL_PROPAGATORS` envvar to create propagators -> This functionality already resides in `NodeSDK` (from `@opentelemetry/sdk-node`).
- The following internal properties were removed from `BasicTracerProvider`: `_registeredExporters`, `_getSpanExporter`, `_buildExporterFromEnv`
- The following exports were dropped from `@opentelemetry/sdk-trace-*`:
- `EXPORTER_FACTORY` is not used anymore and has been removed
- `PROPAGATOR_FACTORY` is not used anymore and has been removed
- `ForceFlushState` was intended for internal use and has been removed
- the `Tracer` class was unintentionally exported and has been removed
- to obtain a `Tracer`, please use `BasicTracerProvider#getTracer()`, `NodeTracerProvider#getTracer()` or `WebTracerProvider#getTracer()`
- to reference the `Tracer` type, please use the `Tracer` type from `@opentelemetry/api`
- removed `BasicTracerProvider#register()` -> use `NodeTracerProvider#register()` or `WebTracerProvider#register()`, or call `trace.setGlobalTracerProvider()` et al manually (see [#5503](https://github.com/open-telemetry/opentelemetry-js/pull/5503))
<br/>
The export of the `Span` class has been removed. It was not intended to be used directly. One should always use methods on a `Tracer` instance (e.g. `startSpan()`) for creating spans.
- `new Span(...)` -> use `tracer.startSpan(...)`
<br/>
The `parentSpanId` field on the `Span` and `ReadableSpan` interfaces was replaced by `parentSpanContext`, to adhere to the OTel spec. [#5450](https://github.com/open-telemetry/opentelemetry-js/pull/5450)
- `span.parentSpanId` -> `span.parentSpanContext?.spanId`
<br/>
As mentioned above in the "core" section, `InstrumentationLibrary` has been changed to `InstrumentationScope`:
- `ReadableSpan.instrumentationLibrary` -> `ReadableSpan.instrumentationScope`
<br/>
When invalid data is set on `OTEL_TRACES_SAMPLER`, the SDK now uses `ParentBasedAlwaysOnSampler` rather than `AlwaysOnSampler`, per [spec](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration).
> [!NOTE]
> Related issues and PRs:
> [#5290](https://github.com/open-telemetry/opentelemetry-js/issues/5290)
> [#5134](https://github.com/open-telemetry/opentelemetry-js/pull/5134)
> [#5192](https://github.com/open-telemetry/opentelemetry-js/pull/5192)
> [#5239](https://github.com/open-telemetry/opentelemetry-js/pull/5239)
> [#5355](https://github.com/open-telemetry/opentelemetry-js/pull/5355)
> [#5405](https://github.com/open-telemetry/opentelemetry-js/pull/5405)
> [#5048](https://github.com/open-telemetry/opentelemetry-js/pull/5048)
> [#5450](https://github.com/open-telemetry/opentelemetry-js/pull/5450)
> [#5308](https://github.com/open-telemetry/opentelemetry-js/pull/5308)
> [#5503](https://github.com/open-telemetry/opentelemetry-js/pull/5503)
## 💥 `@opentelemetry/sdk-metrics` API changes
The Metrics SDK now internally uses the `Gauge` and `MetricAdvice` types from the API package, which requires bumping its peer dependency.
- bumped minimum version of `@opentelemetry/api` peer dependency to 1.9.0
<br/>
The `View` *class* has been removed in favor of passing an object of `type ViewOptions` to a MeterProvider. As well, the `*Aggregation` classes have been removed in favor of `type AggregationOption` and the `AggregationType` enum. (See [#4931](https://github.com/open-telemetry/opentelemetry-js/pull/4931) for motivation.)
- removed class `View` -> pass a `type ViewOptions` object to a MeterProvider
- removed `Aggregation` -> pass a `type ViewOptions` object to a MeterProvider
- removed `DefaultAggregation` -> pass a ViewOptions object with `type: AggregationType.DEFAULT`
- removed `DropAggregation` -> pass a ViewOptions object with `type: AggregationType.DROP`
- removed `ExponentialHistogramAggregation` -> pass a ViewOptions object with `type: AggregationType.EXPONENTIAL_HISTOGRAM`
- removed `ExplicitBucketHistogramAggregation` -> pass a ViewOptions object with `type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM`
- removed `HistogramAggregation` -> pass a ViewOptions object with `type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM`
- removed `LastValueAggregation` -> pass a ViewOptions object with `type: AggregationType.LAST_VALUE`
- removed `SumAggregation` -> pass a ViewOptions object with `type: AggregationType.SUM`
For example:
```js
// Before
import {
MeterProvider,
View,
InstrumentType,
ExplicitBucketHistogramAggregation
} from '@opentelemetry/sdk-metrics';
const provider = new MeterProvider({
views: [
new View({
instrumentName: 'http.server.duration',
instrumentType: InstrumentType.HISTOGRAM,
aggregation: new ExplicitBucketHistogramAggregation([0, 1, 5, 10, 15, 20, 25, 30]),
})
]
});
// After
import {MeterProvider, InstrumentType, AggregationType} from '@opentelemetry/sdk-metrics';
const provider = new MeterProvider({
views: [
{ // type ViewOptions
instrumentName: 'http.server.duration',
instrumentType: InstrumentType.HISTOGRAM,
aggregation: { // type AggregationOption
type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM,
options: {
boundaries: [0, 1, 5, 10, 15, 20, 25, 30],
}
}
}
]
});
```
<br/>
The `attributeKeys` View option has been replaced with more capable filtering. (See [#4532](https://github.com/open-telemetry/opentelemetry-js/pull/4532).)
- `attributeKeys` `View` option -> use the `attributesProcessors` ViewOptions property, and `createAllowListAttributesProcessor()` or `createDenyListAttributesProcessor()`
For example:
```js
// Before
import {MeterProvider, View} from '@opentelemetry/sdk-metrics';
const provider = new MeterProvider({
views: [
new View({
attributeKeys: ['attrib1'],
})
]
});
// After
import {MeterProvider, createAllowListAttributesProcessor} from '@opentelemetry/sdk-metrics';
const provider = new MeterProvider({
views: [
{
attributesProcessors: [
createAllowListAttributesProcessor(['attrib1']),
],
}
]
});
```
<br/>
Some deprecated things have been removed:
- drop deprecated `type` field on interface `MetricDescriptor`
- drop deprecated `InstrumentDescriptor` type -> use `MetricDescriptor` instead
<br/>
The following changes were made to MetricReader-related APIs:
- removed `MeterProvider.addMetricReader()` -> use the `readers` constructor option
- new `IMetricReader` interface -> This is preferred to the `MetricReader` abstract class. The `MeterProviderOptions` `readers` constructor option now uses this slightly narrower type.
- If you accept `MetricReader` in your public interface, prefer accepting the more general `IMetricReader` type instead to avoid unintentional breaking changes.
<br/>
> [!NOTE]
> Related issues and PRs:
> [#5254](https://github.com/open-telemetry/opentelemetry-js/pull/5254)
> [#4931](https://github.com/open-telemetry/opentelemetry-js/pull/4931)
> [#4532](https://github.com/open-telemetry/opentelemetry-js/pull/4532)
> [#5291](https://github.com/open-telemetry/opentelemetry-js/pull/5291)
> [#5266](https://github.com/open-telemetry/opentelemetry-js/pull/5266)
> [#4419](https://github.com/open-telemetry/opentelemetry-js/pull/4419)
> [#5311](https://github.com/open-telemetry/opentelemetry-js/pull/5311)
## 💥 `@opentelemetry/resources` changes for *implementors* of Resource Detectors
If you maintain an *implementation* of a resource detector, then you will need to update for JS SDK 2.x. If you have a class that `implements DetectorSync` (or the deprecated `Detector`) interface from `@opentelemetry/resources`, then this section applies to you. There are two cases: if your detector can gather all attribute data *synchronously* (this is the easy case), or if your detector needs to *asynchronously* gather some attribute data.
### Synchronous Resource Detector migration
Before:
```ts
import {
DetectorSync,
Resource,
IResource,
} from '@opentelemetry/resources';
class FooDetector implements DetectorSync {
detect(): IResource {
const attributes = {
'foo.bar': process.env.FOO_BAR,
'foo.baz': process.env.FOO_BAZ,
};
return new Resource(attributes);
}
}
export const fooDetector = new FooDetector();
```
After:
```ts
import { ResourceDetector, DetectedResource } from '@opentelemetry/resources';
// 1. `ResourceDetector` is the interface name now
class FooDetector implements ResourceDetector {
detect(): DetectedResource { // 2.
const attributes = {
'foo.bar': process.env.FOO_BAR,
'foo.baz': process.env.FOO_BAZ,
};
// 2. The `.detect()` method now returns a vanilla JS object with the
// attributes, rather than building a `Resource` instance. The
// type is `DetectedResource` rather than `IResource`.
return { attributes };
}
}
export const fooDetector = new FooDetector();
```
### Asynchronous Resource Detector migration
If your resource detector implementation *asynchronously* gathers attribute data, then the migration to JS SDK 2.x will be a little bit more work. In the newer `@opentelemetry/resources`, the `ResourceDetector#detect()` method must *synchronously* return every attribute *name* that it *may* provide. Any of those attribute *values* can be a Promise that resolves to a value or to `undefined` if not applicable.
Before:
```ts
import {
DetectorSync,
Resource,
IResource,
ResourceAttributes,
} from '@opentelemetry/resources';
class FooDetector implements DetectorSync {
detect(): IResource {
// A common pattern was to asynchronously gather attributes in a separate
// async function and pass that Promise to the second argument to
// `new Resource(...)`.
return new Resource({}, this._getAttributes());
}
private async _getAttributes(): Promise<ResourceAttributes> {
try {
const data = await this._someAsyncFunctionToGatherData();
return {
'foo.pid': data.pid,
'foo.agentUuid': data.agentUuid,
};
} catch {
return {};
}
}
}
export const fooDetector = new FooDetector();
```
After:
```ts
import {
ResourceDetector,
DetectedResource,
DetectedResourceAttributes,
} from '@opentelemetry/resources';
// 1. `ResourceDetector` is the interface name now.
class FooDetector implements ResourceDetector {
// 2. `DetectedResource` is the return type now.
detect(): DetectedResource {
// 3. Get all attributes, as before. Cannot `await` them.
const dataPromise = this._gatherData();
// 4. List all the possible attribute names returned by this detector.
const attrNames = [
'foo.pid',
'foo.agentUuid',
];
const attributes = {} as DetectedResourceAttributes;
attrNames.forEach(name => {
// Each resource attribute is determined asynchronously in _gatherData().
attributes[name] = dataPromise.then(data => data[name]);
});
return { attributes };
}
// 5. Other than the change in function name and return type, this method is
// unchanged from the `_getAttributes` above.
private async _gatherData(): Promise<DetectedResourceAttributes> {
try {
const data = await this._someAsyncFunctionToGatherData();
return {
'foo.pid': data.pid,
'foo.agentUuid': data.agentUuid,
};
} catch {
return {};
}
}
}
export const fooDetector = new FooDetector();
```
This shows **one way** that can localize all code changes to the `.detect()` method.
A concrete example of this can be found in [this commit](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e6c5dbacc2a105ad1f2006504b6984fac97838d7#diff-7c36e5027a21a15157754a62c4b1b7cac3714d92ba263b843af8124c76fb58e1) that migrated the `InstanaAgentDetector` in the `@opentelemetry/resource-detector-instana` package.
### Resource Detector test changes
In your tests, you may need to change how to get a `Resource` instance for assertions.
Before:
```ts
const resource = await fooDetector.detect();
assert.deepStrictEqual(resource.attributes, { ... });
```
After:
```ts
import { detectResources } from '@opentelemetry/resources';
const resource = detectResources({ detectors: [fooDetector] });
await resource.waitForAsyncAttributes?.();
assert.deepStrictEqual(resource.attributes, { ... });
```
## 💥 Other changes
This section describes the remaining breaking changes, not otherwise mentioned in a section above.
Usage of the deprecated `SpanAttributes` and `MetricAttributes` types from the API package has been changed to use the `Attributes` type.
- bumped minimum version of `@opentelemetry/api` peer dependency to 1.1.0 for the following packages: `@opentelemetry/core` [#4408](https://github.com/open-telemetry/opentelemetry-js/pull/4408), `@opentelemetry/resources` [#4428](https://github.com/open-telemetry/opentelemetry-js/pull/4428), `@opentelemetry/sdk-trace-base` [#5009](https://github.com/open-telemetry/opentelemetry-js/pull/5009), `@opentelemetry/shim-opentracing` [#4430](https://github.com/open-telemetry/opentelemetry-js/pull/4430)
<br/>
And finally:
- `@opentelemetry/sdk-node`: The type of `NodeSDKConfiguration.metricReader` has narrowed slightly from `MetricReader` to `IMetricReader`. [#5311](https://github.com/open-telemetry/opentelemetry-js/pull/5311)
- `@opentelemetry/exporter-jaeger`: `ReadableSpan.instrumentationLibrary` -> `ReadableSpan.instrumentationScope` [#5308](https://github.com/open-telemetry/opentelemetry-js/pull/5308)
- `@opentelemetry/exporter-zipkin`: `ReadableSpan.instrumentationLibrary` -> `ReadableSpan.instrumentationScope` [#5308](https://github.com/open-telemetry/opentelemetry-js/pull/5308)
- `@opentelemetry/exporter-prometheus`: Any non-monotonic sums will now be treated as counters and will now include the `_total` suffix. [#5291](https://github.com/open-telemetry/opentelemetry-js/pull/5291) [#5266 (comment)](https://github.com/open-telemetry/opentelemetry-js/pull/5266#issuecomment-2556564698)
- `@opentelemetry/shim-opencenus`: stop mapping removed Instrument `type` to OpenTelemetry metrics [#5291](https://github.com/open-telemetry/opentelemetry-js/pull/5291)
- `@opentelemetry/instrumentation-fetch`: Passthrough original response to `applyCustomAttributes` hook, rather than cloning the response. This means it is no longer possibly to consume the response in `applyCustomAttributes`. [#5281](https://github.com/open-telemetry/opentelemetry-js/pull/5281)

View File

@ -7,7 +7,7 @@ This document describes the OpenTelemetry context API for JavaScript and how it
_Context Specification: <https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.0/specification/context/context.md>_
_Context API Reference: <https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api._opentelemetry_api.ContextAPI.html>_
_Context API Reference: <https://open-telemetry.github.io/opentelemetry-js-api/classes/contextapi.html>_
- [Context Manager](#context-manager)
- [Root Context](#root-context)
@ -32,7 +32,7 @@ import * as api from "@opentelemetry/api";
import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks";
const contextManager = new AsyncHooksContextManager();
contextManager.enable();
context.Manager.enable();
api.context.setGlobalContextManager(contextManager);
```
@ -138,7 +138,7 @@ import * as api from "@opentelemetry/api";
// Returns the active context
// If no context is active, the ROOT_CONTEXT is returned
const ctx = api.context.active();
const ctx = api.context.active();
```
### Set Active Context

3
docs/library-author.md Normal file
View File

@ -0,0 +1,3 @@
# OpenTelemetry for Library Authors
TODO

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