Compare commits

...

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

1488 changed files with 224278 additions and 1027 deletions

View File

@ -1,64 +0,0 @@
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
#
* @dyladan @mayurkale22 @OlivierAlbertini @vmarchaud @markwolff @obecny @mwear @naseemkullah @legendecas @Flarna @johnbley @MSNev @Rauno56
* @open-telemetry/javascript-approvers

139
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View File

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

12
.github/ISSUE_TEMPLATE/discussion.md vendored Normal file
View File

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

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

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

43
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

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

45
.github/repository-settings.md vendored Normal file
View File

@ -0,0 +1,45 @@
# 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)`

55
.github/workflows/benchmark.yml vendored Normal file
View File

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

36
.github/workflows/changelog.yml vendored Normal file
View File

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

27
.github/workflows/close-stale.yml vendored Normal file
View File

@ -0,0 +1,27 @@
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,34 +1,32 @@
name: "CodeQL"
name: "CodeQL Analysis"
on:
workflow_dispatch:
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 * * *'
push:
branches: [ main ]
pull_request:
permissions:
contents: read
jobs:
CodeQL-Build:
permissions:
security-events: write
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v3
with:
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3

View File

@ -0,0 +1,65 @@
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,24 +4,40 @@ 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@v2
- name: Checkout
uses: actions/checkout@v4
- name: Install root dependencies
run: npm install --ignore-scripts
- name: Build 🔧
run: |
npm run compile
npm run docs
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
- uses: actions/setup-node@v4
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: docs/out # The folder the action should deploy.
cache: 'npm'
cache-dependency-path: |
package-lock.json
node-version: '22'
- name: Install and Build 🔧
run: |
npm ci
npm run compile
- 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
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/**

76
.github/workflows/e2e.yml vendored Normal file
View File

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

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

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

View File

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

39
.github/workflows/lint.yml vendored Normal file
View File

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

47
.github/workflows/ossf-scorecard.yml vendored Normal file
View File

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

30
.github/workflows/peer-api.yml vendored Normal file
View File

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

44
.github/workflows/publish-to-npm.yml vendored Normal file
View File

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

79
.github/workflows/sbom.yml vendored Normal file
View File

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

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

View File

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

160
.github/workflows/unit-test.yml vendored Normal file
View File

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

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

17
.gitignore vendored
View File

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

3
.gitmodules vendored Normal file
View File

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

15
.markdownlint-cli2.jsonc Normal file
View File

@ -0,0 +1,15 @@
// 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
}

View File

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

1
.mocharc.yml Normal file
View File

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

1
.npmrc Normal file
View File

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

20
.nycrc Normal file
View File

@ -0,0 +1,20 @@
{
"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

324
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,324 @@
# 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,145 +2,403 @@
---
<p align="center">
<strong>
<a href="https://open-telemetry.github.io/opentelemetry-js-api">API Documentation<a/>
<a href="https://opentelemetry.io/docs/languages/js/getting-started/">Getting Started</a>
&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://github.com/open-telemetry/opentelemetry-js/discussions">Getting In Touch (GitHub Discussions)<a/>
<a href="https://open-telemetry.github.io/opentelemetry-js">API and SDK Reference</a>
</strong>
</p>
<p align="center">
<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 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>
<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 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>
<a href="https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE">
<a href="https://github.com/open-telemetry/opentelemetry-js/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-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 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>
<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>
---
# OpenTelemetry API for JavaScript
## About this project
[![NPM Published Version][npm-img]][npm-url]
[![dependencies][dependencies-image]][dependencies-url]
[![devDependencies][devDependencies-image]][devDependencies-url]
This is the JavaScript version of [OpenTelemetry](https://opentelemetry.io/), a framework for collecting traces, metrics, and logs from applications.
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.
## Quick Start
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].
**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).
## Tracing Quick Start
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/>.
### You Will Need
### Installation
- 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
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.
**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
```shell
npm install --save @opentelemetry/api
npm install --save @opentelemetry/sdk-node
npm install --save @opentelemetry/auto-instrumentations-node
```
### Trace Your Application
**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.
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].
### Set up Tracing
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].
```js
// tracing.js
```javascript
const { trace } = require("@opentelemetry/api");
const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require("@opentelemetry/tracing");
'use strict'
// Create and register an SDK
const provider = new BasicTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
trace.setGlobalTracerProvider(provider);
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');
// 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);
// 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()]
});
// Trace your application by creating spans
async function operation() {
const span = tracer.startSpan("do operation");
// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start();
// 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();
// 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));
});
```
## Version Compatibility
### Run Your Application
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.
```shell
node -r ./tracing.js app.js
```
## Upgrade Guidelines
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]
### 0.21.0 to 1.0.0
## Library Author
No breaking changes
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.
### 0.20.0 to 0.21.0
## Supported Runtimes
- [#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`.
| 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 |
### 1.0.0-rc.3 to 0.20.0
### Node Support
- 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
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 |
## 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-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
[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

1
api/.eslintignore Normal file
View File

@ -0,0 +1 @@
build

8
api/.eslintrc.js Normal file
View File

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

295
api/CHANGELOG.md Normal file
View File

@ -0,0 +1,295 @@
<!-- 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).

201
api/LICENSE Normal file
View File

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

117
api/README.md Normal file
View File

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

24
api/karma.conf.js Normal file
View File

@ -0,0 +1,24 @@
/*!
* 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,
}))
};

24
api/karma.worker.js Normal file
View File

@ -0,0 +1,24 @@
/*!
* 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,
}))
};

103
api/package.json Normal file
View File

@ -0,0 +1,103 @@
{
"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

@ -28,6 +28,8 @@ const NOOP_CONTEXT_MANAGER = new NoopContextManager();
/**
* Singleton object which represents the entry point to the OpenTelemetry Context API
*
* @since 1.0.0
*/
export class ContextAPI {
private static _instance?: ContextAPI;

View File

@ -20,6 +20,7 @@ import {
ComponentLoggerOptions,
DiagLogFunction,
DiagLogger,
DiagLoggerApi,
DiagLogLevel,
} from '../diag/types';
import {
@ -33,8 +34,10 @@ const API_NAME = 'diag';
/**
* Singleton object which represents the entry point to the OpenTelemetry internal
* diagnostic API
*
* @since 1.0.0
*/
export class DiagAPI implements DiagLogger {
export class DiagAPI implements DiagLogger, DiagLoggerApi {
private static _instance?: DiagAPI;
/** Get the singleton instance of the DiagAPI API */
@ -52,16 +55,11 @@ export class DiagAPI implements DiagLogger {
*/
private constructor() {
function _logProxy(funcName: keyof DiagLogger): DiagLogFunction {
return function () {
return function (...args) {
const logger = getGlobal('diag');
// shortcut if logger not set
if (!logger) return;
return logger[funcName].apply(
logger,
// work around Function.prototype.apply types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
arguments as any
);
return logger[funcName](...args);
};
}
@ -70,9 +68,9 @@ export class DiagAPI implements DiagLogger {
// DiagAPI specific functions
self.setLogger = (
logger: DiagLogger,
logLevel: DiagLogLevel = DiagLogLevel.INFO
const setLogger: DiagLoggerApi['setLogger'] = (
logger,
optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }
) => {
if (logger === self) {
// There isn't much we can do here.
@ -85,10 +83,19 @@ export class DiagAPI implements DiagLogger {
return false;
}
if (typeof optionsOrLogLevel === 'number') {
optionsOrLogLevel = {
logLevel: optionsOrLogLevel,
};
}
const oldLogger = getGlobal('diag');
const newLogger = createLogLevelDiagLogger(logLevel, logger);
const newLogger = createLogLevelDiagLogger(
optionsOrLogLevel.logLevel ?? DiagLogLevel.INFO,
logger
);
// There already is an logger registered. We'll let it know before overwriting it.
if (oldLogger) {
if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
const stack = new Error().stack ?? '<failed to generate stacktrace>';
oldLogger.warn(`Current logger will be overwritten from ${stack}`);
newLogger.warn(
@ -99,6 +106,8 @@ export class DiagAPI implements DiagLogger {
return registerGlobal('diag', newLogger, self, true);
};
self.setLogger = setLogger;
self.disable = () => {
unregisterGlobal(API_NAME, self);
};
@ -114,15 +123,7 @@ export class DiagAPI implements DiagLogger {
self.error = _logProxy('error');
}
/**
* Set the global DiagLogger and DiagLogLevel.
* If a global diag logger is already set, this will override it.
*
* @param logger - [Optional] The DiagLogger instance to set as the default logger.
* @param logLevel - [Optional] The DiagLogLevel used to filter logs sent to the logger. If not provided it will default to INFO.
* @returns true if the logger was successfully registered, else false
*/
public setLogger!: (logger: DiagLogger, logLevel?: DiagLogLevel) => boolean;
public setLogger!: DiagLoggerApi['setLogger'];
/**
*
*/

77
api/src/api/metrics.ts Normal file
View File

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

@ -30,6 +30,7 @@ import {
} from '../propagation/TextMapPropagator';
import {
getBaggage,
getActiveBaggage,
setBaggage,
deleteBaggage,
} from '../baggage/context-helpers';
@ -41,6 +42,8 @@ const NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator();
/**
* Singleton object which represents the entry point to the OpenTelemetry Propagation API
*
* @since 1.0.0
*/
export class PropagationAPI {
private static _instance?: PropagationAPI;
@ -112,6 +115,8 @@ export class PropagationAPI {
public getBaggage = getBaggage;
public getActiveBaggage = getActiveBaggage;
public setBaggage = setBaggage;
public deleteBaggage = deleteBaggage;

View File

@ -28,6 +28,7 @@ import { Tracer } from '../trace/tracer';
import { TracerProvider } from '../trace/tracer_provider';
import {
deleteSpan,
getActiveSpan,
getSpan,
getSpanContext,
setSpan,
@ -39,6 +40,8 @@ const API_NAME = 'trace';
/**
* Singleton object which represents the entry point to the OpenTelemetry Tracing API
*
* @since 1.0.0
*/
export class TraceAPI {
private static _instance?: TraceAPI;
@ -102,6 +105,8 @@ export class TraceAPI {
public getSpan = getSpan;
public getActiveSpan = getActiveSpan;
public getSpanContext = getSpanContext;
public setSpan = setSpan;

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
import { ContextAPI } from '../api/context';
import { createContextKey } from '../context/context';
import { Context } from '../context/types';
import { Baggage } from './types';
@ -33,6 +34,15 @@ export function getBaggage(context: Context): Baggage | undefined {
return (context.getValue(BAGGAGE_KEY) as Baggage) || undefined;
}
/**
* Retrieve the current baggage from the active/current context
*
* @returns {Baggage} Extracted baggage from the context
*/
export function getActiveBaggage(): Baggage | undefined {
return getBaggage(ContextAPI.getInstance().active());
}
/**
* Store a baggage in the given context
*

View File

@ -32,6 +32,9 @@ import { baggageEntryMetadataSymbol } from './internal/symbol';
* limitations under the License.
*/
/**
* @since 1.0.0
*/
export interface BaggageEntry {
/** `String` value of the `BaggageEntry`. */
value: string;
@ -45,6 +48,8 @@ export interface BaggageEntry {
/**
* Serializable Metadata defined by the W3C baggage specification.
* It currently has no special meaning defined by the OpenTelemetry or W3C.
*
* @since 1.0.0
*/
export type BaggageEntryMetadata = { toString(): string } & {
__TYPE__: typeof baggageEntryMetadataSymbol;
@ -54,6 +59,8 @@ export type BaggageEntryMetadata = { toString(): string } & {
* Baggage represents collection of key-value pairs with optional metadata.
* Each key of Baggage is associated with exactly one value.
* Baggage may be used to annotate and enrich telemetry data.
*
* @since 1.0.0
*/
export interface Baggage {
/**

View File

@ -14,11 +14,13 @@
* limitations under the License.
*/
import { diag } from '..';
import { DiagAPI } from '../api/diag';
import { BaggageImpl } from './internal/baggage-impl';
import { baggageEntryMetadataSymbol } from './internal/symbol';
import { Baggage, BaggageEntry, BaggageEntryMetadata } from './types';
const diag = DiagAPI.instance();
/**
* Create a new Baggage with optional entries
*
@ -35,6 +37,7 @@ export function createBaggage(
*
* @param str string metadata. Format is currently not defined by the spec and has no special meaning.
*
* @since 1.0.0
*/
export function baggageEntryMetadataFromString(
str: string

View File

@ -14,16 +14,25 @@
* limitations under the License.
*/
export interface SpanAttributes {
[attributeKey: string]: SpanAttributeValue | undefined;
/**
* Attributes is a map from string to attribute values.
*
* Note: only the own enumerable keys are counted as valid attribute keys.
*
* @since 1.3.0
*/
export interface Attributes {
[attributeKey: string]: AttributeValue | undefined;
}
/**
* Attribute values may be any non-nullish primitive value except an object.
*
* null or undefined attribute values are invalid and will result in undefined behavior.
*
* @since 1.3.0
*/
export type SpanAttributeValue =
export type AttributeValue =
| string
| number
| boolean

View File

@ -39,6 +39,8 @@ interface ExceptionWithName {
* Defines Exception.
*
* string or an object with one of (message or name or code) and optional stack
*
* @since 1.0.0
*/
export type Exception =
| ExceptionWithCode

39
api/src/common/Time.ts Normal file
View File

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

24
api/src/context-api.ts Normal file
View File

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

@ -16,7 +16,11 @@
import { Context } from './types';
/** Get a key to uniquely identify a context value */
/**
* Get a key to uniquely identify a context value
*
* @since 1.0.0
*/
export function createContextKey(description: string) {
// The specification states that for the same input, multiple calls should
// return different keys. Due to the nature of the JS dependency management
@ -81,5 +85,9 @@ class BaseContext implements Context {
public deleteValue!: (key: symbol) => Context;
}
/** The root context is used as the default parent context when there is no active context */
/**
* The root context is used as the default parent context when there is no active context
*
* @since 1.0.0
*/
export const ROOT_CONTEXT: Context = new BaseContext();

View File

@ -14,6 +14,9 @@
* limitations under the License.
*/
/**
* @since 1.0.0
*/
export interface Context {
/**
* Get a value from the context.
@ -40,6 +43,9 @@ export interface Context {
deleteValue(key: symbol): Context;
}
/**
* @since 1.0.0
*/
export interface ContextManager {
/**
* Get the current active context

28
api/src/diag-api.ts Normal file
View File

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

@ -15,7 +15,7 @@
*/
import { getGlobal } from '../internal/global-utils';
import { ComponentLoggerOptions, DiagLogger } from './types';
import { ComponentLoggerOptions, DiagLogger, DiagLogFunction } from './types';
/**
* Component Logger which is meant to be used as part of any component which
@ -33,23 +33,23 @@ export class DiagComponentLogger implements DiagLogger {
this._namespace = props.namespace || 'DiagComponentLogger';
}
public debug(...args: any[]): void {
public debug(...args: unknown[]): void {
return logProxy('debug', this._namespace, args);
}
public error(...args: any[]): void {
public error(...args: unknown[]): void {
return logProxy('error', this._namespace, args);
}
public info(...args: any[]): void {
public info(...args: unknown[]): void {
return logProxy('info', this._namespace, args);
}
public warn(...args: any[]): void {
public warn(...args: unknown[]): void {
return logProxy('warn', this._namespace, args);
}
public verbose(...args: any[]): void {
public verbose(...args: unknown[]): void {
return logProxy('verbose', this._namespace, args);
}
}
@ -57,7 +57,7 @@ export class DiagComponentLogger implements DiagLogger {
function logProxy(
funcName: keyof DiagLogger,
namespace: string,
args: any
args: unknown[]
): void {
const logger = getGlobal('diag');
// shortcut if logger not set
@ -66,5 +66,5 @@ function logProxy(
}
args.unshift(namespace);
return logger[funcName].apply(logger, args);
return logger[funcName](...(args as Parameters<DiagLogFunction>));
}

View File

@ -16,7 +16,8 @@
import { DiagLogger, DiagLogFunction } from './types';
const consoleMap: { n: keyof DiagLogger; c: keyof Console }[] = [
type ConsoleMapKeys = 'error' | 'warn' | 'info' | 'debug' | 'trace';
const consoleMap: { n: keyof DiagLogger; c: ConsoleMapKeys }[] = [
{ n: 'error', c: 'error' },
{ n: 'warn', c: 'warn' },
{ n: 'info', c: 'info' },
@ -28,23 +29,26 @@ const consoleMap: { n: keyof DiagLogger; c: keyof Console }[] = [
* A simple Immutable Console based diagnostic logger which will output any messages to the Console.
* If you want to limit the amount of logging to a specific level or lower use the
* {@link createLogLevelDiagLogger}
*
* @since 1.0.0
*/
export class DiagConsoleLogger implements DiagLogger {
constructor() {
function _consoleFunc(funcName: keyof Console): DiagLogFunction {
return function () {
const orgArguments = arguments;
function _consoleFunc(funcName: ConsoleMapKeys): DiagLogFunction {
return function (...args) {
if (console) {
// Some environments only expose the console when the F12 developer console is open
// eslint-disable-next-line no-console
let theFunc = console[funcName];
if (typeof theFunc !== 'function') {
// Not all environments support all functions
// eslint-disable-next-line no-console
theFunc = console.log;
}
// One last final check
if (typeof theFunc === 'function') {
return theFunc.apply(console, orgArguments);
return theFunc.apply(console, args);
}
}
};

View File

@ -14,6 +14,9 @@
* limitations under the License.
*/
/**
* @since 1.0.0
*/
export type DiagLogFunction = (message: string, ...args: unknown[]) => void;
/**
@ -23,6 +26,8 @@ export type DiagLogFunction = (message: string, ...args: unknown[]) => void;
* - a No-Op {@link createNoopDiagLogger}
* - a {@link DiagLogLevel} filtering wrapper {@link createLogLevelDiagLogger}
* - a general Console {@link DiagConsoleLogger} version.
*
* @since 1.0.0
*/
export interface DiagLogger {
/** Log an error scenario that was not expected and caused the requested operation to fail. */
@ -92,7 +97,46 @@ export enum DiagLogLevel {
/**
* Defines options for ComponentLogger
*
* @since 1.0.0
*/
export interface ComponentLoggerOptions {
namespace: string;
}
/**
* @since 1.4.1
*/
export interface DiagLoggerOptions {
/**
* The {@link DiagLogLevel} used to filter logs sent to the logger.
*
* @defaultValue DiagLogLevel.INFO
*/
logLevel?: DiagLogLevel;
/**
* Setting this value to `true` will suppress the warning message normally emitted when registering a logger when another logger is already registered.
*/
suppressOverrideMessage?: boolean;
}
export interface DiagLoggerApi {
/**
* Set the global DiagLogger and DiagLogLevel.
* If a global diag logger is already set, this will override it.
*
* @param logger - The {@link DiagLogger} instance to set as the default logger.
* @param options - A {@link DiagLoggerOptions} object. If not provided, default values will be set.
* @returns `true` if the logger was successfully registered, else `false`
*/
setLogger(logger: DiagLogger, options?: DiagLoggerOptions): boolean;
/**
*
* @param logger - The {@link DiagLogger} instance to set as the default logger.
* @param logLevel - The {@link DiagLogLevel} used to filter logs sent to the logger. If not provided it will default to {@link DiagLogLevel.INFO}.
* @returns `true` if the logger was successfully registered, else `false`
*/
setLogger(logger: DiagLogger, logLevel?: DiagLogLevel): boolean;
}

View File

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

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

@ -0,0 +1,215 @@
/*
* 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);
}
}

133
api/src/index.ts Normal file
View File

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

@ -14,9 +14,9 @@
* limitations under the License.
*/
import type { DiagAPI } from '../api/diag';
import { MeterProvider } from '../metrics/MeterProvider';
import { ContextManager } from '../context/types';
import { DiagLogger } from '../diag';
import { DiagLogger } from '../diag/types';
import { _globalThis } from '../platform';
import { TextMapPropagator } from '../propagation/TextMapPropagator';
import type { TracerProvider } from '../trace/tracer_provider';
@ -33,7 +33,7 @@ const _global = _globalThis as OTelGlobal;
export function registerGlobal<Type extends keyof OTelGlobalAPI>(
type: Type,
instance: OTelGlobalAPI[Type],
diag: DiagAPI,
diag: DiagLogger,
allowOverride = false
): boolean {
const api = (_global[GLOBAL_OPENTELEMETRY_API_KEY] = _global[
@ -54,7 +54,7 @@ export function registerGlobal<Type extends keyof OTelGlobalAPI>(
if (api.version !== VERSION) {
// All registered APIs must be of the same version exactly
const err = new Error(
'@opentelemetry/api: All API registration versions must match'
`@opentelemetry/api: Registration of version v${api.version} for ${type} does not match previously registered API v${VERSION}`
);
diag.error(err.stack || err.message);
return false;
@ -78,7 +78,7 @@ export function getGlobal<Type extends keyof OTelGlobalAPI>(
return _global[GLOBAL_OPENTELEMETRY_API_KEY]?.[type];
}
export function unregisterGlobal(type: keyof OTelGlobalAPI, diag: DiagAPI) {
export function unregisterGlobal(type: keyof OTelGlobalAPI, diag: DiagLogger) {
diag.debug(
`@opentelemetry/api: Unregistering a global for ${type} v${VERSION}.`
);
@ -99,5 +99,6 @@ type OTelGlobalAPI = {
diag?: DiagLogger;
trace?: TracerProvider;
context?: ContextManager;
metrics?: MeterProvider;
propagation?: TextMapPropagator;
};

25
api/src/metrics-api.ts Normal file
View File

@ -0,0 +1,25 @@
/*
* 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();

190
api/src/metrics/Meter.ts Normal file
View File

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

@ -0,0 +1,35 @@
/*
* 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;
}

209
api/src/metrics/Metric.ts Normal file
View File

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

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

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

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

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

@ -14,5 +14,4 @@
* limitations under the License.
*/
export * from './consoleLogger';
export * from './types';
export { _globalThis } from './globalThis';

17
api/src/platform/index.ts Normal file
View File

@ -0,0 +1,17 @@
/*
* 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 './node';

View File

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

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

@ -26,7 +26,10 @@ import { Context } from '../context/types';
* (extractor) side is usually an object such as http headers. Propagation is
* usually implemented via library-specific request interceptors, where the
* client-side injects values and the server-side extracts them.
*
* @since 1.0.0
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface TextMapPropagator<Carrier = any> {
/**
* Injects values from a given `Context` into a carrier.
@ -73,8 +76,11 @@ export interface TextMapPropagator<Carrier = any> {
/**
* A setter is specified by the caller to define a specific method
* to set key/value pairs on the carrier within a propagator.
* to set key/value pairs on the carrier within a propagator
*
* @since 1.0.0
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface TextMapSetter<Carrier = any> {
/**
* Callback used to set a key/value pair on an object.
@ -92,7 +98,10 @@ export interface TextMapSetter<Carrier = any> {
/**
* A getter is specified by the caller to define a specific method
* to get the value of a key from a carrier.
*
* @since 1.0.0
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface TextMapGetter<Carrier = any> {
/**
* Get a list of all keys available on the carrier.
@ -110,6 +119,9 @@ export interface TextMapGetter<Carrier = any> {
get(carrier: Carrier, key: string): undefined | string | string[];
}
/**
* @since 1.0.0
*/
export const defaultTextMapGetter: TextMapGetter = {
get(carrier, key) {
if (carrier == null) {
@ -126,6 +138,9 @@ export const defaultTextMapGetter: TextMapGetter = {
},
};
/**
* @since 1.0.0
*/
export const defaultTextMapSetter: TextMapSetter = {
set(carrier, key, value) {
if (carrier == null) {

26
api/src/trace-api.ts Normal file
View File

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

@ -17,10 +17,11 @@
import { Exception } from '../common/Exception';
import { TimeInput } from '../common/Time';
import { SpanAttributes } from './attributes';
import { INVALID_SPAN_CONTEXT } from './invalid-span-constants';
import { Span } from './span';
import { SpanContext } from './span_context';
import { SpanStatus } from './status';
import { INVALID_SPAN_CONTEXT } from './spancontext-utils';
import { Link } from './link';
/**
* The NonRecordingSpan is the default {@link Span} that is used when no Span
@ -52,6 +53,14 @@ export class NonRecordingSpan implements Span {
return this;
}
addLink(_link: Link): this {
return this;
}
addLinks(_links: Link[]): this {
return this;
}
// By default does nothing
setStatus(_status: SpanStatus): this {
return this;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { context } from '../';
import { ContextAPI } from '../api/context';
import { Context } from '../context/types';
import { getSpanContext, setSpan } from '../trace/context-utils';
import { NonRecordingSpan } from './NonRecordingSpan';
@ -24,12 +24,18 @@ import { SpanOptions } from './SpanOptions';
import { SpanContext } from './span_context';
import { Tracer } from './tracer';
const contextApi = ContextAPI.getInstance();
/**
* No-op implementations of {@link Tracer}.
*/
export class NoopTracer implements Tracer {
// startSpan starts a noop span.
startSpan(name: string, options?: SpanOptions, context?: Context): Span {
startSpan(
name: string,
options?: SpanOptions,
context = contextApi.active()
): Span {
const root = Boolean(options?.root);
if (root) {
return new NonRecordingSpan();
@ -85,19 +91,23 @@ export class NoopTracer implements Tracer {
fn = arg4 as F;
}
const parentContext = ctx ?? context.active();
const parentContext = ctx ?? contextApi.active();
const span = this.startSpan(name, opts, parentContext);
const contextWithSpanSet = setSpan(parentContext, span);
return context.with(contextWithSpanSet, fn, undefined, span);
return contextApi.with(contextWithSpanSet, fn, undefined, span);
}
}
function isSpanContext(spanContext: any): spanContext is SpanContext {
function isSpanContext(spanContext: unknown): spanContext is SpanContext {
return (
spanContext !== null &&
typeof spanContext === 'object' &&
'spanId' in spanContext &&
typeof spanContext['spanId'] === 'string' &&
'traceId' in spanContext &&
typeof spanContext['traceId'] === 'string' &&
'traceFlags' in spanContext &&
typeof spanContext['traceFlags'] === 'number'
);
}

View File

@ -16,6 +16,7 @@
import { NoopTracer } from './NoopTracer';
import { Tracer } from './tracer';
import { TracerOptions } from './tracer_options';
import { TracerProvider } from './tracer_provider';
/**
@ -25,7 +26,11 @@ import { TracerProvider } from './tracer_provider';
* All operations are no-op.
*/
export class NoopTracerProvider implements TracerProvider {
getTracer(_name?: string, _version?: string): Tracer {
getTracer(
_name?: string,
_version?: string,
_options?: TracerOptions
): Tracer {
return new NoopTracer();
}
}

View File

@ -16,24 +16,27 @@
import { Context } from '../context/types';
import { NoopTracer } from './NoopTracer';
import { ProxyTracerProvider } from './ProxyTracerProvider';
import { Span } from './span';
import { SpanOptions } from './SpanOptions';
import { Tracer } from './tracer';
import { TracerOptions } from './tracer_options';
const NOOP_TRACER = new NoopTracer();
/**
* Proxy tracer provided by the proxy tracer provider
*
* @since 1.0.0
*/
export class ProxyTracer implements Tracer {
// When a real implementation is provided, this will be it
private _delegate?: Tracer;
constructor(
private _provider: ProxyTracerProvider,
private _provider: TracerDelegator,
public readonly name: string,
public readonly version?: string
public readonly version?: string,
public readonly options?: TracerOptions
) {}
startSpan(name: string, options?: SpanOptions, context?: Context): Span {
@ -59,7 +62,11 @@ export class ProxyTracer implements Tracer {
return this._delegate;
}
const tracer = this._provider.getDelegateTracer(this.name, this.version);
const tracer = this._provider.getDelegateTracer(
this.name,
this.version,
this.options
);
if (!tracer) {
return NOOP_TRACER;
@ -69,3 +76,14 @@ export class ProxyTracer implements Tracer {
return this._delegate;
}
}
/**
* @since 1.0.3
*/
export interface TracerDelegator {
getDelegateTracer(
name: string,
version?: string,
options?: TracerOptions
): Tracer | undefined;
}

View File

@ -18,6 +18,7 @@ import { Tracer } from './tracer';
import { TracerProvider } from './tracer_provider';
import { ProxyTracer } from './ProxyTracer';
import { NoopTracerProvider } from './NoopTracerProvider';
import { TracerOptions } from './tracer_options';
const NOOP_TRACER_PROVIDER = new NoopTracerProvider();
@ -28,6 +29,8 @@ const NOOP_TRACER_PROVIDER = new NoopTracerProvider();
* When a delegate is set, traces are provided from the delegate.
* When a delegate is set after tracers have already been provided,
* all tracers already provided will use the provided delegate implementation.
*
* @since 1.0.0
*/
export class ProxyTracerProvider implements TracerProvider {
private _delegate?: TracerProvider;
@ -35,10 +38,10 @@ export class ProxyTracerProvider implements TracerProvider {
/**
* Get a {@link ProxyTracer}
*/
getTracer(name: string, version?: string): Tracer {
getTracer(name: string, version?: string, options?: TracerOptions): Tracer {
return (
this.getDelegateTracer(name, version) ??
new ProxyTracer(this, name, version)
this.getDelegateTracer(name, version, options) ??
new ProxyTracer(this, name, version, options)
);
}
@ -53,7 +56,11 @@ export class ProxyTracerProvider implements TracerProvider {
this._delegate = delegate;
}
getDelegateTracer(name: string, version?: string): Tracer | undefined {
return this._delegate?.getTracer(name, version);
getDelegateTracer(
name: string,
version?: string,
options?: TracerOptions
): Tracer | undefined {
return this._delegate?.getTracer(name, version, options);
}
}

View File

@ -21,9 +21,12 @@ import { SamplingResult } from './SamplingResult';
import { SpanKind } from './span_kind';
/**
* @deprecated use the one declared in @opentelemetry/sdk-trace-base instead.
* This interface represent a sampler. Sampling is a mechanism to control the
* noise and overhead introduced by OpenTelemetry by reducing the number of
* samples of traces collected and sent to the backend.
*
* @since 1.0.0
*/
export interface Sampler {
/**

View File

@ -15,10 +15,14 @@
*/
import { SpanAttributes } from './attributes';
import { TraceState } from './trace_state';
/**
* @deprecated use the one declared in @opentelemetry/sdk-trace-base instead.
* A sampling decision that determines how a {@link Span} will be recorded
* and collected.
*
* @since 1.0.0
*/
export enum SamplingDecision {
/**
@ -39,8 +43,11 @@ export enum SamplingDecision {
}
/**
* @deprecated use the one declared in @opentelemetry/sdk-trace-base instead.
* A sampling result contains a decision for a {@link Span} and additional
* attributes the sampler would like to added to the Span.
*
* @since 1.0.0
*/
export interface SamplingResult {
/**
@ -53,4 +60,11 @@ export interface SamplingResult {
* can safely cache the returned value.
*/
attributes?: Readonly<SpanAttributes>;
/**
* A {@link TraceState} that will be associated with the {@link Span} through
* the new {@link SpanContext}. Samplers SHOULD return the TraceState from
* the passed-in {@link Context} if they do not intend to change it. Leaving
* the value undefined will also leave the TraceState unchanged.
*/
traceState?: TraceState;
}

View File

@ -21,6 +21,8 @@ import { SpanKind } from './span_kind';
/**
* Options needed for span creation
*
* @since 1.0.0
*/
export interface SpanOptions {
/**

View File

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

@ -19,6 +19,7 @@ import { Context } from '../context/types';
import { Span } from './span';
import { SpanContext } from './span_context';
import { NonRecordingSpan } from './NonRecordingSpan';
import { ContextAPI } from '../api/context';
/**
* span key
@ -34,6 +35,13 @@ export function getSpan(context: Context): Span | undefined {
return (context.getValue(SPAN_KEY) as Span) || undefined;
}
/**
* Gets the span from the current context, if one exists.
*/
export function getActiveSpan(): Span | undefined {
return getSpan(ContextAPI.getInstance().active());
}
/**
* Set the span on a context
*

View File

@ -0,0 +1,110 @@
/*
* 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;
}
}

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