diff --git a/.codespellrc b/.codespellrc index b81e62f640..b82bff4671 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] # skipping auto generated folders -skip = ./.tox,./.mypy_cache,./docs/_build,./target,*/LICENSE,./venv,.git,./opentelemetry-semantic-conventions +skip = ./.tox,./.mypy_cache,./docs/_build,./target,*/LICENSE,./venv,.git,./opentelemetry-semantic-conventions,*-requirements*.txt ignore-words-list = ans,ue,ot,hist,ro diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2597b185d0..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Bug Report -about: Create a report to help us improve -labels: bug ---- - -**Describe your environment** Describe any aspect of your environment relevant to the problem, including your Python version, [platform](https://docs.python.org/3/library/platform.html), version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main. - -**Steps to reproduce** -Describe exactly how to reproduce the error. Include a code sample if applicable. - -**What is the expected behavior?** -What did you expect to see? - -**What is the actual behavior?** -What did you see instead? - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000000..0ffee73b03 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,68 @@ +--- +name: Bug Report +description: Create a report to help us improve +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down your bug as quickly as possible. + + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-python/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if your bug is already addressed. + If your bug is related to an instrumentation or plugin in [opentelemetry-python-contrib](https://github.com/open-telemetry/opentelemetry-python-contrib) please be sure to file it there. + + - type: textarea + id: environment + attributes: + label: Describe your environment + description: | + Please describe any aspect of your environment relevant to the problem, including your Python version, [platform](https://docs.python.org/3/library/platform.html), version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main. + value: | + OS: (e.g, Ubuntu) + Python version: (e.g., Python 3.8.10) + SDK version: (e.g., 1.25.0) + API version: (e.g., 1.25.0) + + - type: textarea + attributes: + label: What happened? + description: Please provide as much detail as you reasonably can. + validations: + required: true + + - type: textarea + attributes: + label: Steps to Reproduce + description: Provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). We will close the issue if the repro project you share with us is complex or we cannot reproduce the behavior you are reporting. We cannot investigate custom projects, so don't point us to such, please. + validations: + required: true + + - type: textarea + attributes: + label: Expected Result + description: What did you expect to see? + validations: + required: true + + - type: textarea + attributes: + label: Actual Result + description: What did you see instead? + validations: + required: true + + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Add any other context about the problem here. + placeholder: Any additional information... + + - type: dropdown + id: contribute + attributes: + label: Would you like to implement a fix? + description: For guidance on how to get started, refer to the [contribution guide](https://github.com/open-telemetry/opentelemetry-python/blob/main/CONTRIBUTING.md). + options: + - "No" + - "Yes" diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..f6acad9c9b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: Slack + url: https://cloud-native.slack.com/archives/C01PD4HUVBL + about: Or the `#otel-python` channel in the CNCF Slack instance. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 973549ab2d..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Feature Request -about: Suggest an idea for this project -labels: feature-request ---- - -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?** -If so, provide a concise description of the problem. - -**Describe the solution you'd like** -What do you want to happen instead? What is the expected behavior? - -**Describe alternatives you've considered** -Which alternative solutions or features have you considered? - -**Additional context** -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000000..c2e5a1b8c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,50 @@ +--- +name: Feature Request +description: Suggest an idea for this project +labels: [feature-request] +body: + - type: markdown + attributes: + value: | + 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. + - type: textarea + id: related-problem + attributes: + label: Is your feature request related to a problem? + description: Is your feature request related to a problem? If so, provide a concise description of the problem. + placeholder: Include the Issue ID from this or other repos. + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe the solution you'd like + description: What do you want to happen instead? What is the expected behavior? + placeholder: I'd like to ... + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you've considered + description: Which alternative solutions or features have you considered? + placeholder: Some potential solutions + validations: + required: false + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: Add any other context about the feature request here. + placeholder: Some related requests in other projects or upstream spec proposals. + validations: + required: false + - type: dropdown + id: contribute + attributes: + label: Would you like to implement a fix? + description: | + For guidance on how to get started, refer to the [contribution guide](https://github.com/open-telemetry/opentelemetry-python/blob/main/CONTRIBUTING.md). + options: + - "No" + - "Yes" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d564f69c67..cce42bc9fd 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,8 @@ # Description + Fixes # (issue) @@ -21,6 +23,7 @@ Please describe the tests that you ran to verify your changes. Provide instructi # Does This PR Require a Contrib Repo Change? + - [ ] Yes. - Link to PR: - [ ] No. diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index aa909250ad..965b701f31 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -7,42 +7,25 @@ on: jobs: sdk-benchmarks: env: - py311: "3.11" - RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-sdk-${{ matrix.os }} runs-on: self-hosted - strategy: - # Ensures the entire test matrix is run, even if one permutation fails - fail-fast: false - matrix: - python-version: [py311] - os: [ubuntu-20.04, windows-2019] steps: - name: Checkout Core Repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python ${{ env[matrix.python-version] }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env[matrix.python-version] }} + python-version: "3.12" architecture: 'x64' - name: Install tox run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v3-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', - 'dev-requirements.txt') }}-core - name: Run tox - run: tox -f ${{ matrix.python-version }}-sdk -- -k opentelemetry-sdk/tests/performance/benchmarks --benchmark-json=opentelemetry-sdk/tests/output.json + run: tox -e benchmark-opentelemetry-sdk -- -k opentelemetry-sdk/benchmarks --benchmark-json=opentelemetry-sdk/output.json - name: Report on SDK benchmark results uses: benchmark-action/github-action-benchmark@v1 with: - name: OpenTelemetry Python SDK Benchmarks - Python ${{ env[matrix.python-version ]}} - SDK + name: OpenTelemetry Python SDK Benchmarks tool: pytest - output-file-path: opentelemetry-sdk/tests/output.json + output-file-path: opentelemetry-sdk/output.json gh-pages-branch: gh-pages github-token: ${{ secrets.GITHUB_TOKEN }} # Make a commit on `gh-pages` with benchmarks from previous step diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000000..3ef461853c --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,54 @@ +name: Lint tests + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +jobs: + lint-3_12: + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + package: + - "opentelemetry-api" + - "opentelemetry-proto" + - "opentelemetry-sdk" + - "opentelemetry-semantic-conventions" + - "opentelemetry-getting-started" + - "opentelemetry-opentracing-shim" + - "opentelemetry-opencensus-shim" + - "opentelemetry-exporter-opencensus" + - "opentelemetry-exporter-otlp-proto-common" + - "opentelemetry-exporter-otlp-combined" + - "opentelemetry-exporter-otlp-proto-grpc" + - "opentelemetry-exporter-otlp-proto-http" + - "opentelemetry-exporter-otlp-proto-prometheus" + - "opentelemetry-exporter-otlp-proto-zipkin-combined" + - "opentelemetry-exporter-otlp-proto-zipkin-proto-http" + - "opentelemetry-exporter-otlp-proto-zipkin-json" + - "opentelemetry-propagator-b3" + - "opentelemetry-propagator-jaeger" + - "opentelemetry-test-utils" + os: [ubuntu-20.04] + runs-on: ubuntu-20.04 + steps: + - name: Checkout Core Repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: Install tox + run: pip install tox + - name: Cache tox environment + # Preserves .tox directory between runs for faster installs + uses: actions/cache@v4 + with: + path: | + .tox + ~/.cache/pip + key: v7-build-tox-cache-${{ matrix.package }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} + - name: run tox + run: tox -e lint-${{ matrix.package }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 47339d8057..179233c925 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,6 +31,7 @@ jobs: py39: 3.9 py310: "3.10" py311: "3.11" + py312: "3.12" pypy3: pypy-3.8 RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} @@ -38,7 +39,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - python-version: [py38, py39, py310, py311, pypy3] + python-version: [py38, py39, py310, py311, py312, pypy3] package: - "api" - "sdk" @@ -55,7 +56,7 @@ jobs: - "exporter-zipkin-combined" - "exporter-zipkin-proto-http" - "exporter-zipkin-json" - - "protobuf" + - "proto" - "propagator-b3" - "propagator-jaeger" os: [ubuntu-20.04, windows-2019] @@ -68,6 +69,8 @@ jobs: package: "exporter-otlp-combined" - python-version: pypy3 package: "exporter-otlp-proto-grpc" + - python-version: pypy3 + package: "getting-started" steps: - name: Checkout Core Repo @ SHA - ${{ github.sha }} @@ -92,13 +95,12 @@ jobs: if: ${{ matrix.os == 'windows-2019'}} run: git config --system core.longpaths true - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-json=${{ - env.RUN_MATRIX_COMBINATION }}-benchmark.json + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra misc: strategy: fail-fast: false matrix: - tox-environment: ["docker-tests-proto3", "docker-tests-proto4", "lint", "spellcheck", + tox-environment: ["docker-tests-proto3", "docker-tests-proto4", "spellcheck", "docs", "mypy", "mypyinstalled", "tracecontext"] name: ${{ matrix.tox-environment }} runs-on: ubuntu-20.04 diff --git a/.gitignore b/.gitignore index f2324c7bfc..07c7b9aa6e 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,6 @@ docs/examples/django/db.sqlite3 # Semantic conventions scripts/semconv/semantic-conventions + +# Benchmark result files +*-benchmark.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbdffe129b..b01b7ce4d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: rev: 24.3.0 hooks: - id: black - language_version: python3.11 + language_version: python3.12 - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: diff --git a/.pylintrc b/.pylintrc index 976ef7f473..de94393031 100644 --- a/.pylintrc +++ b/.pylintrc @@ -44,6 +44,9 @@ suggestion-mode=yes # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no +# Run python dependant checks considering the baseline version +py-version=3.8 + [MESSAGES CONTROL] diff --git a/CHANGELOG.md b/CHANGELOG.md index 242e82a324..44938228ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- OTLP exporter is encoding invalid span/trace IDs in the logs fix + ([#4006](https://github.com/open-telemetry/opentelemetry-python/pull/4006)) +- Update sdk process resource detector `process.command_args` attribute to also include the executable itself + ([#4032](https://github.com/open-telemetry/opentelemetry-python/pull/4032)) +- Fix `start_time_unix_nano` for delta collection for explicit bucket histogram aggregation + ([#4009](https://github.com/open-telemetry/opentelemetry-python/pull/4009)) +- Fix `start_time_unix_nano` for delta collection for sum aggregation + ([#4011](https://github.com/open-telemetry/opentelemetry-python/pull/4011)) +- Update opentracing and opencesus docs examples to not use JaegerExporter + ([#4023](https://github.com/open-telemetry/opentelemetry-python/pull/4023)) +- Do not execute Flask Tests in debug mode + ([#3956](https://github.com/open-telemetry/opentelemetry-python/pull/3956)) +- When encountering an error encoding metric attributes in the OTLP exporter, log the key that had an error. + ([#3838](https://github.com/open-telemetry/opentelemetry-python/pull/3838)) +- Log a warning when a `LogRecord` in `sdk/log` has dropped attributes + due to reaching limits + ([#3946](https://github.com/open-telemetry/opentelemetry-python/pull/3946)) +- Fix RandomIdGenerator can generate invalid Span/Trace Ids + ([#3949](https://github.com/open-telemetry/opentelemetry-python/pull/3949)) +- Add Python 3.12 to tox + ([#3616](https://github.com/open-telemetry/opentelemetry-python/pull/3616)) +- Improve resource field structure for LogRecords + ([#3972](https://github.com/open-telemetry/opentelemetry-python/pull/3972)) +- Update Semantic Conventions code generation scripts: + - fix namespace exclusion that resulted in dropping `os` and `net` namespaces. + - add `Final` decorator to constants to prevent collisions + - enable mypy and fix detected issues + - allow to drop specific attributes in preparation for Semantic Conventions v1.26.0 + ([#3973](https://github.com/open-telemetry/opentelemetry-python/pull/3966)) +- Update semantic conventions to version 1.26.0. + ([#3964](https://github.com/open-telemetry/opentelemetry-python/pull/3964)) +- Use semconv exception attributes for record exceptions in spans + ([#3979](https://github.com/open-telemetry/opentelemetry-python/pull/3979)) +- Fix _encode_events assumes events.attributes.dropped exists + ([#3965](https://github.com/open-telemetry/opentelemetry-python/pull/3965)) +- Validate links at span creation + ([#3991](https://github.com/open-telemetry/opentelemetry-python/pull/3991)) +- Add attributes field in `MeterProvider.get_meter` and `InstrumentationScope` + ([#4015](https://github.com/open-telemetry/opentelemetry-python/pull/4015)) + ## Version 1.25.0/0.46b0 (2024-05-30) - Fix class BoundedAttributes to have RLock rather than Lock @@ -57,7 +97,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - units with slash are converted e.g. `m/s` -> `meters_per_second`. - The exporter's API is not changed - Add parameters for Distros and configurators to configure autoinstrumentation in addition to existing environment variables. - ([#3864] (https://github.com/open-telemetry/opentelemetry-python/pull/3864)) + ([#3864](https://github.com/open-telemetry/opentelemetry-python/pull/3864)) ## Version 1.24.0/0.45b0 (2024-03-28) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec155c5e72..048a9daa6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,10 +54,10 @@ You can run `tox` with the following arguments: under multiple Python versions - `tox -e docs` to regenerate the API docs - `tox -e opentelemetry-api` and `tox -e opentelemetry-sdk` to run the API and SDK unit tests -- `tox -e py311-opentelemetry-api` to e.g. run the API unit tests under a specific +- `tox -e py312-opentelemetry-api` to e.g. run the API unit tests under a specific Python version - `tox -e spellcheck` to run a spellcheck on all the code -- `tox -e lint` to run lint checks on all code +- `tox -e lint-some-package` to run lint checks on `some-package` `black` and `isort` are executed when `tox -e lint` is run. The reported errors can be tedious to fix manually. An easier way to do so is: @@ -126,7 +126,7 @@ The continuation integration overrides that environment variable with as per the ### Benchmarks -Running the `tox` tests also runs the performance tests if any are available. Benchmarking tests are done with `pytest-benchmark` and they output a table with results to the console. +Some packages have benchmark tests. To run them, run `tox -f benchmark`. Benchmark tests use `pytest-benchmark` and they output a table with results to the console. To write benchmarks, simply use the [pytest benchmark fixture](https://pytest-benchmark.readthedocs.io/en/latest/usage.html#usage) like the following: @@ -142,10 +142,10 @@ def test_simple_start_span(benchmark): benchmark(benchmark_start_as_current_span, "benchmarkedSpan", 42) ``` -Make sure the test file is under the `tests/performance/benchmarks/` folder of +Make sure the test file is under the `benchmarks/` folder of the package it is benchmarking and further has a path that corresponds to the file in the package it is testing. Make sure that the file name begins with -`test_benchmark_`. (e.g. `opentelemetry-sdk/tests/performance/benchmarks/trace/propagation/test_benchmark_b3_format.py`) +`test_benchmark_`. (e.g. `opentelemetry-sdk/benchmarks/trace/propagation/test_benchmark_b3_format.py`) ## Pull Requests @@ -158,6 +158,7 @@ To create a new PR, fork the project in GitHub and clone the upstream repo: ```console $ git clone https://github.com/open-telemetry/opentelemetry-python.git +$ cd opentelemetry-python ``` Add your fork as an origin: @@ -262,3 +263,24 @@ automatically load as options for the `opentelemetry-instrument` command. as specified with the [napoleon extension](http://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#google-vs-numpy) extension in [Sphinx](http://www.sphinx-doc.org/en/master/index.html). + +## Updating supported Python versions + +### Bumping the Python baseline + +When updating the minimum supported Python version remember to: + +- Remove the version in `pyproject.toml` trove classifiers +- Remove the version from `tox.ini` +- Search for `sys.version_info` usage and remove code for unsupported versions +- Bump `py-version` in `.pylintrc` for Python version dependent checks + +### Adding support for a new Python release + +When adding support for a new Python release remember to: + +- Add the version in `tox.ini` +- Add the version in `pyproject.toml` trove classifiers +- Update github workflows accordingly; lint and benchmarks use the latest supported version +- Update `.pre-commit-config.yaml` +- Update tox examples in the documentation diff --git a/dev-requirements.txt b/dev-requirements.txt index 180bccada8..0e63f79d1a 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,17 +7,16 @@ mypy==1.9.0 sphinx==7.1.2 sphinx-rtd-theme==2.0.0rc4 sphinx-autodoc-typehints==1.25.2 -pytest==7.1.3 +pytest==7.4.4 pytest-cov==4.1.0 readme-renderer==42.0 markupsafe==2.1.3 bleach==4.1.0 # This dependency was updated to a breaking version. codespell==2.1.0 -requests==2.31.0 +requests==2.32.3 ruamel.yaml==0.17.21 asgiref==3.7.2 psutil==5.9.6 GitPython==3.1.41 -flaky==3.7.0 pre-commit==3.7.0; python_version >= '3.9' pre-commit==3.5.0; python_version < '3.9' diff --git a/docs/examples/error_handler/error_handler_0/pyproject.toml b/docs/examples/error_handler/error_handler_0/pyproject.toml index 7869303c11..fb8c889e61 100644 --- a/docs/examples/error_handler/error_handler_0/pyproject.toml +++ b/docs/examples/error_handler/error_handler_0/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-sdk ~= 1.3", diff --git a/docs/examples/error_handler/error_handler_1/pyproject.toml b/docs/examples/error_handler/error_handler_1/pyproject.toml index b2e04d4a67..5f72ff5848 100644 --- a/docs/examples/error_handler/error_handler_1/pyproject.toml +++ b/docs/examples/error_handler/error_handler_1/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-sdk ~= 1.3", diff --git a/docs/examples/metrics/instruments/requirements.txt b/docs/examples/metrics/instruments/requirements.txt new file mode 100644 index 0000000000..5c5cb8b1e1 --- /dev/null +++ b/docs/examples/metrics/instruments/requirements.txt @@ -0,0 +1,3 @@ +opentelemetry-api~=1.25 +opentelemetry-sdk~=1.25 +opentelemetry-exporter-otlp~=1.25 diff --git a/docs/examples/opencensus-shim/README.rst b/docs/examples/opencensus-shim/README.rst index 9c24440172..f620fdc086 100644 --- a/docs/examples/opencensus-shim/README.rst +++ b/docs/examples/opencensus-shim/README.rst @@ -20,10 +20,10 @@ Start Jaeger .. code-block:: sh docker run --rm \ - -p 6831:6831/udp \ - -p 6832:6832/udp \ + -p 4317:4317 \ + -p 4318:4318 \ -p 16686:16686 \ - jaegertracing/all-in-one:1.13 \ + jaegertracing/all-in-one:latest \ --log-level=debug Python Dependencies @@ -43,7 +43,7 @@ Alternatively, you can install the Python dependencies separately: pip install \ opentelemetry-api \ opentelemetry-sdk \ - opentelemetry-exporter-jaeger \ + opentelemetry-exporter-otlp \ opentelemetry-opencensus-shim \ opentelemetry-instrumentation-sqlite3 \ opencensus \ diff --git a/docs/examples/opencensus-shim/app.py b/docs/examples/opencensus-shim/app.py index 5c8b7f744b..9103ba5333 100644 --- a/docs/examples/opencensus-shim/app.py +++ b/docs/examples/opencensus-shim/app.py @@ -18,7 +18,9 @@ from opencensus.ext.flask.flask_middleware import FlaskMiddleware from opentelemetry import trace -from opentelemetry.exporter.jaeger.thrift import JaegerExporter +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter, +) from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider @@ -40,9 +42,8 @@ # Configure OTel to export traces to Jaeger tracer_provider.add_span_processor( BatchSpanProcessor( - JaegerExporter( - agent_host_name="localhost", - agent_port=6831, + OTLPSpanExporter( + endpoint="localhost:4317", ) ) ) diff --git a/docs/examples/opencensus-shim/requirements.txt b/docs/examples/opencensus-shim/requirements.txt index da9f0f3f96..9e619db7c9 100644 --- a/docs/examples/opencensus-shim/requirements.txt +++ b/docs/examples/opencensus-shim/requirements.txt @@ -1,6 +1,6 @@ opentelemetry-api opentelemetry-sdk -opentelemetry-exporter-jaeger +opentelemetry-exporter-otlp opentelemetry-opencensus-shim opentelemetry-instrumentation-sqlite3 opencensus diff --git a/docs/examples/opentracing/README.rst b/docs/examples/opentracing/README.rst index 0bf5f8dca3..d811c36fd4 100644 --- a/docs/examples/opentracing/README.rst +++ b/docs/examples/opentracing/README.rst @@ -26,10 +26,10 @@ Start Jaeger .. code-block:: sh docker run --rm \ - -p 6831:6831/udp \ - -p 6832:6832/udp \ + -p 4317:4317 \ + -p 4318:4318 \ -p 16686:16686 \ - jaegertracing/all-in-one:1.13 \ + jaegertracing/all-in-one:latest \ --log-level=debug Redis @@ -61,7 +61,7 @@ Alternatively, you can install the Python dependencies separately: pip install \ opentelemetry-api \ opentelemetry-sdk \ - opentelemetry-exporter-jaeger \ + opentelemetry-exporter-otlp \ opentelemetry-opentracing-shim \ redis \ redis_opentracing diff --git a/docs/examples/opentracing/main.py b/docs/examples/opentracing/main.py index 3975c4a45d..f8a9c55cc5 100755 --- a/docs/examples/opentracing/main.py +++ b/docs/examples/opentracing/main.py @@ -3,7 +3,9 @@ from rediscache import RedisCache from opentelemetry import trace -from opentelemetry.exporter.jaeger.thrift import JaegerExporter +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter, +) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.shim import opentracing_shim @@ -12,13 +14,16 @@ trace.set_tracer_provider(TracerProvider()) tracer_provider = trace.get_tracer_provider() -# Configure the tracer to export traces to Jaeger -jaeger_exporter = JaegerExporter( - agent_host_name="localhost", - agent_port=6831, +# Create an OTLP gRPC span exporter +otlp_exporter = OTLPSpanExporter( + endpoint="http://localhost:4317", + # For insecure connection, useful for testing + insecure=True, +) +# Add the exporter to the tracer provider +trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(otlp_exporter) ) -span_processor = BatchSpanProcessor(jaeger_exporter) -tracer_provider.add_span_processor(span_processor) # Create an OpenTracing shim. This implements the OpenTracing tracer API, but # forwards calls to the underlying OpenTelemetry tracer. diff --git a/docs/examples/opentracing/requirements.txt b/docs/examples/opentracing/requirements.txt index fa4b520936..db390be5fd 100644 --- a/docs/examples/opentracing/requirements.txt +++ b/docs/examples/opentracing/requirements.txt @@ -1,6 +1,6 @@ opentelemetry-api opentelemetry-sdk -opentelemetry-exporter-jaeger +opentelemetry-exporter-otlp opentelemetry-opentracing-shim redis redis_opentracing diff --git a/opentelemetry-api/src/opentelemetry/py.typed b/docs/getting_started/__init__.py similarity index 100% rename from opentelemetry-api/src/opentelemetry/py.typed rename to docs/getting_started/__init__.py diff --git a/docs/getting_started/flask_example.py b/docs/getting_started/flask_example.py index 64ed606c7f..3ddf61d15f 100644 --- a/docs/getting_started/flask_example.py +++ b/docs/getting_started/flask_example.py @@ -40,7 +40,7 @@ @app.route("/") def hello(): with tracer.start_as_current_span("example-request"): - requests.get("http://www.example.com") + requests.get("http://www.example.com", timeout=10) return "hello" diff --git a/docs/getting_started/tests/requirements.txt b/docs/getting_started/tests/requirements.txt index b1246ae9c9..41880ca863 100644 --- a/docs/getting_started/tests/requirements.txt +++ b/docs/getting_started/tests/requirements.txt @@ -1,10 +1,9 @@ asgiref==3.7.2 attrs==23.1.0 -certifi==2023.7.22 +certifi==2024.7.4 charset-normalizer==2.0.12 click==8.1.7 Deprecated==1.2.14 -flaky==3.7.0 Flask==2.3.3 idna==3.7 importlib-metadata==6.8.0 @@ -12,19 +11,20 @@ iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.4 MarkupSafe==2.1.3 -packaging==23.2 +packaging==24.0 pluggy==1.3.0 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 -requests==2.31.0 +pytest==7.4.4 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.8.0 -urllib3==1.26.18 +urllib3==1.26.19 Werkzeug==3.0.3 wrapt==1.15.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-semantic-conventions +-e opentelemetry-proto +-e exporter/opentelemetry-exporter-otlp-proto-common +-e exporter/opentelemetry-exporter-otlp-proto-grpc -e opentelemetry-api -e opentelemetry-sdk diff --git a/docs/getting_started/tests/test_flask.py b/docs/getting_started/tests/test_flask.py index 4d6127f792..ffaa7deb21 100644 --- a/docs/getting_started/tests/test_flask.py +++ b/docs/getting_started/tests/test_flask.py @@ -19,14 +19,16 @@ import requests from requests.adapters import HTTPAdapter -from requests.packages.urllib3.util.retry import Retry +from requests.packages.urllib3.util.retry import ( # pylint: disable=import-error + Retry, +) class TestFlask(unittest.TestCase): def test_flask(self): dirpath = os.path.dirname(os.path.realpath(__file__)) server_script = f"{dirpath}/../flask_example.py" - server = subprocess.Popen( + server = subprocess.Popen( # pylint: disable=consider-using-with [sys.executable, server_script], stdout=subprocess.PIPE, ) diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/py.typed b/exporter/opentelemetry-exporter-jaeger-proto-grpc/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/py.typed b/exporter/opentelemetry-exporter-jaeger-thrift/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-jaeger/py.typed b/exporter/opentelemetry-exporter-jaeger/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-opencensus/py.typed b/exporter/opentelemetry-exporter-opencensus/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-opencensus/pyproject.toml b/exporter/opentelemetry-exporter-opencensus/pyproject.toml index 98a2b49cc0..04af7aca18 100644 --- a/exporter/opentelemetry-exporter-opencensus/pyproject.toml +++ b/exporter/opentelemetry-exporter-opencensus/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/exporter/opentelemetry-exporter-opencensus/test-requirements.txt b/exporter/opentelemetry-exporter-opencensus/test-requirements.txt index c45564ffdb..aad1363f39 100644 --- a/exporter/opentelemetry-exporter-opencensus/test-requirements.txt +++ b/exporter/opentelemetry-exporter-opencensus/test-requirements.txt @@ -1,22 +1,18 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 grpcio==1.62.0 importlib-metadata==6.11.0 iniconfig==2.0.0 opencensus-proto==0.1.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e tests/opentelemetry-test-utils diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/py.typed b/exporter/opentelemetry-exporter-otlp-proto-common/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/pyproject.toml b/exporter/opentelemetry-exporter-otlp-proto-common/pyproject.toml index 8adb298346..a9bdec583b 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/pyproject.toml +++ b/exporter/opentelemetry-exporter-otlp-proto-common/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-proto == 1.26.0.dev", diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py index ba833c95bf..23bc23822c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py @@ -110,7 +110,7 @@ def _encode_attributes( try: pb2_attributes.append(_encode_key_value(key, value)) except Exception as error: - _logger.exception(error) + _logger.exception("Failed to encode key %s: %s", key, error) else: pb2_attributes = None return pb2_attributes diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py index 4252ab7f13..47ff0cf3e0 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py @@ -39,11 +39,21 @@ def encode_logs(batch: Sequence[LogData]) -> ExportLogsServiceRequest: def _encode_log(log_data: LogData) -> PB2LogRecord: + span_id = ( + None + if log_data.log_record.span_id == 0 + else _encode_span_id(log_data.log_record.span_id) + ) + trace_id = ( + None + if log_data.log_record.trace_id == 0 + else _encode_trace_id(log_data.log_record.trace_id) + ) return PB2LogRecord( time_unix_nano=log_data.log_record.timestamp, observed_time_unix_nano=log_data.log_record.observed_timestamp, - span_id=_encode_span_id(log_data.log_record.span_id), - trace_id=_encode_trace_id(log_data.log_record.trace_id), + span_id=span_id, + trace_id=trace_id, flags=int(log_data.log_record.trace_flags), body=_encode_value(log_data.log_record.body), severity_text=log_data.log_record.severity_text, diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py index dd3d2fc50b..97cf608ac8 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py @@ -142,7 +142,7 @@ def _encode_events( name=event.name, time_unix_nano=event.timestamp, attributes=_encode_attributes(event.attributes), - dropped_attributes_count=event.attributes.dropped, + dropped_attributes_count=event.dropped_attributes, ) pb2_events.append(encoded_event) return pb2_events diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt index 276d5f064a..093b69f3fe 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt +++ b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt @@ -1,20 +1,16 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e opentelemetry-semantic-conventions diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt index 658bfcfd62..27e61810db 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt +++ b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt @@ -1,20 +1,16 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==4.25.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e opentelemetry-semantic-conventions diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_attribute_encoder.py b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_attribute_encoder.py new file mode 100644 index 0000000000..0185661103 --- /dev/null +++ b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_attribute_encoder.py @@ -0,0 +1,100 @@ +# 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. + +import unittest +from logging import ERROR + +from opentelemetry.exporter.otlp.proto.common._internal import ( + _encode_attributes, +) +from opentelemetry.proto.common.v1.common_pb2 import AnyValue as PB2AnyValue +from opentelemetry.proto.common.v1.common_pb2 import ( + ArrayValue as PB2ArrayValue, +) +from opentelemetry.proto.common.v1.common_pb2 import KeyValue as PB2KeyValue + + +class TestOTLPAttributeEncoder(unittest.TestCase): + def test_encode_attributes_all_kinds(self): + result = _encode_attributes( + { + "a": 1, # int + "b": 3.14, # float + "c": False, # bool + "hello": "world", # str + "greet": ["hola", "bonjour"], # Sequence[str] + "data": [1, 2], # Sequence[int] + "data_granular": [1.4, 2.4], # Sequence[float] + } + ) + self.assertEqual( + result, + [ + PB2KeyValue(key="a", value=PB2AnyValue(int_value=1)), + PB2KeyValue(key="b", value=PB2AnyValue(double_value=3.14)), + PB2KeyValue(key="c", value=PB2AnyValue(bool_value=False)), + PB2KeyValue( + key="hello", value=PB2AnyValue(string_value="world") + ), + PB2KeyValue( + key="greet", + value=PB2AnyValue( + array_value=PB2ArrayValue( + values=[ + PB2AnyValue(string_value="hola"), + PB2AnyValue(string_value="bonjour"), + ] + ) + ), + ), + PB2KeyValue( + key="data", + value=PB2AnyValue( + array_value=PB2ArrayValue( + values=[ + PB2AnyValue(int_value=1), + PB2AnyValue(int_value=2), + ] + ) + ), + ), + PB2KeyValue( + key="data_granular", + value=PB2AnyValue( + array_value=PB2ArrayValue( + values=[ + PB2AnyValue(double_value=1.4), + PB2AnyValue(double_value=2.4), + ] + ) + ), + ), + ], + ) + + def test_encode_attributes_error_logs_key(self): + with self.assertLogs(level=ERROR) as error: + result = _encode_attributes({"a": 1, "bad_key": None, "b": 2}) + + self.assertEqual(len(error.records), 1) + self.assertEqual(error.records[0].msg, "Failed to encode key %s: %s") + self.assertEqual(error.records[0].args[0], "bad_key") + self.assertIsInstance(error.records[0].args[1], Exception) + self.assertEqual( + result, + [ + PB2KeyValue(key="a", value=PB2AnyValue(int_value=1)), + PB2KeyValue(key="b", value=PB2AnyValue(int_value=2)), + ], + ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py index 58620b963e..158940585c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py @@ -239,8 +239,8 @@ def get_test_logs( PB2LogRecord( time_unix_nano=1644650249738562048, observed_time_unix_nano=1644650249738562049, - trace_id=_encode_trace_id(0), - span_id=_encode_span_id(0), + trace_id=None, + span_id=None, flags=int(TraceFlags.DEFAULT), severity_text="WARN", severity_number=SeverityNumber.WARN.value, diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_metrics_encoder.py b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_metrics_encoder.py index 70863bb44a..6d68b48f25 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_metrics_encoder.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_metrics_encoder.py @@ -296,6 +296,7 @@ def test_encode_gauge_int(self): ), ], time_unix_nano=1641946016139533244, + start_time_unix_nano=0, as_int=9000, ) ], diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/benchmark-requirements.txt b/exporter/opentelemetry-exporter-otlp-proto-grpc/benchmark-requirements.txt new file mode 100644 index 0000000000..44564857ef --- /dev/null +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/benchmark-requirements.txt @@ -0,0 +1 @@ +pytest-benchmark==4.0.0 diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/performance/benchmarks/test_benchmark_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/benchmarks/test_benchmark_trace_exporter.py similarity index 100% rename from exporter/opentelemetry-exporter-otlp-proto-grpc/tests/performance/benchmarks/test_benchmark_trace_exporter.py rename to exporter/opentelemetry-exporter-otlp-proto-grpc/benchmarks/test_benchmark_trace_exporter.py diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/py.typed b/exporter/opentelemetry-exporter-otlp-proto-grpc/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml b/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml index db4639e601..3f1735799a 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "Deprecated >= 1.2.6", diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt b/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt index 5834ac3fcc..abbd8927d0 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt @@ -1,22 +1,18 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 googleapis-common-protos==1.62.0 grpcio==1.62.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e tests/opentelemetry-test-utils -e exporter/opentelemetry-exporter-otlp-proto-common diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt b/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt index c801d210d5..250b55bed8 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt @@ -1,22 +1,18 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 googleapis-common-protos==1.62.0 grpcio==1.62.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==4.25.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e tests/opentelemetry-test-utils -e exporter/opentelemetry-exporter-otlp-proto-common diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index da66f830c2..b81fa4e7bb 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -21,6 +21,7 @@ from google.protobuf.duration_pb2 import ( # pylint: disable=no-name-in-module Duration, ) +from google.protobuf.json_format import MessageToDict from google.rpc.error_details_pb2 import RetryInfo from grpc import ChannelCredentials, Compression, StatusCode, server @@ -77,7 +78,7 @@ def Export(self, request, context): ( "google.rpc.retryinfo-bin", RetryInfo( - retry_delay=Duration(seconds=4) + retry_delay=Duration(nanos=int(1e7)) ).SerializeToString(), ), ) @@ -167,6 +168,36 @@ def setUp(self): "third_name", "third_version" ), ) + self.log_data_4 = LogData( + log_record=LogRecord( + timestamp=int(time.time() * 1e9), + trace_id=0, + span_id=5213367945872657629, + trace_flags=TraceFlags(0x01), + severity_text="ERROR", + severity_number=SeverityNumber.WARN, + body="Invalid trace id check", + resource=SDKResource({"service": "myapp"}), + ), + instrumentation_scope=InstrumentationScope( + "fourth_name", "fourth_version" + ), + ) + self.log_data_5 = LogData( + log_record=LogRecord( + timestamp=int(time.time() * 1e9), + trace_id=2604504634922341076776623263868986801, + span_id=0, + trace_flags=TraceFlags(0x01), + severity_text="ERROR", + severity_number=SeverityNumber.WARN, + body="Invalid span id check", + resource=SDKResource({"service": "myapp"}), + ), + instrumentation_scope=InstrumentationScope( + "fifth_name", "fifth_version" + ), + ) def tearDown(self): self.server.stop(None) @@ -300,7 +331,7 @@ def test_otlp_headers_from_env(self): @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep") def test_unavailable(self, mock_sleep, mock_expo): - mock_expo.configure_mock(**{"return_value": [1]}) + mock_expo.configure_mock(**{"return_value": [0.01]}) add_LogsServiceServicer_to_server( LogsServiceServicerUNAVAILABLE(), self.server @@ -308,7 +339,7 @@ def test_unavailable(self, mock_sleep, mock_expo): self.assertEqual( self.exporter.export([self.log_data_1]), LogExportResult.FAILURE ) - mock_sleep.assert_called_with(1) + mock_sleep.assert_called_with(0.01) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator" @@ -324,7 +355,7 @@ def test_unavailable_delay(self, mock_sleep, mock_expo): self.assertEqual( self.exporter.export([self.log_data_1]), LogExportResult.FAILURE ) - mock_sleep.assert_called_with(4) + mock_sleep.assert_called_with(0.01) def test_success(self): add_LogsServiceServicer_to_server( @@ -342,6 +373,43 @@ def test_failure(self): self.exporter.export([self.log_data_1]), LogExportResult.FAILURE ) + def export_log_and_deserialize(self, log_data): + # pylint: disable=protected-access + translated_data = self.exporter._translate_data([log_data]) + request_dict = MessageToDict(translated_data) + log_records = ( + request_dict.get("resourceLogs")[0] + .get("scopeLogs")[0] + .get("logRecords") + ) + return log_records + + def test_exported_log_without_trace_id(self): + log_records = self.export_log_and_deserialize(self.log_data_4) + if log_records: + log_record = log_records[0] + self.assertIn("spanId", log_record) + self.assertNotIn( + "traceId", + log_record, + "traceId should not be present in the log record", + ) + else: + self.fail("No log records found") + + def test_exported_log_without_span_id(self): + log_records = self.export_log_and_deserialize(self.log_data_5) + if log_records: + log_record = log_records[0] + self.assertIn("traceId", log_record) + self.assertNotIn( + "spanId", + log_record, + "spanId should not be present in the log record", + ) + else: + self.fail("No log records found") + def test_translate_log_data(self): expected = ExportLogsServiceRequest( diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py index c5e1ed76e7..f7bbdabb11 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py @@ -13,8 +13,8 @@ # limitations under the License. import threading -import time from logging import WARNING +from time import time_ns from types import MethodType from typing import Sequence from unittest import TestCase @@ -163,7 +163,7 @@ def code(self): def trailing_metadata(self): return { "google.rpc.retryinfo-bin": RetryInfo( - retry_delay=Duration(seconds=1) + retry_delay=Duration(nanos=int(1e7)) ).SerializeToString() } @@ -196,9 +196,9 @@ def _exporting(self) -> str: # pylint: disable=protected-access self.assertTrue(otlp_mock_exporter._export_lock.locked()) # delay is 1 second while the default shutdown timeout is 30_000 milliseconds - start_time = time.time() + start_time = time_ns() otlp_mock_exporter.shutdown() - now = time.time() + now = time_ns() self.assertGreaterEqual(now, (start_time + 30 / 1000)) # pylint: disable=protected-access self.assertTrue(otlp_mock_exporter._shutdown) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index c52e94a00e..38304962ba 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -13,13 +13,13 @@ # limitations under the License. import threading -import time from concurrent.futures import ThreadPoolExecutor # pylint: disable=too-many-lines from logging import WARNING from os import environ from os.path import dirname +from time import time_ns from typing import List from unittest import TestCase from unittest.mock import patch @@ -97,7 +97,7 @@ def Export(self, request, context): ( "google.rpc.retryinfo-bin", RetryInfo( - retry_delay=Duration(seconds=4) + retry_delay=Duration(nanos=int(1e7)) ).SerializeToString(), ), ) @@ -423,7 +423,7 @@ def test_otlp_exporter_otlp_compression_unspecified( @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep") def test_unavailable(self, mock_sleep, mock_expo): - mock_expo.configure_mock(**{"return_value": [1]}) + mock_expo.configure_mock(**{"return_value": [0.01]}) add_MetricsServiceServicer_to_server( MetricsServiceServicerUNAVAILABLE(), self.server @@ -432,7 +432,7 @@ def test_unavailable(self, mock_sleep, mock_expo): self.exporter.export(self.metrics["sum_int"]), MetricExportResult.FAILURE, ) - mock_sleep.assert_called_with(1) + mock_sleep.assert_called_with(0.01) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator" @@ -449,7 +449,7 @@ def test_unavailable_delay(self, mock_sleep, mock_expo): self.exporter.export(self.metrics["sum_int"]), MetricExportResult.FAILURE, ) - mock_sleep.assert_called_with(4) + mock_sleep.assert_called_with(0.01) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator" @@ -802,9 +802,9 @@ def test_shutdown_wait_last_export(self): # pylint: disable=protected-access self.assertTrue(self.exporter._export_lock.locked()) # delay is 4 seconds while the default shutdown timeout is 30_000 milliseconds - start_time = time.time() + start_time = time_ns() self.exporter.shutdown() - now = time.time() + now = time_ns() self.assertGreaterEqual(now, (start_time + 30 / 1000)) # pylint: disable=protected-access self.assertTrue(self.exporter._shutdown) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 46c467fb2a..46624df1e6 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -14,9 +14,9 @@ import os import threading -import time from concurrent.futures import ThreadPoolExecutor from logging import WARNING +from time import time_ns from unittest import TestCase from unittest.mock import Mock, PropertyMock, patch @@ -91,7 +91,7 @@ def Export(self, request, context): ( "google.rpc.retryinfo-bin", RetryInfo( - retry_delay=Duration(seconds=4) + retry_delay=Duration(nanos=int(1e7)) ).SerializeToString(), ), ) @@ -149,7 +149,7 @@ def setUp(self): ) type(event_mock).name = PropertyMock(return_value="a") - + type(event_mock).dropped_attributes = PropertyMock(return_value=0) self.span = _Span( "a", context=Mock( @@ -466,14 +466,14 @@ def test_otlp_headers(self, mock_ssl_channel, mock_secure): @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep") def test_unavailable(self, mock_sleep, mock_expo): - mock_expo.configure_mock(**{"return_value": [1]}) + mock_expo.configure_mock(**{"return_value": [0.01]}) add_TraceServiceServicer_to_server( TraceServiceServicerUNAVAILABLE(), self.server ) result = self.exporter.export([self.span]) self.assertEqual(result, SpanExportResult.FAILURE) - mock_sleep.assert_called_with(1) + mock_sleep.assert_called_with(0.01) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator" @@ -489,7 +489,7 @@ def test_unavailable_delay(self, mock_sleep, mock_expo): self.assertEqual( self.exporter.export([self.span]), SpanExportResult.FAILURE ) - mock_sleep.assert_called_with(4) + mock_sleep.assert_called_with(0.01) def test_success(self): add_TraceServiceServicer_to_server( @@ -954,9 +954,9 @@ def test_shutdown_wait_last_export(self): # pylint: disable=protected-access self.assertTrue(self.exporter._export_lock.locked()) # delay is 4 seconds while the default shutdown timeout is 30_000 milliseconds - start_time = time.time() + start_time = time_ns() self.exporter.shutdown() - now = time.time() + now = time_ns() self.assertGreaterEqual(now, (start_time + 30 / 1000)) # pylint: disable=protected-access self.assertTrue(self.exporter._shutdown) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/py.typed b/exporter/opentelemetry-exporter-otlp-proto-http/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml b/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml index ab56683b8b..47a7ceae84 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml +++ b/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "Deprecated >= 1.2.6", diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt b/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt index da3590c27c..6d83270f10 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt +++ b/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt @@ -1,28 +1,24 @@ asgiref==3.7.2 -attrs==23.2.0 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 -flaky==3.7.0 googleapis-common-protos==1.62.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 PyYAML==6.0.1 -requests==2.31.0 +requests==2.32.3 responses==0.24.1 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e tests/opentelemetry-test-utils -e exporter/opentelemetry-exporter-otlp-proto-common diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt b/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt index 0faee2e519..28e23c5edf 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt +++ b/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt @@ -1,28 +1,24 @@ asgiref==3.7.2 -attrs==23.2.0 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 -flaky==3.7.0 googleapis-common-protos==1.62.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==4.25.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 PyYAML==6.0.1 -requests==2.31.0 +requests==2.32.3 responses==0.24.1 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e tests/opentelemetry-test-utils -e exporter/opentelemetry-exporter-otlp-proto-common diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index 6b6aafd465..e92ea389af 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -20,6 +20,7 @@ import requests import responses +from google.protobuf.json_format import MessageToDict from opentelemetry._logs import SeverityNumber from opentelemetry.exporter.otlp.proto.http import Compression @@ -31,6 +32,9 @@ OTLPLogExporter, ) from opentelemetry.exporter.otlp.proto.http.version import __version__ +from opentelemetry.proto.collector.logs.v1.logs_service_pb2 import ( + ExportLogsServiceRequest, +) from opentelemetry.sdk._logs import LogData from opentelemetry.sdk._logs import LogRecord as SDKLogRecord from opentelemetry.sdk._logs.export import LogExportResult @@ -167,6 +171,76 @@ def test_exporter_env(self): ) self.assertIsInstance(exporter._session, requests.Session) + @staticmethod + def export_log_and_deserialize(log): + with patch("requests.Session.post") as mock_post: + exporter = OTLPLogExporter() + exporter.export([log]) + request_body = mock_post.call_args[1]["data"] + request = ExportLogsServiceRequest() + request.ParseFromString(request_body) + request_dict = MessageToDict(request) + log_records = ( + request_dict.get("resourceLogs")[0] + .get("scopeLogs")[0] + .get("logRecords") + ) + return log_records + + def test_exported_log_without_trace_id(self): + log = LogData( + log_record=SDKLogRecord( + timestamp=1644650195189786182, + trace_id=0, + span_id=1312458408527513292, + trace_flags=TraceFlags(0x01), + severity_text="WARN", + severity_number=SeverityNumber.WARN, + body="Invalid trace id check", + resource=SDKResource({"first_resource": "value"}), + attributes={"a": 1, "b": "c"}, + ), + instrumentation_scope=InstrumentationScope("name", "version"), + ) + log_records = TestOTLPHTTPLogExporter.export_log_and_deserialize(log) + if log_records: + log_record = log_records[0] + self.assertIn("spanId", log_record) + self.assertNotIn( + "traceId", + log_record, + "trace_id should not be present in the log record", + ) + else: + self.fail("No log records found") + + def test_exported_log_without_span_id(self): + log = LogData( + log_record=SDKLogRecord( + timestamp=1644650195189786360, + trace_id=89564621134313219400156819398935297696, + span_id=0, + trace_flags=TraceFlags(0x01), + severity_text="WARN", + severity_number=SeverityNumber.WARN, + body="Invalid span id check", + resource=SDKResource({"first_resource": "value"}), + attributes={"a": 1, "b": "c"}, + ), + instrumentation_scope=InstrumentationScope("name", "version"), + ) + log_records = TestOTLPHTTPLogExporter.export_log_and_deserialize(log) + if log_records: + log_record = log_records[0] + self.assertIn("traceId", log_record) + self.assertNotIn( + "spanId", + log_record, + "spanId should not be present in the log record", + ) + else: + self.fail("No log records found") + @responses.activate @patch("opentelemetry.exporter.otlp.proto.http._log_exporter.sleep") def test_exponential_backoff(self, mock_sleep): diff --git a/exporter/opentelemetry-exporter-otlp/py.typed b/exporter/opentelemetry-exporter-otlp/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-otlp/pyproject.toml b/exporter/opentelemetry-exporter-otlp/pyproject.toml index 9493120a7a..04967c702a 100644 --- a/exporter/opentelemetry-exporter-otlp/pyproject.toml +++ b/exporter/opentelemetry-exporter-otlp/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/exporter/opentelemetry-exporter-otlp/test-requirements.txt b/exporter/opentelemetry-exporter-otlp/test-requirements.txt index c4283443df..bdb237ab62 100644 --- a/exporter/opentelemetry-exporter-otlp/test-requirements.txt +++ b/exporter/opentelemetry-exporter-otlp/test-requirements.txt @@ -1,19 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e tests/opentelemetry-test-utils -e exporter/opentelemetry-exporter-otlp-proto-common diff --git a/exporter/opentelemetry-exporter-prometheus/py.typed b/exporter/opentelemetry-exporter-prometheus/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-prometheus/pyproject.toml b/exporter/opentelemetry-exporter-prometheus/pyproject.toml index 969b506709..914a848caf 100644 --- a/exporter/opentelemetry-exporter-prometheus/pyproject.toml +++ b/exporter/opentelemetry-exporter-prometheus/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/exporter/opentelemetry-exporter-prometheus/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus/test-requirements.txt index e47c9c80bc..7116753406 100644 --- a/exporter/opentelemetry-exporter-prometheus/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus/test-requirements.txt @@ -1,20 +1,16 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 prometheus_client==0.20.0 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e tests/opentelemetry-test-utils diff --git a/exporter/opentelemetry-exporter-zipkin-json/py.typed b/exporter/opentelemetry-exporter-zipkin-json/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-zipkin-json/pyproject.toml b/exporter/opentelemetry-exporter-zipkin-json/pyproject.toml index f2657001e2..70b4f72ea4 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/pyproject.toml +++ b/exporter/opentelemetry-exporter-zipkin-json/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt b/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt index 98deaf9a6c..6b304a56dd 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt +++ b/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt @@ -1,24 +1,20 @@ asgiref==3.7.2 -attrs==23.2.0 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 -flaky==3.7.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 -requests==2.31.0 +pytest==7.4.4 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e opentelemetry-semantic-conventions diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/py.typed b/exporter/opentelemetry-exporter-zipkin-proto-http/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/pyproject.toml b/exporter/opentelemetry-exporter-zipkin-proto-http/pyproject.toml index 4795ce0425..3ece52427f 100644 --- a/exporter/opentelemetry-exporter-zipkin-proto-http/pyproject.toml +++ b/exporter/opentelemetry-exporter-zipkin-proto-http/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt b/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt index a4536e5fa4..c1913e6928 100644 --- a/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt +++ b/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt @@ -1,26 +1,23 @@ asgiref==3.7.2 -attrs==23.2.0 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 -flaky==3.7.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 -requests==2.31.0 +pytest==7.4.4 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api +-e opentelemetry-proto -e exporter/opentelemetry-exporter-zipkin-json -e opentelemetry-sdk -e tests/opentelemetry-test-utils diff --git a/exporter/opentelemetry-exporter-zipkin/py.typed b/exporter/opentelemetry-exporter-zipkin/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-zipkin/pyproject.toml b/exporter/opentelemetry-exporter-zipkin/pyproject.toml index fc9e3e4ee9..fce1da40e3 100644 --- a/exporter/opentelemetry-exporter-zipkin/pyproject.toml +++ b/exporter/opentelemetry-exporter-zipkin/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/exporter/opentelemetry-exporter-zipkin/test-requirements.txt b/exporter/opentelemetry-exporter-zipkin/test-requirements.txt index b859e401d5..6174e79ba3 100644 --- a/exporter/opentelemetry-exporter-zipkin/test-requirements.txt +++ b/exporter/opentelemetry-exporter-zipkin/test-requirements.txt @@ -1,19 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e exporter/opentelemetry-exporter-zipkin-json -e exporter/opentelemetry-exporter-zipkin-proto-http diff --git a/lint-requirements.txt b/lint-requirements.txt new file mode 100644 index 0000000000..006edb46e8 --- /dev/null +++ b/lint-requirements.txt @@ -0,0 +1,15 @@ +astroid==3.0.3 +black==24.3.0 +click==8.1.7 +dill==0.3.8 +flake8==6.1.0 +isort==5.12.0 +mccabe==0.7.0 +mypy-extensions==1.0.0 +packaging==24.0 +pathspec==0.12.1 +platformdirs==4.2.1 +pycodestyle==2.11.1 +pyflakes==3.1.0 +pylint==3.0.2 +tomlkit==0.12.4 diff --git a/mypy-requirements.txt b/mypy-requirements.txt new file mode 100644 index 0000000000..6b0535fc1c --- /dev/null +++ b/mypy-requirements.txt @@ -0,0 +1 @@ +mypy==1.9.0 diff --git a/opentelemetry-api/py.typed b/opentelemetry-api/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/pyproject.toml b/opentelemetry-api/pyproject.toml index ade38a1cee..7278412f25 100644 --- a/opentelemetry-api/pyproject.toml +++ b/opentelemetry-api/pyproject.toml @@ -22,13 +22,14 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ "Deprecated >= 1.2.6", # FIXME This should be able to be removed after 3.12 is released if there is a reliable API # in importlib.metadata. - "importlib-metadata >= 6.0, <= 7.1", + "importlib-metadata >= 6.0, <= 8.0.0", ] dynamic = [ "version", @@ -54,7 +55,7 @@ default_tracer_provider = "opentelemetry.trace:NoOpTracerProvider" Homepage = "https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-api" [tool.hatch.version] -path = "src/opentelemetry/version.py" +path = "src/opentelemetry/version/__init__.py" [tool.hatch.build.targets.sdist] include = [ diff --git a/opentelemetry-api/src/opentelemetry/_logs/_internal/__init__.py b/opentelemetry-api/src/opentelemetry/_logs/_internal/__init__.py index ccf9f4597a..c02f0bb3dd 100644 --- a/opentelemetry-api/src/opentelemetry/_logs/_internal/__init__.py +++ b/opentelemetry-api/src/opentelemetry/_logs/_internal/__init__.py @@ -14,8 +14,7 @@ """ The OpenTelemetry logging API describes the classes used to generate logs and events. -The :class:`.LoggerProvider` provides users access to the :class:`.Logger` which in -turn is used to create :class:`.Event` and :class:`.Log` objects. +The :class:`.LoggerProvider` provides users access to the :class:`.Logger`. This module provides abstract (i.e. unimplemented) classes required for logging, and a concrete no-op implementation :class:`.NoOpLogger` that allows applications diff --git a/opentelemetry-api/src/opentelemetry/_logs/py.typed b/opentelemetry-api/src/opentelemetry/_logs/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/attributes/py.typed b/opentelemetry-api/src/opentelemetry/attributes/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/baggage/py.typed b/opentelemetry-api/src/opentelemetry/baggage/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/context/py.typed b/opentelemetry-api/src/opentelemetry/context/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/environment_variables.py b/opentelemetry-api/src/opentelemetry/environment_variables/__init__.py similarity index 100% rename from opentelemetry-api/src/opentelemetry/environment_variables.py rename to opentelemetry-api/src/opentelemetry/environment_variables/__init__.py diff --git a/opentelemetry-api/src/opentelemetry/environment_variables/py.typed b/opentelemetry-api/src/opentelemetry/environment_variables/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py b/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py index 9cbf14d2ed..972ff2707c 100644 --- a/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py +++ b/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py @@ -75,6 +75,7 @@ ) from opentelemetry.util._once import Once from opentelemetry.util._providers import _load_provider +from opentelemetry.util.types import Attributes _logger = getLogger(__name__) @@ -102,6 +103,7 @@ def get_meter( name: str, version: Optional[str] = None, schema_url: Optional[str] = None, + attributes: Optional[Attributes] = None, ) -> "Meter": """Returns a `Meter` for use by the given instrumentation library. @@ -128,6 +130,7 @@ def get_meter( ``importlib.metadata.version(instrumenting_library_name)``. schema_url: Optional. Specifies the Schema URL of the emitted telemetry. + attributes: Optional. Attributes that are associated with the emitted telemetry. """ @@ -139,6 +142,7 @@ def get_meter( name: str, version: Optional[str] = None, schema_url: Optional[str] = None, + attributes: Optional[Attributes] = None, ) -> "Meter": """Returns a NoOpMeter.""" return NoOpMeter(name, version=version, schema_url=schema_url) @@ -155,6 +159,7 @@ def get_meter( name: str, version: Optional[str] = None, schema_url: Optional[str] = None, + attributes: Optional[Attributes] = None, ) -> "Meter": with self._lock: if self._real_meter_provider is not None: diff --git a/opentelemetry-api/src/opentelemetry/metrics/py.typed b/opentelemetry-api/src/opentelemetry/metrics/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/propagate/py.typed b/opentelemetry-api/src/opentelemetry/propagate/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/propagators/py.typed b/opentelemetry-api/src/opentelemetry/propagators/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/trace/py.typed b/opentelemetry-api/src/opentelemetry/trace/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/util/py.typed b/opentelemetry-api/src/opentelemetry/util/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/src/opentelemetry/version.py b/opentelemetry-api/src/opentelemetry/version/__init__.py similarity index 100% rename from opentelemetry-api/src/opentelemetry/version.py rename to opentelemetry-api/src/opentelemetry/version/__init__.py diff --git a/opentelemetry-api/src/opentelemetry/version/py.typed b/opentelemetry-api/src/opentelemetry/version/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-api/test-requirements.txt b/opentelemetry-api/test-requirements.txt index 90247015a0..9dbb8596c7 100644 --- a/opentelemetry-api/test-requirements.txt +++ b/opentelemetry-api/test-requirements.txt @@ -1,19 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-sdk -e opentelemetry-semantic-conventions -e tests/opentelemetry-test-utils diff --git a/opentelemetry-proto/py.typed b/opentelemetry-proto/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-proto/pyproject.toml b/opentelemetry-proto/pyproject.toml index 0e0c133119..505a88f4d5 100644 --- a/opentelemetry-proto/pyproject.toml +++ b/opentelemetry-proto/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "protobuf>=3.19, < 5.0", @@ -32,7 +33,7 @@ dependencies = [ Homepage = "https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-proto" [tool.hatch.version] -path = "src/opentelemetry/proto/version.py" +path = "src/opentelemetry/proto/version/__init__.py" [tool.hatch.build.targets.sdist] include = [ diff --git a/opentelemetry-proto/src/opentelemetry/proto/version.py b/opentelemetry-proto/src/opentelemetry/proto/version/__init__.py similarity index 100% rename from opentelemetry-proto/src/opentelemetry/proto/version.py rename to opentelemetry-proto/src/opentelemetry/proto/version/__init__.py diff --git a/opentelemetry-proto/test-requirements-0.txt b/opentelemetry-proto/test-requirements-0.txt index 811544a082..671756980c 100644 --- a/opentelemetry-proto/test-requirements-0.txt +++ b/opentelemetry-proto/test-requirements-0.txt @@ -1,18 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-proto diff --git a/opentelemetry-proto/test-requirements-1.txt b/opentelemetry-proto/test-requirements-1.txt index 5b10e6867a..b598b4f172 100644 --- a/opentelemetry-proto/test-requirements-1.txt +++ b/opentelemetry-proto/test-requirements-1.txt @@ -1,18 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==4.25.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-proto diff --git a/opentelemetry-sdk/benchmark-requirements.txt b/opentelemetry-sdk/benchmark-requirements.txt new file mode 100644 index 0000000000..44564857ef --- /dev/null +++ b/opentelemetry-sdk/benchmark-requirements.txt @@ -0,0 +1 @@ +pytest-benchmark==4.0.0 diff --git a/opentelemetry-sdk/tests/performance/benchmarks/metrics/test_benchmark_metrics.py b/opentelemetry-sdk/benchmarks/metrics/test_benchmark_metrics.py similarity index 100% rename from opentelemetry-sdk/tests/performance/benchmarks/metrics/test_benchmark_metrics.py rename to opentelemetry-sdk/benchmarks/metrics/test_benchmark_metrics.py diff --git a/opentelemetry-sdk/tests/performance/benchmarks/metrics/test_benchmark_metrics_histogram,.py b/opentelemetry-sdk/benchmarks/metrics/test_benchmark_metrics_histogram,.py similarity index 100% rename from opentelemetry-sdk/tests/performance/benchmarks/metrics/test_benchmark_metrics_histogram,.py rename to opentelemetry-sdk/benchmarks/metrics/test_benchmark_metrics_histogram,.py diff --git a/opentelemetry-sdk/tests/performance/benchmarks/trace/test_benchmark_trace.py b/opentelemetry-sdk/benchmarks/trace/test_benchmark_trace.py similarity index 100% rename from opentelemetry-sdk/tests/performance/benchmarks/trace/test_benchmark_trace.py rename to opentelemetry-sdk/benchmarks/trace/test_benchmark_trace.py diff --git a/opentelemetry-sdk/py.typed b/opentelemetry-sdk/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/pyproject.toml b/opentelemetry-sdk/pyproject.toml index 6ba709e629..a606f47f1d 100644 --- a/opentelemetry-sdk/pyproject.toml +++ b/opentelemetry-sdk/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ @@ -71,7 +72,7 @@ process = "opentelemetry.sdk.resources:ProcessResourceDetector" Homepage = "https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-sdk" [tool.hatch.version] -path = "src/opentelemetry/sdk/version.py" +path = "src/opentelemetry/sdk/version/__init__.py" [tool.hatch.build.targets.sdist] include = [ diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/__init__.py index 881bb9a4b2..0254c135e8 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/__init__.py @@ -15,6 +15,7 @@ from opentelemetry.sdk._logs._internal import ( LogData, + LogDroppedAttributesWarning, Logger, LoggerProvider, LoggingHandler, @@ -31,4 +32,5 @@ "LogLimits", "LogRecord", "LogRecordProcessor", + "LogDroppedAttributesWarning", ] diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py index 0883594297..81103ea163 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py @@ -19,6 +19,7 @@ import logging import threading import traceback +import warnings from os import environ from time import time_ns from typing import Any, Callable, Optional, Tuple, Union # noqa @@ -57,6 +58,18 @@ _ENV_VALUE_UNSET = "" +class LogDroppedAttributesWarning(UserWarning): + """Custom warning to indicate dropped log attributes due to limits. + + This class is used to filter and handle these specific warnings separately + from other warnings, ensuring that they are only shown once without + interfering with default user warnings. + """ + + +warnings.simplefilter("once", LogDroppedAttributesWarning) + + class LogLimits: """This class is based on a SpanLimits class in the Tracing module. @@ -189,7 +202,15 @@ def __init__( ), } ) - self.resource = resource + self.resource = ( + resource if isinstance(resource, Resource) else Resource.create({}) + ) + if self.dropped_attributes > 0: + warnings.warn( + "Log record attributes were dropped due to limits", + LogDroppedAttributesWarning, + stacklevel=2, + ) def __eq__(self, other: object) -> bool: if not isinstance(other, LogRecord): @@ -219,9 +240,7 @@ def to_json(self, indent=4) -> str: else "" ), "trace_flags": self.trace_flags, - "resource": ( - repr(self.resource.attributes) if self.resource else "" - ), + "resource": json.loads(self.resource.to_json()), }, indent=indent, ) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/__init__.py similarity index 100% rename from opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py rename to opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/__init__.py diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py index 1e3a4528e3..9dc95c0edb 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py @@ -54,6 +54,7 @@ from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.util.instrumentation import InstrumentationScope from opentelemetry.util._once import Once +from opentelemetry.util.types import Attributes _logger = getLogger(__name__) @@ -518,6 +519,7 @@ def get_meter( name: str, version: Optional[str] = None, schema_url: Optional[str] = None, + attributes: Optional[Attributes] = None, ) -> Meter: if self._disabled: @@ -534,7 +536,7 @@ def get_meter( _logger.warning("Meter name cannot be None or empty.") return NoOpMeter(name, version=version, schema_url=schema_url) - info = InstrumentationScope(name, version, schema_url) + info = InstrumentationScope(name, version, schema_url, attributes) with self._meter_lock: if not self._meters.get(info): # FIXME #2558 pass SDKConfig object to meter so that the meter diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py index 9bec7de3e7..3a09cdcfea 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py @@ -278,9 +278,6 @@ def collect( is AggregationTemporality.DELTA ): - if current_value is None: - return None - previous_collection_start_nano = ( self._previous_collection_start_nano ) @@ -288,6 +285,9 @@ def collect( collection_start_nano ) + if current_value is None: + return None + return NumberDataPoint( attributes=self._attributes, start_time_unix_nano=previous_collection_start_nano, @@ -370,7 +370,7 @@ def collect( return NumberDataPoint( attributes=self._attributes, - start_time_unix_nano=0, + start_time_unix_nano=None, time_unix_nano=collection_start_nano, value=value, ) @@ -471,9 +471,6 @@ def collect( is AggregationTemporality.DELTA ): - if current_value is None: - return None - previous_collection_start_nano = ( self._previous_collection_start_nano ) @@ -481,6 +478,9 @@ def collect( collection_start_nano ) + if current_value is None: + return None + return HistogramDataPoint( attributes=self._attributes, start_time_unix_nano=previous_collection_start_nano, diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md index ba9601bdf9..0cf5c8c59b 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md @@ -54,7 +54,7 @@ $mantissa$ is a positive fractional number whose integer part is $1$, for exampl $1.2345 \dots$. The `mantissa` bits represent only the fractional part and the $mantissa$ value can be calculated as: -$$mantissa = 1 + \sum_{i=1}^{52} b_{i} \times 2^{-i} = 1 + \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{63}}{2^{63}} + \frac{b_{52}}{2^{52}}$$ +$$mantissa = 1 + \sum_{i=1}^{52} b_{i} \times 2^{-i} = 1 + \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{51}}{2^{51}} + \frac{b_{52}}{2^{52}}$$ Where $b_{i}$ is: @@ -67,7 +67,7 @@ $mantissa$ is a positive fractional number whose integer part is $0$, for exampl $0.12345 \dots$. The `mantissa` bits represent only the fractional part and the $mantissa$ value can be calculated as: -$$mantissa = \sum_{i=1}^{52} b_{i} \times 2^{-i} = \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{63}}{2^{63}} + \frac{b_{52}}{2^{52}}$$ +$$mantissa = \sum_{i=1}^{52} b_{i} \times 2^{-i} = \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{51}}{2^{51}} + \frac{b_{52}}{2^{52}}$$ Where $b_{i}$ is: diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py index 53268fc749..eb946ec647 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py @@ -519,7 +519,13 @@ def _ticker(self) -> None: exc_info=True, ) # one last collection below before shutting down completely - self.collect(timeout_millis=self._export_interval_millis) + try: + self.collect(timeout_millis=self._export_interval_millis) + except MetricsTimeoutError: + _logger.warning( + "Metric collection timed out.", + exc_info=True, + ) def _receive_metrics( self, diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 0cdd70d97c..1fed32c0be 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -81,7 +81,7 @@ psutil = None LabelValue = AttributeValue -Attributes = typing.Dict[str, LabelValue] +Attributes = typing.Mapping[str, LabelValue] logger = logging.getLogger(__name__) CLOUD_PROVIDER = ResourceAttributes.CLOUD_PROVIDER @@ -348,7 +348,7 @@ def detect(self) -> "Resource": _process_executable_path = os.path.dirname(_process_executable_name) _process_command = sys.argv[0] _process_command_line = " ".join(sys.argv) - _process_command_args = sys.argv[1:] + _process_command_args = sys.argv resource_info = { PROCESS_RUNTIME_DESCRIPTION: sys.version, PROCESS_RUNTIME_NAME: sys.implementation.name, diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/resources/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 301c64a012..dab489f376 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -64,6 +64,12 @@ InstrumentationInfo, InstrumentationScope, ) +from opentelemetry.semconv.attributes.exception_attributes import ( + EXCEPTION_ESCAPED, + EXCEPTION_MESSAGE, + EXCEPTION_STACKTRACE, + EXCEPTION_TYPE, +) from opentelemetry.trace import NoOpTracer, SpanContext from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util import types @@ -331,6 +337,12 @@ def __init__( def attributes(self) -> types.Attributes: return self._attributes + @property + def dropped_attributes(self) -> int: + if isinstance(self._attributes, BoundedAttributes): + return self._attributes.dropped + return 0 + def _check_span_ended(func): def wrapper(self, *args, **kwargs): @@ -808,16 +820,7 @@ def __init__( ) self._events.append(event) - if links is None: - self._links = self._new_links() - else: - for link in links: - link._attributes = BoundedAttributes( - self._limits.max_link_attributes, - link.attributes, - max_value_len=self._limits.max_attribute_length, - ) - self._links = BoundedList.from_seq(self._limits.max_links, links) + self._links = self._new_links(links) def __repr__(self): return f'{type(self).__name__}(name="{self._name}", context={self._context})' @@ -825,8 +828,22 @@ def __repr__(self): def _new_events(self): return BoundedList(self._limits.max_events) - def _new_links(self): - return BoundedList(self._limits.max_links) + def _new_links(self, links: Sequence[trace_api.Link]): + if not links: + return BoundedList(self._limits.max_links) + + valid_links = [] + for link in links: + if link and _is_valid_link(link.context, link.attributes): + # pylint: disable=protected-access + link._attributes = BoundedAttributes( + self._limits.max_link_attributes, + link.attributes, + max_value_len=self._limits.max_attribute_length, + ) + valid_links.append(link) + + return BoundedList.from_seq(self._limits.max_links, valid_links) def get_span_context(self): return self._context @@ -1020,10 +1037,10 @@ def record_exception( else qualname ) _attributes: MutableMapping[str, types.AttributeValue] = { - "exception.type": exception_type, - "exception.message": str(exception), - "exception.stacktrace": stacktrace, - "exception.escaped": str(escaped), + EXCEPTION_TYPE: exception_type, + EXCEPTION_MESSAGE: str(exception), + EXCEPTION_STACKTRACE: stacktrace, + EXCEPTION_ESCAPED: str(escaped), } if attributes: _attributes.update(attributes) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/id_generator.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/id_generator.py index 62b12a9492..cd1f89bcde 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/id_generator.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/id_generator.py @@ -15,6 +15,8 @@ import abc import random +from opentelemetry import trace + class IdGenerator(abc.ABC): @abc.abstractmethod @@ -46,7 +48,13 @@ class RandomIdGenerator(IdGenerator): """ def generate_span_id(self) -> int: - return random.getrandbits(64) + span_id = random.getrandbits(64) + while span_id == trace.INVALID_SPAN_ID: + span_id = random.getrandbits(64) + return span_id def generate_trace_id(self) -> int: - return random.getrandbits(128) + trace_id = random.getrandbits(128) + while trace_id == trace.INVALID_TRACE_ID: + trace_id = random.getrandbits(128) + return trace_id diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/trace/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/util/instrumentation.py b/opentelemetry-sdk/src/opentelemetry/sdk/util/instrumentation.py index 085d3fd874..a6fd7d7f66 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/util/instrumentation.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/util/instrumentation.py @@ -16,6 +16,9 @@ from deprecated import deprecated +from opentelemetry.attributes import BoundedAttributes +from opentelemetry.util.types import Attributes + class InstrumentationInfo: """Immutable information about an instrumentation library module. @@ -82,22 +85,24 @@ class InstrumentationScope: properties. """ - __slots__ = ("_name", "_version", "_schema_url") + __slots__ = ("_name", "_version", "_schema_url", "_attributes") def __init__( self, name: str, version: Optional[str] = None, schema_url: Optional[str] = None, + attributes: Optional[Attributes] = None, ) -> None: self._name = name self._version = version if schema_url is None: schema_url = "" self._schema_url = schema_url + self._attributes = BoundedAttributes(attributes=attributes) def __repr__(self) -> str: - return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url})" + return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url}, {self._attributes})" def __hash__(self) -> int: return hash((self._name, self._version, self._schema_url)) @@ -105,19 +110,31 @@ def __hash__(self) -> int: def __eq__(self, value: object) -> bool: if not isinstance(value, InstrumentationScope): return NotImplemented - return (self._name, self._version, self._schema_url) == ( + return ( + self._name, + self._version, + self._schema_url, + self._attributes, + ) == ( value._name, value._version, value._schema_url, + value._attributes, ) def __lt__(self, value: object) -> bool: if not isinstance(value, InstrumentationScope): return NotImplemented - return (self._name, self._version, self._schema_url) < ( + return ( + self._name, + self._version, + self._schema_url, + self._attributes, + ) < ( value._name, value._version, value._schema_url, + value._attributes, ) @property @@ -132,12 +149,19 @@ def version(self) -> Optional[str]: def name(self) -> str: return self._name + @property + def attributes(self) -> Attributes: + return self._attributes + def to_json(self, indent=4) -> str: return dumps( { "name": self._name, "version": self._version, "schema_url": self._schema_url, + "attributes": ( + dict(self._attributes) if bool(self._attributes) else None + ), }, indent=indent, ) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/util/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/util/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/version.py b/opentelemetry-sdk/src/opentelemetry/sdk/version/__init__.py similarity index 100% rename from opentelemetry-sdk/src/opentelemetry/sdk/version.py rename to opentelemetry-sdk/src/opentelemetry/sdk/version/__init__.py diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/version/py.typed b/opentelemetry-sdk/src/opentelemetry/sdk/version/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-sdk/test-requirements.txt b/opentelemetry-sdk/test-requirements.txt index 9612f35439..8a7ccc7bd7 100644 --- a/opentelemetry-sdk/test-requirements.txt +++ b/opentelemetry-sdk/test-requirements.txt @@ -1,19 +1,16 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e tests/opentelemetry-test-utils -e opentelemetry-api -e opentelemetry-semantic-conventions diff --git a/opentelemetry-sdk/tests/logs/test_log_record.py b/opentelemetry-sdk/tests/logs/test_log_record.py index 6a33db101c..9c3746989b 100644 --- a/opentelemetry-sdk/tests/logs/test_log_record.py +++ b/opentelemetry-sdk/tests/logs/test_log_record.py @@ -14,9 +14,15 @@ import json import unittest +import warnings from opentelemetry.attributes import BoundedAttributes -from opentelemetry.sdk._logs import LogLimits, LogRecord +from opentelemetry.sdk._logs import ( + LogDroppedAttributesWarning, + LogLimits, + LogRecord, +) +from opentelemetry.sdk.resources import Resource class TestLogRecord(unittest.TestCase): @@ -33,7 +39,10 @@ def test_log_record_to_json(self): "trace_id": "", "span_id": "", "trace_flags": None, - "resource": "", + "resource": { + "attributes": {"service.name": "foo"}, + "schema_url": "", + }, }, indent=4, ) @@ -41,8 +50,14 @@ def test_log_record_to_json(self): timestamp=0, observed_timestamp=0, body="a log line", - ).to_json() - self.assertEqual(expected, actual) + resource=Resource({"service.name": "foo"}), + ) + + self.assertEqual(expected, actual.to_json(indent=4)) + self.assertEqual( + actual.to_json(indent=None), + '{"body": "a log line", "severity_number": "None", "severity_text": null, "attributes": null, "dropped_attributes": 0, "timestamp": "1970-01-01T00:00:00.000000Z", "observed_timestamp": "1970-01-01T00:00:00.000000Z", "trace_id": "", "span_id": "", "trace_flags": null, "resource": {"attributes": {"service.name": "foo"}, "schema_url": ""}}', + ) def test_log_record_bounded_attributes(self): attr = {"key": "value"} @@ -98,6 +113,28 @@ def test_log_record_dropped_attributes_set_limits(self): self.assertTrue(result.dropped_attributes == 1) self.assertEqual(expected, result.attributes) + def test_log_record_dropped_attributes_set_limits_warning_once(self): + attr = {"key1": "value1", "key2": "value2"} + limits = LogLimits( + max_attributes=1, + max_attribute_length=1, + ) + + with warnings.catch_warnings(record=True) as cw: + for _ in range(10): + LogRecord( + timestamp=0, + body="a log line", + attributes=attr, + limits=limits, + ) + self.assertEqual(len(cw), 1) + self.assertIsInstance(cw[-1].message, LogDroppedAttributesWarning) + self.assertIn( + "Log record attributes were dropped due to limits", + str(cw[-1].message), + ) + def test_log_record_dropped_attributes_unset_limits(self): attr = {"key": "value", "key2": "value2"} limits = LogLimits() diff --git a/opentelemetry-sdk/tests/metrics/integration_test/test_explicit_bucket_histogram_aggregation.py b/opentelemetry-sdk/tests/metrics/integration_test/test_explicit_bucket_histogram_aggregation.py index bdae2aad13..b705be3356 100644 --- a/opentelemetry-sdk/tests/metrics/integration_test/test_explicit_bucket_histogram_aggregation.py +++ b/opentelemetry-sdk/tests/metrics/integration_test/test_explicit_bucket_histogram_aggregation.py @@ -13,6 +13,7 @@ # limitations under the License. from platform import system +from time import sleep from unittest import TestCase from pytest import mark @@ -123,11 +124,43 @@ def test_synchronous_delta_temporality(self): results.append(reader.get_metrics_data()) - provider.shutdown() - for metrics_data in results: self.assertIsNone(metrics_data) + results = [] + + histogram.record(1) + results.append(reader.get_metrics_data()) + + sleep(0.1) + results.append(reader.get_metrics_data()) + + histogram.record(2) + results.append(reader.get_metrics_data()) + + metric_data_0 = ( + results[0] + .resource_metrics[0] + .scope_metrics[0] + .metrics[0] + .data.data_points[0] + ) + metric_data_2 = ( + results[2] + .resource_metrics[0] + .scope_metrics[0] + .metrics[0] + .data.data_points[0] + ) + + self.assertIsNone(results[1]) + + self.assertGreater( + metric_data_2.start_time_unix_nano, metric_data_0.time_unix_nano + ) + + provider.shutdown() + @mark.skipif( system() != "Linux", reason=( diff --git a/opentelemetry-sdk/tests/metrics/integration_test/test_sum_aggregation.py b/opentelemetry-sdk/tests/metrics/integration_test/test_sum_aggregation.py index 708b44f5fe..74a77eb534 100644 --- a/opentelemetry-sdk/tests/metrics/integration_test/test_sum_aggregation.py +++ b/opentelemetry-sdk/tests/metrics/integration_test/test_sum_aggregation.py @@ -15,6 +15,7 @@ from itertools import count from logging import ERROR from platform import system +from time import sleep from unittest import TestCase from pytest import mark @@ -345,11 +346,43 @@ def test_synchronous_delta_temporality(self): results.append(reader.get_metrics_data()) - provider.shutdown() - for metrics_data in results: self.assertIsNone(metrics_data) + results = [] + + counter.add(1) + results.append(reader.get_metrics_data()) + + sleep(0.1) + results.append(reader.get_metrics_data()) + + counter.add(2) + results.append(reader.get_metrics_data()) + + metric_data_0 = ( + results[0] + .resource_metrics[0] + .scope_metrics[0] + .metrics[0] + .data.data_points[0] + ) + metric_data_2 = ( + results[2] + .resource_metrics[0] + .scope_metrics[0] + .metrics[0] + .data.data_points[0] + ) + + self.assertIsNone(results[1]) + + self.assertGreater( + metric_data_2.start_time_unix_nano, metric_data_0.time_unix_nano + ) + + provider.shutdown() + @mark.skipif( system() != "Linux", reason=( diff --git a/opentelemetry-sdk/tests/metrics/test_aggregation.py b/opentelemetry-sdk/tests/metrics/test_aggregation.py index 37656b0a34..fb87d177e8 100644 --- a/opentelemetry-sdk/tests/metrics/test_aggregation.py +++ b/opentelemetry-sdk/tests/metrics/test_aggregation.py @@ -236,6 +236,8 @@ def test_collect(self): self.assertEqual(first_number_data_point.value, 1) + self.assertIsNone(first_number_data_point.start_time_unix_nano) + last_value_aggregation.aggregate(measurement(1)) # CI fails the last assertion without this @@ -249,6 +251,8 @@ def test_collect(self): self.assertEqual(second_number_data_point.value, 1) + self.assertIsNone(second_number_data_point.start_time_unix_nano) + self.assertGreater( second_number_data_point.time_unix_nano, first_number_data_point.time_unix_nano, diff --git a/opentelemetry-sdk/tests/metrics/test_measurement_consumer.py b/opentelemetry-sdk/tests/metrics/test_measurement_consumer.py index b1f3dc2a38..9d3b9691d6 100644 --- a/opentelemetry-sdk/tests/metrics/test_measurement_consumer.py +++ b/opentelemetry-sdk/tests/metrics/test_measurement_consumer.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from sys import version_info from time import sleep from unittest import TestCase from unittest.mock import MagicMock, Mock, patch @@ -175,14 +174,9 @@ def sleep_1(*args, **kwargs): consumer.collect(reader_mock) - if version_info < (3, 8): - callback_options_time_call = mock_callback_options.mock_calls[-1][ - 2 - ]["timeout_millis"] - else: - callback_options_time_call = mock_callback_options.mock_calls[ - -1 - ].kwargs["timeout_millis"] + callback_options_time_call = mock_callback_options.mock_calls[ + -1 + ].kwargs["timeout_millis"] self.assertLess( callback_options_time_call, diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 199305005b..d55262274b 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -18,6 +18,7 @@ from typing import Iterable, Sequence from unittest.mock import MagicMock, Mock, patch +from opentelemetry.attributes import BoundedAttributes from opentelemetry.metrics import NoOpMeter from opentelemetry.sdk.environment_variables import OTEL_SDK_DISABLED from opentelemetry.sdk.metrics import ( @@ -126,11 +127,36 @@ def test_get_meter(self): "name", version="version", schema_url="schema_url", + attributes={"key": "value"}, ) self.assertEqual(meter._instrumentation_scope.name, "name") self.assertEqual(meter._instrumentation_scope.version, "version") self.assertEqual(meter._instrumentation_scope.schema_url, "schema_url") + self.assertEqual( + meter._instrumentation_scope.attributes, {"key": "value"} + ) + + def test_get_meter_attributes(self): + """ + `MeterProvider.get_meter` arguments are used to create an + `InstrumentationScope` object on the created `Meter`. + """ + + meter = MeterProvider().get_meter( + "name", + version="version", + schema_url="schema_url", + attributes={"key": "value", "key2": 5, "key3": "value3"}, + ) + + self.assertEqual(meter._instrumentation_scope.name, "name") + self.assertEqual(meter._instrumentation_scope.version, "version") + self.assertEqual(meter._instrumentation_scope.schema_url, "schema_url") + self.assertEqual( + meter._instrumentation_scope.attributes, + {"key": "value", "key2": 5, "key3": "value3"}, + ) def test_get_meter_empty(self): """ @@ -180,6 +206,44 @@ def test_get_meter_duplicate(self): self.assertIs(meter1, meter2) self.assertIsNot(meter1, meter3) + def test_get_meter_comparison_with_attributes(self): + """ + Subsequent calls to `MeterProvider.get_meter` with the same arguments + should return the same `Meter` instance. + """ + mp = MeterProvider() + meter1 = mp.get_meter( + "name", + version="version", + schema_url="schema_url", + attributes={"key": "value", "key2": 5, "key3": "value3"}, + ) + meter2 = mp.get_meter( + "name", + version="version", + schema_url="schema_url", + attributes={"key": "value", "key2": 5, "key3": "value3"}, + ) + meter3 = mp.get_meter( + "name2", + version="version", + schema_url="schema_url", + ) + meter4 = mp.get_meter( + "name", + version="version", + schema_url="schema_url", + attributes={"key": "value", "key2": 5, "key3": "value4"}, + ) + self.assertIs(meter1, meter2) + self.assertIsNot(meter1, meter3) + self.assertTrue( + meter3._instrumentation_scope > meter4._instrumentation_scope + ) + self.assertIsInstance( + meter4._instrumentation_scope.attributes, BoundedAttributes + ) + def test_shutdown(self): mock_metric_reader_0 = MagicMock( diff --git a/opentelemetry-sdk/tests/metrics/test_point.py b/opentelemetry-sdk/tests/metrics/test_point.py index 20dd0e7238..cff07ff6ae 100644 --- a/opentelemetry-sdk/tests/metrics/test_point.py +++ b/opentelemetry-sdk/tests/metrics/test_point.py @@ -178,7 +178,7 @@ def setUpClass(cls): metrics=[cls.metric_0, cls.metric_1, cls.metric_2], schema_url="schema_url_0", ) - cls.scope_metrics_0_str = f'{{"scope": {{"name": "name_0", "version": "version_0", "schema_url": "schema_url_0"}}, "metrics": [{cls.metric_0_str}, {cls.metric_1_str}, {cls.metric_2_str}], "schema_url": "schema_url_0"}}' + cls.scope_metrics_0_str = f'{{"scope": {{"name": "name_0", "version": "version_0", "schema_url": "schema_url_0", "attributes": null}}, "metrics": [{cls.metric_0_str}, {cls.metric_1_str}, {cls.metric_2_str}], "schema_url": "schema_url_0"}}' cls.scope_metrics_1 = ScopeMetrics( scope=InstrumentationScope( @@ -189,7 +189,7 @@ def setUpClass(cls): metrics=[cls.metric_0, cls.metric_1, cls.metric_2], schema_url="schema_url_1", ) - cls.scope_metrics_1_str = f'{{"scope": {{"name": "name_1", "version": "version_1", "schema_url": "schema_url_1"}}, "metrics": [{cls.metric_0_str}, {cls.metric_1_str}, {cls.metric_2_str}], "schema_url": "schema_url_1"}}' + cls.scope_metrics_1_str = f'{{"scope": {{"name": "name_1", "version": "version_1", "schema_url": "schema_url_1", "attributes": null}}, "metrics": [{cls.metric_0_str}, {cls.metric_1_str}, {cls.metric_2_str}], "schema_url": "schema_url_1"}}' cls.resource_metrics_0 = ResourceMetrics( resource=Resource( diff --git a/opentelemetry-sdk/tests/performance/resource-usage/trace/profile_resource_usage_batch_export.py b/opentelemetry-sdk/tests/performance/resource-usage/trace/profile_resource_usage_batch_export.py deleted file mode 100644 index 3e9a201c96..0000000000 --- a/opentelemetry-sdk/tests/performance/resource-usage/trace/profile_resource_usage_batch_export.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( - OTLPSpanExporter, -) -from opentelemetry.sdk.trace import TracerProvider, sampling -from opentelemetry.sdk.trace.export import BatchSpanProcessor - -TEST_DURATION_SECONDS = 15 -SPANS_PER_SECOND = 10_000 - - -class MockTraceServiceStub: - def __init__(self, channel): - self.Export = lambda *args, **kwargs: None - - -old_stub = OTLPSpanExporter._stub -OTLPSpanExporter._stub = MockTraceServiceStub - -simple_span_processor = BatchSpanProcessor(OTLPSpanExporter()) -tracer = TracerProvider( - active_span_processor=simple_span_processor, - sampler=sampling.DEFAULT_ON, -).get_tracer("resource_usage_tracer") - -starttime = time.time() -for _ in range(TEST_DURATION_SECONDS): - for _ in range(SPANS_PER_SECOND): - span = tracer.start_span("benchmarkedSpan") - span.end() - time_to_finish_spans = time.time() - starttime - time.sleep(1.0 - time_to_finish_spans if time_to_finish_spans < 1.0 else 0) - -OTLPSpanExporter._stub = old_stub diff --git a/opentelemetry-sdk/tests/performance/resource-usage/trace/profile_resource_usage_simple_export.py b/opentelemetry-sdk/tests/performance/resource-usage/trace/profile_resource_usage_simple_export.py deleted file mode 100644 index bc27fb519d..0000000000 --- a/opentelemetry-sdk/tests/performance/resource-usage/trace/profile_resource_usage_simple_export.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( - OTLPSpanExporter, -) -from opentelemetry.sdk.trace import TracerProvider, sampling -from opentelemetry.sdk.trace.export import SimpleSpanProcessor - -TEST_DURATION_SECONDS = 15 -SPANS_PER_SECOND = 10_000 - - -class MockTraceServiceStub: - def __init__(self, channel): - self.Export = lambda *args, **kwargs: None - - -old_stub = OTLPSpanExporter._stub -OTLPSpanExporter._stub = MockTraceServiceStub - -simple_span_processor = SimpleSpanProcessor(OTLPSpanExporter()) -tracer = TracerProvider( - active_span_processor=simple_span_processor, - sampler=sampling.DEFAULT_ON, -).get_tracer("resource_usage_tracer") - -starttime = time.time() -for _ in range(TEST_DURATION_SECONDS): - for _ in range(SPANS_PER_SECOND): - span = tracer.start_span("benchmarkedSpan") - span.end() - time_to_finish_spans = time.time() - starttime - time.sleep(1.0 - time_to_finish_spans if time_to_finish_spans < 1.0 else 0) - -OTLPSpanExporter._stub = old_stub diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index a0c6159010..8a42d0c6d0 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -608,7 +608,7 @@ def test_process_detector(self): ) self.assertEqual( aggregated_resource.attributes[PROCESS_COMMAND_ARGS], - tuple(sys.argv[1:]), + tuple(sys.argv), ) def test_resource_detector_entry_points_default(self): diff --git a/opentelemetry-sdk/tests/trace/export/test_export.py b/opentelemetry-sdk/tests/trace/export/test_export.py index 339b0c7f89..7a29ef3c42 100644 --- a/opentelemetry-sdk/tests/trace/export/test_export.py +++ b/opentelemetry-sdk/tests/trace/export/test_export.py @@ -461,6 +461,10 @@ def _target(): span_processor.shutdown() + @mark.skipif( + python_implementation() == "PyPy" or system() == "Windows", + reason="This test randomly fails with huge delta in Windows or PyPy", + ) def test_batch_span_processor_scheduled_delay(self): """Test that spans are exported each schedule_delay_millis""" spans_names_list = [] @@ -482,7 +486,7 @@ def test_batch_span_processor_scheduled_delay(self): self.assertTrue(export_event.wait(2)) export_time = time.time() self.assertEqual(len(spans_names_list), 1) - self.assertGreaterEqual((export_time - start_time) * 1e3, 500) + self.assertAlmostEqual((export_time - start_time) * 1e3, 500, delta=25) span_processor.shutdown() diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 30f4f0e273..9f37564309 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -27,6 +27,7 @@ from unittest.mock import Mock, patch from opentelemetry import trace as trace_api +from opentelemetry.attributes import BoundedAttributes from opentelemetry.context import Context from opentelemetry.sdk import resources, trace from opentelemetry.sdk.environment_variables import ( @@ -635,6 +636,15 @@ def test_events(self): span = trace.ReadableSpan("test", events=events) self.assertEqual(span.events, tuple(events)) + def test_event_dropped_attributes(self): + event1 = trace.Event( + "foo1", BoundedAttributes(0, attributes={"bar1": "baz1"}) + ) + self.assertEqual(event1.dropped_attributes, 1) + + event2 = trace.Event("foo2", {"bar2": "baz2"}) + self.assertEqual(event2.dropped_attributes, 0) + class DummyError(Exception): pass @@ -944,14 +954,29 @@ def test_add_link_with_invalid_span_context(self): root.add_link(None) self.assertEqual(len(root.links), 0) + with self.tracer.start_as_current_span( + "root", links=[trace_api.Link(other_context), None] + ) as root: + self.assertEqual(len(root.links), 0) + def test_add_link_with_invalid_span_context_with_attributes(self): invalid_context = trace_api.INVALID_SPAN_CONTEXT with self.tracer.start_as_current_span("root") as root: + root.add_link(invalid_context) root.add_link(invalid_context, {"name": "neighbor"}) self.assertEqual(len(root.links), 1) self.assertEqual(root.links[0].attributes, {"name": "neighbor"}) + with self.tracer.start_as_current_span( + "root", + links=[ + trace_api.Link(invalid_context, {"name": "neighbor"}), + trace_api.Link(invalid_context), + ], + ) as root: + self.assertEqual(len(root.links), 1) + def test_add_link_with_invalid_span_context_with_tracestate(self): invalid_context = trace.SpanContext( trace_api.INVALID_TRACE_ID, @@ -962,9 +987,19 @@ def test_add_link_with_invalid_span_context_with_tracestate(self): with self.tracer.start_as_current_span("root") as root: root.add_link(invalid_context) + root.add_link(trace_api.INVALID_SPAN_CONTEXT) self.assertEqual(len(root.links), 1) self.assertEqual(root.links[0].context.trace_state, "foo=bar") + with self.tracer.start_as_current_span( + "root", + links=[ + trace_api.Link(invalid_context), + trace_api.Link(trace_api.INVALID_SPAN_CONTEXT), + ], + ) as root: + self.assertEqual(len(root.links), 1) + def test_update_name(self): with self.tracer.start_as_current_span("root") as root: # name @@ -1837,7 +1872,7 @@ def test_dropped_attributes(self): self.assertEqual(1, span.dropped_links) self.assertEqual(2, span.dropped_attributes) self.assertEqual(3, span.dropped_events) - self.assertEqual(2, span.events[0].attributes.dropped) + self.assertEqual(2, span.events[0].dropped_attributes) self.assertEqual(2, span.links[0].attributes.dropped) def _test_span_limits( @@ -2061,3 +2096,35 @@ def test_tracer_provider_init_default(self, resource_patch, sample_patch): sample_patch.assert_called_once() self.assertIsNotNone(tracer_provider._span_limits) self.assertIsNotNone(tracer_provider._atexit_handler) + + +class TestRandomIdGenerator(unittest.TestCase): + _TRACE_ID_MAX_VALUE = 2**128 - 1 + _SPAN_ID_MAX_VALUE = 2**64 - 1 + + @patch( + "random.getrandbits", + side_effect=[trace_api.INVALID_SPAN_ID, 0x00000000DEADBEF0], + ) + def test_generate_span_id_avoids_invalid(self, mock_getrandbits): + generator = RandomIdGenerator() + span_id = generator.generate_span_id() + + self.assertNotEqual(span_id, trace_api.INVALID_SPAN_ID) + mock_getrandbits.assert_any_call(64) + self.assertEqual(mock_getrandbits.call_count, 2) + + @patch( + "random.getrandbits", + side_effect=[ + trace_api.INVALID_TRACE_ID, + 0x000000000000000000000000DEADBEEF, + ], + ) + def test_generate_trace_id_avoids_invalid(self, mock_getrandbits): + generator = RandomIdGenerator() + trace_id = generator.generate_trace_id() + + self.assertNotEqual(trace_id, trace_api.INVALID_TRACE_ID) + mock_getrandbits.assert_any_call(128) + self.assertEqual(mock_getrandbits.call_count, 2) diff --git a/opentelemetry-semantic-conventions/py.typed b/opentelemetry-semantic-conventions/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-semantic-conventions/pyproject.toml b/opentelemetry-semantic-conventions/pyproject.toml index eb7dbcbfa1..17954a3485 100644 --- a/opentelemetry-semantic-conventions/pyproject.toml +++ b/opentelemetry-semantic-conventions/pyproject.toml @@ -23,17 +23,19 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api == 1.26.0.dev", + "Deprecated >= 1.2.6", ] [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-semantic-conventions" [tool.hatch.version] -path = "src/opentelemetry/semconv/version.py" +path = "src/opentelemetry/semconv/version/__init__.py" [tool.hatch.build.targets.sdist] include = [ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/aws_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/aws_attributes.py index f5edbbcb80..12c50ae9ba 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/aws_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/aws_attributes.py @@ -12,207 +12,217 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS = "aws.dynamodb.attribute_definitions" +AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS: Final = ( + "aws.dynamodb.attribute_definitions" +) """ The JSON-serialized value of each item in the `AttributeDefinitions` request field. """ -AWS_DYNAMODB_ATTRIBUTES_TO_GET = "aws.dynamodb.attributes_to_get" +AWS_DYNAMODB_ATTRIBUTES_TO_GET: Final = "aws.dynamodb.attributes_to_get" """ The value of the `AttributesToGet` request parameter. """ -AWS_DYNAMODB_CONSISTENT_READ = "aws.dynamodb.consistent_read" +AWS_DYNAMODB_CONSISTENT_READ: Final = "aws.dynamodb.consistent_read" """ The value of the `ConsistentRead` request parameter. """ -AWS_DYNAMODB_CONSUMED_CAPACITY = "aws.dynamodb.consumed_capacity" +AWS_DYNAMODB_CONSUMED_CAPACITY: Final = "aws.dynamodb.consumed_capacity" """ The JSON-serialized value of each item in the `ConsumedCapacity` response field. """ -AWS_DYNAMODB_COUNT = "aws.dynamodb.count" +AWS_DYNAMODB_COUNT: Final = "aws.dynamodb.count" """ The value of the `Count` response parameter. """ -AWS_DYNAMODB_EXCLUSIVE_START_TABLE = "aws.dynamodb.exclusive_start_table" +AWS_DYNAMODB_EXCLUSIVE_START_TABLE: Final = ( + "aws.dynamodb.exclusive_start_table" +) """ The value of the `ExclusiveStartTableName` request parameter. """ -AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES = ( +AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES: Final = ( "aws.dynamodb.global_secondary_index_updates" ) """ The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. """ -AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES = "aws.dynamodb.global_secondary_indexes" +AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES: Final = ( + "aws.dynamodb.global_secondary_indexes" +) """ The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field. """ -AWS_DYNAMODB_INDEX_NAME = "aws.dynamodb.index_name" +AWS_DYNAMODB_INDEX_NAME: Final = "aws.dynamodb.index_name" """ The value of the `IndexName` request parameter. """ -AWS_DYNAMODB_ITEM_COLLECTION_METRICS = "aws.dynamodb.item_collection_metrics" +AWS_DYNAMODB_ITEM_COLLECTION_METRICS: Final = ( + "aws.dynamodb.item_collection_metrics" +) """ The JSON-serialized value of the `ItemCollectionMetrics` response field. """ -AWS_DYNAMODB_LIMIT = "aws.dynamodb.limit" +AWS_DYNAMODB_LIMIT: Final = "aws.dynamodb.limit" """ The value of the `Limit` request parameter. """ -AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES = "aws.dynamodb.local_secondary_indexes" +AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES: Final = ( + "aws.dynamodb.local_secondary_indexes" +) """ The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. """ -AWS_DYNAMODB_PROJECTION = "aws.dynamodb.projection" +AWS_DYNAMODB_PROJECTION: Final = "aws.dynamodb.projection" """ The value of the `ProjectionExpression` request parameter. """ -AWS_DYNAMODB_PROVISIONED_READ_CAPACITY = ( +AWS_DYNAMODB_PROVISIONED_READ_CAPACITY: Final = ( "aws.dynamodb.provisioned_read_capacity" ) """ The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. """ -AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY = ( +AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY: Final = ( "aws.dynamodb.provisioned_write_capacity" ) """ The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. """ -AWS_DYNAMODB_SCAN_FORWARD = "aws.dynamodb.scan_forward" +AWS_DYNAMODB_SCAN_FORWARD: Final = "aws.dynamodb.scan_forward" """ The value of the `ScanIndexForward` request parameter. """ -AWS_DYNAMODB_SCANNED_COUNT = "aws.dynamodb.scanned_count" +AWS_DYNAMODB_SCANNED_COUNT: Final = "aws.dynamodb.scanned_count" """ The value of the `ScannedCount` response parameter. """ -AWS_DYNAMODB_SEGMENT = "aws.dynamodb.segment" +AWS_DYNAMODB_SEGMENT: Final = "aws.dynamodb.segment" """ The value of the `Segment` request parameter. """ -AWS_DYNAMODB_SELECT = "aws.dynamodb.select" +AWS_DYNAMODB_SELECT: Final = "aws.dynamodb.select" """ The value of the `Select` request parameter. """ -AWS_DYNAMODB_TABLE_COUNT = "aws.dynamodb.table_count" +AWS_DYNAMODB_TABLE_COUNT: Final = "aws.dynamodb.table_count" """ The number of items in the `TableNames` response parameter. """ -AWS_DYNAMODB_TABLE_NAMES = "aws.dynamodb.table_names" +AWS_DYNAMODB_TABLE_NAMES: Final = "aws.dynamodb.table_names" """ The keys in the `RequestItems` object field. """ -AWS_DYNAMODB_TOTAL_SEGMENTS = "aws.dynamodb.total_segments" +AWS_DYNAMODB_TOTAL_SEGMENTS: Final = "aws.dynamodb.total_segments" """ The value of the `TotalSegments` request parameter. """ -AWS_ECS_CLUSTER_ARN = "aws.ecs.cluster.arn" +AWS_ECS_CLUSTER_ARN: Final = "aws.ecs.cluster.arn" """ The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). """ -AWS_ECS_CONTAINER_ARN = "aws.ecs.container.arn" +AWS_ECS_CONTAINER_ARN: Final = "aws.ecs.container.arn" """ The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). """ -AWS_ECS_LAUNCHTYPE = "aws.ecs.launchtype" +AWS_ECS_LAUNCHTYPE: Final = "aws.ecs.launchtype" """ The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. """ -AWS_ECS_TASK_ARN = "aws.ecs.task.arn" +AWS_ECS_TASK_ARN: Final = "aws.ecs.task.arn" """ The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). """ -AWS_ECS_TASK_FAMILY = "aws.ecs.task.family" +AWS_ECS_TASK_FAMILY: Final = "aws.ecs.task.family" """ The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. """ -AWS_ECS_TASK_ID = "aws.ecs.task.id" +AWS_ECS_TASK_ID: Final = "aws.ecs.task.id" """ The ID of a running ECS task. The ID MUST be extracted from `task.arn`. """ -AWS_ECS_TASK_REVISION = "aws.ecs.task.revision" +AWS_ECS_TASK_REVISION: Final = "aws.ecs.task.revision" """ The revision for the task definition used to create the ECS task. """ -AWS_EKS_CLUSTER_ARN = "aws.eks.cluster.arn" +AWS_EKS_CLUSTER_ARN: Final = "aws.eks.cluster.arn" """ The ARN of an EKS cluster. """ -AWS_LAMBDA_INVOKED_ARN = "aws.lambda.invoked_arn" +AWS_LAMBDA_INVOKED_ARN: Final = "aws.lambda.invoked_arn" """ The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). Note: This may be different from `cloud.resource_id` if an alias is involved. """ -AWS_LOG_GROUP_ARNS = "aws.log.group.arns" +AWS_LOG_GROUP_ARNS: Final = "aws.log.group.arns" """ The Amazon Resource Name(s) (ARN) of the AWS log group(s). Note: See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). """ -AWS_LOG_GROUP_NAMES = "aws.log.group.names" +AWS_LOG_GROUP_NAMES: Final = "aws.log.group.names" """ The name(s) of the AWS log group(s) an application is writing to. Note: Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. """ -AWS_LOG_STREAM_ARNS = "aws.log.stream.arns" +AWS_LOG_STREAM_ARNS: Final = "aws.log.stream.arns" """ The ARN(s) of the AWS log stream(s). Note: See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. """ -AWS_LOG_STREAM_NAMES = "aws.log.stream.names" +AWS_LOG_STREAM_NAMES: Final = "aws.log.stream.names" """ The name(s) of the AWS log stream(s) an application is writing to. """ -AWS_REQUEST_ID = "aws.request_id" +AWS_REQUEST_ID: Final = "aws.request_id" """ The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. """ -AWS_S3_BUCKET = "aws.s3.bucket" +AWS_S3_BUCKET: Final = "aws.s3.bucket" """ The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. Note: The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations except `list-buckets`. """ -AWS_S3_COPY_SOURCE = "aws.s3.copy_source" +AWS_S3_COPY_SOURCE: Final = "aws.s3.copy_source" """ The source object (in the form `bucket`/`key`) for the copy operation. Note: The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter @@ -223,7 +233,7 @@ - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). """ -AWS_S3_DELETE = "aws.s3.delete" +AWS_S3_DELETE: Final = "aws.s3.delete" """ The delete request container that specifies the objects to be deleted. Note: The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. @@ -231,7 +241,7 @@ [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). """ -AWS_S3_KEY = "aws.s3.key" +AWS_S3_KEY: Final = "aws.s3.key" """ The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. Note: The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. @@ -252,7 +262,7 @@ - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). """ -AWS_S3_PART_NUMBER = "aws.s3.part_number" +AWS_S3_PART_NUMBER: Final = "aws.s3.part_number" """ The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. Note: The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) @@ -261,7 +271,7 @@ [upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). """ -AWS_S3_UPLOAD_ID = "aws.s3.upload_id" +AWS_S3_UPLOAD_ID: Final = "aws.s3.upload_id" """ Upload ID that identifies the multipart upload. Note: The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter @@ -277,7 +287,7 @@ class AwsEcsLaunchtypeValues(Enum): - EC2 = "ec2" + EC2: Final = "ec2" """ec2.""" - FARGATE = "fargate" + FARGATE: Final = "fargate" """fargate.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/browser_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/browser_attributes.py index e792af8073..ea1dbd4d10 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/browser_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/browser_attributes.py @@ -12,26 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -BROWSER_BRANDS = "browser.brands" +BROWSER_BRANDS: Final = "browser.brands" """ Array of brand name and version separated by a space. Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). """ -BROWSER_LANGUAGE = "browser.language" +BROWSER_LANGUAGE: Final = "browser.language" """ Preferred language of the user using the browser. Note: This value is intended to be taken from the Navigator API `navigator.language`. """ -BROWSER_MOBILE = "browser.mobile" +BROWSER_MOBILE: Final = "browser.mobile" """ A boolean that is true if the browser is running on a mobile device. Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. """ -BROWSER_PLATFORM = "browser.platform" +BROWSER_PLATFORM: Final = "browser.platform" """ The platform on which the browser is running. Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/client_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/client_attributes.py index a8514b5639..a6511e7672 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/client_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/client_attributes.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -CLIENT_ADDRESS = "client.address" +CLIENT_ADDRESS: Final = "client.address" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.client_attributes.CLIENT_ADDRESS`. """ -CLIENT_PORT = "client.port" +CLIENT_PORT: Final = "client.port" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.client_attributes.CLIENT_PORT`. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py index 43e181e308..00f5dda31f 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py @@ -12,38 +12,38 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -CLOUD_ACCOUNT_ID = "cloud.account.id" +CLOUD_ACCOUNT_ID: Final = "cloud.account.id" """ The cloud account ID the resource is assigned to. """ -CLOUD_AVAILABILITY_ZONE = "cloud.availability_zone" +CLOUD_AVAILABILITY_ZONE: Final = "cloud.availability_zone" """ Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud. """ -CLOUD_PLATFORM = "cloud.platform" +CLOUD_PLATFORM: Final = "cloud.platform" """ The cloud platform in use. Note: The prefix of the service SHOULD match the one specified in `cloud.provider`. """ -CLOUD_PROVIDER = "cloud.provider" +CLOUD_PROVIDER: Final = "cloud.provider" """ Name of the cloud provider. """ -CLOUD_REGION = "cloud.region" +CLOUD_REGION: Final = "cloud.region" """ The geographical region the resource is running. Note: Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). """ -CLOUD_RESOURCE_ID = "cloud.resource_id" +CLOUD_RESOURCE_ID: Final = "cloud.resource_id" """ Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP). Note: On some cloud providers, it may not be possible to determine the full ID at startup, @@ -67,76 +67,76 @@ class CloudPlatformValues(Enum): - ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs" + ALIBABA_CLOUD_ECS: Final = "alibaba_cloud_ecs" """Alibaba Cloud Elastic Compute Service.""" - ALIBABA_CLOUD_FC = "alibaba_cloud_fc" + ALIBABA_CLOUD_FC: Final = "alibaba_cloud_fc" """Alibaba Cloud Function Compute.""" - ALIBABA_CLOUD_OPENSHIFT = "alibaba_cloud_openshift" + ALIBABA_CLOUD_OPENSHIFT: Final = "alibaba_cloud_openshift" """Red Hat OpenShift on Alibaba Cloud.""" - AWS_EC2 = "aws_ec2" + AWS_EC2: Final = "aws_ec2" """AWS Elastic Compute Cloud.""" - AWS_ECS = "aws_ecs" + AWS_ECS: Final = "aws_ecs" """AWS Elastic Container Service.""" - AWS_EKS = "aws_eks" + AWS_EKS: Final = "aws_eks" """AWS Elastic Kubernetes Service.""" - AWS_LAMBDA = "aws_lambda" + AWS_LAMBDA: Final = "aws_lambda" """AWS Lambda.""" - AWS_ELASTIC_BEANSTALK = "aws_elastic_beanstalk" + AWS_ELASTIC_BEANSTALK: Final = "aws_elastic_beanstalk" """AWS Elastic Beanstalk.""" - AWS_APP_RUNNER = "aws_app_runner" + AWS_APP_RUNNER: Final = "aws_app_runner" """AWS App Runner.""" - AWS_OPENSHIFT = "aws_openshift" + AWS_OPENSHIFT: Final = "aws_openshift" """Red Hat OpenShift on AWS (ROSA).""" - AZURE_VM = "azure_vm" + AZURE_VM: Final = "azure_vm" """Azure Virtual Machines.""" - AZURE_CONTAINER_APPS = "azure_container_apps" + AZURE_CONTAINER_APPS: Final = "azure_container_apps" """Azure Container Apps.""" - AZURE_CONTAINER_INSTANCES = "azure_container_instances" + AZURE_CONTAINER_INSTANCES: Final = "azure_container_instances" """Azure Container Instances.""" - AZURE_AKS = "azure_aks" + AZURE_AKS: Final = "azure_aks" """Azure Kubernetes Service.""" - AZURE_FUNCTIONS = "azure_functions" + AZURE_FUNCTIONS: Final = "azure_functions" """Azure Functions.""" - AZURE_APP_SERVICE = "azure_app_service" + AZURE_APP_SERVICE: Final = "azure_app_service" """Azure App Service.""" - AZURE_OPENSHIFT = "azure_openshift" + AZURE_OPENSHIFT: Final = "azure_openshift" """Azure Red Hat OpenShift.""" - GCP_BARE_METAL_SOLUTION = "gcp_bare_metal_solution" + GCP_BARE_METAL_SOLUTION: Final = "gcp_bare_metal_solution" """Google Bare Metal Solution (BMS).""" - GCP_COMPUTE_ENGINE = "gcp_compute_engine" + GCP_COMPUTE_ENGINE: Final = "gcp_compute_engine" """Google Cloud Compute Engine (GCE).""" - GCP_CLOUD_RUN = "gcp_cloud_run" + GCP_CLOUD_RUN: Final = "gcp_cloud_run" """Google Cloud Run.""" - GCP_KUBERNETES_ENGINE = "gcp_kubernetes_engine" + GCP_KUBERNETES_ENGINE: Final = "gcp_kubernetes_engine" """Google Cloud Kubernetes Engine (GKE).""" - GCP_CLOUD_FUNCTIONS = "gcp_cloud_functions" + GCP_CLOUD_FUNCTIONS: Final = "gcp_cloud_functions" """Google Cloud Functions (GCF).""" - GCP_APP_ENGINE = "gcp_app_engine" + GCP_APP_ENGINE: Final = "gcp_app_engine" """Google Cloud App Engine (GAE).""" - GCP_OPENSHIFT = "gcp_openshift" + GCP_OPENSHIFT: Final = "gcp_openshift" """Red Hat OpenShift on Google Cloud.""" - IBM_CLOUD_OPENSHIFT = "ibm_cloud_openshift" + IBM_CLOUD_OPENSHIFT: Final = "ibm_cloud_openshift" """Red Hat OpenShift on IBM Cloud.""" - TENCENT_CLOUD_CVM = "tencent_cloud_cvm" + TENCENT_CLOUD_CVM: Final = "tencent_cloud_cvm" """Tencent Cloud Cloud Virtual Machine (CVM).""" - TENCENT_CLOUD_EKS = "tencent_cloud_eks" + TENCENT_CLOUD_EKS: Final = "tencent_cloud_eks" """Tencent Cloud Elastic Kubernetes Service (EKS).""" - TENCENT_CLOUD_SCF = "tencent_cloud_scf" + TENCENT_CLOUD_SCF: Final = "tencent_cloud_scf" """Tencent Cloud Serverless Cloud Function (SCF).""" class CloudProviderValues(Enum): - ALIBABA_CLOUD = "alibaba_cloud" + ALIBABA_CLOUD: Final = "alibaba_cloud" """Alibaba Cloud.""" - AWS = "aws" + AWS: Final = "aws" """Amazon Web Services.""" - AZURE = "azure" + AZURE: Final = "azure" """Microsoft Azure.""" - GCP = "gcp" + GCP: Final = "gcp" """Google Cloud Platform.""" - HEROKU = "heroku" + HEROKU: Final = "heroku" """Heroku Platform as a Service.""" - IBM_CLOUD = "ibm_cloud" + IBM_CLOUD: Final = "ibm_cloud" """IBM Cloud.""" - TENCENT_CLOUD = "tencent_cloud" + TENCENT_CLOUD: Final = "tencent_cloud" """Tencent Cloud.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py index 30fe19c74e..ca13ee9942 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py @@ -12,28 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -CLOUDEVENTS_EVENT_ID = "cloudevents.event_id" +CLOUDEVENTS_EVENT_ID: Final = "cloudevents.event_id" """ The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. """ -CLOUDEVENTS_EVENT_SOURCE = "cloudevents.event_source" +CLOUDEVENTS_EVENT_SOURCE: Final = "cloudevents.event_source" """ The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. """ -CLOUDEVENTS_EVENT_SPEC_VERSION = "cloudevents.event_spec_version" +CLOUDEVENTS_EVENT_SPEC_VERSION: Final = "cloudevents.event_spec_version" """ The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. """ -CLOUDEVENTS_EVENT_SUBJECT = "cloudevents.event_subject" +CLOUDEVENTS_EVENT_SUBJECT: Final = "cloudevents.event_subject" """ The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). """ -CLOUDEVENTS_EVENT_TYPE = "cloudevents.event_type" +CLOUDEVENTS_EVENT_TYPE: Final = "cloudevents.event_type" """ The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/code_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/code_attributes.py index 6a9d55ec0a..81aacca6e9 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/code_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/code_attributes.py @@ -12,33 +12,34 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -CODE_COLUMN = "code.column" +CODE_COLUMN: Final = "code.column" """ The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. """ -CODE_FILEPATH = "code.filepath" +CODE_FILEPATH: Final = "code.filepath" """ The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). """ -CODE_FUNCTION = "code.function" +CODE_FUNCTION: Final = "code.function" """ The method or function name, or equivalent (usually rightmost part of the code unit's name). """ -CODE_LINENO = "code.lineno" +CODE_LINENO: Final = "code.lineno" """ The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. """ -CODE_NAMESPACE = "code.namespace" +CODE_NAMESPACE: Final = "code.namespace" """ The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. """ -CODE_STACKTRACE = "code.stacktrace" +CODE_STACKTRACE: Final = "code.stacktrace" """ A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/container_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/container_attributes.py index 03391d1114..fbb74a1b14 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/container_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/container_attributes.py @@ -12,84 +12,84 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -CONTAINER_COMMAND = "container.command" +CONTAINER_COMMAND: Final = "container.command" """ The command used to run the container (i.e. the command name). Note: If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. """ -CONTAINER_COMMAND_ARGS = "container.command_args" +CONTAINER_COMMAND_ARGS: Final = "container.command_args" """ All the command arguments (including the command/executable itself) run by the container. [2]. """ -CONTAINER_COMMAND_LINE = "container.command_line" +CONTAINER_COMMAND_LINE: Final = "container.command_line" """ The full command run by the container as a single string representing the full command. [2]. """ -CONTAINER_CPU_STATE = "container.cpu.state" +CONTAINER_CPU_STATE: Final = "container.cpu.state" """ The CPU state for this data point. """ -CONTAINER_ID = "container.id" +CONTAINER_ID: Final = "container.id" """ Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. """ -CONTAINER_IMAGE_ID = "container.image.id" +CONTAINER_IMAGE_ID: Final = "container.image.id" """ Runtime specific image identifier. Usually a hash algorithm followed by a UUID. Note: Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. - The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. + The ID is assigned by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. """ -CONTAINER_IMAGE_NAME = "container.image.name" +CONTAINER_IMAGE_NAME: Final = "container.image.name" """ Name of the image the container was built on. """ -CONTAINER_IMAGE_REPO_DIGESTS = "container.image.repo_digests" +CONTAINER_IMAGE_REPO_DIGESTS: Final = "container.image.repo_digests" """ Repo digests of the container image as provided by the container runtime. Note: [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. """ -CONTAINER_IMAGE_TAGS = "container.image.tags" +CONTAINER_IMAGE_TAGS: Final = "container.image.tags" """ Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. """ -CONTAINER_LABEL_TEMPLATE = "container.label" +CONTAINER_LABEL_TEMPLATE: Final = "container.label" """ Container labels, `` being the label name, the value being the label value. """ -CONTAINER_LABELS_TEMPLATE = "container.labels" +CONTAINER_LABELS_TEMPLATE: Final = "container.labels" """ Deprecated: Replaced by `container.label`. """ -CONTAINER_NAME = "container.name" +CONTAINER_NAME: Final = "container.name" """ Container name used by container runtime. """ -CONTAINER_RUNTIME = "container.runtime" +CONTAINER_RUNTIME: Final = "container.runtime" """ The container runtime managing this container. """ class ContainerCpuStateValues(Enum): - USER = "user" + USER: Final = "user" """When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows).""" - SYSTEM = "system" + SYSTEM: Final = "system" """When CPU is used by the system (host OS).""" - KERNEL = "kernel" + KERNEL: Final = "kernel" """When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows).""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/db_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/db_attributes.py index e1cf5e017d..86db338a3e 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/db_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/db_attributes.py @@ -12,335 +12,383 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -DB_CASSANDRA_CONSISTENCY_LEVEL = "db.cassandra.consistency_level" +DB_CASSANDRA_CONSISTENCY_LEVEL: Final = "db.cassandra.consistency_level" """ The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). """ -DB_CASSANDRA_COORDINATOR_DC = "db.cassandra.coordinator.dc" +DB_CASSANDRA_COORDINATOR_DC: Final = "db.cassandra.coordinator.dc" """ The data center of the coordinating node for a query. """ -DB_CASSANDRA_COORDINATOR_ID = "db.cassandra.coordinator.id" +DB_CASSANDRA_COORDINATOR_ID: Final = "db.cassandra.coordinator.id" """ The ID of the coordinating node for a query. """ -DB_CASSANDRA_IDEMPOTENCE = "db.cassandra.idempotence" +DB_CASSANDRA_IDEMPOTENCE: Final = "db.cassandra.idempotence" """ Whether or not the query is idempotent. """ -DB_CASSANDRA_PAGE_SIZE = "db.cassandra.page_size" +DB_CASSANDRA_PAGE_SIZE: Final = "db.cassandra.page_size" """ The fetch size used for paging, i.e. how many rows will be returned at once. """ -DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT = ( +DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT: Final = ( "db.cassandra.speculative_execution_count" ) """ The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. """ -DB_CASSANDRA_TABLE = "db.cassandra.table" +DB_CASSANDRA_TABLE: Final = "db.cassandra.table" +""" +Deprecated: Replaced by `db.collection.name`. +""" + +DB_CLIENT_CONNECTIONS_POOL_NAME: Final = "db.client.connections.pool.name" +""" +The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. +""" + +DB_CLIENT_CONNECTIONS_STATE: Final = "db.client.connections.state" """ -The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). -Note: This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +The state of a connection in the pool. """ -DB_CONNECTION_STRING = "db.connection_string" +DB_COLLECTION_NAME: Final = "db.collection.name" +""" +The name of a collection (table, container) within the database. +Note: If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. + It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. +""" + +DB_CONNECTION_STRING: Final = "db.connection_string" """ Deprecated: "Replaced by `server.address` and `server.port`.". """ -DB_COSMOSDB_CLIENT_ID = "db.cosmosdb.client_id" +DB_COSMOSDB_CLIENT_ID: Final = "db.cosmosdb.client_id" """ Unique Cosmos client instance id. """ -DB_COSMOSDB_CONNECTION_MODE = "db.cosmosdb.connection_mode" +DB_COSMOSDB_CONNECTION_MODE: Final = "db.cosmosdb.connection_mode" """ Cosmos client connection mode. """ -DB_COSMOSDB_CONTAINER = "db.cosmosdb.container" +DB_COSMOSDB_CONTAINER: Final = "db.cosmosdb.container" """ -Cosmos DB container name. +Deprecated: Replaced by `db.collection.name`. """ -DB_COSMOSDB_OPERATION_TYPE = "db.cosmosdb.operation_type" +DB_COSMOSDB_OPERATION_TYPE: Final = "db.cosmosdb.operation_type" """ CosmosDB Operation Type. """ -DB_COSMOSDB_REQUEST_CHARGE = "db.cosmosdb.request_charge" +DB_COSMOSDB_REQUEST_CHARGE: Final = "db.cosmosdb.request_charge" """ RU consumed for that operation. """ -DB_COSMOSDB_REQUEST_CONTENT_LENGTH = "db.cosmosdb.request_content_length" +DB_COSMOSDB_REQUEST_CONTENT_LENGTH: Final = ( + "db.cosmosdb.request_content_length" +) """ Request payload size in bytes. """ -DB_COSMOSDB_STATUS_CODE = "db.cosmosdb.status_code" +DB_COSMOSDB_STATUS_CODE: Final = "db.cosmosdb.status_code" """ Cosmos DB status code. """ -DB_COSMOSDB_SUB_STATUS_CODE = "db.cosmosdb.sub_status_code" +DB_COSMOSDB_SUB_STATUS_CODE: Final = "db.cosmosdb.sub_status_code" """ Cosmos DB sub status code. """ -DB_ELASTICSEARCH_CLUSTER_NAME = "db.elasticsearch.cluster.name" +DB_ELASTICSEARCH_CLUSTER_NAME: Final = "db.elasticsearch.cluster.name" """ Represents the identifier of an Elasticsearch cluster. """ -DB_ELASTICSEARCH_NODE_NAME = "db.elasticsearch.node.name" +DB_ELASTICSEARCH_NODE_NAME: Final = "db.elasticsearch.node.name" """ -Deprecated: Replaced by `db.instance.id`. +Represents the human-readable identifier of the node/instance to which a request was routed. """ -DB_ELASTICSEARCH_PATH_PARTS_TEMPLATE = "db.elasticsearch.path_parts" +DB_ELASTICSEARCH_PATH_PARTS_TEMPLATE: Final = "db.elasticsearch.path_parts" """ A dynamic value in the url path. Note: Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. """ -DB_INSTANCE_ID = "db.instance.id" +DB_INSTANCE_ID: Final = "db.instance.id" """ -An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. +Deprecated: Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. """ -DB_JDBC_DRIVER_CLASSNAME = "db.jdbc.driver_classname" +DB_JDBC_DRIVER_CLASSNAME: Final = "db.jdbc.driver_classname" """ Deprecated: Removed as not used. """ -DB_MONGODB_COLLECTION = "db.mongodb.collection" +DB_MONGODB_COLLECTION: Final = "db.mongodb.collection" """ -The MongoDB collection being accessed within the database stated in `db.name`. +Deprecated: Replaced by `db.collection.name`. """ -DB_MSSQL_INSTANCE_NAME = "db.mssql.instance_name" +DB_MSSQL_INSTANCE_NAME: Final = "db.mssql.instance_name" """ -The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. -Note: If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). +Deprecated: Deprecated, no replacement at this time. """ -DB_NAME = "db.name" +DB_NAME: Final = "db.name" """ -This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). -Note: In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +Deprecated: Replaced by `db.namespace`. """ -DB_OPERATION = "db.operation" +DB_NAMESPACE: Final = "db.namespace" """ -The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. -Note: When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. +The name of the database, fully qualified within the server address and port. +Note: If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. + It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. """ -DB_REDIS_DATABASE_INDEX = "db.redis.database_index" +DB_OPERATION: Final = "db.operation" """ -The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. +Deprecated: Replaced by `db.operation.name`. """ -DB_SQL_TABLE = "db.sql.table" +DB_OPERATION_NAME: Final = "db.operation.name" """ -The name of the primary table that the operation is acting upon, including the database name (if applicable). -Note: It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +The name of the operation or command being executed. +Note: It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. """ -DB_STATEMENT = "db.statement" +DB_QUERY_PARAMETER_TEMPLATE: Final = "db.query.parameter" """ -The database statement being executed. +The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. +Note: Query parameters should only be captured when `db.query.text` is parameterized with placeholders. + If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. """ -DB_SYSTEM = "db.system" +DB_QUERY_TEXT: Final = "db.query.text" """ -An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. +The database query being executed. """ -DB_USER = "db.user" +DB_REDIS_DATABASE_INDEX: Final = "db.redis.database_index" """ -Username for accessing the database. +Deprecated: Replaced by `db.namespace`. +""" + +DB_SQL_TABLE: Final = "db.sql.table" +""" +Deprecated: Replaced by `db.collection.name`. +""" + +DB_STATEMENT: Final = "db.statement" +""" +Deprecated: Replaced by `db.query.text`. +""" + +DB_SYSTEM: Final = "db.system" +""" +The database management system (DBMS) product as identified by the client instrumentation. +Note: The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. +""" + +DB_USER: Final = "db.user" +""" +Deprecated: No replacement at this time. """ class DbCassandraConsistencyLevelValues(Enum): - ALL = "all" + ALL: Final = "all" """all.""" - EACH_QUORUM = "each_quorum" + EACH_QUORUM: Final = "each_quorum" """each_quorum.""" - QUORUM = "quorum" + QUORUM: Final = "quorum" """quorum.""" - LOCAL_QUORUM = "local_quorum" + LOCAL_QUORUM: Final = "local_quorum" """local_quorum.""" - ONE = "one" + ONE: Final = "one" """one.""" - TWO = "two" + TWO: Final = "two" """two.""" - THREE = "three" + THREE: Final = "three" """three.""" - LOCAL_ONE = "local_one" + LOCAL_ONE: Final = "local_one" """local_one.""" - ANY = "any" + ANY: Final = "any" """any.""" - SERIAL = "serial" + SERIAL: Final = "serial" """serial.""" - LOCAL_SERIAL = "local_serial" + LOCAL_SERIAL: Final = "local_serial" """local_serial.""" +class DbClientConnectionsStateValues(Enum): + IDLE: Final = "idle" + """idle.""" + USED: Final = "used" + """used.""" + + class DbCosmosdbConnectionModeValues(Enum): - GATEWAY = "gateway" + GATEWAY: Final = "gateway" """Gateway (HTTP) connections mode.""" - DIRECT = "direct" + DIRECT: Final = "direct" """Direct connection.""" class DbCosmosdbOperationTypeValues(Enum): - INVALID = "Invalid" + INVALID: Final = "Invalid" """invalid.""" - CREATE = "Create" + CREATE: Final = "Create" """create.""" - PATCH = "Patch" + PATCH: Final = "Patch" """patch.""" - READ = "Read" + READ: Final = "Read" """read.""" - READ_FEED = "ReadFeed" + READ_FEED: Final = "ReadFeed" """read_feed.""" - DELETE = "Delete" + DELETE: Final = "Delete" """delete.""" - REPLACE = "Replace" + REPLACE: Final = "Replace" """replace.""" - EXECUTE = "Execute" + EXECUTE: Final = "Execute" """execute.""" - QUERY = "Query" + QUERY: Final = "Query" """query.""" - HEAD = "Head" + HEAD: Final = "Head" """head.""" - HEAD_FEED = "HeadFeed" + HEAD_FEED: Final = "HeadFeed" """head_feed.""" - UPSERT = "Upsert" + UPSERT: Final = "Upsert" """upsert.""" - BATCH = "Batch" + BATCH: Final = "Batch" """batch.""" - QUERY_PLAN = "QueryPlan" + QUERY_PLAN: Final = "QueryPlan" """query_plan.""" - EXECUTE_JAVASCRIPT = "ExecuteJavaScript" + EXECUTE_JAVASCRIPT: Final = "ExecuteJavaScript" """execute_javascript.""" class DbSystemValues(Enum): - OTHER_SQL = "other_sql" + OTHER_SQL: Final = "other_sql" """Some other SQL database. Fallback only. See notes.""" - MSSQL = "mssql" + MSSQL: Final = "mssql" """Microsoft SQL Server.""" - MSSQLCOMPACT = "mssqlcompact" + MSSQLCOMPACT: Final = "mssqlcompact" """Microsoft SQL Server Compact.""" - MYSQL = "mysql" + MYSQL: Final = "mysql" """MySQL.""" - ORACLE = "oracle" + ORACLE: Final = "oracle" """Oracle Database.""" - DB2 = "db2" + DB2: Final = "db2" """IBM Db2.""" - POSTGRESQL = "postgresql" + POSTGRESQL: Final = "postgresql" """PostgreSQL.""" - REDSHIFT = "redshift" + REDSHIFT: Final = "redshift" """Amazon Redshift.""" - HIVE = "hive" + HIVE: Final = "hive" """Apache Hive.""" - CLOUDSCAPE = "cloudscape" + CLOUDSCAPE: Final = "cloudscape" """Cloudscape.""" - HSQLDB = "hsqldb" + HSQLDB: Final = "hsqldb" """HyperSQL DataBase.""" - PROGRESS = "progress" + PROGRESS: Final = "progress" """Progress Database.""" - MAXDB = "maxdb" + MAXDB: Final = "maxdb" """SAP MaxDB.""" - HANADB = "hanadb" + HANADB: Final = "hanadb" """SAP HANA.""" - INGRES = "ingres" + INGRES: Final = "ingres" """Ingres.""" - FIRSTSQL = "firstsql" + FIRSTSQL: Final = "firstsql" """FirstSQL.""" - EDB = "edb" + EDB: Final = "edb" """EnterpriseDB.""" - CACHE = "cache" + CACHE: Final = "cache" """InterSystems Caché.""" - ADABAS = "adabas" + ADABAS: Final = "adabas" """Adabas (Adaptable Database System).""" - FIREBIRD = "firebird" + FIREBIRD: Final = "firebird" """Firebird.""" - DERBY = "derby" + DERBY: Final = "derby" """Apache Derby.""" - FILEMAKER = "filemaker" + FILEMAKER: Final = "filemaker" """FileMaker.""" - INFORMIX = "informix" + INFORMIX: Final = "informix" """Informix.""" - INSTANTDB = "instantdb" + INSTANTDB: Final = "instantdb" """InstantDB.""" - INTERBASE = "interbase" + INTERBASE: Final = "interbase" """InterBase.""" - MARIADB = "mariadb" + MARIADB: Final = "mariadb" """MariaDB.""" - NETEZZA = "netezza" + NETEZZA: Final = "netezza" """Netezza.""" - PERVASIVE = "pervasive" + PERVASIVE: Final = "pervasive" """Pervasive PSQL.""" - POINTBASE = "pointbase" + POINTBASE: Final = "pointbase" """PointBase.""" - SQLITE = "sqlite" + SQLITE: Final = "sqlite" """SQLite.""" - SYBASE = "sybase" + SYBASE: Final = "sybase" """Sybase.""" - TERADATA = "teradata" + TERADATA: Final = "teradata" """Teradata.""" - VERTICA = "vertica" + VERTICA: Final = "vertica" """Vertica.""" - H2 = "h2" + H2: Final = "h2" """H2.""" - COLDFUSION = "coldfusion" + COLDFUSION: Final = "coldfusion" """ColdFusion IMQ.""" - CASSANDRA = "cassandra" + CASSANDRA: Final = "cassandra" """Apache Cassandra.""" - HBASE = "hbase" + HBASE: Final = "hbase" """Apache HBase.""" - MONGODB = "mongodb" + MONGODB: Final = "mongodb" """MongoDB.""" - REDIS = "redis" + REDIS: Final = "redis" """Redis.""" - COUCHBASE = "couchbase" + COUCHBASE: Final = "couchbase" """Couchbase.""" - COUCHDB = "couchdb" + COUCHDB: Final = "couchdb" """CouchDB.""" - COSMOSDB = "cosmosdb" + COSMOSDB: Final = "cosmosdb" """Microsoft Azure Cosmos DB.""" - DYNAMODB = "dynamodb" + DYNAMODB: Final = "dynamodb" """Amazon DynamoDB.""" - NEO4J = "neo4j" + NEO4J: Final = "neo4j" """Neo4j.""" - GEODE = "geode" + GEODE: Final = "geode" """Apache Geode.""" - ELASTICSEARCH = "elasticsearch" + ELASTICSEARCH: Final = "elasticsearch" """Elasticsearch.""" - MEMCACHED = "memcached" + MEMCACHED: Final = "memcached" """Memcached.""" - COCKROACHDB = "cockroachdb" + COCKROACHDB: Final = "cockroachdb" """CockroachDB.""" - OPENSEARCH = "opensearch" + OPENSEARCH: Final = "opensearch" """OpenSearch.""" - CLICKHOUSE = "clickhouse" + CLICKHOUSE: Final = "clickhouse" """ClickHouse.""" - SPANNER = "spanner" + SPANNER: Final = "spanner" """Cloud Spanner.""" - TRINO = "trino" + TRINO: Final = "trino" """Trino.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py index c735bf2a10..da93768810 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -DEPLOYMENT_ENVIRONMENT = "deployment.environment" +DEPLOYMENT_ENVIRONMENT: Final = "deployment.environment" """ Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). Note: `deployment.environment` does not affect the uniqueness constraints defined through diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/destination_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/destination_attributes.py index c96ae68f43..8fa4949c66 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/destination_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/destination_attributes.py @@ -12,14 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -DESTINATION_ADDRESS = "destination.address" +DESTINATION_ADDRESS: Final = "destination.address" """ Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. Note: When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. """ -DESTINATION_PORT = "destination.port" +DESTINATION_PORT: Final = "destination.port" """ Destination port number. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/device_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/device_attributes.py index f9fc6503eb..0a65761cff 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/device_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/device_attributes.py @@ -12,26 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -DEVICE_ID = "device.id" +DEVICE_ID: Final = "device.id" """ A unique identifier representing the device. Note: The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. """ -DEVICE_MANUFACTURER = "device.manufacturer" +DEVICE_MANUFACTURER: Final = "device.manufacturer" """ The name of the device manufacturer. Note: The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. """ -DEVICE_MODEL_IDENTIFIER = "device.model.identifier" +DEVICE_MODEL_IDENTIFIER: Final = "device.model.identifier" """ The model identifier for the device. Note: It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. """ -DEVICE_MODEL_NAME = "device.model.name" +DEVICE_MODEL_NAME: Final = "device.model.name" """ The marketing name for the device model. Note: It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/disk_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/disk_attributes.py index 0553eb2625..8177905601 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/disk_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/disk_attributes.py @@ -12,17 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -DISK_IO_DIRECTION = "disk.io.direction" +DISK_IO_DIRECTION: Final = "disk.io.direction" """ The disk IO operation direction. """ class DiskIoDirectionValues(Enum): - READ = "read" + READ: Final = "read" """read.""" - WRITE = "write" + WRITE: Final = "write" """write.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/dns_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/dns_attributes.py index 899e2587d0..cfb00bcf30 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/dns_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/dns_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -DNS_QUESTION_NAME = "dns.question.name" +DNS_QUESTION_NAME: Final = "dns.question.name" """ The name being queried. Note: If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \\t, \\r, and \\n respectively. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py index 05d83db373..d7e58c8095 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py @@ -12,18 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -ENDUSER_ID = "enduser.id" +ENDUSER_ID: Final = "enduser.id" """ Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. """ -ENDUSER_ROLE = "enduser.role" +ENDUSER_ROLE: Final = "enduser.role" """ Actual/assumed role the client is making the request under extracted from token or application security context. """ -ENDUSER_SCOPE = "enduser.scope" +ENDUSER_SCOPE: Final = "enduser.scope" """ Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/error_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/error_attributes.py index 603d6ed72e..4c24bd27bb 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/error_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/error_attributes.py @@ -12,20 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final from deprecated import deprecated -ERROR_TYPE = "error.type" +ERROR_TYPE: Final = "error.type" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ERROR_TYPE`. """ -@deprecated( - reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ErrorTypeValues`." -) +@deprecated(reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ErrorTypeValues`.") # type: ignore class ErrorTypeValues(Enum): - OTHER = "_OTHER" + OTHER: Final = "_OTHER" """A fallback error value to be used when the instrumentation doesn't define a custom value.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/event_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/event_attributes.py index c417cc70d3..7950283d6a 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/event_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/event_attributes.py @@ -12,9 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -EVENT_NAME = "event.name" +EVENT_NAME: Final = "event.name" """ Identifies the class / type of event. -Note: Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. +Note: Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.33.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/exception_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/exception_attributes.py index dd78656b4a..4d0a392527 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/exception_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/exception_attributes.py @@ -12,23 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -EXCEPTION_ESCAPED = "exception.escaped" +EXCEPTION_ESCAPED: Final = "exception.escaped" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_ESCAPED`. """ -EXCEPTION_MESSAGE = "exception.message" +EXCEPTION_MESSAGE: Final = "exception.message" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_MESSAGE`. """ -EXCEPTION_STACKTRACE = "exception.stacktrace" +EXCEPTION_STACKTRACE: Final = "exception.stacktrace" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_STACKTRACE`. """ -EXCEPTION_TYPE = "exception.type" +EXCEPTION_TYPE: Final = "exception.type" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_TYPE`. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/faas_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/faas_attributes.py index f93a016414..bf2595aa25 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/faas_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/faas_attributes.py @@ -12,75 +12,75 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -FAAS_COLDSTART = "faas.coldstart" +FAAS_COLDSTART: Final = "faas.coldstart" """ A boolean that is true if the serverless function is executed for the first time (aka cold-start). """ -FAAS_CRON = "faas.cron" +FAAS_CRON: Final = "faas.cron" """ A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). """ -FAAS_DOCUMENT_COLLECTION = "faas.document.collection" +FAAS_DOCUMENT_COLLECTION: Final = "faas.document.collection" """ The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. """ -FAAS_DOCUMENT_NAME = "faas.document.name" +FAAS_DOCUMENT_NAME: Final = "faas.document.name" """ The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. """ -FAAS_DOCUMENT_OPERATION = "faas.document.operation" +FAAS_DOCUMENT_OPERATION: Final = "faas.document.operation" """ Describes the type of the operation that was performed on the data. """ -FAAS_DOCUMENT_TIME = "faas.document.time" +FAAS_DOCUMENT_TIME: Final = "faas.document.time" """ A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). """ -FAAS_INSTANCE = "faas.instance" +FAAS_INSTANCE: Final = "faas.instance" """ The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. Note: * **AWS Lambda:** Use the (full) log stream name. """ -FAAS_INVOCATION_ID = "faas.invocation_id" +FAAS_INVOCATION_ID: Final = "faas.invocation_id" """ The invocation ID of the current function invocation. """ -FAAS_INVOKED_NAME = "faas.invoked_name" +FAAS_INVOKED_NAME: Final = "faas.invoked_name" """ The name of the invoked function. Note: SHOULD be equal to the `faas.name` resource attribute of the invoked function. """ -FAAS_INVOKED_PROVIDER = "faas.invoked_provider" +FAAS_INVOKED_PROVIDER: Final = "faas.invoked_provider" """ The cloud provider of the invoked function. Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked function. """ -FAAS_INVOKED_REGION = "faas.invoked_region" +FAAS_INVOKED_REGION: Final = "faas.invoked_region" """ The cloud region of the invoked function. Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked function. """ -FAAS_MAX_MEMORY = "faas.max_memory" +FAAS_MAX_MEMORY: Final = "faas.max_memory" """ The amount of memory available to the serverless function converted to Bytes. Note: It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). """ -FAAS_NAME = "faas.name" +FAAS_NAME: Final = "faas.name" """ The name of the single function that this runtime instance executes. Note: This is the name of the function as configured/deployed on the FaaS @@ -101,17 +101,17 @@ a TracerProvider (see also the `cloud.resource_id` attribute). """ -FAAS_TIME = "faas.time" +FAAS_TIME: Final = "faas.time" """ A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). """ -FAAS_TRIGGER = "faas.trigger" +FAAS_TRIGGER: Final = "faas.trigger" """ Type of the trigger which caused this function invocation. """ -FAAS_VERSION = "faas.version" +FAAS_VERSION: Final = "faas.version" """ The immutable version of the function being executed. Note: Depending on the cloud provider and platform, use: @@ -127,35 +127,35 @@ class FaasDocumentOperationValues(Enum): - INSERT = "insert" + INSERT: Final = "insert" """When a new object is created.""" - EDIT = "edit" + EDIT: Final = "edit" """When an object is modified.""" - DELETE = "delete" + DELETE: Final = "delete" """When an object is deleted.""" class FaasInvokedProviderValues(Enum): - ALIBABA_CLOUD = "alibaba_cloud" + ALIBABA_CLOUD: Final = "alibaba_cloud" """Alibaba Cloud.""" - AWS = "aws" + AWS: Final = "aws" """Amazon Web Services.""" - AZURE = "azure" + AZURE: Final = "azure" """Microsoft Azure.""" - GCP = "gcp" + GCP: Final = "gcp" """Google Cloud Platform.""" - TENCENT_CLOUD = "tencent_cloud" + TENCENT_CLOUD: Final = "tencent_cloud" """Tencent Cloud.""" class FaasTriggerValues(Enum): - DATASOURCE = "datasource" + DATASOURCE: Final = "datasource" """A response to some data source operation such as a database or filesystem read/write.""" - HTTP = "http" + HTTP: Final = "http" """To provide an answer to an inbound HTTP request.""" - PUBSUB = "pubsub" + PUBSUB: Final = "pubsub" """A function is set to be executed when messages are sent to a messaging system.""" - TIMER = "timer" + TIMER: Final = "timer" """A function is scheduled to be executed regularly.""" - OTHER = "other" + OTHER: Final = "other" """If none of the others apply.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py index 8302f9666a..f5a37f04c9 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py @@ -12,18 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -FEATURE_FLAG_KEY = "feature_flag.key" +FEATURE_FLAG_KEY: Final = "feature_flag.key" """ The unique identifier of the feature flag. """ -FEATURE_FLAG_PROVIDER_NAME = "feature_flag.provider_name" +FEATURE_FLAG_PROVIDER_NAME: Final = "feature_flag.provider_name" """ The name of the service provider that performs the flag evaluation. """ -FEATURE_FLAG_VARIANT = "feature_flag.variant" +FEATURE_FLAG_VARIANT: Final = "feature_flag.variant" """ SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. Note: A semantic identifier, commonly referred to as a variant, provides a means diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/file_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/file_attributes.py index 1b760c4d1d..3546465c22 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/file_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/file_attributes.py @@ -12,29 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -FILE_DIRECTORY = "file.directory" +FILE_DIRECTORY: Final = "file.directory" """ Directory where the file is located. It should include the drive letter, when appropriate. """ -FILE_EXTENSION = "file.extension" +FILE_EXTENSION: Final = "file.extension" """ File extension, excluding the leading dot. Note: When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). """ -FILE_NAME = "file.name" +FILE_NAME: Final = "file.name" """ Name of the file including the extension, without the directory. """ -FILE_PATH = "file.path" +FILE_PATH: Final = "file.path" """ Full path to the file, including the file name. It should include the drive letter, when appropriate. """ -FILE_SIZE = "file.size" +FILE_SIZE: Final = "file.size" """ File size in bytes. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py index 0b5f6a0c96..1a17e3ee2f 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py @@ -12,23 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -GCP_CLOUD_RUN_JOB_EXECUTION = "gcp.cloud_run.job.execution" +GCP_CLOUD_RUN_JOB_EXECUTION: Final = "gcp.cloud_run.job.execution" """ The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. """ -GCP_CLOUD_RUN_JOB_TASK_INDEX = "gcp.cloud_run.job.task_index" +GCP_CLOUD_RUN_JOB_TASK_INDEX: Final = "gcp.cloud_run.job.task_index" """ The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. """ -GCP_GCE_INSTANCE_HOSTNAME = "gcp.gce.instance.hostname" +GCP_GCE_INSTANCE_HOSTNAME: Final = "gcp.gce.instance.hostname" """ The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). """ -GCP_GCE_INSTANCE_NAME = "gcp.gce.instance.name" +GCP_GCE_INSTANCE_NAME: Final = "gcp.gce.instance.name" """ The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py new file mode 100644 index 0000000000..d8b60f52f0 --- /dev/null +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py @@ -0,0 +1,84 @@ +# 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. + +from enum import Enum +from typing import Final + +GEN_AI_COMPLETION: Final = "gen_ai.completion" +""" +The full response received from the LLM. +Note: It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation). +""" + +GEN_AI_PROMPT: Final = "gen_ai.prompt" +""" +The full prompt sent to an LLM. +Note: It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation). +""" + +GEN_AI_REQUEST_MAX_TOKENS: Final = "gen_ai.request.max_tokens" +""" +The maximum number of tokens the LLM generates for a request. +""" + +GEN_AI_REQUEST_MODEL: Final = "gen_ai.request.model" +""" +The name of the LLM a request is being made to. +""" + +GEN_AI_REQUEST_TEMPERATURE: Final = "gen_ai.request.temperature" +""" +The temperature setting for the LLM request. +""" + +GEN_AI_REQUEST_TOP_P: Final = "gen_ai.request.top_p" +""" +The top_p sampling setting for the LLM request. +""" + +GEN_AI_RESPONSE_FINISH_REASONS: Final = "gen_ai.response.finish_reasons" +""" +Array of reasons the model stopped generating tokens, corresponding to each generation received. +""" + +GEN_AI_RESPONSE_ID: Final = "gen_ai.response.id" +""" +The unique identifier for the completion. +""" + +GEN_AI_RESPONSE_MODEL: Final = "gen_ai.response.model" +""" +The name of the LLM a response was generated from. +""" + +GEN_AI_SYSTEM: Final = "gen_ai.system" +""" +The Generative AI product as identified by the client instrumentation. +Note: The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. +""" + +GEN_AI_USAGE_COMPLETION_TOKENS: Final = "gen_ai.usage.completion_tokens" +""" +The number of tokens used in the LLM response (completion). +""" + +GEN_AI_USAGE_PROMPT_TOKENS: Final = "gen_ai.usage.prompt_tokens" +""" +The number of tokens used in the LLM prompt. +""" + + +class GenAiSystemValues(Enum): + OPENAI: Final = "openai" + """OpenAI.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py index f005d167d6..34595f2c92 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py @@ -12,30 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -GRAPHQL_DOCUMENT = "graphql.document" +GRAPHQL_DOCUMENT: Final = "graphql.document" """ The GraphQL document being executed. Note: The value may be sanitized to exclude sensitive information. """ -GRAPHQL_OPERATION_NAME = "graphql.operation.name" +GRAPHQL_OPERATION_NAME: Final = "graphql.operation.name" """ The name of the operation being executed. """ -GRAPHQL_OPERATION_TYPE = "graphql.operation.type" +GRAPHQL_OPERATION_TYPE: Final = "graphql.operation.type" """ The type of the operation being executed. """ class GraphqlOperationTypeValues(Enum): - QUERY = "query" + QUERY: Final = "query" """GraphQL query.""" - MUTATION = "mutation" + MUTATION: Final = "mutation" """GraphQL mutation.""" - SUBSCRIPTION = "subscription" + SUBSCRIPTION: Final = "subscription" """GraphQL subscription.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py index 27ec50229e..83ba66b193 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py @@ -12,18 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -HEROKU_APP_ID = "heroku.app.id" +HEROKU_APP_ID: Final = "heroku.app.id" """ Unique identifier for the application. """ -HEROKU_RELEASE_COMMIT = "heroku.release.commit" +HEROKU_RELEASE_COMMIT: Final = "heroku.release.commit" """ Commit hash for the current release. """ -HEROKU_RELEASE_CREATION_TIMESTAMP = "heroku.release.creation_timestamp" +HEROKU_RELEASE_CREATION_TIMESTAMP: Final = "heroku.release.creation_timestamp" """ Time and date the release was created. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/host_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/host_attributes.py index 994c57a406..dc0a953d51 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/host_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/host_attributes.py @@ -12,102 +12,102 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -HOST_ARCH = "host.arch" +HOST_ARCH: Final = "host.arch" """ The CPU architecture the host system is running on. """ -HOST_CPU_CACHE_L2_SIZE = "host.cpu.cache.l2.size" +HOST_CPU_CACHE_L2_SIZE: Final = "host.cpu.cache.l2.size" """ The amount of level 2 memory cache available to the processor (in Bytes). """ -HOST_CPU_FAMILY = "host.cpu.family" +HOST_CPU_FAMILY: Final = "host.cpu.family" """ Family or generation of the CPU. """ -HOST_CPU_MODEL_ID = "host.cpu.model.id" +HOST_CPU_MODEL_ID: Final = "host.cpu.model.id" """ Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. """ -HOST_CPU_MODEL_NAME = "host.cpu.model.name" +HOST_CPU_MODEL_NAME: Final = "host.cpu.model.name" """ Model designation of the processor. """ -HOST_CPU_STEPPING = "host.cpu.stepping" +HOST_CPU_STEPPING: Final = "host.cpu.stepping" """ Stepping or core revisions. """ -HOST_CPU_VENDOR_ID = "host.cpu.vendor.id" +HOST_CPU_VENDOR_ID: Final = "host.cpu.vendor.id" """ Processor manufacturer identifier. A maximum 12-character string. Note: [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. """ -HOST_ID = "host.id" +HOST_ID: Final = "host.id" """ Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. """ -HOST_IMAGE_ID = "host.image.id" +HOST_IMAGE_ID: Final = "host.image.id" """ VM image ID or host OS image ID. For Cloud, this value is from the provider. """ -HOST_IMAGE_NAME = "host.image.name" +HOST_IMAGE_NAME: Final = "host.image.name" """ Name of the VM image or OS install the host was instantiated from. """ -HOST_IMAGE_VERSION = "host.image.version" +HOST_IMAGE_VERSION: Final = "host.image.version" """ The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). """ -HOST_IP = "host.ip" +HOST_IP: Final = "host.ip" """ Available IP addresses of the host, excluding loopback interfaces. Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. """ -HOST_MAC = "host.mac" +HOST_MAC: Final = "host.mac" """ Available MAC addresses of the host, excluding loopback interfaces. Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. """ -HOST_NAME = "host.name" +HOST_NAME: Final = "host.name" """ Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. """ -HOST_TYPE = "host.type" +HOST_TYPE: Final = "host.type" """ Type of host. For Cloud, this must be the machine type. """ class HostArchValues(Enum): - AMD64 = "amd64" + AMD64: Final = "amd64" """AMD64.""" - ARM32 = "arm32" + ARM32: Final = "arm32" """ARM32.""" - ARM64 = "arm64" + ARM64: Final = "arm64" """ARM64.""" - IA64 = "ia64" + IA64: Final = "ia64" """Itanium.""" - PPC32 = "ppc32" + PPC32: Final = "ppc32" """32-bit PowerPC.""" - PPC64 = "ppc64" + PPC64: Final = "ppc64" """64-bit PowerPC.""" - S390X = "s390x" + S390X: Final = "s390x" """IBM z/Architecture.""" - X86 = "x86" + X86: Final = "x86" """32-bit x86.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/http_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/http_attributes.py index 70e0e8d2f3..74cacb5108 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/http_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/http_attributes.py @@ -12,163 +12,188 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final from deprecated import deprecated -HTTP_CONNECTION_STATE = "http.connection.state" +HTTP_CLIENT_IP: Final = "http.client_ip" +""" +Deprecated: Replaced by `client.address`. +""" + +HTTP_CONNECTION_STATE: Final = "http.connection.state" """ State of the HTTP connection in the HTTP connection pool. """ -HTTP_FLAVOR = "http.flavor" +HTTP_FLAVOR: Final = "http.flavor" """ Deprecated: Replaced by `network.protocol.name`. """ -HTTP_METHOD = "http.method" +HTTP_HOST: Final = "http.host" +""" +Deprecated: Replaced by one of `server.address`, `client.address` or `http.request.header.host`, depending on the usage. +""" + +HTTP_METHOD: Final = "http.method" """ Deprecated: Replaced by `http.request.method`. """ -HTTP_REQUEST_BODY_SIZE = "http.request.body.size" +HTTP_REQUEST_BODY_SIZE: Final = "http.request.body.size" """ The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. """ -HTTP_REQUEST_HEADER_TEMPLATE = "http.request.header" +HTTP_REQUEST_HEADER_TEMPLATE: Final = "http.request.header" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_HEADER_TEMPLATE`. """ -HTTP_REQUEST_METHOD = "http.request.method" +HTTP_REQUEST_METHOD: Final = "http.request.method" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_METHOD`. """ -HTTP_REQUEST_METHOD_ORIGINAL = "http.request.method_original" +HTTP_REQUEST_METHOD_ORIGINAL: Final = "http.request.method_original" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_METHOD_ORIGINAL`. """ -HTTP_REQUEST_RESEND_COUNT = "http.request.resend_count" +HTTP_REQUEST_RESEND_COUNT: Final = "http.request.resend_count" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_RESEND_COUNT`. """ -HTTP_REQUEST_SIZE = "http.request.size" +HTTP_REQUEST_SIZE: Final = "http.request.size" """ The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. """ -HTTP_REQUEST_CONTENT_LENGTH = "http.request_content_length" +HTTP_REQUEST_CONTENT_LENGTH: Final = "http.request_content_length" """ Deprecated: Replaced by `http.request.header.content-length`. """ -HTTP_RESPONSE_BODY_SIZE = "http.response.body.size" +HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED: Final = ( + "http.request_content_length_uncompressed" +) +""" +Deprecated: Replaced by `http.request.body.size`. +""" + +HTTP_RESPONSE_BODY_SIZE: Final = "http.response.body.size" """ The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. """ -HTTP_RESPONSE_HEADER_TEMPLATE = "http.response.header" +HTTP_RESPONSE_HEADER_TEMPLATE: Final = "http.response.header" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_RESPONSE_HEADER_TEMPLATE`. """ -HTTP_RESPONSE_SIZE = "http.response.size" +HTTP_RESPONSE_SIZE: Final = "http.response.size" """ The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. """ -HTTP_RESPONSE_STATUS_CODE = "http.response.status_code" +HTTP_RESPONSE_STATUS_CODE: Final = "http.response.status_code" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_RESPONSE_STATUS_CODE`. """ -HTTP_RESPONSE_CONTENT_LENGTH = "http.response_content_length" +HTTP_RESPONSE_CONTENT_LENGTH: Final = "http.response_content_length" """ Deprecated: Replaced by `http.response.header.content-length`. """ -HTTP_ROUTE = "http.route" +HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED: Final = ( + "http.response_content_length_uncompressed" +) +""" +Deprecated: Replace by `http.response.body.size`. +""" + +HTTP_ROUTE: Final = "http.route" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_ROUTE`. """ -HTTP_SCHEME = "http.scheme" +HTTP_SCHEME: Final = "http.scheme" """ Deprecated: Replaced by `url.scheme` instead. """ -HTTP_STATUS_CODE = "http.status_code" +HTTP_SERVER_NAME: Final = "http.server_name" +""" +Deprecated: Replaced by `server.address`. +""" + +HTTP_STATUS_CODE: Final = "http.status_code" """ Deprecated: Replaced by `http.response.status_code`. """ -HTTP_TARGET = "http.target" +HTTP_TARGET: Final = "http.target" """ Deprecated: Split to `url.path` and `url.query. """ -HTTP_URL = "http.url" +HTTP_URL: Final = "http.url" """ Deprecated: Replaced by `url.full`. """ -HTTP_USER_AGENT = "http.user_agent" +HTTP_USER_AGENT: Final = "http.user_agent" """ Deprecated: Replaced by `user_agent.original`. """ class HttpConnectionStateValues(Enum): - ACTIVE = "active" + ACTIVE: Final = "active" """active state.""" - IDLE = "idle" + IDLE: Final = "idle" """idle state.""" -@deprecated( - reason="The attribute http.flavor is deprecated - Replaced by `network.protocol.name`" -) +@deprecated(reason="The attribute http.flavor is deprecated - Replaced by `network.protocol.name`") # type: ignore class HttpFlavorValues(Enum): - HTTP_1_0 = "1.0" + HTTP_1_0: Final = "1.0" """HTTP/1.0.""" - HTTP_1_1 = "1.1" + HTTP_1_1: Final = "1.1" """HTTP/1.1.""" - HTTP_2_0 = "2.0" + HTTP_2_0: Final = "2.0" """HTTP/2.""" - HTTP_3_0 = "3.0" + HTTP_3_0: Final = "3.0" """HTTP/3.""" - SPDY = "SPDY" + SPDY: Final = "SPDY" """SPDY protocol.""" - QUIC = "QUIC" + QUIC: Final = "QUIC" """QUIC protocol.""" -@deprecated( - reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues`." -) +@deprecated(reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues`.") # type: ignore class HttpRequestMethodValues(Enum): - CONNECT = "CONNECT" + CONNECT: Final = "CONNECT" """CONNECT method.""" - DELETE = "DELETE" + DELETE: Final = "DELETE" """DELETE method.""" - GET = "GET" + GET: Final = "GET" """GET method.""" - HEAD = "HEAD" + HEAD: Final = "HEAD" """HEAD method.""" - OPTIONS = "OPTIONS" + OPTIONS: Final = "OPTIONS" """OPTIONS method.""" - PATCH = "PATCH" + PATCH: Final = "PATCH" """PATCH method.""" - POST = "POST" + POST: Final = "POST" """POST method.""" - PUT = "PUT" + PUT: Final = "PUT" """PUT method.""" - TRACE = "TRACE" + TRACE: Final = "TRACE" """TRACE method.""" - OTHER = "_OTHER" + OTHER: Final = "_OTHER" """Any HTTP method that the instrumentation has no prior knowledge of.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py index fcc1d0d8de..f5faf84181 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -K8S_CLUSTER_NAME = "k8s.cluster.name" +K8S_CLUSTER_NAME: Final = "k8s.cluster.name" """ The name of the cluster. """ -K8S_CLUSTER_UID = "k8s.cluster.uid" +K8S_CLUSTER_UID: Final = "k8s.cluster.uid" """ A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. Note: K8s doesn't have support for obtaining a cluster ID. If this is ever @@ -45,112 +46,119 @@ conflict. """ -K8S_CONTAINER_NAME = "k8s.container.name" +K8S_CONTAINER_NAME: Final = "k8s.container.name" """ The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). """ -K8S_CONTAINER_RESTART_COUNT = "k8s.container.restart_count" +K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart_count" """ Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. """ -K8S_CRONJOB_NAME = "k8s.cronjob.name" +K8S_CONTAINER_STATUS_LAST_TERMINATED_REASON: Final = ( + "k8s.container.status.last_terminated_reason" +) +""" +Last terminated reason of the Container. +""" + +K8S_CRONJOB_NAME: Final = "k8s.cronjob.name" """ The name of the CronJob. """ -K8S_CRONJOB_UID = "k8s.cronjob.uid" +K8S_CRONJOB_UID: Final = "k8s.cronjob.uid" """ The UID of the CronJob. """ -K8S_DAEMONSET_NAME = "k8s.daemonset.name" +K8S_DAEMONSET_NAME: Final = "k8s.daemonset.name" """ The name of the DaemonSet. """ -K8S_DAEMONSET_UID = "k8s.daemonset.uid" +K8S_DAEMONSET_UID: Final = "k8s.daemonset.uid" """ The UID of the DaemonSet. """ -K8S_DEPLOYMENT_NAME = "k8s.deployment.name" +K8S_DEPLOYMENT_NAME: Final = "k8s.deployment.name" """ The name of the Deployment. """ -K8S_DEPLOYMENT_UID = "k8s.deployment.uid" +K8S_DEPLOYMENT_UID: Final = "k8s.deployment.uid" """ The UID of the Deployment. """ -K8S_JOB_NAME = "k8s.job.name" +K8S_JOB_NAME: Final = "k8s.job.name" """ The name of the Job. """ -K8S_JOB_UID = "k8s.job.uid" +K8S_JOB_UID: Final = "k8s.job.uid" """ The UID of the Job. """ -K8S_NAMESPACE_NAME = "k8s.namespace.name" +K8S_NAMESPACE_NAME: Final = "k8s.namespace.name" """ The name of the namespace that the pod is running in. """ -K8S_NODE_NAME = "k8s.node.name" +K8S_NODE_NAME: Final = "k8s.node.name" """ The name of the Node. """ -K8S_NODE_UID = "k8s.node.uid" +K8S_NODE_UID: Final = "k8s.node.uid" """ The UID of the Node. """ -K8S_POD_ANNOTATION_TEMPLATE = "k8s.pod.annotation" +K8S_POD_ANNOTATION_TEMPLATE: Final = "k8s.pod.annotation" """ The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. """ -K8S_POD_LABEL_TEMPLATE = "k8s.pod.label" +K8S_POD_LABEL_TEMPLATE: Final = "k8s.pod.label" """ The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. """ -K8S_POD_LABELS_TEMPLATE = "k8s.pod.labels" +K8S_POD_LABELS_TEMPLATE: Final = "k8s.pod.labels" """ Deprecated: Replaced by `k8s.pod.label`. """ -K8S_POD_NAME = "k8s.pod.name" +K8S_POD_NAME: Final = "k8s.pod.name" """ The name of the Pod. """ -K8S_POD_UID = "k8s.pod.uid" +K8S_POD_UID: Final = "k8s.pod.uid" """ The UID of the Pod. """ -K8S_REPLICASET_NAME = "k8s.replicaset.name" +K8S_REPLICASET_NAME: Final = "k8s.replicaset.name" """ The name of the ReplicaSet. """ -K8S_REPLICASET_UID = "k8s.replicaset.uid" +K8S_REPLICASET_UID: Final = "k8s.replicaset.uid" """ The UID of the ReplicaSet. """ -K8S_STATEFULSET_NAME = "k8s.statefulset.name" +K8S_STATEFULSET_NAME: Final = "k8s.statefulset.name" """ The name of the StatefulSet. """ -K8S_STATEFULSET_UID = "k8s.statefulset.uid" +K8S_STATEFULSET_UID: Final = "k8s.statefulset.uid" """ The UID of the StatefulSet. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/log_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/log_attributes.py index ff94348558..6159fefe7c 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/log_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/log_attributes.py @@ -12,35 +12,35 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -LOG_FILE_NAME = "log.file.name" +LOG_FILE_NAME: Final = "log.file.name" """ The basename of the file. """ -LOG_FILE_NAME_RESOLVED = "log.file.name_resolved" +LOG_FILE_NAME_RESOLVED: Final = "log.file.name_resolved" """ The basename of the file, with symlinks resolved. """ -LOG_FILE_PATH = "log.file.path" +LOG_FILE_PATH: Final = "log.file.path" """ The full path to the file. """ -LOG_FILE_PATH_RESOLVED = "log.file.path_resolved" +LOG_FILE_PATH_RESOLVED: Final = "log.file.path_resolved" """ The full path to the file, with symlinks resolved. """ -LOG_IOSTREAM = "log.iostream" +LOG_IOSTREAM: Final = "log.iostream" """ The stream associated with the log. See below for a list of well-known values. """ -LOG_RECORD_UID = "log.record.uid" +LOG_RECORD_UID: Final = "log.record.uid" """ A unique identifier for the Log Record. Note: If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. @@ -49,7 +49,7 @@ class LogIostreamValues(Enum): - STDOUT = "stdout" + STDOUT: Final = "stdout" """Logs from stdout stream.""" - STDERR = "stderr" + STDERR: Final = "stderr" """Events from stderr stream.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/message_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/message_attributes.py index dea3ba65ae..1124daaee1 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/message_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/message_attributes.py @@ -12,33 +12,35 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final + +from deprecated import deprecated -MESSAGE_COMPRESSED_SIZE = "message.compressed_size" +MESSAGE_COMPRESSED_SIZE: Final = "message.compressed_size" """ -Compressed size of the message in bytes. +Deprecated: Replaced by `rpc.message.compressed_size`. """ -MESSAGE_ID = "message.id" +MESSAGE_ID: Final = "message.id" """ -MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. -Note: This way we guarantee that the values will be consistent between different implementations. +Deprecated: Replaced by `rpc.message.id`. """ -MESSAGE_TYPE = "message.type" +MESSAGE_TYPE: Final = "message.type" """ -Whether this is a received or sent message. +Deprecated: Replaced by `rpc.message.type`. """ -MESSAGE_UNCOMPRESSED_SIZE = "message.uncompressed_size" +MESSAGE_UNCOMPRESSED_SIZE: Final = "message.uncompressed_size" """ -Uncompressed size of the message in bytes. +Deprecated: Replaced by `rpc.message.uncompressed_size`. """ +@deprecated(reason="The attribute message.type is deprecated - Replaced by `rpc.message.type`") # type: ignore class MessageTypeValues(Enum): - SENT = "SENT" + SENT: Final = "SENT" """sent.""" - RECEIVED = "RECEIVED" + RECEIVED: Final = "RECEIVED" """received.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py index c3c7ce85c6..a684e4471f 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py @@ -12,294 +12,340 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -MESSAGING_BATCH_MESSAGE_COUNT = "messaging.batch.message_count" +MESSAGING_BATCH_MESSAGE_COUNT: Final = "messaging.batch.message_count" """ The number of messages sent, received, or processed in the scope of the batching operation. Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. """ -MESSAGING_CLIENT_ID = "messaging.client_id" +MESSAGING_CLIENT_ID: Final = "messaging.client.id" """ A unique identifier for the client that consumes or produces a message. """ -MESSAGING_DESTINATION_ANONYMOUS = "messaging.destination.anonymous" +# MESSAGING_CLIENT_ID: Final = "messaging.client_id" + +# Deprecated: Replaced by `messaging.client.id`. + +MESSAGING_DESTINATION_ANONYMOUS: Final = "messaging.destination.anonymous" """ A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). """ -MESSAGING_DESTINATION_NAME = "messaging.destination.name" +MESSAGING_DESTINATION_NAME: Final = "messaging.destination.name" """ The message destination name. Note: Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. """ -MESSAGING_DESTINATION_PARTITION_ID = "messaging.destination.partition.id" +MESSAGING_DESTINATION_PARTITION_ID: Final = ( + "messaging.destination.partition.id" +) """ The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. """ -MESSAGING_DESTINATION_TEMPLATE = "messaging.destination.template" +MESSAGING_DESTINATION_TEMPLATE: Final = "messaging.destination.template" """ Low cardinality representation of the messaging destination name. Note: Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. """ -MESSAGING_DESTINATION_TEMPORARY = "messaging.destination.temporary" +MESSAGING_DESTINATION_TEMPORARY: Final = "messaging.destination.temporary" """ A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. """ -MESSAGING_DESTINATION_PUBLISH_ANONYMOUS = ( +MESSAGING_DESTINATION_PUBLISH_ANONYMOUS: Final = ( "messaging.destination_publish.anonymous" ) """ A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). """ -MESSAGING_DESTINATION_PUBLISH_NAME = "messaging.destination_publish.name" +MESSAGING_DESTINATION_PUBLISH_NAME: Final = ( + "messaging.destination_publish.name" +) """ The name of the original destination the message was published to. Note: The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. """ -MESSAGING_EVENTHUBS_CONSUMER_GROUP = "messaging.eventhubs.consumer.group" +MESSAGING_EVENTHUBS_CONSUMER_GROUP: Final = ( + "messaging.eventhubs.consumer.group" +) """ The name of the consumer group the event consumer is associated with. """ -MESSAGING_EVENTHUBS_MESSAGE_ENQUEUED_TIME = ( +MESSAGING_EVENTHUBS_MESSAGE_ENQUEUED_TIME: Final = ( "messaging.eventhubs.message.enqueued_time" ) """ The UTC epoch seconds at which the message has been accepted and stored in the entity. """ -MESSAGING_GCP_PUBSUB_MESSAGE_ORDERING_KEY = ( +MESSAGING_GCP_PUBSUB_MESSAGE_ACK_DEADLINE: Final = ( + "messaging.gcp_pubsub.message.ack_deadline" +) +""" +The ack deadline in seconds set for the modify ack deadline request. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_ACK_ID: Final = ( + "messaging.gcp_pubsub.message.ack_id" +) +""" +The ack id for a given message. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_DELIVERY_ATTEMPT: Final = ( + "messaging.gcp_pubsub.message.delivery_attempt" +) +""" +The delivery attempt for a given message. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_ORDERING_KEY: Final = ( "messaging.gcp_pubsub.message.ordering_key" ) """ The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. """ -MESSAGING_KAFKA_CONSUMER_GROUP = "messaging.kafka.consumer.group" +MESSAGING_KAFKA_CONSUMER_GROUP: Final = "messaging.kafka.consumer.group" """ Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. """ -MESSAGING_KAFKA_DESTINATION_PARTITION = "messaging.kafka.destination.partition" +MESSAGING_KAFKA_DESTINATION_PARTITION: Final = ( + "messaging.kafka.destination.partition" +) """ Deprecated: Replaced by `messaging.destination.partition.id`. """ -MESSAGING_KAFKA_MESSAGE_KEY = "messaging.kafka.message.key" +MESSAGING_KAFKA_MESSAGE_KEY: Final = "messaging.kafka.message.key" """ Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. Note: If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. """ -MESSAGING_KAFKA_MESSAGE_OFFSET = "messaging.kafka.message.offset" +MESSAGING_KAFKA_MESSAGE_OFFSET: Final = "messaging.kafka.message.offset" """ The offset of a record in the corresponding Kafka partition. """ -MESSAGING_KAFKA_MESSAGE_TOMBSTONE = "messaging.kafka.message.tombstone" +MESSAGING_KAFKA_MESSAGE_TOMBSTONE: Final = "messaging.kafka.message.tombstone" """ A boolean that is true if the message is a tombstone. """ -MESSAGING_MESSAGE_BODY_SIZE = "messaging.message.body.size" +MESSAGING_MESSAGE_BODY_SIZE: Final = "messaging.message.body.size" """ The size of the message body in bytes. Note: This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. """ -MESSAGING_MESSAGE_CONVERSATION_ID = "messaging.message.conversation_id" +MESSAGING_MESSAGE_CONVERSATION_ID: Final = "messaging.message.conversation_id" """ The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". """ -MESSAGING_MESSAGE_ENVELOPE_SIZE = "messaging.message.envelope.size" +MESSAGING_MESSAGE_ENVELOPE_SIZE: Final = "messaging.message.envelope.size" """ The size of the message body and metadata in bytes. Note: This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. """ -MESSAGING_MESSAGE_ID = "messaging.message.id" +MESSAGING_MESSAGE_ID: Final = "messaging.message.id" """ A value used by the messaging system as an identifier for the message, represented as a string. """ -MESSAGING_OPERATION = "messaging.operation" +MESSAGING_OPERATION: Final = "messaging.operation" +""" +Deprecated: Replaced by `messaging.operation.type`. """ -A string identifying the kind of messaging operation. + +MESSAGING_OPERATION_NAME: Final = "messaging.operation.name" +""" +The system-specific name of the messaging operation. +""" + +MESSAGING_OPERATION_TYPE: Final = "messaging.operation.type" +""" +A string identifying the type of the messaging operation. Note: If a custom value is used, it MUST be of low cardinality. """ -MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY = ( +MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY: Final = ( "messaging.rabbitmq.destination.routing_key" ) """ RabbitMQ message routing key. """ -MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG = ( +MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG: Final = ( "messaging.rabbitmq.message.delivery_tag" ) """ RabbitMQ message delivery tag. """ -MESSAGING_ROCKETMQ_CLIENT_GROUP = "messaging.rocketmq.client_group" +MESSAGING_ROCKETMQ_CLIENT_GROUP: Final = "messaging.rocketmq.client_group" """ Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. """ -MESSAGING_ROCKETMQ_CONSUMPTION_MODEL = "messaging.rocketmq.consumption_model" +MESSAGING_ROCKETMQ_CONSUMPTION_MODEL: Final = ( + "messaging.rocketmq.consumption_model" +) """ Model of message consumption. This only applies to consumer spans. """ -MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL = ( +MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL: Final = ( "messaging.rocketmq.message.delay_time_level" ) """ The delay time level for delay message, which determines the message delay time. """ -MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP = ( +MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP: Final = ( "messaging.rocketmq.message.delivery_timestamp" ) """ The timestamp in milliseconds that the delay message is expected to be delivered to consumer. """ -MESSAGING_ROCKETMQ_MESSAGE_GROUP = "messaging.rocketmq.message.group" +MESSAGING_ROCKETMQ_MESSAGE_GROUP: Final = "messaging.rocketmq.message.group" """ It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. """ -MESSAGING_ROCKETMQ_MESSAGE_KEYS = "messaging.rocketmq.message.keys" +MESSAGING_ROCKETMQ_MESSAGE_KEYS: Final = "messaging.rocketmq.message.keys" """ Key(s) of message, another way to mark message besides message id. """ -MESSAGING_ROCKETMQ_MESSAGE_TAG = "messaging.rocketmq.message.tag" +MESSAGING_ROCKETMQ_MESSAGE_TAG: Final = "messaging.rocketmq.message.tag" """ The secondary classifier of message besides topic. """ -MESSAGING_ROCKETMQ_MESSAGE_TYPE = "messaging.rocketmq.message.type" +MESSAGING_ROCKETMQ_MESSAGE_TYPE: Final = "messaging.rocketmq.message.type" """ Type of message. """ -MESSAGING_ROCKETMQ_NAMESPACE = "messaging.rocketmq.namespace" +MESSAGING_ROCKETMQ_NAMESPACE: Final = "messaging.rocketmq.namespace" """ Namespace of RocketMQ resources, resources in different namespaces are individual. """ -MESSAGING_SERVICEBUS_DESTINATION_SUBSCRIPTION_NAME = ( +MESSAGING_SERVICEBUS_DESTINATION_SUBSCRIPTION_NAME: Final = ( "messaging.servicebus.destination.subscription_name" ) """ The name of the subscription in the topic messages are received from. """ -MESSAGING_SERVICEBUS_DISPOSITION_STATUS = ( +MESSAGING_SERVICEBUS_DISPOSITION_STATUS: Final = ( "messaging.servicebus.disposition_status" ) """ Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). """ -MESSAGING_SERVICEBUS_MESSAGE_DELIVERY_COUNT = ( +MESSAGING_SERVICEBUS_MESSAGE_DELIVERY_COUNT: Final = ( "messaging.servicebus.message.delivery_count" ) """ Number of deliveries that have been attempted for this message. """ -MESSAGING_SERVICEBUS_MESSAGE_ENQUEUED_TIME = ( +MESSAGING_SERVICEBUS_MESSAGE_ENQUEUED_TIME: Final = ( "messaging.servicebus.message.enqueued_time" ) """ The UTC epoch seconds at which the message has been accepted and stored in the entity. """ -MESSAGING_SYSTEM = "messaging.system" +MESSAGING_SYSTEM: Final = "messaging.system" """ -An identifier for the messaging system being used. See below for a list of well-known identifiers. +The messaging system as identified by the client instrumentation. +Note: The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. """ -class MessagingOperationValues(Enum): - PUBLISH = "publish" +class MessagingOperationTypeValues(Enum): + PUBLISH: Final = "publish" """One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created.""" - CREATE = "create" + CREATE: Final = "create" """A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios.""" - RECEIVE = "receive" + RECEIVE: Final = "receive" """One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.""" - DELIVER = "process" + DELIVER: Final = "process" """One or more messages are delivered to or processed by a consumer.""" - SETTLE = "settle" + SETTLE: Final = "settle" """One or more messages are settled.""" class MessagingRocketmqConsumptionModelValues(Enum): - CLUSTERING = "clustering" + CLUSTERING: Final = "clustering" """Clustering consumption model.""" - BROADCASTING = "broadcasting" + BROADCASTING: Final = "broadcasting" """Broadcasting consumption model.""" class MessagingRocketmqMessageTypeValues(Enum): - NORMAL = "normal" + NORMAL: Final = "normal" """Normal message.""" - FIFO = "fifo" + FIFO: Final = "fifo" """FIFO message.""" - DELAY = "delay" + DELAY: Final = "delay" """Delay message.""" - TRANSACTION = "transaction" + TRANSACTION: Final = "transaction" """Transaction message.""" class MessagingServicebusDispositionStatusValues(Enum): - COMPLETE = "complete" + COMPLETE: Final = "complete" """Message is completed.""" - ABANDON = "abandon" + ABANDON: Final = "abandon" """Message is abandoned.""" - DEAD_LETTER = "dead_letter" + DEAD_LETTER: Final = "dead_letter" """Message is sent to dead letter queue.""" - DEFER = "defer" + DEFER: Final = "defer" """Message is deferred.""" class MessagingSystemValues(Enum): - ACTIVEMQ = "activemq" + ACTIVEMQ: Final = "activemq" """Apache ActiveMQ.""" - AWS_SQS = "aws_sqs" + AWS_SQS: Final = "aws_sqs" """Amazon Simple Queue Service (SQS).""" - EVENTGRID = "eventgrid" + EVENTGRID: Final = "eventgrid" """Azure Event Grid.""" - EVENTHUBS = "eventhubs" + EVENTHUBS: Final = "eventhubs" """Azure Event Hubs.""" - SERVICEBUS = "servicebus" + SERVICEBUS: Final = "servicebus" """Azure Service Bus.""" - GCP_PUBSUB = "gcp_pubsub" + GCP_PUBSUB: Final = "gcp_pubsub" """Google Cloud Pub/Sub.""" - JMS = "jms" + JMS: Final = "jms" """Java Message Service.""" - KAFKA = "kafka" + KAFKA: Final = "kafka" """Apache Kafka.""" - RABBITMQ = "rabbitmq" + RABBITMQ: Final = "rabbitmq" """RabbitMQ.""" - ROCKETMQ = "rocketmq" + ROCKETMQ: Final = "rocketmq" """Apache RocketMQ.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/net_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/net_attributes.py new file mode 100644 index 0000000000..da0e3828e7 --- /dev/null +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/net_attributes.py @@ -0,0 +1,117 @@ +# 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. + +from enum import Enum +from typing import Final + +from deprecated import deprecated + +NET_HOST_IP: Final = "net.host.ip" +""" +Deprecated: Replaced by `network.local.address`. +""" + +NET_HOST_NAME: Final = "net.host.name" +""" +Deprecated: Replaced by `server.address`. +""" + +NET_HOST_PORT: Final = "net.host.port" +""" +Deprecated: Replaced by `server.port`. +""" + +NET_PEER_IP: Final = "net.peer.ip" +""" +Deprecated: Replaced by `network.peer.address`. +""" + +NET_PEER_NAME: Final = "net.peer.name" +""" +Deprecated: Replaced by `server.address` on client spans and `client.address` on server spans. +""" + +NET_PEER_PORT: Final = "net.peer.port" +""" +Deprecated: Replaced by `server.port` on client spans and `client.port` on server spans. +""" + +NET_PROTOCOL_NAME: Final = "net.protocol.name" +""" +Deprecated: Replaced by `network.protocol.name`. +""" + +NET_PROTOCOL_VERSION: Final = "net.protocol.version" +""" +Deprecated: Replaced by `network.protocol.version`. +""" + +NET_SOCK_FAMILY: Final = "net.sock.family" +""" +Deprecated: Split to `network.transport` and `network.type`. +""" + +NET_SOCK_HOST_ADDR: Final = "net.sock.host.addr" +""" +Deprecated: Replaced by `network.local.address`. +""" + +NET_SOCK_HOST_PORT: Final = "net.sock.host.port" +""" +Deprecated: Replaced by `network.local.port`. +""" + +NET_SOCK_PEER_ADDR: Final = "net.sock.peer.addr" +""" +Deprecated: Replaced by `network.peer.address`. +""" + +NET_SOCK_PEER_NAME: Final = "net.sock.peer.name" +""" +Deprecated: Removed. +""" + +NET_SOCK_PEER_PORT: Final = "net.sock.peer.port" +""" +Deprecated: Replaced by `network.peer.port`. +""" + +NET_TRANSPORT: Final = "net.transport" +""" +Deprecated: Replaced by `network.transport`. +""" + + +@deprecated(reason="The attribute net.sock.family is deprecated - Split to `network.transport` and `network.type`") # type: ignore +class NetSockFamilyValues(Enum): + INET: Final = "inet" + """IPv4 address.""" + INET6: Final = "inet6" + """IPv6 address.""" + UNIX: Final = "unix" + """Unix domain socket path.""" + + +@deprecated(reason="The attribute net.transport is deprecated - Replaced by `network.transport`") # type: ignore +class NetTransportValues(Enum): + IP_TCP: Final = "ip_tcp" + """ip_tcp.""" + IP_UDP: Final = "ip_udp" + """ip_udp.""" + PIPE: Final = "pipe" + """Named or anonymous pipe.""" + INPROC: Final = "inproc" + """In-process communication.""" + OTHER: Final = "other" + """Something else (non IP-based).""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/network_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/network_attributes.py index d226ff311c..7474e391bd 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/network_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/network_attributes.py @@ -12,171 +12,167 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final from deprecated import deprecated -NETWORK_CARRIER_ICC = "network.carrier.icc" +NETWORK_CARRIER_ICC: Final = "network.carrier.icc" """ The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. """ -NETWORK_CARRIER_MCC = "network.carrier.mcc" +NETWORK_CARRIER_MCC: Final = "network.carrier.mcc" """ The mobile carrier country code. """ -NETWORK_CARRIER_MNC = "network.carrier.mnc" +NETWORK_CARRIER_MNC: Final = "network.carrier.mnc" """ The mobile carrier network code. """ -NETWORK_CARRIER_NAME = "network.carrier.name" +NETWORK_CARRIER_NAME: Final = "network.carrier.name" """ The name of the mobile carrier. """ -NETWORK_CONNECTION_SUBTYPE = "network.connection.subtype" +NETWORK_CONNECTION_SUBTYPE: Final = "network.connection.subtype" """ This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. """ -NETWORK_CONNECTION_TYPE = "network.connection.type" +NETWORK_CONNECTION_TYPE: Final = "network.connection.type" """ The internet connection type. """ -NETWORK_IO_DIRECTION = "network.io.direction" +NETWORK_IO_DIRECTION: Final = "network.io.direction" """ The network IO operation direction. """ -NETWORK_LOCAL_ADDRESS = "network.local.address" +NETWORK_LOCAL_ADDRESS: Final = "network.local.address" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_LOCAL_ADDRESS`. """ -NETWORK_LOCAL_PORT = "network.local.port" +NETWORK_LOCAL_PORT: Final = "network.local.port" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_LOCAL_PORT`. """ -NETWORK_PEER_ADDRESS = "network.peer.address" +NETWORK_PEER_ADDRESS: Final = "network.peer.address" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PEER_ADDRESS`. """ -NETWORK_PEER_PORT = "network.peer.port" +NETWORK_PEER_PORT: Final = "network.peer.port" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PEER_PORT`. """ -NETWORK_PROTOCOL_NAME = "network.protocol.name" +NETWORK_PROTOCOL_NAME: Final = "network.protocol.name" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PROTOCOL_NAME`. """ -NETWORK_PROTOCOL_VERSION = "network.protocol.version" +NETWORK_PROTOCOL_VERSION: Final = "network.protocol.version" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PROTOCOL_VERSION`. """ -NETWORK_TRANSPORT = "network.transport" +NETWORK_TRANSPORT: Final = "network.transport" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_TRANSPORT`. """ -NETWORK_TYPE = "network.type" +NETWORK_TYPE: Final = "network.type" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_TYPE`. """ class NetworkConnectionSubtypeValues(Enum): - GPRS = "gprs" + GPRS: Final = "gprs" """GPRS.""" - EDGE = "edge" + EDGE: Final = "edge" """EDGE.""" - UMTS = "umts" + UMTS: Final = "umts" """UMTS.""" - CDMA = "cdma" + CDMA: Final = "cdma" """CDMA.""" - EVDO_0 = "evdo_0" + EVDO_0: Final = "evdo_0" """EVDO Rel. 0.""" - EVDO_A = "evdo_a" + EVDO_A: Final = "evdo_a" """EVDO Rev. A.""" - CDMA2000_1XRTT = "cdma2000_1xrtt" + CDMA2000_1XRTT: Final = "cdma2000_1xrtt" """CDMA2000 1XRTT.""" - HSDPA = "hsdpa" + HSDPA: Final = "hsdpa" """HSDPA.""" - HSUPA = "hsupa" + HSUPA: Final = "hsupa" """HSUPA.""" - HSPA = "hspa" + HSPA: Final = "hspa" """HSPA.""" - IDEN = "iden" + IDEN: Final = "iden" """IDEN.""" - EVDO_B = "evdo_b" + EVDO_B: Final = "evdo_b" """EVDO Rev. B.""" - LTE = "lte" + LTE: Final = "lte" """LTE.""" - EHRPD = "ehrpd" + EHRPD: Final = "ehrpd" """EHRPD.""" - HSPAP = "hspap" + HSPAP: Final = "hspap" """HSPAP.""" - GSM = "gsm" + GSM: Final = "gsm" """GSM.""" - TD_SCDMA = "td_scdma" + TD_SCDMA: Final = "td_scdma" """TD-SCDMA.""" - IWLAN = "iwlan" + IWLAN: Final = "iwlan" """IWLAN.""" - NR = "nr" + NR: Final = "nr" """5G NR (New Radio).""" - NRNSA = "nrnsa" + NRNSA: Final = "nrnsa" """5G NRNSA (New Radio Non-Standalone).""" - LTE_CA = "lte_ca" + LTE_CA: Final = "lte_ca" """LTE CA.""" class NetworkConnectionTypeValues(Enum): - WIFI = "wifi" + WIFI: Final = "wifi" """wifi.""" - WIRED = "wired" + WIRED: Final = "wired" """wired.""" - CELL = "cell" + CELL: Final = "cell" """cell.""" - UNAVAILABLE = "unavailable" + UNAVAILABLE: Final = "unavailable" """unavailable.""" - UNKNOWN = "unknown" + UNKNOWN: Final = "unknown" """unknown.""" class NetworkIoDirectionValues(Enum): - TRANSMIT = "transmit" + TRANSMIT: Final = "transmit" """transmit.""" - RECEIVE = "receive" + RECEIVE: Final = "receive" """receive.""" -@deprecated( - reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues`." -) +@deprecated(reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues`.") # type: ignore class NetworkTransportValues(Enum): - TCP = "tcp" + TCP: Final = "tcp" """TCP.""" - UDP = "udp" + UDP: Final = "udp" """UDP.""" - PIPE = "pipe" + PIPE: Final = "pipe" """Named or anonymous pipe.""" - UNIX = "unix" + UNIX: Final = "unix" """Unix domain socket.""" -@deprecated( - reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues`." -) +@deprecated(reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues`.") # type: ignore class NetworkTypeValues(Enum): - IPV4 = "ipv4" + IPV4: Final = "ipv4" """IPv4.""" - IPV6 = "ipv6" + IPV6: Final = "ipv6" """IPv6.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/oci_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/oci_attributes.py index bda352d8ba..22c05bc4ae 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/oci_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/oci_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -OCI_MANIFEST_DIGEST = "oci.manifest.digest" +OCI_MANIFEST_DIGEST: Final = "oci.manifest.digest" """ The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. Note: Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py index 6c2f4143b9..71c0fad390 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -OPENTRACING_REF_TYPE = "opentracing.ref_type" +OPENTRACING_REF_TYPE: Final = "opentracing.ref_type" """ Parent-child Reference type. Note: The causal relationship between a child Span and a parent Span. @@ -23,7 +23,7 @@ class OpentracingRefTypeValues(Enum): - CHILD_OF = "child_of" + CHILD_OF: Final = "child_of" """The parent Span depends on the child Span in some capacity.""" - FOLLOWS_FROM = "follows_from" + FOLLOWS_FROM: Final = "follows_from" """The parent Span doesn't depend in any way on the result of the child Span.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/os_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/os_attributes.py new file mode 100644 index 0000000000..eb36333115 --- /dev/null +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/os_attributes.py @@ -0,0 +1,66 @@ +# 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. + +from enum import Enum +from typing import Final + +OS_BUILD_ID: Final = "os.build_id" +""" +Unique identifier for a particular build or compilation of the operating system. +""" + +OS_DESCRIPTION: Final = "os.description" +""" +Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. +""" + +OS_NAME: Final = "os.name" +""" +Human readable operating system name. +""" + +OS_TYPE: Final = "os.type" +""" +The operating system type. +""" + +OS_VERSION: Final = "os.version" +""" +The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). +""" + + +class OsTypeValues(Enum): + WINDOWS: Final = "windows" + """Microsoft Windows.""" + LINUX: Final = "linux" + """Linux.""" + DARWIN: Final = "darwin" + """Apple Darwin.""" + FREEBSD: Final = "freebsd" + """FreeBSD.""" + NETBSD: Final = "netbsd" + """NetBSD.""" + OPENBSD: Final = "openbsd" + """OpenBSD.""" + DRAGONFLYBSD: Final = "dragonflybsd" + """DragonFly BSD.""" + HPUX: Final = "hpux" + """HP-UX (Hewlett Packard Unix).""" + AIX: Final = "aix" + """AIX (Advanced Interactive eXecutive).""" + SOLARIS: Final = "solaris" + """SunOS, Oracle Solaris.""" + Z_OS: Final = "z_os" + """IBM z/OS.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/otel_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/otel_attributes.py index 9a04a2ac95..5ee8ad13bf 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/otel_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/otel_attributes.py @@ -12,47 +12,45 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final from deprecated import deprecated -OTEL_LIBRARY_NAME = "otel.library.name" +OTEL_LIBRARY_NAME: Final = "otel.library.name" """ Deprecated: use the `otel.scope.name` attribute. """ -OTEL_LIBRARY_VERSION = "otel.library.version" +OTEL_LIBRARY_VERSION: Final = "otel.library.version" """ Deprecated: use the `otel.scope.version` attribute. """ -OTEL_SCOPE_NAME = "otel.scope.name" +OTEL_SCOPE_NAME: Final = "otel.scope.name" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_SCOPE_NAME`. """ -OTEL_SCOPE_VERSION = "otel.scope.version" +OTEL_SCOPE_VERSION: Final = "otel.scope.version" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_SCOPE_VERSION`. """ -OTEL_STATUS_CODE = "otel.status_code" +OTEL_STATUS_CODE: Final = "otel.status_code" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_STATUS_CODE`. """ -OTEL_STATUS_DESCRIPTION = "otel.status_description" +OTEL_STATUS_DESCRIPTION: Final = "otel.status_description" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_STATUS_DESCRIPTION`. """ -@deprecated( - reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues`." -) +@deprecated(reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues`.") # type: ignore class OtelStatusCodeValues(Enum): - OK = "OK" + OK: Final = "OK" """The operation has been validated by an Application developer or Operator to have completed successfully.""" - ERROR = "ERROR" + ERROR: Final = "ERROR" """The operation contains an error.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/other_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/other_attributes.py index 53f5cfc638..d95b7ec609 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/other_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/other_attributes.py @@ -12,17 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final + +from deprecated import deprecated -STATE = "state" +STATE: Final = "state" """ -The state of a connection in the pool. +Deprecated: Replaced by `db.client.connections.state`. """ +@deprecated(reason="The attribute state is deprecated - Replaced by `db.client.connections.state`") # type: ignore class StateValues(Enum): - IDLE = "idle" + IDLE: Final = "idle" """idle.""" - USED = "used" + USED: Final = "used" """used.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/peer_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/peer_attributes.py index 74a6926822..eac8e77cb8 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/peer_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/peer_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -PEER_SERVICE = "peer.service" +PEER_SERVICE: Final = "peer.service" """ The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/pool_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/pool_attributes.py index f02d6101d5..8feecee761 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/pool_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/pool_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -POOL_NAME = "pool.name" +POOL_NAME: Final = "pool.name" """ -The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. +Deprecated: Replaced by `db.client.connections.pool.name`. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/process_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/process_attributes.py index 5ab7c72f49..322d694923 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/process_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/process_attributes.py @@ -12,98 +12,164 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -PROCESS_COMMAND = "process.command" +PROCESS_COMMAND: Final = "process.command" """ The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. """ -PROCESS_COMMAND_ARGS = "process.command_args" +PROCESS_COMMAND_ARGS: Final = "process.command_args" """ All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. """ -PROCESS_COMMAND_LINE = "process.command_line" +PROCESS_COMMAND_LINE: Final = "process.command_line" """ The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. """ -PROCESS_CONTEXT_SWITCH_TYPE = "process.context_switch_type" +PROCESS_CONTEXT_SWITCH_TYPE: Final = "process.context_switch_type" """ Specifies whether the context switches for this data point were voluntary or involuntary. """ -PROCESS_CPU_STATE = "process.cpu.state" +PROCESS_CPU_STATE: Final = "process.cpu.state" """ -The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. +The CPU state of the process. """ -PROCESS_EXECUTABLE_NAME = "process.executable.name" +PROCESS_CREATION_TIME: Final = "process.creation.time" +""" +The date and time the process was created, in ISO 8601 format. +""" + +PROCESS_EXECUTABLE_NAME: Final = "process.executable.name" """ The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. """ -PROCESS_EXECUTABLE_PATH = "process.executable.path" +PROCESS_EXECUTABLE_PATH: Final = "process.executable.path" """ The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. """ -PROCESS_OWNER = "process.owner" +PROCESS_EXIT_CODE: Final = "process.exit.code" +""" +The exit code of the process. +""" + +PROCESS_EXIT_TIME: Final = "process.exit.time" +""" +The date and time the process exited, in ISO 8601 format. +""" + +PROCESS_GROUP_LEADER_PID: Final = "process.group_leader.pid" +""" +The PID of the process's group leader. This is also the process group ID (PGID) of the process. +""" + +PROCESS_INTERACTIVE: Final = "process.interactive" +""" +Whether the process is connected to an interactive shell. +""" + +PROCESS_OWNER: Final = "process.owner" """ The username of the user that owns the process. """ -PROCESS_PAGING_FAULT_TYPE = "process.paging.fault_type" +PROCESS_PAGING_FAULT_TYPE: Final = "process.paging.fault_type" """ The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. """ -PROCESS_PARENT_PID = "process.parent_pid" +PROCESS_PARENT_PID: Final = "process.parent_pid" """ Parent Process identifier (PPID). """ -PROCESS_PID = "process.pid" +PROCESS_PID: Final = "process.pid" """ Process identifier (PID). """ -PROCESS_RUNTIME_DESCRIPTION = "process.runtime.description" +PROCESS_REAL_USER_ID: Final = "process.real_user.id" +""" +The real user ID (RUID) of the process. +""" + +PROCESS_REAL_USER_NAME: Final = "process.real_user.name" +""" +The username of the real user of the process. +""" + +PROCESS_RUNTIME_DESCRIPTION: Final = "process.runtime.description" """ An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. """ -PROCESS_RUNTIME_NAME = "process.runtime.name" +PROCESS_RUNTIME_NAME: Final = "process.runtime.name" """ The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. """ -PROCESS_RUNTIME_VERSION = "process.runtime.version" +PROCESS_RUNTIME_VERSION: Final = "process.runtime.version" """ The version of the runtime of this process, as returned by the runtime without modification. """ +PROCESS_SAVED_USER_ID: Final = "process.saved_user.id" +""" +The saved user ID (SUID) of the process. +""" + +PROCESS_SAVED_USER_NAME: Final = "process.saved_user.name" +""" +The username of the saved user. +""" + +PROCESS_SESSION_LEADER_PID: Final = "process.session_leader.pid" +""" +The PID of the process's session leader. This is also the session ID (SID) of the process. +""" + +PROCESS_USER_ID: Final = "process.user.id" +""" +The effective user ID (EUID) of the process. +""" + +PROCESS_USER_NAME: Final = "process.user.name" +""" +The username of the effective user of the process. +""" + +PROCESS_VPID: Final = "process.vpid" +""" +Virtual process identifier. +Note: The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. +""" + class ProcessContextSwitchTypeValues(Enum): - VOLUNTARY = "voluntary" + VOLUNTARY: Final = "voluntary" """voluntary.""" - INVOLUNTARY = "involuntary" + INVOLUNTARY: Final = "involuntary" """involuntary.""" class ProcessCpuStateValues(Enum): - SYSTEM = "system" + SYSTEM: Final = "system" """system.""" - USER = "user" + USER: Final = "user" """user.""" - WAIT = "wait" + WAIT: Final = "wait" """wait.""" class ProcessPagingFaultTypeValues(Enum): - MAJOR = "major" + MAJOR: Final = "major" """major.""" - MINOR = "minor" + MINOR: Final = "minor" """minor.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py index 0d86cc211c..0dd632ceda 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py @@ -12,21 +12,23 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -RPC_CONNECT_RPC_ERROR_CODE = "rpc.connect_rpc.error_code" +RPC_CONNECT_RPC_ERROR_CODE: Final = "rpc.connect_rpc.error_code" """ The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. """ -RPC_CONNECT_RPC_REQUEST_METADATA_TEMPLATE = "rpc.connect_rpc.request.metadata" +RPC_CONNECT_RPC_REQUEST_METADATA_TEMPLATE: Final = ( + "rpc.connect_rpc.request.metadata" +) """ Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. """ -RPC_CONNECT_RPC_RESPONSE_METADATA_TEMPLATE = ( +RPC_CONNECT_RPC_RESPONSE_METADATA_TEMPLATE: Final = ( "rpc.connect_rpc.response.metadata" ) """ @@ -34,141 +36,169 @@ Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. """ -RPC_GRPC_REQUEST_METADATA_TEMPLATE = "rpc.grpc.request.metadata" +RPC_GRPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.grpc.request.metadata" """ gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. """ -RPC_GRPC_RESPONSE_METADATA_TEMPLATE = "rpc.grpc.response.metadata" +RPC_GRPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.grpc.response.metadata" """ gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. """ -RPC_GRPC_STATUS_CODE = "rpc.grpc.status_code" +RPC_GRPC_STATUS_CODE: Final = "rpc.grpc.status_code" """ The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. """ -RPC_JSONRPC_ERROR_CODE = "rpc.jsonrpc.error_code" +RPC_JSONRPC_ERROR_CODE: Final = "rpc.jsonrpc.error_code" """ `error.code` property of response if it is an error response. """ -RPC_JSONRPC_ERROR_MESSAGE = "rpc.jsonrpc.error_message" +RPC_JSONRPC_ERROR_MESSAGE: Final = "rpc.jsonrpc.error_message" """ `error.message` property of response if it is an error response. """ -RPC_JSONRPC_REQUEST_ID = "rpc.jsonrpc.request_id" +RPC_JSONRPC_REQUEST_ID: Final = "rpc.jsonrpc.request_id" """ `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. """ -RPC_JSONRPC_VERSION = "rpc.jsonrpc.version" +RPC_JSONRPC_VERSION: Final = "rpc.jsonrpc.version" """ Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. """ -RPC_METHOD = "rpc.method" +RPC_MESSAGE_COMPRESSED_SIZE: Final = "rpc.message.compressed_size" +""" +Compressed size of the message in bytes. +""" + +RPC_MESSAGE_ID: Final = "rpc.message.id" +""" +MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. +Note: This way we guarantee that the values will be consistent between different implementations. +""" + +RPC_MESSAGE_TYPE: Final = "rpc.message.type" +""" +Whether this is a received or sent message. +""" + +RPC_MESSAGE_UNCOMPRESSED_SIZE: Final = "rpc.message.uncompressed_size" +""" +Uncompressed size of the message in bytes. +""" + +RPC_METHOD: Final = "rpc.method" """ The name of the (logical) method being called, must be equal to the $method part in the span name. Note: This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). """ -RPC_SERVICE = "rpc.service" +RPC_SERVICE: Final = "rpc.service" """ The full (logical) name of the service being called, including its package name, if applicable. Note: This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). """ -RPC_SYSTEM = "rpc.system" +RPC_SYSTEM: Final = "rpc.system" """ A string identifying the remoting system. See below for a list of well-known identifiers. """ class RpcConnectRpcErrorCodeValues(Enum): - CANCELLED = "cancelled" + CANCELLED: Final = "cancelled" """cancelled.""" - UNKNOWN = "unknown" + UNKNOWN: Final = "unknown" """unknown.""" - INVALID_ARGUMENT = "invalid_argument" + INVALID_ARGUMENT: Final = "invalid_argument" """invalid_argument.""" - DEADLINE_EXCEEDED = "deadline_exceeded" + DEADLINE_EXCEEDED: Final = "deadline_exceeded" """deadline_exceeded.""" - NOT_FOUND = "not_found" + NOT_FOUND: Final = "not_found" """not_found.""" - ALREADY_EXISTS = "already_exists" + ALREADY_EXISTS: Final = "already_exists" """already_exists.""" - PERMISSION_DENIED = "permission_denied" + PERMISSION_DENIED: Final = "permission_denied" """permission_denied.""" - RESOURCE_EXHAUSTED = "resource_exhausted" + RESOURCE_EXHAUSTED: Final = "resource_exhausted" """resource_exhausted.""" - FAILED_PRECONDITION = "failed_precondition" + FAILED_PRECONDITION: Final = "failed_precondition" """failed_precondition.""" - ABORTED = "aborted" + ABORTED: Final = "aborted" """aborted.""" - OUT_OF_RANGE = "out_of_range" + OUT_OF_RANGE: Final = "out_of_range" """out_of_range.""" - UNIMPLEMENTED = "unimplemented" + UNIMPLEMENTED: Final = "unimplemented" """unimplemented.""" - INTERNAL = "internal" + INTERNAL: Final = "internal" """internal.""" - UNAVAILABLE = "unavailable" + UNAVAILABLE: Final = "unavailable" """unavailable.""" - DATA_LOSS = "data_loss" + DATA_LOSS: Final = "data_loss" """data_loss.""" - UNAUTHENTICATED = "unauthenticated" + UNAUTHENTICATED: Final = "unauthenticated" """unauthenticated.""" class RpcGrpcStatusCodeValues(Enum): - OK = 0 + OK: Final = 0 """OK.""" - CANCELLED = 1 + CANCELLED: Final = 1 """CANCELLED.""" - UNKNOWN = 2 + UNKNOWN: Final = 2 """UNKNOWN.""" - INVALID_ARGUMENT = 3 + INVALID_ARGUMENT: Final = 3 """INVALID_ARGUMENT.""" - DEADLINE_EXCEEDED = 4 + DEADLINE_EXCEEDED: Final = 4 """DEADLINE_EXCEEDED.""" - NOT_FOUND = 5 + NOT_FOUND: Final = 5 """NOT_FOUND.""" - ALREADY_EXISTS = 6 + ALREADY_EXISTS: Final = 6 """ALREADY_EXISTS.""" - PERMISSION_DENIED = 7 + PERMISSION_DENIED: Final = 7 """PERMISSION_DENIED.""" - RESOURCE_EXHAUSTED = 8 + RESOURCE_EXHAUSTED: Final = 8 """RESOURCE_EXHAUSTED.""" - FAILED_PRECONDITION = 9 + FAILED_PRECONDITION: Final = 9 """FAILED_PRECONDITION.""" - ABORTED = 10 + ABORTED: Final = 10 """ABORTED.""" - OUT_OF_RANGE = 11 + OUT_OF_RANGE: Final = 11 """OUT_OF_RANGE.""" - UNIMPLEMENTED = 12 + UNIMPLEMENTED: Final = 12 """UNIMPLEMENTED.""" - INTERNAL = 13 + INTERNAL: Final = 13 """INTERNAL.""" - UNAVAILABLE = 14 + UNAVAILABLE: Final = 14 """UNAVAILABLE.""" - DATA_LOSS = 15 + DATA_LOSS: Final = 15 """DATA_LOSS.""" - UNAUTHENTICATED = 16 + UNAUTHENTICATED: Final = 16 """UNAUTHENTICATED.""" +class RpcMessageTypeValues(Enum): + SENT: Final = "SENT" + """sent.""" + RECEIVED: Final = "RECEIVED" + """received.""" + + class RpcSystemValues(Enum): - GRPC = "grpc" + GRPC: Final = "grpc" """gRPC.""" - JAVA_RMI = "java_rmi" + JAVA_RMI: Final = "java_rmi" """Java RMI.""" - DOTNET_WCF = "dotnet_wcf" + DOTNET_WCF: Final = "dotnet_wcf" """.NET WCF.""" - APACHE_DUBBO = "apache_dubbo" + APACHE_DUBBO: Final = "apache_dubbo" """Apache Dubbo.""" - CONNECT_RPC = "connect_rpc" + CONNECT_RPC: Final = "connect_rpc" """Connect RPC.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/server_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/server_attributes.py index b763be9a6c..a9e3ab43fa 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/server_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/server_attributes.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -SERVER_ADDRESS = "server.address" +SERVER_ADDRESS: Final = "server.address" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.server_attributes.SERVER_ADDRESS`. """ -SERVER_PORT = "server.port" +SERVER_PORT: Final = "server.port" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.server_attributes.SERVER_PORT`. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/service_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/service_attributes.py index eb8e9f498d..d1c729368b 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/service_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/service_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -SERVICE_INSTANCE_ID = "service.instance.id" +SERVICE_INSTANCE_ID: Final = "service.instance.id" """ The string ID of the service instance. Note: MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words @@ -44,18 +45,18 @@ port. """ -SERVICE_NAME = "service.name" +SERVICE_NAME: Final = "service.name" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_NAME`. """ -SERVICE_NAMESPACE = "service.namespace" +SERVICE_NAMESPACE: Final = "service.namespace" """ A namespace for `service.name`. Note: A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. """ -SERVICE_VERSION = "service.version" +SERVICE_VERSION: Final = "service.version" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_VERSION`. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/session_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/session_attributes.py index a0a9170aa3..1d5ff3406f 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/session_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/session_attributes.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -SESSION_ID = "session.id" +SESSION_ID: Final = "session.id" """ A unique id to identify a session. """ -SESSION_PREVIOUS_ID = "session.previous_id" +SESSION_PREVIOUS_ID: Final = "session.previous_id" """ The previous `session.id` for this user, when known. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/source_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/source_attributes.py index b6020b30f6..ea49387f3c 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/source_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/source_attributes.py @@ -12,14 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -SOURCE_ADDRESS = "source.address" +SOURCE_ADDRESS: Final = "source.address" """ Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. Note: When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. """ -SOURCE_PORT = "source.port" +SOURCE_PORT: Final = "source.port" """ Source port number. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/system_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/system_attributes.py index eef4116900..bfb0dedc27 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/system_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/system_attributes.py @@ -12,204 +12,202 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final from deprecated import deprecated -SYSTEM_CPU_LOGICAL_NUMBER = "system.cpu.logical_number" +SYSTEM_CPU_LOGICAL_NUMBER: Final = "system.cpu.logical_number" """ The logical CPU number [0..n-1]. """ -SYSTEM_CPU_STATE = "system.cpu.state" +SYSTEM_CPU_STATE: Final = "system.cpu.state" """ -The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. +The state of the CPU. """ -SYSTEM_DEVICE = "system.device" +SYSTEM_DEVICE: Final = "system.device" """ The device identifier. """ -SYSTEM_FILESYSTEM_MODE = "system.filesystem.mode" +SYSTEM_FILESYSTEM_MODE: Final = "system.filesystem.mode" """ The filesystem mode. """ -SYSTEM_FILESYSTEM_MOUNTPOINT = "system.filesystem.mountpoint" +SYSTEM_FILESYSTEM_MOUNTPOINT: Final = "system.filesystem.mountpoint" """ The filesystem mount path. """ -SYSTEM_FILESYSTEM_STATE = "system.filesystem.state" +SYSTEM_FILESYSTEM_STATE: Final = "system.filesystem.state" """ The filesystem state. """ -SYSTEM_FILESYSTEM_TYPE = "system.filesystem.type" +SYSTEM_FILESYSTEM_TYPE: Final = "system.filesystem.type" """ The filesystem type. """ -SYSTEM_MEMORY_STATE = "system.memory.state" +SYSTEM_MEMORY_STATE: Final = "system.memory.state" """ The memory state. """ -SYSTEM_NETWORK_STATE = "system.network.state" +SYSTEM_NETWORK_STATE: Final = "system.network.state" """ A stateless protocol MUST NOT set this attribute. """ -SYSTEM_PAGING_DIRECTION = "system.paging.direction" +SYSTEM_PAGING_DIRECTION: Final = "system.paging.direction" """ The paging access direction. """ -SYSTEM_PAGING_STATE = "system.paging.state" +SYSTEM_PAGING_STATE: Final = "system.paging.state" """ The memory paging state. """ -SYSTEM_PAGING_TYPE = "system.paging.type" +SYSTEM_PAGING_TYPE: Final = "system.paging.type" """ The memory paging type. """ -SYSTEM_PROCESS_STATUS = "system.process.status" +SYSTEM_PROCESS_STATUS: Final = "system.process.status" """ The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES). """ -SYSTEM_PROCESSES_STATUS = "system.processes.status" +SYSTEM_PROCESSES_STATUS: Final = "system.processes.status" """ Deprecated: Replaced by `system.process.status`. """ class SystemCpuStateValues(Enum): - USER = "user" + USER: Final = "user" """user.""" - SYSTEM = "system" + SYSTEM: Final = "system" """system.""" - NICE = "nice" + NICE: Final = "nice" """nice.""" - IDLE = "idle" + IDLE: Final = "idle" """idle.""" - IOWAIT = "iowait" + IOWAIT: Final = "iowait" """iowait.""" - INTERRUPT = "interrupt" + INTERRUPT: Final = "interrupt" """interrupt.""" - STEAL = "steal" + STEAL: Final = "steal" """steal.""" class SystemFilesystemStateValues(Enum): - USED = "used" + USED: Final = "used" """used.""" - FREE = "free" + FREE: Final = "free" """free.""" - RESERVED = "reserved" + RESERVED: Final = "reserved" """reserved.""" class SystemFilesystemTypeValues(Enum): - FAT32 = "fat32" + FAT32: Final = "fat32" """fat32.""" - EXFAT = "exfat" + EXFAT: Final = "exfat" """exfat.""" - NTFS = "ntfs" + NTFS: Final = "ntfs" """ntfs.""" - REFS = "refs" + REFS: Final = "refs" """refs.""" - HFSPLUS = "hfsplus" + HFSPLUS: Final = "hfsplus" """hfsplus.""" - EXT4 = "ext4" + EXT4: Final = "ext4" """ext4.""" class SystemMemoryStateValues(Enum): - USED = "used" + USED: Final = "used" """used.""" - FREE = "free" + FREE: Final = "free" """free.""" - SHARED = "shared" + SHARED: Final = "shared" """shared.""" - BUFFERS = "buffers" + BUFFERS: Final = "buffers" """buffers.""" - CACHED = "cached" + CACHED: Final = "cached" """cached.""" class SystemNetworkStateValues(Enum): - CLOSE = "close" + CLOSE: Final = "close" """close.""" - CLOSE_WAIT = "close_wait" + CLOSE_WAIT: Final = "close_wait" """close_wait.""" - CLOSING = "closing" + CLOSING: Final = "closing" """closing.""" - DELETE = "delete" + DELETE: Final = "delete" """delete.""" - ESTABLISHED = "established" + ESTABLISHED: Final = "established" """established.""" - FIN_WAIT_1 = "fin_wait_1" + FIN_WAIT_1: Final = "fin_wait_1" """fin_wait_1.""" - FIN_WAIT_2 = "fin_wait_2" + FIN_WAIT_2: Final = "fin_wait_2" """fin_wait_2.""" - LAST_ACK = "last_ack" + LAST_ACK: Final = "last_ack" """last_ack.""" - LISTEN = "listen" + LISTEN: Final = "listen" """listen.""" - SYN_RECV = "syn_recv" + SYN_RECV: Final = "syn_recv" """syn_recv.""" - SYN_SENT = "syn_sent" + SYN_SENT: Final = "syn_sent" """syn_sent.""" - TIME_WAIT = "time_wait" + TIME_WAIT: Final = "time_wait" """time_wait.""" class SystemPagingDirectionValues(Enum): - IN = "in" + IN: Final = "in" """in.""" - OUT = "out" + OUT: Final = "out" """out.""" class SystemPagingStateValues(Enum): - USED = "used" + USED: Final = "used" """used.""" - FREE = "free" + FREE: Final = "free" """free.""" class SystemPagingTypeValues(Enum): - MAJOR = "major" + MAJOR: Final = "major" """major.""" - MINOR = "minor" + MINOR: Final = "minor" """minor.""" class SystemProcessStatusValues(Enum): - RUNNING = "running" + RUNNING: Final = "running" """running.""" - SLEEPING = "sleeping" + SLEEPING: Final = "sleeping" """sleeping.""" - STOPPED = "stopped" + STOPPED: Final = "stopped" """stopped.""" - DEFUNCT = "defunct" + DEFUNCT: Final = "defunct" """defunct.""" -@deprecated( - reason="The attribute system.processes.status is deprecated - Replaced by `system.process.status`" -) +@deprecated(reason="The attribute system.processes.status is deprecated - Replaced by `system.process.status`") # type: ignore class SystemProcessesStatusValues(Enum): - RUNNING = "running" + RUNNING: Final = "running" """running.""" - SLEEPING = "sleeping" + SLEEPING: Final = "sleeping" """sleeping.""" - STOPPED = "stopped" + STOPPED: Final = "stopped" """stopped.""" - DEFUNCT = "defunct" + DEFUNCT: Final = "defunct" """defunct.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py index b7ac5fac6c..8f0eac938c 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py @@ -12,64 +12,62 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final from deprecated import deprecated -TELEMETRY_DISTRO_NAME = "telemetry.distro.name" +TELEMETRY_DISTRO_NAME: Final = "telemetry.distro.name" """ The name of the auto instrumentation agent or distribution, if used. Note: Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. """ -TELEMETRY_DISTRO_VERSION = "telemetry.distro.version" +TELEMETRY_DISTRO_VERSION: Final = "telemetry.distro.version" """ The version string of the auto instrumentation agent or distribution, if used. """ -TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language" +TELEMETRY_SDK_LANGUAGE: Final = "telemetry.sdk.language" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_LANGUAGE`. """ -TELEMETRY_SDK_NAME = "telemetry.sdk.name" +TELEMETRY_SDK_NAME: Final = "telemetry.sdk.name" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_NAME`. """ -TELEMETRY_SDK_VERSION = "telemetry.sdk.version" +TELEMETRY_SDK_VERSION: Final = "telemetry.sdk.version" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_VERSION`. """ -@deprecated( - reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues`." -) +@deprecated(reason="Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues`.") # type: ignore class TelemetrySdkLanguageValues(Enum): - CPP = "cpp" + CPP: Final = "cpp" """cpp.""" - DOTNET = "dotnet" + DOTNET: Final = "dotnet" """dotnet.""" - ERLANG = "erlang" + ERLANG: Final = "erlang" """erlang.""" - GO = "go" + GO: Final = "go" """go.""" - JAVA = "java" + JAVA: Final = "java" """java.""" - NODEJS = "nodejs" + NODEJS: Final = "nodejs" """nodejs.""" - PHP = "php" + PHP: Final = "php" """php.""" - PYTHON = "python" + PYTHON: Final = "python" """python.""" - RUBY = "ruby" + RUBY: Final = "ruby" """ruby.""" - RUST = "rust" + RUST: Final = "rust" """rust.""" - SWIFT = "swift" + SWIFT: Final = "swift" """swift.""" - WEBJS = "webjs" + WEBJS: Final = "webjs" """webjs.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/thread_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/thread_attributes.py index cd68db8197..a7b4ce8287 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/thread_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/thread_attributes.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -THREAD_ID = "thread.id" +THREAD_ID: Final = "thread.id" """ Current "managed" thread ID (as opposed to OS thread ID). """ -THREAD_NAME = "thread.name" +THREAD_NAME: Final = "thread.name" """ Current thread name. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/tls_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/tls_attributes.py index 2abaa8cd60..93e74eb02f 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/tls_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/tls_attributes.py @@ -12,158 +12,158 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -TLS_CIPHER = "tls.cipher" +TLS_CIPHER: Final = "tls.cipher" """ String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). """ -TLS_CLIENT_CERTIFICATE = "tls.client.certificate" +TLS_CLIENT_CERTIFICATE: Final = "tls.client.certificate" """ PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. """ -TLS_CLIENT_CERTIFICATE_CHAIN = "tls.client.certificate_chain" +TLS_CLIENT_CERTIFICATE_CHAIN: Final = "tls.client.certificate_chain" """ Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. """ -TLS_CLIENT_HASH_MD5 = "tls.client.hash.md5" +TLS_CLIENT_HASH_MD5: Final = "tls.client.hash.md5" """ Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. """ -TLS_CLIENT_HASH_SHA1 = "tls.client.hash.sha1" +TLS_CLIENT_HASH_SHA1: Final = "tls.client.hash.sha1" """ Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. """ -TLS_CLIENT_HASH_SHA256 = "tls.client.hash.sha256" +TLS_CLIENT_HASH_SHA256: Final = "tls.client.hash.sha256" """ Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. """ -TLS_CLIENT_ISSUER = "tls.client.issuer" +TLS_CLIENT_ISSUER: Final = "tls.client.issuer" """ Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. """ -TLS_CLIENT_JA3 = "tls.client.ja3" +TLS_CLIENT_JA3: Final = "tls.client.ja3" """ A hash that identifies clients based on how they perform an SSL/TLS handshake. """ -TLS_CLIENT_NOT_AFTER = "tls.client.not_after" +TLS_CLIENT_NOT_AFTER: Final = "tls.client.not_after" """ Date/Time indicating when client certificate is no longer considered valid. """ -TLS_CLIENT_NOT_BEFORE = "tls.client.not_before" +TLS_CLIENT_NOT_BEFORE: Final = "tls.client.not_before" """ Date/Time indicating when client certificate is first considered valid. """ -TLS_CLIENT_SERVER_NAME = "tls.client.server_name" +TLS_CLIENT_SERVER_NAME: Final = "tls.client.server_name" """ Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. """ -TLS_CLIENT_SUBJECT = "tls.client.subject" +TLS_CLIENT_SUBJECT: Final = "tls.client.subject" """ Distinguished name of subject of the x.509 certificate presented by the client. """ -TLS_CLIENT_SUPPORTED_CIPHERS = "tls.client.supported_ciphers" +TLS_CLIENT_SUPPORTED_CIPHERS: Final = "tls.client.supported_ciphers" """ Array of ciphers offered by the client during the client hello. """ -TLS_CURVE = "tls.curve" +TLS_CURVE: Final = "tls.curve" """ String indicating the curve used for the given cipher, when applicable. """ -TLS_ESTABLISHED = "tls.established" +TLS_ESTABLISHED: Final = "tls.established" """ Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. """ -TLS_NEXT_PROTOCOL = "tls.next_protocol" +TLS_NEXT_PROTOCOL: Final = "tls.next_protocol" """ String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. """ -TLS_PROTOCOL_NAME = "tls.protocol.name" +TLS_PROTOCOL_NAME: Final = "tls.protocol.name" """ Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES). """ -TLS_PROTOCOL_VERSION = "tls.protocol.version" +TLS_PROTOCOL_VERSION: Final = "tls.protocol.version" """ Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES). """ -TLS_RESUMED = "tls.resumed" +TLS_RESUMED: Final = "tls.resumed" """ Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. """ -TLS_SERVER_CERTIFICATE = "tls.server.certificate" +TLS_SERVER_CERTIFICATE: Final = "tls.server.certificate" """ PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. """ -TLS_SERVER_CERTIFICATE_CHAIN = "tls.server.certificate_chain" +TLS_SERVER_CERTIFICATE_CHAIN: Final = "tls.server.certificate_chain" """ Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. """ -TLS_SERVER_HASH_MD5 = "tls.server.hash.md5" +TLS_SERVER_HASH_MD5: Final = "tls.server.hash.md5" """ Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. """ -TLS_SERVER_HASH_SHA1 = "tls.server.hash.sha1" +TLS_SERVER_HASH_SHA1: Final = "tls.server.hash.sha1" """ Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. """ -TLS_SERVER_HASH_SHA256 = "tls.server.hash.sha256" +TLS_SERVER_HASH_SHA256: Final = "tls.server.hash.sha256" """ Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. """ -TLS_SERVER_ISSUER = "tls.server.issuer" +TLS_SERVER_ISSUER: Final = "tls.server.issuer" """ Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. """ -TLS_SERVER_JA3S = "tls.server.ja3s" +TLS_SERVER_JA3S: Final = "tls.server.ja3s" """ A hash that identifies servers based on how they perform an SSL/TLS handshake. """ -TLS_SERVER_NOT_AFTER = "tls.server.not_after" +TLS_SERVER_NOT_AFTER: Final = "tls.server.not_after" """ Date/Time indicating when server certificate is no longer considered valid. """ -TLS_SERVER_NOT_BEFORE = "tls.server.not_before" +TLS_SERVER_NOT_BEFORE: Final = "tls.server.not_before" """ Date/Time indicating when server certificate is first considered valid. """ -TLS_SERVER_SUBJECT = "tls.server.subject" +TLS_SERVER_SUBJECT: Final = "tls.server.subject" """ Distinguished name of subject of the x.509 certificate presented by the server. """ class TlsProtocolNameValues(Enum): - SSL = "ssl" + SSL: Final = "ssl" """ssl.""" - TLS = "tls" + TLS: Final = "tls" """tls.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/url_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/url_attributes.py index 6646f2e68d..89ce57bd78 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/url_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/url_attributes.py @@ -12,69 +12,75 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -URL_DOMAIN = "url.domain" +URL_DOMAIN: Final = "url.domain" """ Domain extracted from the `url.full`, such as "opentelemetry.io". Note: In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. """ -URL_EXTENSION = "url.extension" +URL_EXTENSION: Final = "url.extension" """ The file extension extracted from the `url.full`, excluding the leading dot. Note: The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions `example.tar.gz`, only the last one should be captured `gz`, not `tar.gz`. """ -URL_FRAGMENT = "url.fragment" +URL_FRAGMENT: Final = "url.fragment" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_FRAGMENT`. """ -URL_FULL = "url.full" +URL_FULL: Final = "url.full" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_FULL`. """ -URL_ORIGINAL = "url.original" +URL_ORIGINAL: Final = "url.original" """ Unmodified original URL as seen in the event source. Note: In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. `url.original` might contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. """ -URL_PATH = "url.path" +URL_PATH: Final = "url.path" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_PATH`. """ -URL_PORT = "url.port" +URL_PORT: Final = "url.port" """ Port extracted from the `url.full`. """ -URL_QUERY = "url.query" +URL_QUERY: Final = "url.query" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_QUERY`. """ -URL_REGISTERED_DOMAIN = "url.registered_domain" +URL_REGISTERED_DOMAIN: Final = "url.registered_domain" """ The highest registered url domain, stripped of the subdomain. Note: This value can be determined precisely with the [public suffix list](http://publicsuffix.org). For example, the registered domain for `foo.example.com` is `example.com`. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. """ -URL_SCHEME = "url.scheme" +URL_SCHEME: Final = "url.scheme" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_SCHEME`. """ -URL_SUBDOMAIN = "url.subdomain" +URL_SUBDOMAIN: Final = "url.subdomain" """ The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. """ -URL_TOP_LEVEL_DOMAIN = "url.top_level_domain" +URL_TEMPLATE: Final = "url.template" +""" +The low-cardinality template of an [absolute path reference](https://www.rfc-editor.org/rfc/rfc3986#section-4.2). +""" + +URL_TOP_LEVEL_DOMAIN: Final = "url.top_level_domain" """ The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. Note: This value can be determined precisely with the [public suffix list](http://publicsuffix.org). diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py index 2237a2d3f1..2583a1d314 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py @@ -12,19 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -USER_AGENT_NAME = "user_agent.name" +USER_AGENT_NAME: Final = "user_agent.name" """ Name of the user-agent extracted from original. Usually refers to the browser's name. Note: [Example](https://www.whatsmyua.info) of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with `user_agent.version`. """ -USER_AGENT_ORIGINAL = "user_agent.original" +USER_AGENT_ORIGINAL: Final = "user_agent.original" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.user_agent_attributes.USER_AGENT_ORIGINAL`. """ -USER_AGENT_VERSION = "user_agent.version" +USER_AGENT_VERSION: Final = "user_agent.version" """ Version of the user-agent extracted from original. Usually refers to the browser's version. Note: [Example](https://www.whatsmyua.info) of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant version SHOULD be selected. In such a scenario it should align with `user_agent.name`. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py index e29971b032..15175428d3 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py @@ -12,18 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -WEBENGINE_DESCRIPTION = "webengine.description" +WEBENGINE_DESCRIPTION: Final = "webengine.description" """ Additional description of the web engine (e.g. detailed version and edition information). """ -WEBENGINE_NAME = "webengine.name" +WEBENGINE_NAME: Final = "webengine.name" """ The name of the web engine. """ -WEBENGINE_VERSION = "webengine.version" +WEBENGINE_VERSION: Final = "webengine.version" """ The version of the web engine. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/container_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/container_metrics.py index d4c8437ece..5030b61c85 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/container_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/container_metrics.py @@ -13,9 +13,11 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Counter, Meter -CONTAINER_CPU_TIME = "container.cpu.time" +CONTAINER_CPU_TIME: Final = "container.cpu.time" """ Total CPU time consumed Instrument: counter @@ -27,13 +29,13 @@ def create_container_cpu_time(meter: Meter) -> Counter: """Total CPU time consumed""" return meter.create_counter( - name="container.cpu.time", + name=CONTAINER_CPU_TIME, description="Total CPU time consumed", unit="s", ) -CONTAINER_DISK_IO = "container.disk.io" +CONTAINER_DISK_IO: Final = "container.disk.io" """ Disk bytes for the container Instrument: counter @@ -45,13 +47,13 @@ def create_container_cpu_time(meter: Meter) -> Counter: def create_container_disk_io(meter: Meter) -> Counter: """Disk bytes for the container""" return meter.create_counter( - name="container.disk.io", + name=CONTAINER_DISK_IO, description="Disk bytes for the container.", unit="By", ) -CONTAINER_MEMORY_USAGE = "container.memory.usage" +CONTAINER_MEMORY_USAGE: Final = "container.memory.usage" """ Memory usage of the container Instrument: counter @@ -63,13 +65,13 @@ def create_container_disk_io(meter: Meter) -> Counter: def create_container_memory_usage(meter: Meter) -> Counter: """Memory usage of the container""" return meter.create_counter( - name="container.memory.usage", + name=CONTAINER_MEMORY_USAGE, description="Memory usage of the container.", unit="By", ) -CONTAINER_NETWORK_IO = "container.network.io" +CONTAINER_NETWORK_IO: Final = "container.network.io" """ Network bytes for the container Instrument: counter @@ -81,7 +83,7 @@ def create_container_memory_usage(meter: Meter) -> Counter: def create_container_network_io(meter: Meter) -> Counter: """Network bytes for the container""" return meter.create_counter( - name="container.network.io", + name=CONTAINER_NETWORK_IO, description="Network bytes for the container.", unit="By", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/db_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/db_metrics.py index 63a86e91c1..1d959d1bde 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/db_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/db_metrics.py @@ -13,26 +13,45 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter -DB_CLIENT_CONNECTIONS_CREATE_TIME = "db.client.connections.create_time" +DB_CLIENT_CONNECTION_COUNT: Final = "db.client.connection.count" +""" +The number of connections that are currently in state described by the `state` attribute +Instrument: updowncounter +Unit: {connection} +""" + + +def create_db_client_connection_count(meter: Meter) -> UpDownCounter: + """The number of connections that are currently in state described by the `state` attribute""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTION_COUNT, + description="The number of connections that are currently in state described by the `state` attribute", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTION_CREATE_TIME: Final = "db.client.connection.create_time" """ The time it took to create a new connection Instrument: histogram -Unit: ms +Unit: s """ -def create_db_client_connections_create_time(meter: Meter) -> Histogram: +def create_db_client_connection_create_time(meter: Meter) -> Histogram: """The time it took to create a new connection""" return meter.create_histogram( - name="db.client.connections.create_time", + name=DB_CLIENT_CONNECTION_CREATE_TIME, description="The time it took to create a new connection", - unit="ms", + unit="s", ) -DB_CLIENT_CONNECTIONS_IDLE_MAX = "db.client.connections.idle.max" +DB_CLIENT_CONNECTION_IDLE_MAX: Final = "db.client.connection.idle.max" """ The maximum number of idle open connections allowed Instrument: updowncounter @@ -40,16 +59,16 @@ def create_db_client_connections_create_time(meter: Meter) -> Histogram: """ -def create_db_client_connections_idle_max(meter: Meter) -> UpDownCounter: +def create_db_client_connection_idle_max(meter: Meter) -> UpDownCounter: """The maximum number of idle open connections allowed""" return meter.create_up_down_counter( - name="db.client.connections.idle.max", + name=DB_CLIENT_CONNECTION_IDLE_MAX, description="The maximum number of idle open connections allowed", unit="{connection}", ) -DB_CLIENT_CONNECTIONS_IDLE_MIN = "db.client.connections.idle.min" +DB_CLIENT_CONNECTION_IDLE_MIN: Final = "db.client.connection.idle.min" """ The minimum number of idle open connections allowed Instrument: updowncounter @@ -57,16 +76,16 @@ def create_db_client_connections_idle_max(meter: Meter) -> UpDownCounter: """ -def create_db_client_connections_idle_min(meter: Meter) -> UpDownCounter: +def create_db_client_connection_idle_min(meter: Meter) -> UpDownCounter: """The minimum number of idle open connections allowed""" return meter.create_up_down_counter( - name="db.client.connections.idle.min", + name=DB_CLIENT_CONNECTION_IDLE_MIN, description="The minimum number of idle open connections allowed", unit="{connection}", ) -DB_CLIENT_CONNECTIONS_MAX = "db.client.connections.max" +DB_CLIENT_CONNECTION_MAX: Final = "db.client.connection.max" """ The maximum number of open connections allowed Instrument: updowncounter @@ -74,17 +93,17 @@ def create_db_client_connections_idle_min(meter: Meter) -> UpDownCounter: """ -def create_db_client_connections_max(meter: Meter) -> UpDownCounter: +def create_db_client_connection_max(meter: Meter) -> UpDownCounter: """The maximum number of open connections allowed""" return meter.create_up_down_counter( - name="db.client.connections.max", + name=DB_CLIENT_CONNECTION_MAX, description="The maximum number of open connections allowed", unit="{connection}", ) -DB_CLIENT_CONNECTIONS_PENDING_REQUESTS = ( - "db.client.connections.pending_requests" +DB_CLIENT_CONNECTION_PENDING_REQUESTS: Final = ( + "db.client.connection.pending_requests" ) """ The number of pending requests for an open connection, cumulative for the entire pool @@ -93,18 +112,18 @@ def create_db_client_connections_max(meter: Meter) -> UpDownCounter: """ -def create_db_client_connections_pending_requests( +def create_db_client_connection_pending_requests( meter: Meter, ) -> UpDownCounter: """The number of pending requests for an open connection, cumulative for the entire pool""" return meter.create_up_down_counter( - name="db.client.connections.pending_requests", + name=DB_CLIENT_CONNECTION_PENDING_REQUESTS, description="The number of pending requests for an open connection, cumulative for the entire pool", unit="{request}", ) -DB_CLIENT_CONNECTIONS_TIMEOUTS = "db.client.connections.timeouts" +DB_CLIENT_CONNECTION_TIMEOUTS: Final = "db.client.connection.timeouts" """ The number of connection timeouts that have occurred trying to obtain a connection from the pool Instrument: counter @@ -112,61 +131,200 @@ def create_db_client_connections_pending_requests( """ -def create_db_client_connections_timeouts(meter: Meter) -> Counter: +def create_db_client_connection_timeouts(meter: Meter) -> Counter: """The number of connection timeouts that have occurred trying to obtain a connection from the pool""" return meter.create_counter( - name="db.client.connections.timeouts", + name=DB_CLIENT_CONNECTION_TIMEOUTS, description="The number of connection timeouts that have occurred trying to obtain a connection from the pool", unit="{timeout}", ) -DB_CLIENT_CONNECTIONS_USAGE = "db.client.connections.usage" +DB_CLIENT_CONNECTION_USE_TIME: Final = "db.client.connection.use_time" """ -The number of connections that are currently in state described by the `state` attribute -Instrument: updowncounter -Unit: {connection} +The time between borrowing a connection and returning it to the pool +Instrument: histogram +Unit: s +""" + + +def create_db_client_connection_use_time(meter: Meter) -> Histogram: + """The time between borrowing a connection and returning it to the pool""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTION_USE_TIME, + description="The time between borrowing a connection and returning it to the pool", + unit="s", + ) + + +DB_CLIENT_CONNECTION_WAIT_TIME: Final = "db.client.connection.wait_time" +""" +The time it took to obtain an open connection from the pool +Instrument: histogram +Unit: s +""" + + +def create_db_client_connection_wait_time(meter: Meter) -> Histogram: + """The time it took to obtain an open connection from the pool""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTION_WAIT_TIME, + description="The time it took to obtain an open connection from the pool", + unit="s", + ) + + +DB_CLIENT_CONNECTIONS_CREATE_TIME: Final = "db.client.connections.create_time" +""" +Deprecated: Replaced by `db.client.connection.create_time`. Note: the unit also changed from `ms` to `s`. +""" + + +def create_db_client_connections_create_time(meter: Meter) -> Histogram: + """Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTIONS_CREATE_TIME, + description="Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`.", + unit="ms", + ) + + +DB_CLIENT_CONNECTIONS_IDLE_MAX: Final = "db.client.connections.idle.max" +""" +Deprecated: Replaced by `db.client.connection.idle.max`. +""" + + +def create_db_client_connections_idle_max(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.idle.max` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_IDLE_MAX, + description="Deprecated, use `db.client.connection.idle.max` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_IDLE_MIN: Final = "db.client.connections.idle.min" +""" +Deprecated: Replaced by `db.client.connection.idle.min`. +""" + + +def create_db_client_connections_idle_min(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.idle.min` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_IDLE_MIN, + description="Deprecated, use `db.client.connection.idle.min` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_MAX: Final = "db.client.connections.max" +""" +Deprecated: Replaced by `db.client.connection.max`. +""" + + +def create_db_client_connections_max(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.max` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_MAX, + description="Deprecated, use `db.client.connection.max` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_PENDING_REQUESTS: Final = ( + "db.client.connections.pending_requests" +) +""" +Deprecated: Replaced by `db.client.connection.pending_requests`. +""" + + +def create_db_client_connections_pending_requests( + meter: Meter, +) -> UpDownCounter: + """Deprecated, use `db.client.connection.pending_requests` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_PENDING_REQUESTS, + description="Deprecated, use `db.client.connection.pending_requests` instead.", + unit="{request}", + ) + + +DB_CLIENT_CONNECTIONS_TIMEOUTS: Final = "db.client.connections.timeouts" +""" +Deprecated: Replaced by `db.client.connection.timeouts`. +""" + + +def create_db_client_connections_timeouts(meter: Meter) -> Counter: + """Deprecated, use `db.client.connection.timeouts` instead""" + return meter.create_counter( + name=DB_CLIENT_CONNECTIONS_TIMEOUTS, + description="Deprecated, use `db.client.connection.timeouts` instead.", + unit="{timeout}", + ) + + +DB_CLIENT_CONNECTIONS_USAGE: Final = "db.client.connections.usage" +""" +Deprecated: Replaced by `db.client.connection.count`. """ def create_db_client_connections_usage(meter: Meter) -> UpDownCounter: - """The number of connections that are currently in state described by the `state` attribute""" + """Deprecated, use `db.client.connection.count` instead""" return meter.create_up_down_counter( - name="db.client.connections.usage", - description="The number of connections that are currently in state described by the `state` attribute", + name=DB_CLIENT_CONNECTIONS_USAGE, + description="Deprecated, use `db.client.connection.count` instead.", unit="{connection}", ) -DB_CLIENT_CONNECTIONS_USE_TIME = "db.client.connections.use_time" +DB_CLIENT_CONNECTIONS_USE_TIME: Final = "db.client.connections.use_time" """ -The time between borrowing a connection and returning it to the pool -Instrument: histogram -Unit: ms +Deprecated: Replaced by `db.client.connection.use_time`. Note: the unit also changed from `ms` to `s`. """ def create_db_client_connections_use_time(meter: Meter) -> Histogram: - """The time between borrowing a connection and returning it to the pool""" + """Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`""" return meter.create_histogram( - name="db.client.connections.use_time", - description="The time between borrowing a connection and returning it to the pool", + name=DB_CLIENT_CONNECTIONS_USE_TIME, + description="Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`.", unit="ms", ) -DB_CLIENT_CONNECTIONS_WAIT_TIME = "db.client.connections.wait_time" +DB_CLIENT_CONNECTIONS_WAIT_TIME: Final = "db.client.connections.wait_time" """ -The time it took to obtain an open connection from the pool -Instrument: histogram -Unit: ms +Deprecated: Replaced by `db.client.connection.wait_time`. Note: the unit also changed from `ms` to `s`. """ def create_db_client_connections_wait_time(meter: Meter) -> Histogram: - """The time it took to obtain an open connection from the pool""" + """Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`""" return meter.create_histogram( - name="db.client.connections.wait_time", - description="The time it took to obtain an open connection from the pool", + name=DB_CLIENT_CONNECTIONS_WAIT_TIME, + description="Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`.", unit="ms", ) + + +DB_CLIENT_OPERATION_DURATION: Final = "db.client.operation.duration" +""" +Duration of database client operations +Instrument: histogram +Unit: s +""" + + +def create_db_client_operation_duration(meter: Meter) -> Histogram: + """Duration of database client operations""" + return meter.create_histogram( + name=DB_CLIENT_OPERATION_DURATION, + description="Duration of database client operations.", + unit="s", + ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/dns_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/dns_metrics.py index 200b309c95..53fb3d2698 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/dns_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/dns_metrics.py @@ -13,9 +13,11 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Histogram, Meter -DNS_LOOKUP_DURATION = "dns.lookup.duration" +DNS_LOOKUP_DURATION: Final = "dns.lookup.duration" """ Measures the time taken to perform a DNS lookup Instrument: histogram @@ -26,7 +28,7 @@ def create_dns_lookup_duration(meter: Meter) -> Histogram: """Measures the time taken to perform a DNS lookup""" return meter.create_histogram( - name="dns.lookup.duration", + name=DNS_LOOKUP_DURATION, description="Measures the time taken to perform a DNS lookup.", unit="s", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/faas_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/faas_metrics.py index f93e707c00..5fd14149ab 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/faas_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/faas_metrics.py @@ -13,9 +13,11 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Counter, Histogram, Meter -FAAS_COLDSTARTS = "faas.coldstarts" +FAAS_COLDSTARTS: Final = "faas.coldstarts" """ Number of invocation cold starts Instrument: counter @@ -26,13 +28,13 @@ def create_faas_coldstarts(meter: Meter) -> Counter: """Number of invocation cold starts""" return meter.create_counter( - name="faas.coldstarts", + name=FAAS_COLDSTARTS, description="Number of invocation cold starts", unit="{coldstart}", ) -FAAS_CPU_USAGE = "faas.cpu_usage" +FAAS_CPU_USAGE: Final = "faas.cpu_usage" """ Distribution of CPU usage per invocation Instrument: histogram @@ -43,13 +45,13 @@ def create_faas_coldstarts(meter: Meter) -> Counter: def create_faas_cpu_usage(meter: Meter) -> Histogram: """Distribution of CPU usage per invocation""" return meter.create_histogram( - name="faas.cpu_usage", + name=FAAS_CPU_USAGE, description="Distribution of CPU usage per invocation", unit="s", ) -FAAS_ERRORS = "faas.errors" +FAAS_ERRORS: Final = "faas.errors" """ Number of invocation errors Instrument: counter @@ -60,13 +62,13 @@ def create_faas_cpu_usage(meter: Meter) -> Histogram: def create_faas_errors(meter: Meter) -> Counter: """Number of invocation errors""" return meter.create_counter( - name="faas.errors", + name=FAAS_ERRORS, description="Number of invocation errors", unit="{error}", ) -FAAS_INIT_DURATION = "faas.init_duration" +FAAS_INIT_DURATION: Final = "faas.init_duration" """ Measures the duration of the function's initialization, such as a cold start Instrument: histogram @@ -77,13 +79,13 @@ def create_faas_errors(meter: Meter) -> Counter: def create_faas_init_duration(meter: Meter) -> Histogram: """Measures the duration of the function's initialization, such as a cold start""" return meter.create_histogram( - name="faas.init_duration", + name=FAAS_INIT_DURATION, description="Measures the duration of the function's initialization, such as a cold start", unit="s", ) -FAAS_INVOCATIONS = "faas.invocations" +FAAS_INVOCATIONS: Final = "faas.invocations" """ Number of successful invocations Instrument: counter @@ -94,13 +96,13 @@ def create_faas_init_duration(meter: Meter) -> Histogram: def create_faas_invocations(meter: Meter) -> Counter: """Number of successful invocations""" return meter.create_counter( - name="faas.invocations", + name=FAAS_INVOCATIONS, description="Number of successful invocations", unit="{invocation}", ) -FAAS_INVOKE_DURATION = "faas.invoke_duration" +FAAS_INVOKE_DURATION: Final = "faas.invoke_duration" """ Measures the duration of the function's logic execution Instrument: histogram @@ -111,13 +113,13 @@ def create_faas_invocations(meter: Meter) -> Counter: def create_faas_invoke_duration(meter: Meter) -> Histogram: """Measures the duration of the function's logic execution""" return meter.create_histogram( - name="faas.invoke_duration", + name=FAAS_INVOKE_DURATION, description="Measures the duration of the function's logic execution", unit="s", ) -FAAS_MEM_USAGE = "faas.mem_usage" +FAAS_MEM_USAGE: Final = "faas.mem_usage" """ Distribution of max memory usage per invocation Instrument: histogram @@ -128,13 +130,13 @@ def create_faas_invoke_duration(meter: Meter) -> Histogram: def create_faas_mem_usage(meter: Meter) -> Histogram: """Distribution of max memory usage per invocation""" return meter.create_histogram( - name="faas.mem_usage", + name=FAAS_MEM_USAGE, description="Distribution of max memory usage per invocation", unit="By", ) -FAAS_NET_IO = "faas.net_io" +FAAS_NET_IO: Final = "faas.net_io" """ Distribution of net I/O usage per invocation Instrument: histogram @@ -145,13 +147,13 @@ def create_faas_mem_usage(meter: Meter) -> Histogram: def create_faas_net_io(meter: Meter) -> Histogram: """Distribution of net I/O usage per invocation""" return meter.create_histogram( - name="faas.net_io", + name=FAAS_NET_IO, description="Distribution of net I/O usage per invocation", unit="By", ) -FAAS_TIMEOUTS = "faas.timeouts" +FAAS_TIMEOUTS: Final = "faas.timeouts" """ Number of invocation timeouts Instrument: counter @@ -162,7 +164,7 @@ def create_faas_net_io(meter: Meter) -> Histogram: def create_faas_timeouts(meter: Meter) -> Counter: """Number of invocation timeouts""" return meter.create_counter( - name="faas.timeouts", + name=FAAS_TIMEOUTS, description="Number of invocation timeouts", unit="{timeout}", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/http_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/http_metrics.py index 7852a39587..86d0317e3b 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/http_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/http_metrics.py @@ -13,9 +13,11 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Histogram, Meter, UpDownCounter -HTTP_CLIENT_ACTIVE_REQUESTS = "http.client.active_requests" +HTTP_CLIENT_ACTIVE_REQUESTS: Final = "http.client.active_requests" """ Number of active HTTP requests Instrument: updowncounter @@ -26,13 +28,13 @@ def create_http_client_active_requests(meter: Meter) -> UpDownCounter: """Number of active HTTP requests""" return meter.create_up_down_counter( - name="http.client.active_requests", + name=HTTP_CLIENT_ACTIVE_REQUESTS, description="Number of active HTTP requests.", unit="{request}", ) -HTTP_CLIENT_CONNECTION_DURATION = "http.client.connection.duration" +HTTP_CLIENT_CONNECTION_DURATION: Final = "http.client.connection.duration" """ The duration of the successfully established outbound HTTP connections Instrument: histogram @@ -43,13 +45,13 @@ def create_http_client_active_requests(meter: Meter) -> UpDownCounter: def create_http_client_connection_duration(meter: Meter) -> Histogram: """The duration of the successfully established outbound HTTP connections""" return meter.create_histogram( - name="http.client.connection.duration", + name=HTTP_CLIENT_CONNECTION_DURATION, description="The duration of the successfully established outbound HTTP connections.", unit="s", ) -HTTP_CLIENT_OPEN_CONNECTIONS = "http.client.open_connections" +HTTP_CLIENT_OPEN_CONNECTIONS: Final = "http.client.open_connections" """ Number of outbound HTTP connections that are currently active or idle on the client Instrument: updowncounter @@ -60,13 +62,13 @@ def create_http_client_connection_duration(meter: Meter) -> Histogram: def create_http_client_open_connections(meter: Meter) -> UpDownCounter: """Number of outbound HTTP connections that are currently active or idle on the client""" return meter.create_up_down_counter( - name="http.client.open_connections", + name=HTTP_CLIENT_OPEN_CONNECTIONS, description="Number of outbound HTTP connections that are currently active or idle on the client.", unit="{connection}", ) -HTTP_CLIENT_REQUEST_BODY_SIZE = "http.client.request.body.size" +HTTP_CLIENT_REQUEST_BODY_SIZE: Final = "http.client.request.body.size" """ Size of HTTP client request bodies Instrument: histogram @@ -78,13 +80,13 @@ def create_http_client_open_connections(meter: Meter) -> UpDownCounter: def create_http_client_request_body_size(meter: Meter) -> Histogram: """Size of HTTP client request bodies""" return meter.create_histogram( - name="http.client.request.body.size", + name=HTTP_CLIENT_REQUEST_BODY_SIZE, description="Size of HTTP client request bodies.", unit="By", ) -HTTP_CLIENT_REQUEST_DURATION = "http.client.request.duration" +HTTP_CLIENT_REQUEST_DURATION: Final = "http.client.request.duration" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.http_metrics.HTTP_CLIENT_REQUEST_DURATION`. """ @@ -93,13 +95,13 @@ def create_http_client_request_body_size(meter: Meter) -> Histogram: def create_http_client_request_duration(meter: Meter) -> Histogram: """Duration of HTTP client requests""" return meter.create_histogram( - name="http.client.request.duration", + name=HTTP_CLIENT_REQUEST_DURATION, description="Duration of HTTP client requests.", unit="s", ) -HTTP_CLIENT_RESPONSE_BODY_SIZE = "http.client.response.body.size" +HTTP_CLIENT_RESPONSE_BODY_SIZE: Final = "http.client.response.body.size" """ Size of HTTP client response bodies Instrument: histogram @@ -111,13 +113,13 @@ def create_http_client_request_duration(meter: Meter) -> Histogram: def create_http_client_response_body_size(meter: Meter) -> Histogram: """Size of HTTP client response bodies""" return meter.create_histogram( - name="http.client.response.body.size", + name=HTTP_CLIENT_RESPONSE_BODY_SIZE, description="Size of HTTP client response bodies.", unit="By", ) -HTTP_SERVER_ACTIVE_REQUESTS = "http.server.active_requests" +HTTP_SERVER_ACTIVE_REQUESTS: Final = "http.server.active_requests" """ Number of active HTTP server requests Instrument: updowncounter @@ -128,13 +130,13 @@ def create_http_client_response_body_size(meter: Meter) -> Histogram: def create_http_server_active_requests(meter: Meter) -> UpDownCounter: """Number of active HTTP server requests""" return meter.create_up_down_counter( - name="http.server.active_requests", + name=HTTP_SERVER_ACTIVE_REQUESTS, description="Number of active HTTP server requests.", unit="{request}", ) -HTTP_SERVER_REQUEST_BODY_SIZE = "http.server.request.body.size" +HTTP_SERVER_REQUEST_BODY_SIZE: Final = "http.server.request.body.size" """ Size of HTTP server request bodies Instrument: histogram @@ -146,13 +148,13 @@ def create_http_server_active_requests(meter: Meter) -> UpDownCounter: def create_http_server_request_body_size(meter: Meter) -> Histogram: """Size of HTTP server request bodies""" return meter.create_histogram( - name="http.server.request.body.size", + name=HTTP_SERVER_REQUEST_BODY_SIZE, description="Size of HTTP server request bodies.", unit="By", ) -HTTP_SERVER_REQUEST_DURATION = "http.server.request.duration" +HTTP_SERVER_REQUEST_DURATION: Final = "http.server.request.duration" """ Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.http_metrics.HTTP_SERVER_REQUEST_DURATION`. """ @@ -161,13 +163,13 @@ def create_http_server_request_body_size(meter: Meter) -> Histogram: def create_http_server_request_duration(meter: Meter) -> Histogram: """Duration of HTTP server requests""" return meter.create_histogram( - name="http.server.request.duration", + name=HTTP_SERVER_REQUEST_DURATION, description="Duration of HTTP server requests.", unit="s", ) -HTTP_SERVER_RESPONSE_BODY_SIZE = "http.server.response.body.size" +HTTP_SERVER_RESPONSE_BODY_SIZE: Final = "http.server.response.body.size" """ Size of HTTP server response bodies Instrument: histogram @@ -179,7 +181,7 @@ def create_http_server_request_duration(meter: Meter) -> Histogram: def create_http_server_response_body_size(meter: Meter) -> Histogram: """Size of HTTP server response bodies""" return meter.create_histogram( - name="http.server.response.body.size", + name=HTTP_SERVER_RESPONSE_BODY_SIZE, description="Size of HTTP server response bodies.", unit="By", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py index ac3cb549ab..0ca50f28a2 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py @@ -13,9 +13,11 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Counter, Histogram, Meter -MESSAGING_PROCESS_DURATION = "messaging.process.duration" +MESSAGING_PROCESS_DURATION: Final = "messaging.process.duration" """ Measures the duration of process operation Instrument: histogram @@ -26,13 +28,13 @@ def create_messaging_process_duration(meter: Meter) -> Histogram: """Measures the duration of process operation""" return meter.create_histogram( - name="messaging.process.duration", + name=MESSAGING_PROCESS_DURATION, description="Measures the duration of process operation.", unit="s", ) -MESSAGING_PROCESS_MESSAGES = "messaging.process.messages" +MESSAGING_PROCESS_MESSAGES: Final = "messaging.process.messages" """ Measures the number of processed messages Instrument: counter @@ -43,13 +45,13 @@ def create_messaging_process_duration(meter: Meter) -> Histogram: def create_messaging_process_messages(meter: Meter) -> Counter: """Measures the number of processed messages""" return meter.create_counter( - name="messaging.process.messages", + name=MESSAGING_PROCESS_MESSAGES, description="Measures the number of processed messages.", unit="{message}", ) -MESSAGING_PUBLISH_DURATION = "messaging.publish.duration" +MESSAGING_PUBLISH_DURATION: Final = "messaging.publish.duration" """ Measures the duration of publish operation Instrument: histogram @@ -60,13 +62,13 @@ def create_messaging_process_messages(meter: Meter) -> Counter: def create_messaging_publish_duration(meter: Meter) -> Histogram: """Measures the duration of publish operation""" return meter.create_histogram( - name="messaging.publish.duration", + name=MESSAGING_PUBLISH_DURATION, description="Measures the duration of publish operation.", unit="s", ) -MESSAGING_PUBLISH_MESSAGES = "messaging.publish.messages" +MESSAGING_PUBLISH_MESSAGES: Final = "messaging.publish.messages" """ Measures the number of published messages Instrument: counter @@ -77,13 +79,13 @@ def create_messaging_publish_duration(meter: Meter) -> Histogram: def create_messaging_publish_messages(meter: Meter) -> Counter: """Measures the number of published messages""" return meter.create_counter( - name="messaging.publish.messages", + name=MESSAGING_PUBLISH_MESSAGES, description="Measures the number of published messages.", unit="{message}", ) -MESSAGING_RECEIVE_DURATION = "messaging.receive.duration" +MESSAGING_RECEIVE_DURATION: Final = "messaging.receive.duration" """ Measures the duration of receive operation Instrument: histogram @@ -94,13 +96,13 @@ def create_messaging_publish_messages(meter: Meter) -> Counter: def create_messaging_receive_duration(meter: Meter) -> Histogram: """Measures the duration of receive operation""" return meter.create_histogram( - name="messaging.receive.duration", + name=MESSAGING_RECEIVE_DURATION, description="Measures the duration of receive operation.", unit="s", ) -MESSAGING_RECEIVE_MESSAGES = "messaging.receive.messages" +MESSAGING_RECEIVE_MESSAGES: Final = "messaging.receive.messages" """ Measures the number of received messages Instrument: counter @@ -111,7 +113,7 @@ def create_messaging_receive_duration(meter: Meter) -> Histogram: def create_messaging_receive_messages(meter: Meter) -> Counter: """Measures the number of received messages""" return meter.create_counter( - name="messaging.receive.messages", + name=MESSAGING_RECEIVE_MESSAGES, description="Measures the number of received messages.", unit="{message}", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/process_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/process_metrics.py index 8d6e7fc75c..bfcdac86af 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/process_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/process_metrics.py @@ -13,16 +13,33 @@ # limitations under the License. -from typing import Callable, Sequence +from typing import ( + Callable, + Final, + Generator, + Iterable, + Optional, + Sequence, + Union, +) from opentelemetry.metrics import ( + CallbackOptions, Counter, Meter, ObservableGauge, + Observation, UpDownCounter, ) -PROCESS_CONTEXT_SWITCHES = "process.context_switches" +# pylint: disable=invalid-name +CallbackT = Union[ + Callable[[CallbackOptions], Iterable[Observation]], + Generator[Iterable[Observation], CallbackOptions, None], +] + + +PROCESS_CONTEXT_SWITCHES: Final = "process.context_switches" """ Number of times the process has been context switched Instrument: counter @@ -33,13 +50,13 @@ def create_process_context_switches(meter: Meter) -> Counter: """Number of times the process has been context switched""" return meter.create_counter( - name="process.context_switches", + name=PROCESS_CONTEXT_SWITCHES, description="Number of times the process has been context switched.", unit="{count}", ) -PROCESS_CPU_TIME = "process.cpu.time" +PROCESS_CPU_TIME: Final = "process.cpu.time" """ Total CPU seconds broken down by different states Instrument: counter @@ -50,13 +67,13 @@ def create_process_context_switches(meter: Meter) -> Counter: def create_process_cpu_time(meter: Meter) -> Counter: """Total CPU seconds broken down by different states""" return meter.create_counter( - name="process.cpu.time", + name=PROCESS_CPU_TIME, description="Total CPU seconds broken down by different states.", unit="s", ) -PROCESS_CPU_UTILIZATION = "process.cpu.utilization" +PROCESS_CPU_UTILIZATION: Final = "process.cpu.utilization" """ Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process Instrument: gauge @@ -65,18 +82,18 @@ def create_process_cpu_time(meter: Meter) -> Counter: def create_process_cpu_utilization( - meter: Meter, callback: Sequence[Callable] + meter: Meter, callbacks: Optional[Sequence[CallbackT]] ) -> ObservableGauge: """Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process""" return meter.create_observable_gauge( - name="process.cpu.utilization", - callback=callback, + name=PROCESS_CPU_UTILIZATION, + callbacks=callbacks, description="Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process.", unit="1", ) -PROCESS_DISK_IO = "process.disk.io" +PROCESS_DISK_IO: Final = "process.disk.io" """ Disk bytes transferred Instrument: counter @@ -87,13 +104,13 @@ def create_process_cpu_utilization( def create_process_disk_io(meter: Meter) -> Counter: """Disk bytes transferred""" return meter.create_counter( - name="process.disk.io", + name=PROCESS_DISK_IO, description="Disk bytes transferred.", unit="By", ) -PROCESS_MEMORY_USAGE = "process.memory.usage" +PROCESS_MEMORY_USAGE: Final = "process.memory.usage" """ The amount of physical memory in use Instrument: updowncounter @@ -104,13 +121,13 @@ def create_process_disk_io(meter: Meter) -> Counter: def create_process_memory_usage(meter: Meter) -> UpDownCounter: """The amount of physical memory in use""" return meter.create_up_down_counter( - name="process.memory.usage", + name=PROCESS_MEMORY_USAGE, description="The amount of physical memory in use.", unit="By", ) -PROCESS_MEMORY_VIRTUAL = "process.memory.virtual" +PROCESS_MEMORY_VIRTUAL: Final = "process.memory.virtual" """ The amount of committed virtual memory Instrument: updowncounter @@ -121,13 +138,13 @@ def create_process_memory_usage(meter: Meter) -> UpDownCounter: def create_process_memory_virtual(meter: Meter) -> UpDownCounter: """The amount of committed virtual memory""" return meter.create_up_down_counter( - name="process.memory.virtual", + name=PROCESS_MEMORY_VIRTUAL, description="The amount of committed virtual memory.", unit="By", ) -PROCESS_NETWORK_IO = "process.network.io" +PROCESS_NETWORK_IO: Final = "process.network.io" """ Network bytes transferred Instrument: counter @@ -138,13 +155,15 @@ def create_process_memory_virtual(meter: Meter) -> UpDownCounter: def create_process_network_io(meter: Meter) -> Counter: """Network bytes transferred""" return meter.create_counter( - name="process.network.io", + name=PROCESS_NETWORK_IO, description="Network bytes transferred.", unit="By", ) -PROCESS_OPEN_FILE_DESCRIPTOR_COUNT = "process.open_file_descriptor.count" +PROCESS_OPEN_FILE_DESCRIPTOR_COUNT: Final = ( + "process.open_file_descriptor.count" +) """ Number of file descriptors in use by the process Instrument: updowncounter @@ -155,13 +174,13 @@ def create_process_network_io(meter: Meter) -> Counter: def create_process_open_file_descriptor_count(meter: Meter) -> UpDownCounter: """Number of file descriptors in use by the process""" return meter.create_up_down_counter( - name="process.open_file_descriptor.count", + name=PROCESS_OPEN_FILE_DESCRIPTOR_COUNT, description="Number of file descriptors in use by the process.", unit="{count}", ) -PROCESS_PAGING_FAULTS = "process.paging.faults" +PROCESS_PAGING_FAULTS: Final = "process.paging.faults" """ Number of page faults the process has made Instrument: counter @@ -172,13 +191,13 @@ def create_process_open_file_descriptor_count(meter: Meter) -> UpDownCounter: def create_process_paging_faults(meter: Meter) -> Counter: """Number of page faults the process has made""" return meter.create_counter( - name="process.paging.faults", + name=PROCESS_PAGING_FAULTS, description="Number of page faults the process has made.", unit="{fault}", ) -PROCESS_THREAD_COUNT = "process.thread.count" +PROCESS_THREAD_COUNT: Final = "process.thread.count" """ Process threads count Instrument: updowncounter @@ -189,7 +208,7 @@ def create_process_paging_faults(meter: Meter) -> Counter: def create_process_thread_count(meter: Meter) -> UpDownCounter: """Process threads count""" return meter.create_up_down_counter( - name="process.thread.count", + name=PROCESS_THREAD_COUNT, description="Process threads count.", unit="{thread}", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py index eb2f5edd75..ec05ff14bb 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py @@ -13,9 +13,11 @@ # limitations under the License. +from typing import Final + from opentelemetry.metrics import Histogram, Meter -RPC_CLIENT_DURATION = "rpc.client.duration" +RPC_CLIENT_DURATION: Final = "rpc.client.duration" """ Measures the duration of outbound RPC Instrument: histogram @@ -30,13 +32,13 @@ def create_rpc_client_duration(meter: Meter) -> Histogram: """Measures the duration of outbound RPC""" return meter.create_histogram( - name="rpc.client.duration", + name=RPC_CLIENT_DURATION, description="Measures the duration of outbound RPC.", unit="ms", ) -RPC_CLIENT_REQUEST_SIZE = "rpc.client.request.size" +RPC_CLIENT_REQUEST_SIZE: Final = "rpc.client.request.size" """ Measures the size of RPC request messages (uncompressed) Instrument: histogram @@ -48,13 +50,13 @@ def create_rpc_client_duration(meter: Meter) -> Histogram: def create_rpc_client_request_size(meter: Meter) -> Histogram: """Measures the size of RPC request messages (uncompressed)""" return meter.create_histogram( - name="rpc.client.request.size", + name=RPC_CLIENT_REQUEST_SIZE, description="Measures the size of RPC request messages (uncompressed).", unit="By", ) -RPC_CLIENT_REQUESTS_PER_RPC = "rpc.client.requests_per_rpc" +RPC_CLIENT_REQUESTS_PER_RPC: Final = "rpc.client.requests_per_rpc" """ Measures the number of messages received per RPC Instrument: histogram @@ -68,13 +70,13 @@ def create_rpc_client_request_size(meter: Meter) -> Histogram: def create_rpc_client_requests_per_rpc(meter: Meter) -> Histogram: """Measures the number of messages received per RPC""" return meter.create_histogram( - name="rpc.client.requests_per_rpc", + name=RPC_CLIENT_REQUESTS_PER_RPC, description="Measures the number of messages received per RPC.", unit="{count}", ) -RPC_CLIENT_RESPONSE_SIZE = "rpc.client.response.size" +RPC_CLIENT_RESPONSE_SIZE: Final = "rpc.client.response.size" """ Measures the size of RPC response messages (uncompressed) Instrument: histogram @@ -86,13 +88,13 @@ def create_rpc_client_requests_per_rpc(meter: Meter) -> Histogram: def create_rpc_client_response_size(meter: Meter) -> Histogram: """Measures the size of RPC response messages (uncompressed)""" return meter.create_histogram( - name="rpc.client.response.size", + name=RPC_CLIENT_RESPONSE_SIZE, description="Measures the size of RPC response messages (uncompressed).", unit="By", ) -RPC_CLIENT_RESPONSES_PER_RPC = "rpc.client.responses_per_rpc" +RPC_CLIENT_RESPONSES_PER_RPC: Final = "rpc.client.responses_per_rpc" """ Measures the number of messages sent per RPC Instrument: histogram @@ -106,13 +108,13 @@ def create_rpc_client_response_size(meter: Meter) -> Histogram: def create_rpc_client_responses_per_rpc(meter: Meter) -> Histogram: """Measures the number of messages sent per RPC""" return meter.create_histogram( - name="rpc.client.responses_per_rpc", + name=RPC_CLIENT_RESPONSES_PER_RPC, description="Measures the number of messages sent per RPC.", unit="{count}", ) -RPC_SERVER_DURATION = "rpc.server.duration" +RPC_SERVER_DURATION: Final = "rpc.server.duration" """ Measures the duration of inbound RPC Instrument: histogram @@ -127,13 +129,13 @@ def create_rpc_client_responses_per_rpc(meter: Meter) -> Histogram: def create_rpc_server_duration(meter: Meter) -> Histogram: """Measures the duration of inbound RPC""" return meter.create_histogram( - name="rpc.server.duration", + name=RPC_SERVER_DURATION, description="Measures the duration of inbound RPC.", unit="ms", ) -RPC_SERVER_REQUEST_SIZE = "rpc.server.request.size" +RPC_SERVER_REQUEST_SIZE: Final = "rpc.server.request.size" """ Measures the size of RPC request messages (uncompressed) Instrument: histogram @@ -145,13 +147,13 @@ def create_rpc_server_duration(meter: Meter) -> Histogram: def create_rpc_server_request_size(meter: Meter) -> Histogram: """Measures the size of RPC request messages (uncompressed)""" return meter.create_histogram( - name="rpc.server.request.size", + name=RPC_SERVER_REQUEST_SIZE, description="Measures the size of RPC request messages (uncompressed).", unit="By", ) -RPC_SERVER_REQUESTS_PER_RPC = "rpc.server.requests_per_rpc" +RPC_SERVER_REQUESTS_PER_RPC: Final = "rpc.server.requests_per_rpc" """ Measures the number of messages received per RPC Instrument: histogram @@ -165,13 +167,13 @@ def create_rpc_server_request_size(meter: Meter) -> Histogram: def create_rpc_server_requests_per_rpc(meter: Meter) -> Histogram: """Measures the number of messages received per RPC""" return meter.create_histogram( - name="rpc.server.requests_per_rpc", + name=RPC_SERVER_REQUESTS_PER_RPC, description="Measures the number of messages received per RPC.", unit="{count}", ) -RPC_SERVER_RESPONSE_SIZE = "rpc.server.response.size" +RPC_SERVER_RESPONSE_SIZE: Final = "rpc.server.response.size" """ Measures the size of RPC response messages (uncompressed) Instrument: histogram @@ -183,13 +185,13 @@ def create_rpc_server_requests_per_rpc(meter: Meter) -> Histogram: def create_rpc_server_response_size(meter: Meter) -> Histogram: """Measures the size of RPC response messages (uncompressed)""" return meter.create_histogram( - name="rpc.server.response.size", + name=RPC_SERVER_RESPONSE_SIZE, description="Measures the size of RPC response messages (uncompressed).", unit="By", ) -RPC_SERVER_RESPONSES_PER_RPC = "rpc.server.responses_per_rpc" +RPC_SERVER_RESPONSES_PER_RPC: Final = "rpc.server.responses_per_rpc" """ Measures the number of messages sent per RPC Instrument: histogram @@ -203,7 +205,7 @@ def create_rpc_server_response_size(meter: Meter) -> Histogram: def create_rpc_server_responses_per_rpc(meter: Meter) -> Histogram: """Measures the number of messages sent per RPC""" return meter.create_histogram( - name="rpc.server.responses_per_rpc", + name=RPC_SERVER_RESPONSES_PER_RPC, description="Measures the number of messages sent per RPC.", unit="{count}", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/system_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/system_metrics.py index 72fb32649c..3d193ef180 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/system_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/_incubating/metrics/system_metrics.py @@ -13,16 +13,33 @@ # limitations under the License. -from typing import Callable, Sequence +from typing import ( + Callable, + Final, + Generator, + Iterable, + Optional, + Sequence, + Union, +) from opentelemetry.metrics import ( + CallbackOptions, Counter, Meter, ObservableGauge, + Observation, UpDownCounter, ) -SYSTEM_CPU_FREQUENCY = "system.cpu.frequency" +# pylint: disable=invalid-name +CallbackT = Union[ + Callable[[CallbackOptions], Iterable[Observation]], + Generator[Iterable[Observation], CallbackOptions, None], +] + + +SYSTEM_CPU_FREQUENCY: Final = "system.cpu.frequency" """ Reports the current frequency of the CPU in Hz Instrument: gauge @@ -31,18 +48,18 @@ def create_system_cpu_frequency( - meter: Meter, callback: Sequence[Callable] + meter: Meter, callbacks: Optional[Sequence[CallbackT]] ) -> ObservableGauge: """Reports the current frequency of the CPU in Hz""" return meter.create_observable_gauge( - name="system.cpu.frequency", - callback=callback, + name=SYSTEM_CPU_FREQUENCY, + callbacks=callbacks, description="Reports the current frequency of the CPU in Hz", unit="{Hz}", ) -SYSTEM_CPU_LOGICAL_COUNT = "system.cpu.logical.count" +SYSTEM_CPU_LOGICAL_COUNT: Final = "system.cpu.logical.count" """ Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking Instrument: updowncounter @@ -53,13 +70,13 @@ def create_system_cpu_frequency( def create_system_cpu_logical_count(meter: Meter) -> UpDownCounter: """Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking""" return meter.create_up_down_counter( - name="system.cpu.logical.count", + name=SYSTEM_CPU_LOGICAL_COUNT, description="Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking", unit="{cpu}", ) -SYSTEM_CPU_PHYSICAL_COUNT = "system.cpu.physical.count" +SYSTEM_CPU_PHYSICAL_COUNT: Final = "system.cpu.physical.count" """ Reports the number of actual physical processor cores on the hardware Instrument: updowncounter @@ -70,13 +87,13 @@ def create_system_cpu_logical_count(meter: Meter) -> UpDownCounter: def create_system_cpu_physical_count(meter: Meter) -> UpDownCounter: """Reports the number of actual physical processor cores on the hardware""" return meter.create_up_down_counter( - name="system.cpu.physical.count", + name=SYSTEM_CPU_PHYSICAL_COUNT, description="Reports the number of actual physical processor cores on the hardware", unit="{cpu}", ) -SYSTEM_CPU_TIME = "system.cpu.time" +SYSTEM_CPU_TIME: Final = "system.cpu.time" """ Seconds each logical CPU spent on each mode Instrument: counter @@ -87,13 +104,13 @@ def create_system_cpu_physical_count(meter: Meter) -> UpDownCounter: def create_system_cpu_time(meter: Meter) -> Counter: """Seconds each logical CPU spent on each mode""" return meter.create_counter( - name="system.cpu.time", + name=SYSTEM_CPU_TIME, description="Seconds each logical CPU spent on each mode", unit="s", ) -SYSTEM_CPU_UTILIZATION = "system.cpu.utilization" +SYSTEM_CPU_UTILIZATION: Final = "system.cpu.utilization" """ Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs Instrument: gauge @@ -102,18 +119,18 @@ def create_system_cpu_time(meter: Meter) -> Counter: def create_system_cpu_utilization( - meter: Meter, callback: Sequence[Callable] + meter: Meter, callbacks: Optional[Sequence[CallbackT]] ) -> ObservableGauge: """Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs""" return meter.create_observable_gauge( - name="system.cpu.utilization", - callback=callback, + name=SYSTEM_CPU_UTILIZATION, + callbacks=callbacks, description="Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs", unit="1", ) -SYSTEM_DISK_IO = "system.disk.io" +SYSTEM_DISK_IO: Final = "system.disk.io" """ Instrument: counter Unit: By @@ -122,13 +139,13 @@ def create_system_cpu_utilization( def create_system_disk_io(meter: Meter) -> Counter: return meter.create_counter( - name="system.disk.io", + name=SYSTEM_DISK_IO, description="", unit="By", ) -SYSTEM_DISK_IO_TIME = "system.disk.io_time" +SYSTEM_DISK_IO_TIME: Final = "system.disk.io_time" """ Time disk spent activated Instrument: counter @@ -145,13 +162,13 @@ def create_system_disk_io(meter: Meter) -> Counter: def create_system_disk_io_time(meter: Meter) -> Counter: """Time disk spent activated""" return meter.create_counter( - name="system.disk.io_time", + name=SYSTEM_DISK_IO_TIME, description="Time disk spent activated", unit="s", ) -SYSTEM_DISK_MERGED = "system.disk.merged" +SYSTEM_DISK_MERGED: Final = "system.disk.merged" """ Instrument: counter Unit: {operation} @@ -160,13 +177,13 @@ def create_system_disk_io_time(meter: Meter) -> Counter: def create_system_disk_merged(meter: Meter) -> Counter: return meter.create_counter( - name="system.disk.merged", + name=SYSTEM_DISK_MERGED, description="", unit="{operation}", ) -SYSTEM_DISK_OPERATION_TIME = "system.disk.operation_time" +SYSTEM_DISK_OPERATION_TIME: Final = "system.disk.operation_time" """ Sum of the time each operation took to complete Instrument: counter @@ -181,13 +198,13 @@ def create_system_disk_merged(meter: Meter) -> Counter: def create_system_disk_operation_time(meter: Meter) -> Counter: """Sum of the time each operation took to complete""" return meter.create_counter( - name="system.disk.operation_time", + name=SYSTEM_DISK_OPERATION_TIME, description="Sum of the time each operation took to complete", unit="s", ) -SYSTEM_DISK_OPERATIONS = "system.disk.operations" +SYSTEM_DISK_OPERATIONS: Final = "system.disk.operations" """ Instrument: counter Unit: {operation} @@ -196,13 +213,13 @@ def create_system_disk_operation_time(meter: Meter) -> Counter: def create_system_disk_operations(meter: Meter) -> Counter: return meter.create_counter( - name="system.disk.operations", + name=SYSTEM_DISK_OPERATIONS, description="", unit="{operation}", ) -SYSTEM_FILESYSTEM_USAGE = "system.filesystem.usage" +SYSTEM_FILESYSTEM_USAGE: Final = "system.filesystem.usage" """ Instrument: updowncounter Unit: By @@ -211,13 +228,13 @@ def create_system_disk_operations(meter: Meter) -> Counter: def create_system_filesystem_usage(meter: Meter) -> UpDownCounter: return meter.create_up_down_counter( - name="system.filesystem.usage", + name=SYSTEM_FILESYSTEM_USAGE, description="", unit="By", ) -SYSTEM_FILESYSTEM_UTILIZATION = "system.filesystem.utilization" +SYSTEM_FILESYSTEM_UTILIZATION: Final = "system.filesystem.utilization" """ Instrument: gauge Unit: 1 @@ -225,17 +242,17 @@ def create_system_filesystem_usage(meter: Meter) -> UpDownCounter: def create_system_filesystem_utilization( - meter: Meter, callback: Sequence[Callable] + meter: Meter, callbacks: Optional[Sequence[CallbackT]] ) -> ObservableGauge: return meter.create_observable_gauge( - name="system.filesystem.utilization", - callback=callback, + name=SYSTEM_FILESYSTEM_UTILIZATION, + callbacks=callbacks, description="", unit="1", ) -SYSTEM_LINUX_MEMORY_AVAILABLE = "system.linux.memory.available" +SYSTEM_LINUX_MEMORY_AVAILABLE: Final = "system.linux.memory.available" """ An estimate of how much memory is available for starting new applications, without causing swapping Instrument: updowncounter @@ -251,13 +268,13 @@ def create_system_filesystem_utilization( def create_system_linux_memory_available(meter: Meter) -> UpDownCounter: """An estimate of how much memory is available for starting new applications, without causing swapping""" return meter.create_up_down_counter( - name="system.linux.memory.available", + name=SYSTEM_LINUX_MEMORY_AVAILABLE, description="An estimate of how much memory is available for starting new applications, without causing swapping", unit="By", ) -SYSTEM_MEMORY_LIMIT = "system.memory.limit" +SYSTEM_MEMORY_LIMIT: Final = "system.memory.limit" """ Total memory available in the system Instrument: updowncounter @@ -269,13 +286,32 @@ def create_system_linux_memory_available(meter: Meter) -> UpDownCounter: def create_system_memory_limit(meter: Meter) -> UpDownCounter: """Total memory available in the system""" return meter.create_up_down_counter( - name="system.memory.limit", + name=SYSTEM_MEMORY_LIMIT, description="Total memory available in the system.", unit="By", ) -SYSTEM_MEMORY_USAGE = "system.memory.usage" +SYSTEM_MEMORY_SHARED: Final = "system.memory.shared" +""" +Shared memory used (mostly by tmpfs) +Instrument: updowncounter +Unit: By +Note: Equivalent of `shared` from [`free` command](https://man7.org/linux/man-pages/man1/free.1.html) or + `Shmem` from [`/proc/meminfo`](https://man7.org/linux/man-pages/man5/proc.5.html)". +""" + + +def create_system_memory_shared(meter: Meter) -> UpDownCounter: + """Shared memory used (mostly by tmpfs)""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_SHARED, + description="Shared memory used (mostly by tmpfs).", + unit="By", + ) + + +SYSTEM_MEMORY_USAGE: Final = "system.memory.usage" """ Reports memory in use by state Instrument: updowncounter @@ -288,13 +324,13 @@ def create_system_memory_limit(meter: Meter) -> UpDownCounter: def create_system_memory_usage(meter: Meter) -> UpDownCounter: """Reports memory in use by state""" return meter.create_up_down_counter( - name="system.memory.usage", + name=SYSTEM_MEMORY_USAGE, description="Reports memory in use by state.", unit="By", ) -SYSTEM_MEMORY_UTILIZATION = "system.memory.utilization" +SYSTEM_MEMORY_UTILIZATION: Final = "system.memory.utilization" """ Instrument: gauge Unit: 1 @@ -302,17 +338,17 @@ def create_system_memory_usage(meter: Meter) -> UpDownCounter: def create_system_memory_utilization( - meter: Meter, callback: Sequence[Callable] + meter: Meter, callbacks: Optional[Sequence[CallbackT]] ) -> ObservableGauge: return meter.create_observable_gauge( - name="system.memory.utilization", - callback=callback, + name=SYSTEM_MEMORY_UTILIZATION, + callbacks=callbacks, description="", unit="1", ) -SYSTEM_NETWORK_CONNECTIONS = "system.network.connections" +SYSTEM_NETWORK_CONNECTIONS: Final = "system.network.connections" """ Instrument: updowncounter Unit: {connection} @@ -321,13 +357,13 @@ def create_system_memory_utilization( def create_system_network_connections(meter: Meter) -> UpDownCounter: return meter.create_up_down_counter( - name="system.network.connections", + name=SYSTEM_NETWORK_CONNECTIONS, description="", unit="{connection}", ) -SYSTEM_NETWORK_DROPPED = "system.network.dropped" +SYSTEM_NETWORK_DROPPED: Final = "system.network.dropped" """ Count of packets that are dropped or discarded even though there was no error Instrument: counter @@ -343,13 +379,13 @@ def create_system_network_connections(meter: Meter) -> UpDownCounter: def create_system_network_dropped(meter: Meter) -> Counter: """Count of packets that are dropped or discarded even though there was no error""" return meter.create_counter( - name="system.network.dropped", + name=SYSTEM_NETWORK_DROPPED, description="Count of packets that are dropped or discarded even though there was no error", unit="{packet}", ) -SYSTEM_NETWORK_ERRORS = "system.network.errors" +SYSTEM_NETWORK_ERRORS: Final = "system.network.errors" """ Count of network errors detected Instrument: counter @@ -365,13 +401,13 @@ def create_system_network_dropped(meter: Meter) -> Counter: def create_system_network_errors(meter: Meter) -> Counter: """Count of network errors detected""" return meter.create_counter( - name="system.network.errors", + name=SYSTEM_NETWORK_ERRORS, description="Count of network errors detected", unit="{error}", ) -SYSTEM_NETWORK_IO = "system.network.io" +SYSTEM_NETWORK_IO: Final = "system.network.io" """ Instrument: counter Unit: By @@ -380,13 +416,13 @@ def create_system_network_errors(meter: Meter) -> Counter: def create_system_network_io(meter: Meter) -> Counter: return meter.create_counter( - name="system.network.io", + name=SYSTEM_NETWORK_IO, description="", unit="By", ) -SYSTEM_NETWORK_PACKETS = "system.network.packets" +SYSTEM_NETWORK_PACKETS: Final = "system.network.packets" """ Instrument: counter Unit: {packet} @@ -395,13 +431,13 @@ def create_system_network_io(meter: Meter) -> Counter: def create_system_network_packets(meter: Meter) -> Counter: return meter.create_counter( - name="system.network.packets", + name=SYSTEM_NETWORK_PACKETS, description="", unit="{packet}", ) -SYSTEM_PAGING_FAULTS = "system.paging.faults" +SYSTEM_PAGING_FAULTS: Final = "system.paging.faults" """ Instrument: counter Unit: {fault} @@ -410,13 +446,13 @@ def create_system_network_packets(meter: Meter) -> Counter: def create_system_paging_faults(meter: Meter) -> Counter: return meter.create_counter( - name="system.paging.faults", + name=SYSTEM_PAGING_FAULTS, description="", unit="{fault}", ) -SYSTEM_PAGING_OPERATIONS = "system.paging.operations" +SYSTEM_PAGING_OPERATIONS: Final = "system.paging.operations" """ Instrument: counter Unit: {operation} @@ -425,13 +461,13 @@ def create_system_paging_faults(meter: Meter) -> Counter: def create_system_paging_operations(meter: Meter) -> Counter: return meter.create_counter( - name="system.paging.operations", + name=SYSTEM_PAGING_OPERATIONS, description="", unit="{operation}", ) -SYSTEM_PAGING_USAGE = "system.paging.usage" +SYSTEM_PAGING_USAGE: Final = "system.paging.usage" """ Unix swap or windows pagefile usage Instrument: updowncounter @@ -442,13 +478,13 @@ def create_system_paging_operations(meter: Meter) -> Counter: def create_system_paging_usage(meter: Meter) -> UpDownCounter: """Unix swap or windows pagefile usage""" return meter.create_up_down_counter( - name="system.paging.usage", + name=SYSTEM_PAGING_USAGE, description="Unix swap or windows pagefile usage", unit="By", ) -SYSTEM_PAGING_UTILIZATION = "system.paging.utilization" +SYSTEM_PAGING_UTILIZATION: Final = "system.paging.utilization" """ Instrument: gauge Unit: 1 @@ -456,17 +492,17 @@ def create_system_paging_usage(meter: Meter) -> UpDownCounter: def create_system_paging_utilization( - meter: Meter, callback: Sequence[Callable] + meter: Meter, callbacks: Optional[Sequence[CallbackT]] ) -> ObservableGauge: return meter.create_observable_gauge( - name="system.paging.utilization", - callback=callback, + name=SYSTEM_PAGING_UTILIZATION, + callbacks=callbacks, description="", unit="1", ) -SYSTEM_PROCESS_COUNT = "system.process.count" +SYSTEM_PROCESS_COUNT: Final = "system.process.count" """ Total number of processes in each state Instrument: updowncounter @@ -477,13 +513,13 @@ def create_system_paging_utilization( def create_system_process_count(meter: Meter) -> UpDownCounter: """Total number of processes in each state""" return meter.create_up_down_counter( - name="system.process.count", + name=SYSTEM_PROCESS_COUNT, description="Total number of processes in each state", unit="{process}", ) -SYSTEM_PROCESS_CREATED = "system.process.created" +SYSTEM_PROCESS_CREATED: Final = "system.process.created" """ Total number of processes created over uptime of the host Instrument: counter @@ -494,7 +530,7 @@ def create_system_process_count(meter: Meter) -> UpDownCounter: def create_system_process_created(meter: Meter) -> Counter: """Total number of processes created over uptime of the host""" return meter.create_counter( - name="system.process.created", + name=SYSTEM_PROCESS_CREATED, description="Total number of processes created over uptime of the host", unit="{process}", ) diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/client_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/client_attributes.py index 77c904c492..d6dd88bfaf 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/client_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/client_attributes.py @@ -12,14 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -CLIENT_ADDRESS = "client.address" +CLIENT_ADDRESS: Final = "client.address" """ Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. Note: When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. """ -CLIENT_PORT = "client.port" +CLIENT_PORT: Final = "client.port" """ Client port number. Note: When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/error_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/error_attributes.py index 43d1bd8944..9fe10d596d 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/error_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/error_attributes.py @@ -12,13 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -ERROR_TYPE = "error.type" +ERROR_TYPE: Final = "error.type" """ Describes a class of error the operation ended with. -Note: The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Note: The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + + When `error.type` is set to a type (e.g., an exception type), its + canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. @@ -37,5 +41,5 @@ class ErrorTypeValues(Enum): - OTHER = "_OTHER" + OTHER: Final = "_OTHER" """A fallback error value to be used when the instrumentation doesn't define a custom value.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/exception_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/exception_attributes.py index 2d6be1e2be..1d1ebe8415 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/exception_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/exception_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -EXCEPTION_ESCAPED = "exception.escaped" +EXCEPTION_ESCAPED: Final = "exception.escaped" """ SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. Note: An exception is considered to have escaped (or left) the scope of a span, @@ -26,7 +27,7 @@ whether it will escape the scope of a span. However, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span, - as done in the [example for recording span exceptions](#recording-an-exception). + as done in the [example for recording span exceptions](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#recording-an-exception). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, @@ -34,17 +35,17 @@ clear whether the exception will escape. """ -EXCEPTION_MESSAGE = "exception.message" +EXCEPTION_MESSAGE: Final = "exception.message" """ The exception message. """ -EXCEPTION_STACKTRACE = "exception.stacktrace" +EXCEPTION_STACKTRACE: Final = "exception.stacktrace" """ A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. """ -EXCEPTION_TYPE = "exception.type" +EXCEPTION_TYPE: Final = "exception.type" """ The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/http_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/http_attributes.py index 337dbf06e2..1a3238c0ef 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/http_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/http_attributes.py @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -HTTP_REQUEST_HEADER_TEMPLATE = "http.request.header" +HTTP_REQUEST_HEADER_TEMPLATE: Final = "http.request.header" """ HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. Note: Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -23,7 +23,7 @@ The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. """ -HTTP_REQUEST_METHOD = "http.request.method" +HTTP_REQUEST_METHOD: Final = "http.request.method" """ HTTP request method. Note: HTTP request method value SHOULD be "known" to the instrumentation. @@ -42,18 +42,18 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. """ -HTTP_REQUEST_METHOD_ORIGINAL = "http.request.method_original" +HTTP_REQUEST_METHOD_ORIGINAL: Final = "http.request.method_original" """ Original HTTP method sent by the client in the request line. """ -HTTP_REQUEST_RESEND_COUNT = "http.request.resend_count" +HTTP_REQUEST_RESEND_COUNT: Final = "http.request.resend_count" """ The ordinal number of request resending attempt (for any reason, including redirects). Note: The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). """ -HTTP_RESPONSE_HEADER_TEMPLATE = "http.response.header" +HTTP_RESPONSE_HEADER_TEMPLATE: Final = "http.response.header" """ HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. Note: Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -61,12 +61,12 @@ The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. """ -HTTP_RESPONSE_STATUS_CODE = "http.response.status_code" +HTTP_RESPONSE_STATUS_CODE: Final = "http.response.status_code" """ [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). """ -HTTP_ROUTE = "http.route" +HTTP_ROUTE: Final = "http.route" """ The matched route, that is, the path template in the format used by the respective server framework. Note: MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. @@ -75,23 +75,23 @@ class HttpRequestMethodValues(Enum): - CONNECT = "CONNECT" + CONNECT: Final = "CONNECT" """CONNECT method.""" - DELETE = "DELETE" + DELETE: Final = "DELETE" """DELETE method.""" - GET = "GET" + GET: Final = "GET" """GET method.""" - HEAD = "HEAD" + HEAD: Final = "HEAD" """HEAD method.""" - OPTIONS = "OPTIONS" + OPTIONS: Final = "OPTIONS" """OPTIONS method.""" - PATCH = "PATCH" + PATCH: Final = "PATCH" """PATCH method.""" - POST = "POST" + POST: Final = "POST" """POST method.""" - PUT = "PUT" + PUT: Final = "PUT" """PUT method.""" - TRACE = "TRACE" + TRACE: Final = "TRACE" """TRACE method.""" - OTHER = "_OTHER" + OTHER: Final = "_OTHER" """Any HTTP method that the instrumentation has no prior knowledge of.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/network_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/network_attributes.py index fd256ee8a4..f3f1f8ea7b 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/network_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/network_attributes.py @@ -12,42 +12,42 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -NETWORK_LOCAL_ADDRESS = "network.local.address" +NETWORK_LOCAL_ADDRESS: Final = "network.local.address" """ Local address of the network connection - IP address or Unix domain socket name. """ -NETWORK_LOCAL_PORT = "network.local.port" +NETWORK_LOCAL_PORT: Final = "network.local.port" """ Local port number of the network connection. """ -NETWORK_PEER_ADDRESS = "network.peer.address" +NETWORK_PEER_ADDRESS: Final = "network.peer.address" """ Peer address of the network connection - IP address or Unix domain socket name. """ -NETWORK_PEER_PORT = "network.peer.port" +NETWORK_PEER_PORT: Final = "network.peer.port" """ Peer port number of the network connection. """ -NETWORK_PROTOCOL_NAME = "network.protocol.name" +NETWORK_PROTOCOL_NAME: Final = "network.protocol.name" """ [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. Note: The value SHOULD be normalized to lowercase. """ -NETWORK_PROTOCOL_VERSION = "network.protocol.version" +NETWORK_PROTOCOL_VERSION: Final = "network.protocol.version" """ The actual version of the protocol used for network communication. Note: If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. """ -NETWORK_TRANSPORT = "network.transport" +NETWORK_TRANSPORT: Final = "network.transport" """ [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). Note: The value SHOULD be normalized to lowercase. @@ -57,7 +57,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. """ -NETWORK_TYPE = "network.type" +NETWORK_TYPE: Final = "network.type" """ [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. Note: The value SHOULD be normalized to lowercase. @@ -65,18 +65,18 @@ class NetworkTransportValues(Enum): - TCP = "tcp" + TCP: Final = "tcp" """TCP.""" - UDP = "udp" + UDP: Final = "udp" """UDP.""" - PIPE = "pipe" + PIPE: Final = "pipe" """Named or anonymous pipe.""" - UNIX = "unix" + UNIX: Final = "unix" """Unix domain socket.""" class NetworkTypeValues(Enum): - IPV4 = "ipv4" + IPV4: Final = "ipv4" """IPv4.""" - IPV6 = "ipv6" + IPV6: Final = "ipv6" """IPv6.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/otel_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/otel_attributes.py index 1ccb108c3e..3db3683f63 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/otel_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/otel_attributes.py @@ -12,32 +12,32 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -OTEL_SCOPE_NAME = "otel.scope.name" +OTEL_SCOPE_NAME: Final = "otel.scope.name" """ The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). """ -OTEL_SCOPE_VERSION = "otel.scope.version" +OTEL_SCOPE_VERSION: Final = "otel.scope.version" """ The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). """ -OTEL_STATUS_CODE = "otel.status_code" +OTEL_STATUS_CODE: Final = "otel.status_code" """ Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. """ -OTEL_STATUS_DESCRIPTION = "otel.status_description" +OTEL_STATUS_DESCRIPTION: Final = "otel.status_description" """ Description of the Status if it has a value, otherwise not set. """ class OtelStatusCodeValues(Enum): - OK = "OK" + OK: Final = "OK" """The operation has been validated by an Application developer or Operator to have completed successfully.""" - ERROR = "ERROR" + ERROR: Final = "ERROR" """The operation contains an error.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/server_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/server_attributes.py index 1b882a3fd4..6b2658dac3 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/server_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/server_attributes.py @@ -12,14 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -SERVER_ADDRESS = "server.address" +SERVER_ADDRESS: Final = "server.address" """ Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. Note: When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. """ -SERVER_PORT = "server.port" +SERVER_PORT: Final = "server.port" """ Server port number. Note: When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/service_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/service_attributes.py index 4efd06f654..7ad038e92e 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/service_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/service_attributes.py @@ -12,14 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -SERVICE_NAME = "service.name" +SERVICE_NAME: Final = "service.name" """ Logical name of the service. -Note: MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. +Note: MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. """ -SERVICE_VERSION = "service.version" +SERVICE_VERSION: Final = "service.version" """ The version string of the service API or implementation. The format is not defined by these conventions. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/telemetry_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/telemetry_attributes.py index 5909f5d2c4..82275d7717 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/telemetry_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/telemetry_attributes.py @@ -12,15 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. - from enum import Enum +from typing import Final -TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language" +TELEMETRY_SDK_LANGUAGE: Final = "telemetry.sdk.language" """ The language of the telemetry SDK. """ -TELEMETRY_SDK_NAME = "telemetry.sdk.name" +TELEMETRY_SDK_NAME: Final = "telemetry.sdk.name" """ The name of the telemetry SDK as defined above. Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. @@ -31,34 +31,34 @@ All custom identifiers SHOULD be stable across different versions of an implementation. """ -TELEMETRY_SDK_VERSION = "telemetry.sdk.version" +TELEMETRY_SDK_VERSION: Final = "telemetry.sdk.version" """ The version string of the telemetry SDK. """ class TelemetrySdkLanguageValues(Enum): - CPP = "cpp" + CPP: Final = "cpp" """cpp.""" - DOTNET = "dotnet" + DOTNET: Final = "dotnet" """dotnet.""" - ERLANG = "erlang" + ERLANG: Final = "erlang" """erlang.""" - GO = "go" + GO: Final = "go" """go.""" - JAVA = "java" + JAVA: Final = "java" """java.""" - NODEJS = "nodejs" + NODEJS: Final = "nodejs" """nodejs.""" - PHP = "php" + PHP: Final = "php" """php.""" - PYTHON = "python" + PYTHON: Final = "python" """python.""" - RUBY = "ruby" + RUBY: Final = "ruby" """ruby.""" - RUST = "rust" + RUST: Final = "rust" """rust.""" - SWIFT = "swift" + SWIFT: Final = "swift" """swift.""" - WEBJS = "webjs" + WEBJS: Final = "webjs" """webjs.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/url_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/url_attributes.py index feacc0746f..de32d49f66 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/url_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/url_attributes.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -URL_FRAGMENT = "url.fragment" +URL_FRAGMENT: Final = "url.fragment" """ The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component. """ -URL_FULL = "url.full" +URL_FULL: Final = "url.full" """ Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). Note: For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. @@ -26,19 +27,19 @@ `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. """ -URL_PATH = "url.path" +URL_PATH: Final = "url.path" """ The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component. Note: Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. """ -URL_QUERY = "url.query" +URL_QUERY: Final = "url.query" """ The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component. Note: Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. """ -URL_SCHEME = "url.scheme" +URL_SCHEME: Final = "url.scheme" """ The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/user_agent_attributes.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/user_agent_attributes.py index 41ea48eeea..af5002ef34 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/user_agent_attributes.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/attributes/user_agent_attributes.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Final -USER_AGENT_ORIGINAL = "user_agent.original" +USER_AGENT_ORIGINAL: Final = "user_agent.original" """ Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/__init__.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/__init__.py index 3dca9c209e..ce388fbe82 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/__init__.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/__init__.py @@ -16,9 +16,9 @@ @deprecated( - "1.25.0", + version="1.25.0", reason="Use metrics defined in the :py:const:`opentelemetry.semconv.metrics` and :py:const:`opentelemetry.semconv._incubating.metrics` modules instead.", -) +) # type: ignore class MetricInstruments: SCHEMA_URL = "https://opentelemetry.io/schemas/v1.21.0" """ diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/http_metrics.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/http_metrics.py index 9006c83959..d0e0db6501 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/http_metrics.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/http_metrics.py @@ -13,7 +13,9 @@ # limitations under the License. -HTTP_CLIENT_REQUEST_DURATION = "http.client.request.duration" +from typing import Final + +HTTP_CLIENT_REQUEST_DURATION: Final = "http.client.request.duration" """ Duration of HTTP client requests Instrument: histogram @@ -21,7 +23,7 @@ """ -HTTP_SERVER_REQUEST_DURATION = "http.server.request.duration" +HTTP_SERVER_REQUEST_DURATION: Final = "http.server.request.duration" """ Duration of HTTP server requests Instrument: histogram diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/py.typed b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/metrics/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/resource/__init__.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/resource/__init__.py index 47428b7ff4..4015b20767 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/resource/__init__.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/resource/__init__.py @@ -20,9 +20,9 @@ @deprecated( - "1.25.0", + version="1.25.0", reason="Use attributes defined in the :py:const:`opentelemetry.semconv.attributes` and :py:const:`opentelemetry.semconv._incubating.attributes` modules instead.", -) +) # type: ignore class ResourceAttributes: SCHEMA_URL = "https://opentelemetry.io/schemas/v1.21.0" """ @@ -657,9 +657,9 @@ class ResourceAttributes: @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.CloudProviderValues` instead.", -) +) # type: ignore class CloudProviderValues(Enum): ALIBABA_CLOUD = "alibaba_cloud" """Alibaba Cloud.""" @@ -684,9 +684,9 @@ class CloudProviderValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.CloudPlatformValues` instead.", -) +) # type: ignore class CloudPlatformValues(Enum): ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs" """Alibaba Cloud Elastic Compute Service.""" @@ -771,9 +771,9 @@ class CloudPlatformValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.AwsEcsLaunchtypeValues` instead.", -) +) # type: ignore class AwsEcsLaunchtypeValues(Enum): EC2 = "ec2" """ec2.""" @@ -783,9 +783,9 @@ class AwsEcsLaunchtypeValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.HostArchValues` instead.", -) +) # type: ignore class HostArchValues(Enum): AMD64 = "amd64" """AMD64.""" @@ -813,9 +813,9 @@ class HostArchValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.OsTypeValues` instead.", -) +) # type: ignore class OsTypeValues(Enum): WINDOWS = "windows" """Microsoft Windows.""" @@ -852,9 +852,9 @@ class OsTypeValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv.attributes.TelemetrySdkLanguageValues` instead.", -) +) # type: ignore class TelemetrySdkLanguageValues(Enum): CPP = "cpp" """cpp.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/resource/py.typed b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/resource/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/schemas.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/schemas.py index b409960774..9af106cef9 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/schemas.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/schemas.py @@ -26,5 +26,10 @@ class Schemas(Enum): The URL of the OpenTelemetry schema version v1.25.0. """ + V1_26_0 = "https://opentelemetry.io/schemas/v1.26.0" + """ + The URL of the OpenTelemetry schema version v1.26.0. + """ + # when generating new semantic conventions, # make sure to add new versions version here. diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/trace/__init__.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/trace/__init__.py index 3057e0a374..ee63258a05 100644 --- a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/trace/__init__.py +++ b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/trace/__init__.py @@ -20,9 +20,9 @@ @deprecated( - "1.25.0", + version="1.25.0", reason="Use attributes defined in the :py:const:`opentelemetry.semconv.attributes` and :py:const:`opentelemetry.semconv._incubating.attributes` modules instead.", -) +) # type: ignore class SpanAttributes: SCHEMA_URL = "https://opentelemetry.io/schemas/v1.21.0" """ @@ -1406,7 +1406,7 @@ class SpanAttributes: @deprecated( version="1.18.0", reason="Removed from the specification in favor of `network.protocol.name` and `network.protocol.version` attributes", -) +) # type: ignore class HttpFlavorValues(Enum): HTTP_1_0 = "1.0" @@ -1424,7 +1424,7 @@ class HttpFlavorValues(Enum): @deprecated( version="1.18.0", reason="Removed from the specification", -) +) # type: ignore class MessagingDestinationKindValues(Enum): QUEUE = "queue" """A message sent to a queue.""" @@ -1436,7 +1436,7 @@ class MessagingDestinationKindValues(Enum): @deprecated( version="1.21.0", reason="Renamed to NetworkConnectionTypeValues", -) +) # type: ignore class NetHostConnectionTypeValues(Enum): WIFI = "wifi" """wifi.""" @@ -1457,7 +1457,7 @@ class NetHostConnectionTypeValues(Enum): @deprecated( version="1.21.0", reason="Renamed to NetworkConnectionSubtypeValues", -) +) # type: ignore class NetHostConnectionSubtypeValues(Enum): GPRS = "gprs" """GPRS.""" @@ -1524,9 +1524,9 @@ class NetHostConnectionSubtypeValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv.attributes.NetworkTransportValues` instead.", -) +) # type: ignore class NetTransportValues(Enum): IP_TCP = "ip_tcp" """ip_tcp.""" @@ -1545,9 +1545,9 @@ class NetTransportValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv.attributes.NetworkType` instead.", -) +) # type: ignore class NetSockFamilyValues(Enum): INET = "inet" """IPv4 address.""" @@ -1560,9 +1560,9 @@ class NetSockFamilyValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv.attributes.HttpRequestMethodValues` instead.", -) +) # type: ignore class HttpRequestMethodValues(Enum): CONNECT = "CONNECT" """CONNECT method.""" @@ -1595,7 +1595,7 @@ class HttpRequestMethodValues(Enum): """Any HTTP method that the instrumentation has no prior knowledge of.""" -@deprecated("1.25.0", reason="Removed from the specification.") +@deprecated(version="1.25.0", reason="Removed from the specification.") # type: ignore class EventDomainValues(Enum): BROWSER = "browser" """Events from browser apps.""" @@ -1608,9 +1608,9 @@ class EventDomainValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.LogIostreamValues` instead.", -) +) # type: ignore class LogIostreamValues(Enum): STDOUT = "stdout" """Logs from stdout stream.""" @@ -1619,7 +1619,7 @@ class LogIostreamValues(Enum): """Events from stderr stream.""" -@deprecated("1.25.0", reason="Removed from the specification.") +@deprecated(version="1.25.0", reason="Removed from the specification.") # type: ignore class TypeValues(Enum): HEAP = "heap" """Heap memory.""" @@ -1629,9 +1629,9 @@ class TypeValues(Enum): @deprecated( - "1.25.0", + version="1.25.0", reason="Use :py:const:`opentelemetry.semconv._incubating.attributes.OpentracingRefTypeValues` instead.", -) +) # type: ignore class OpentracingRefTypeValues(Enum): CHILD_OF = "child_of" """The parent Span depends on the child Span in some capacity.""" diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/trace/py.typed b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/trace/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/opentelemetry-semantic-conventions/src/opentelemetry/semconv/version.py b/opentelemetry-semantic-conventions/src/opentelemetry/semconv/version/__init__.py similarity index 100% rename from opentelemetry-semantic-conventions/src/opentelemetry/semconv/version.py rename to opentelemetry-semantic-conventions/src/opentelemetry/semconv/version/__init__.py diff --git a/opentelemetry-semantic-conventions/test-requirements.txt b/opentelemetry-semantic-conventions/test-requirements.txt index 31353edec3..cada74f699 100644 --- a/opentelemetry-semantic-conventions/test-requirements.txt +++ b/opentelemetry-semantic-conventions/test-requirements.txt @@ -1,18 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-semantic-conventions diff --git a/propagator/opentelemetry-propagator-b3/benchmark-requirements.txt b/propagator/opentelemetry-propagator-b3/benchmark-requirements.txt new file mode 100644 index 0000000000..44564857ef --- /dev/null +++ b/propagator/opentelemetry-propagator-b3/benchmark-requirements.txt @@ -0,0 +1 @@ +pytest-benchmark==4.0.0 diff --git a/propagator/opentelemetry-propagator-b3/tests/performance/benchmarks/trace/propagation/test_benchmark_b3_format.py b/propagator/opentelemetry-propagator-b3/benchmarks/trace/propagation/test_benchmark_b3_format.py similarity index 100% rename from propagator/opentelemetry-propagator-b3/tests/performance/benchmarks/trace/propagation/test_benchmark_b3_format.py rename to propagator/opentelemetry-propagator-b3/benchmarks/trace/propagation/test_benchmark_b3_format.py diff --git a/propagator/opentelemetry-propagator-b3/py.typed b/propagator/opentelemetry-propagator-b3/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/propagator/opentelemetry-propagator-b3/pyproject.toml b/propagator/opentelemetry-propagator-b3/pyproject.toml index 1f158285e5..f8abf0bc3c 100644 --- a/propagator/opentelemetry-propagator-b3/pyproject.toml +++ b/propagator/opentelemetry-propagator-b3/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/propagator/opentelemetry-propagator-b3/test-requirements.txt b/propagator/opentelemetry-propagator-b3/test-requirements.txt index a3b3b60c6f..9fea63eff9 100644 --- a/propagator/opentelemetry-propagator-b3/test-requirements.txt +++ b/propagator/opentelemetry-propagator-b3/test-requirements.txt @@ -1,19 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e opentelemetry-semantic-conventions diff --git a/propagator/opentelemetry-propagator-jaeger/py.typed b/propagator/opentelemetry-propagator-jaeger/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/propagator/opentelemetry-propagator-jaeger/pyproject.toml b/propagator/opentelemetry-propagator-jaeger/pyproject.toml index 9586fdf474..9bdf0513b0 100644 --- a/propagator/opentelemetry-propagator-jaeger/pyproject.toml +++ b/propagator/opentelemetry-propagator-jaeger/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/propagator/opentelemetry-propagator-jaeger/test-requirements.txt b/propagator/opentelemetry-propagator-jaeger/test-requirements.txt index 8aa93cc474..f1200ed9ee 100644 --- a/propagator/opentelemetry-propagator-jaeger/test-requirements.txt +++ b/propagator/opentelemetry-propagator-jaeger/test-requirements.txt @@ -1,19 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e opentelemetry-semantic-conventions diff --git a/scripts/semconv/generate.sh b/scripts/semconv/generate.sh index 57ae537bfe..12efd2b0b1 100755 --- a/scripts/semconv/generate.sh +++ b/scripts/semconv/generate.sh @@ -5,7 +5,7 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ROOT_DIR="${SCRIPT_DIR}/../../" # freeze the spec version to make SemanticAttributes generation reproducible -SEMCONV_VERSION=v1.25.0 +SEMCONV_VERSION=v1.26.0 OTEL_SEMCONV_GEN_IMG_VERSION=0.24.0 INCUBATING_DIR=_incubating cd ${SCRIPT_DIR} @@ -28,7 +28,13 @@ if ! grep -q $SEMCONV_VERSION "$SCHEMAS_PY_PATH"; then exit 1 fi -EXCLUDED_NAMESPACES="jvm aspnetcore dotnet signalr ios android" +# excluded namespaces will not be generated +# this behavior is fully controlled by jinja templates +EXCLUDED_NAMESPACES="jvm aspnetcore dotnet signalr ios android kestrel" + +# excluded attributes will be commented out in the generated code +# this behavior is fully controlled by jinja templates +EXCLUDED_ATTRIBUTES="messaging.client_id" generate() { TEMPLATE=$1 @@ -48,7 +54,8 @@ generate() { --file-per-group root_namespace \ -Dfilter=${FILTER} \ -Dstable_package=${STABLE_PACKAGE} \ - -Dexcluded_namespaces="$EXCLUDED_NAMESPACES" + -Dexcluded_namespaces="$EXCLUDED_NAMESPACES" \ + -Dexcluded_attributes="$EXCLUDED_ATTRIBUTES" } # stable attributes and metrics diff --git a/scripts/semconv/templates/semantic_attributes.j2 b/scripts/semconv/templates/semantic_attributes.j2 index 11908009ba..7ea1ffde7c 100644 --- a/scripts/semconv/templates/semantic_attributes.j2 +++ b/scripts/semconv/templates/semantic_attributes.j2 @@ -27,22 +27,25 @@ {%- endif -%} {%- endmacro -%} -{%- macro attribute_brief(attribute) -%} -""" +{%- macro attribute_brief(attribute, prefix) -%} +{%- if not prefix %}""" +{%- endif %} {%- if attribute | is_deprecated %} -Deprecated: {{ common.to_docstring(attribute.deprecated) }}. +{{ prefix }}Deprecated: {{ common.to_docstring(attribute.deprecated) }}. {%- elif attribute | is_stable and filter == "any" %} -Deprecated in favor of stable :py:const:`{{stable_class_ref(attribute_name(attribute), '.')}}`. +{{ prefix }}Deprecated in favor of stable :py:const:`{{stable_class_ref(attribute_name(attribute), '.')}}`. {%- else %} -{{ common.to_docstring(attribute.brief) }}. +{{ prefix }}{{ common.to_docstring(attribute.brief) }}. {%- if attribute.note %} -Note: {{ common.to_docstring(attribute.note | indent)}}. +{{ prefix }}Note: {{ common.to_docstring(attribute.note | indent)}}. {%- endif -%} {%- endif %} -""" +{%- if not prefix %} +"""{%- endif %} {%- endmacro -%} -{%- if root_namespace not in excluded_namespaces -%} +{%- if root_namespace not in excluded_namespaces.split(' ') -%} +{%- set excluded_attributes_list = excluded_attributes.split(' ') -%} {%- if filter != 'any' -%} {%- set filtered_attributes = attributes_and_templates | select(filter) | list -%} {%- else -%} @@ -58,6 +61,8 @@ Note: {{ common.to_docstring(attribute.note | indent)}}. {%- set filtered_enum_attributes = enum_attributes | list %} {%- endif -%} +from typing import Final + {{common.import_deprecated(filtered_enum_attributes)}} {% if filtered_enum_attributes | count > 0 %} @@ -67,21 +72,23 @@ from enum import Enum {% else %} {% endif %} + {% for attribute in filtered_attributes -%} -{{attribute_name(attribute)}} = "{{attribute.fqn}}" -{{attribute_brief(attribute)}} +{%- set prefix = "# " if attribute.fqn in excluded_attributes else "" -%} +{{prefix}}{{attribute_name(attribute)}}: Final = "{{attribute.fqn}}" +{{attribute_brief(attribute, prefix)}} {% endfor %} -{%- for attribute in filtered_enum_attributes -%} +{%- for attribute in filtered_enum_attributes | rejectattr("fqn", "in", excluded_attributes) -%} {%- set class_name = attribute.fqn | to_camelcase(True) ~ "Values" -%} {%- if attribute | is_deprecated %} -@deprecated(reason="The attribute {{attribute.fqn}} is deprecated - {{ common.to_docstring(attribute.deprecated) }}") +@deprecated(reason="The attribute {{attribute.fqn}} is deprecated - {{ common.to_docstring(attribute.deprecated) }}") # type: ignore {%- elif attribute | is_stable and filter == "any" %} -@deprecated(reason="Deprecated in favor of stable :py:const:`{{stable_class_ref(class_name, '.')}}`.") +@deprecated(reason="Deprecated in favor of stable :py:const:`{{stable_class_ref(class_name, '.')}}`.") # type: ignore {%- endif %} class {{class_name}}(Enum): {%- for member in attribute.attr_type.members %} - {{ member.member_id | to_const_name }} = {{ attribute | print_member_value(member) }} + {{ member.member_id | to_const_name }}: Final = {{ attribute | print_member_value(member) }} """{{ common.to_docstring(member.brief) }}.""" {%- endfor %} {%- endfor -%} diff --git a/scripts/semconv/templates/semantic_metrics.j2 b/scripts/semconv/templates/semantic_metrics.j2 index fed0e02c8f..e436df2aa5 100644 --- a/scripts/semconv/templates/semantic_metrics.j2 +++ b/scripts/semconv/templates/semantic_metrics.j2 @@ -66,12 +66,7 @@ Note: {{ common.to_docstring(metric.note | indent) }}. {% if filter == "any" %} from opentelemetry.metrics import Meter - {%- if metrics | selectattr("instrument", "equalto", "gauge") | list | count > 0 %} -from typing import Callable, Sequence -from opentelemetry.metrics import ObservableGauge - {%- endif %} - - {%- if metrics | selectattr("instrument", "equalto", "histogram") | list | count > 0 %} +{%- if metrics | selectattr("instrument", "equalto", "histogram") | list | count > 0 %} from opentelemetry.metrics import Histogram {%- endif %} @@ -82,6 +77,17 @@ from opentelemetry.metrics import UpDownCounter {%- if metrics | selectattr("instrument", "equalto", "counter") | list | count > 0 %} from opentelemetry.metrics import Counter {%- endif %} + + {%- if metrics | selectattr("instrument", "equalto", "gauge") | list | count > 0 %} +from typing import Callable, Generator, Iterable, Optional, Sequence, Union +from opentelemetry.metrics import CallbackOptions, ObservableGauge, Observation + +# pylint: disable=invalid-name +CallbackT = Union[ + Callable[[CallbackOptions], Iterable[Observation]], + Generator[Iterable[Observation], CallbackOptions, None], +] + {%- endif %} {%- endif -%} {%- endmacro-%} @@ -96,17 +102,19 @@ from opentelemetry.metrics import Counter {{ common.file_header()}} +from typing import Final {{ import_instrument_classes(filtered_metrics) }} {%- for metric in filtered_metrics %} -{{metric.metric_name | to_const_name}} = "{{metric.metric_name}}" +{% set const_name = metric.metric_name | to_const_name %} +{{const_name}}: Final = "{{metric.metric_name}}" {{metric_brief(metric, metric.metric_name | to_const_name) }} {% if filter == "any" %} {% set metric_name = metric.metric_name | replace(".", "_") %} {%- if metric.instrument == "gauge" %} -def create_{{ metric_name }}(meter: Meter, callback: Sequence[Callable]) -> {{to_python_instrument_type(metric.instrument)}}: +def create_{{ metric_name }}(meter: Meter, callbacks: Optional[Sequence[CallbackT]]) -> {{to_python_instrument_type(metric.instrument)}}: {%- else %} def create_{{ metric_name }}(meter: Meter) -> {{to_python_instrument_type(metric.instrument)}}: {%- endif %} @@ -115,9 +123,9 @@ def create_{{ metric_name }}(meter: Meter) -> {{to_python_instrument_type(metric """{{brief}}""" {%- endif %} return meter.create_{{to_python_instrument_factory(metric.instrument)}}( - name="{{ metric.metric_name }}", + name={{ const_name }}, {%- if metric.instrument == "gauge" %} - callback=callback, + callbacks=callbacks, {%- endif %} description="{{ metric.brief }}", unit="{{ metric.unit }}", diff --git a/shim/opentelemetry-opencensus-shim/pyproject.toml b/shim/opentelemetry-opencensus-shim/pyproject.toml index 02485dcade..b4fdfb6e9f 100644 --- a/shim/opentelemetry-opencensus-shim/pyproject.toml +++ b/shim/opentelemetry-opencensus-shim/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/shim/opentelemetry-opencensus-shim/test-requirements.txt b/shim/opentelemetry-opencensus-shim/test-requirements.txt index c09fe41986..22810bf4d6 100644 --- a/shim/opentelemetry-opencensus-shim/test-requirements.txt +++ b/shim/opentelemetry-opencensus-shim/test-requirements.txt @@ -1,37 +1,33 @@ asgiref==3.7.2 -attrs==23.2.0 cachetools==5.3.3 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 -flaky==3.7.0 google-api-core==2.17.1 google-auth==2.28.1 googleapis-common-protos==1.62.0 grpcio==1.62.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 opencensus==0.11.1 opencensus-context==0.1.3 opencensus-proto==0.1.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 pyasn1==0.5.1 pyasn1-modules==0.3.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 -requests==2.31.0 +pytest==7.4.4 +requests==2.32.3 rsa==4.9 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e tests/opentelemetry-test-utils diff --git a/shim/opentelemetry-opentracing-shim/pyproject.toml b/shim/opentelemetry-opentracing-shim/pyproject.toml index a9869f57f7..0345178f90 100644 --- a/shim/opentelemetry-opentracing-shim/pyproject.toml +++ b/shim/opentelemetry-opentracing-shim/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/shim/opentelemetry-opentracing-shim/test-requirements.txt b/shim/opentelemetry-opentracing-shim/test-requirements.txt index 1bf45ffec3..af2b495543 100644 --- a/shim/opentelemetry-opentracing-shim/test-requirements.txt +++ b/shim/opentelemetry-opentracing-shim/test-requirements.txt @@ -1,20 +1,16 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 opentracing==2.4.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e tests/opentelemetry-test-utils diff --git a/tests/opentelemetry-test-utils/pyproject.toml b/tests/opentelemetry-test-utils/pyproject.toml index b56e274f42..74314eb542 100644 --- a/tests/opentelemetry-test-utils/pyproject.toml +++ b/tests/opentelemetry-test-utils/pyproject.toml @@ -22,6 +22,8 @@ classifiers = [ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "asgiref ~= 3.0", diff --git a/tests/opentelemetry-test-utils/src/opentelemetry/test/metrictestutil.py b/tests/opentelemetry-test-utils/src/opentelemetry/test/metrictestutil.py index 08354bf0de..33f1039ef8 100644 --- a/tests/opentelemetry-test-utils/src/opentelemetry/test/metrictestutil.py +++ b/tests/opentelemetry-test-utils/src/opentelemetry/test/metrictestutil.py @@ -83,7 +83,7 @@ def _generate_gauge( data_points=[ NumberDataPoint( attributes=attributes, - start_time_unix_nano=1641946015139533244, + start_time_unix_nano=None, time_unix_nano=1641946016139533244, value=value, ) diff --git a/tests/opentelemetry-test-utils/test-requirements.txt b/tests/opentelemetry-test-utils/test-requirements.txt index 19b6fb58cb..8e9c26e925 100644 --- a/tests/opentelemetry-test-utils/test-requirements.txt +++ b/tests/opentelemetry-test-utils/test-requirements.txt @@ -1,19 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 -flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-api -e opentelemetry-sdk -e opentelemetry-semantic-conventions diff --git a/tests/opentelemetry-test-utils/tests/test_utils.py b/tests/opentelemetry-test-utils/tests/test_utils.py index cd0aa22f31..180fe55e6f 100644 --- a/tests/opentelemetry-test-utils/tests/test_utils.py +++ b/tests/opentelemetry-test-utils/tests/test_utils.py @@ -74,9 +74,8 @@ def raise_zero_division_error(): raise_zero_division_error() error_lines = error.exception.args[0].split("\n") + stripped_error_lines = [line.strip() for line in error_lines] - self.assertEqual( - error_lines[0].strip(), "Unexpected exception was raised:" - ) - self.assertEqual(error_lines[2].strip(), "raise_zero_division_error()") - self.assertEqual(error_lines[5].strip(), "raise ZeroDivisionError()") + self.assertIn("Unexpected exception was raised:", stripped_error_lines) + self.assertIn("raise_zero_division_error()", stripped_error_lines) + self.assertIn("raise ZeroDivisionError()", stripped_error_lines) diff --git a/tests/w3c_tracecontext_validation_server.py b/tests/w3c_tracecontext_validation_server.py index 5c47708ee1..732ca1e974 100644 --- a/tests/w3c_tracecontext_validation_server.py +++ b/tests/w3c_tracecontext_validation_server.py @@ -70,6 +70,6 @@ def verify_tracecontext(): if __name__ == "__main__": try: - app.run(debug=True) + app.run(debug=False) finally: span_processor.shutdown() diff --git a/tox.ini b/tox.ini index 7c18460b19..dfa3edd028 100644 --- a/tox.ini +++ b/tox.ini @@ -5,83 +5,103 @@ skip_missing_interpreters = True envlist = ; Environments are organized by individual package, allowing ; for specifying supported Python versions per package. - py3{8,9,10,11}-opentelemetry-api - pypy3-opentelemetry-api + + py3{8,9,10,11,12}-test-opentelemetry-api + pypy3-test-opentelemetry-api + lint-opentelemetry-api ; The numbers at the end of the environment names ; below mean these dependencies are being used: ; 0: protobuf==3.20.3 ; 1: protobuf==4.25.3 - py3{8,9,10,11}-opentelemetry-protobuf-{0,1} - pypy3-opentelemetry-protobuf-{0,1} + py3{8,9,10,11,12}-test-opentelemetry-proto-{0,1} + pypy3-test-opentelemetry-proto-{0,1} + lint-opentelemetry-proto - py3{8,9,10,11}-opentelemetry-sdk + py3{8,9,10,11,12}-opentelemetry-sdk pypy3-opentelemetry-sdk + lint-opentelemetry-sdk + benchmark-opentelemetry-sdk - py3{8,9,10,11}-opentelemetry-semantic-conventions - pypy3-opentelemetry-semantic-conventions + py3{8,9,10,11,12}-test-opentelemetry-semantic-conventions + pypy3-test-opentelemetry-semantic-conventions + lint-opentelemetry-semantic-conventions - ; docs/getting-started - py3{8,9,10,11}-opentelemetry-getting-started - pypy3-opentelemetry-getting-started + py3{8,9,10,11,12}-test-opentelemetry-getting-started + lint-opentelemetry-getting-started - py3{8,9,10,11}-opentelemetry-opentracing-shim - pypy3-opentelemetry-opentracing-shim + py3{8,9,10,11,12}-test-opentelemetry-opentracing-shim + pypy3-test-opentelemetry-opentracing-shim + lint-opentelemetry-opentracing-shim - py3{8,9,10,11}-opentelemetry-opencensus-shim + py3{8,9,10,11,12}-test-opentelemetry-opencensus-shim ; opencensus-shim intentionally excluded from pypy3 (grpcio install fails) + lint-opentelemetry-opencensus-shim - py3{8,9,10,11}-opentelemetry-exporter-opencensus + py3{8,9,10,11,12}-test-opentelemetry-exporter-opencensus ; exporter-opencensus intentionally excluded from pypy3 + lint-opentelemetry-exporter-opencensus ; The numbers at the end of the environment names ; below mean these dependencies are being used: ; 0: protobuf==3.20.3 ; 1: protobuf==4.25.3 - py3{8,9,10,11}-opentelemetry-exporter-otlp-proto-common-{0,1} - pypy3-opentelemetry-exporter-otlp-proto-common-{0,1} + py3{8,9,10,11,12}-test-opentelemetry-exporter-otlp-proto-common-{0,1} + pypy3-test-opentelemetry-exporter-otlp-proto-common-{0,1} + lint-opentelemetry-exporter-otlp-proto-common ; opentelemetry-exporter-otlp - py3{8,9,10,11}-opentelemetry-exporter-otlp-combined + py3{8,9,10,11,12}-test-opentelemetry-exporter-otlp-combined ; intentionally excluded from pypy3 + lint-opentelemetry-exporter-otlp-combined ; The numbers at the end of the environment names ; below mean these dependencies are being used: ; 0: protobuf==3.20.3 ; 1: protobuf==4.25.3 - py3{8,9,10,11}-opentelemetry-exporter-otlp-proto-grpc-{0,1} + py3{8,9,10,11,12}-test-opentelemetry-exporter-otlp-proto-grpc-{0,1} ; intentionally excluded from pypy3 + lint-opentelemetry-exporter-otlp-proto-grpc + benchmark-opentelemetry-exporter-otlp-proto-grpc ; The numbers at the end of the environment names ; below mean these dependencies are being used: ; 0: protobuf==3.20.3 ; 1: protobuf==4.25.3 - py3{8,9,10,11}-opentelemetry-exporter-otlp-proto-http-{0,1} - pypy3-opentelemetry-exporter-otlp-proto-http-{0,1} + py3{8,9,10,11,12}-test-opentelemetry-exporter-otlp-proto-http-{0,1} + pypy3-test-opentelemetry-exporter-otlp-proto-http-{0,1} + lint-opentelemetry-exporter-otlp-proto-http - py3{8,9,10,11}-opentelemetry-exporter-prometheus - pypy3-opentelemetry-exporter-prometheus + py3{8,9,10,11,12}-test-opentelemetry-exporter-prometheus + pypy3-test-opentelemetry-exporter-prometheus + lint-opentelemetry-exporter-prometheus ; opentelemetry-exporter-zipkin - py3{8,9,10,11}-opentelemetry-exporter-zipkin-combined - pypy3-opentelemetry-exporter-zipkin-combined + py3{8,9,10,11,12}-test-opentelemetry-exporter-zipkin-combined + pypy3-test-opentelemetry-exporter-zipkin-combined + lint-opentelemetry-exporter-zipkin-combined - py3{8,9,10,11}-opentelemetry-exporter-zipkin-proto-http - pypy3-opentelemetry-exporter-zipkin-proto-http + py3{8,9,10,11,12}-test-opentelemetry-exporter-zipkin-proto-http + pypy3-test-opentelemetry-exporter-zipkin-proto-http + lint-opentelemetry-exporter-zipkin-proto-http - py3{8,9,10,11}-opentelemetry-exporter-zipkin-json - pypy3-opentelemetry-exporter-zipkin-json + py3{8,9,10,11,12}-test-opentelemetry-exporter-zipkin-json + pypy3-test-opentelemetry-exporter-zipkin-json + lint-opentelemetry-exporter-zipkin-json - py3{8,9,10,11}-opentelemetry-propagator-b3 - pypy3-opentelemetry-propagator-b3 + py3{8,9,10,11,12}-test-opentelemetry-propagator-b3 + pypy3-test-opentelemetry-propagator-b3 + lint-opentelemetry-propagator-b3 + benchmark-opentelemetry-propagator-b3 - py3{8,9,10,11}-opentelemetry-propagator-jaeger - pypy3-opentelemetry-propagator-jaeger + py3{8,9,10,11,12}-test-opentelemetry-propagator-jaeger + pypy3-test-opentelemetry-propagator-jaeger + lint-opentelemetry-propagator-jaeger - py3{8,9,10,11}-opentelemetry-test-utils - pypy3-opentelemetry-test-utils + py3{8,9,10,11,12}-test-opentelemetry-test-utils + pypy3-test-opentelemetry-test-utils + lint-opentelemetry-test-utils - lint spellcheck tracecontext mypy,mypyinstalled @@ -91,13 +111,9 @@ envlist = [testenv] deps = - -c dev-requirements.txt - opentelemetry: pytest - opentelemetry: pytest-benchmark - opentelemetry: flaky + lint: -r dev-requirements.txt coverage: pytest coverage: pytest-cov - mypy,mypyinstalled: mypy ; proto 3 and 4 tests install the respective version of protobuf proto3: protobuf~=3.19.0 @@ -113,16 +129,20 @@ setenv = commands_pre = + mypy,mypyinstalled: pip install -r {toxinidir}/mypy-requirements.txt + api: pip install -r {toxinidir}/opentelemetry-api/test-requirements.txt sdk: pip install -r {toxinidir}/opentelemetry-sdk/test-requirements.txt + benchmark-opentelemetry-sdk: pip install -r {toxinidir}/opentelemetry-sdk/benchmark-requirements.txt semantic-conventions: pip install -r {toxinidir}/opentelemetry-semantic-conventions/test-requirements.txt test-utils: pip install -r {toxinidir}/tests/opentelemetry-test-utils/test-requirements.txt - protobuf-0: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-0.txt - protobuf-1: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-1.txt + opentelemetry-proto-0: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-0.txt + opentelemetry-proto-1: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-1.txt + lint-opentelemetry-proto: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-1.txt getting-started: pip install -r {toxinidir}/docs/getting_started/tests/requirements.txt getting-started: pip install -e {env:CONTRIB_REPO}\#egg=opentelemetry-util-http&subdirectory=util/opentelemetry-util-http @@ -135,14 +155,18 @@ commands_pre = exporter-otlp-proto-common-0: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt exporter-otlp-proto-common-1: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt + lint-opentelemetry-exporter-otlp-proto-common: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt exporter-otlp-combined: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp/test-requirements.txt opentelemetry-exporter-otlp-proto-grpc-0: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt opentelemetry-exporter-otlp-proto-grpc-1: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt + lint-opentelemetry-exporter-otlp-proto-grpc: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt + benchmark-exporter-otlp-proto-grpc: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/benchmark-requirements.txt opentelemetry-exporter-otlp-proto-http-0: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt opentelemetry-exporter-otlp-proto-http-1: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt + lint-opentelemetry-exporter-otlp-proto-http: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt opentracing-shim: pip install -r {toxinidir}/shim/opentelemetry-opentracing-shim/test-requirements.txt @@ -157,6 +181,7 @@ commands_pre = exporter-zipkin-json: pip install -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt propagator-b3: pip install -r {toxinidir}/propagator/opentelemetry-propagator-b3/test-requirements.txt + benchmark-opentelemetry-propagator-b3: pip install -r {toxinidir}/propagator/opentelemetry-propagator-b3/benchmark-requirements.txt propagator-jaeger: pip install -r {toxinidir}/propagator/opentelemetry-propagator-jaeger/test-requirements.txt @@ -169,31 +194,145 @@ commands_pre = mypyinstalled: pip install file://{toxinidir}/opentelemetry-api/ commands = - api: pytest {toxinidir}/opentelemetry-api/tests {posargs} - sdk: pytest {toxinidir}/opentelemetry-sdk/tests {posargs} - protobuf: pytest {toxinidir}/opentelemetry-proto/tests {posargs} - semantic-conventions: pytest {toxinidir}/opentelemetry-semantic-conventions/tests {posargs} - getting-started: pytest {toxinidir}/docs/getting_started/tests {posargs} - opentracing-shim: pytest {toxinidir}/shim/opentelemetry-opentracing-shim/tests {posargs} - opencensus-shim: pytest {toxinidir}/shim/opentelemetry-opencensus-shim/tests {posargs} - - exporter-opencensus: pytest {toxinidir}/exporter/opentelemetry-exporter-opencensus/tests {posargs} - exporter-otlp-proto-common: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/tests {posargs} - exporter-otlp-combined: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp/tests {posargs} - exporter-otlp-proto-grpc: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/tests {posargs} - exporter-otlp-proto-http: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/tests {posargs} - exporter-prometheus: pytest {toxinidir}/exporter/opentelemetry-exporter-prometheus/tests {posargs} - exporter-zipkin-combined: pytest {toxinidir}/exporter/opentelemetry-exporter-zipkin/tests {posargs} - exporter-zipkin-proto-http: pytest {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/tests {posargs} - exporter-zipkin-json: pytest {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/tests {posargs} - - propagator-b3: pytest {toxinidir}/propagator/opentelemetry-propagator-b3/tests {posargs} - propagator-jaeger: pytest {toxinidir}/propagator/opentelemetry-propagator-jaeger/tests {posargs} - test-utils: pytest {toxinidir}/tests/opentelemetry-test-utils/tests {posargs} + test-opentelemetry-api: pytest {toxinidir}/opentelemetry-api/tests {posargs} + lint-opentelemetry-api: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-api + lint-opentelemetry-api: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-api + lint-opentelemetry-api: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-api + lint-opentelemetry-api: pylint {toxinidir}/opentelemetry-api/src/opentelemetry + lint-opentelemetry-api: pylint {toxinidir}/opentelemetry-api/tests + + test-opentelemetry-sdk: pytest {toxinidir}/opentelemetry-sdk/tests {posargs} + lint-opentelemetry-sdk: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-sdk + lint-opentelemetry-sdk: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-sdk + lint-opentelemetry-sdk: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-sdk + lint-opentelemetry-sdk: pylint {toxinidir}/opentelemetry-sdk/src/opentelemetry + lint-opentelemetry-sdk: pylint {toxinidir}/opentelemetry-sdk/tests + benchmark-opentelemetry-sdk: pytest {toxinidir}/opentelemetry-sdk/benchmarks {posargs} --benchmark-json=sdk-benchmark.json + + test-opentelemetry-proto: pytest {toxinidir}/opentelemetry-proto/tests {posargs} + lint-opentelemetry-proto: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-proto + lint-opentelemetry-proto: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-proto + lint-opentelemetry-proto: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-proto + lint-opentelemetry-proto: pylint {toxinidir}/opentelemetry-proto/src/opentelemetry + lint-opentelemetry-proto: pylint {toxinidir}/opentelemetry-proto/tests + + test-opentelemetry-semantic-conventions: pytest {toxinidir}/opentelemetry-semantic-conventions/tests {posargs} + lint-opentelemetry-semantic-conventions: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-semantic-conventions + lint-opentelemetry-semantic-conventions: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-semantic-conventions + lint-opentelemetry-semantic-conventions: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-semantic-conventions + lint-opentelemetry-semantic-conventions: pylint {toxinidir}/opentelemetry-semantic-conventions/src/opentelemetry + lint-opentelemetry-semantic-conventions: pylint {toxinidir}/opentelemetry-semantic-conventions/tests + + test-opentelemetry-getting-started: pytest {toxinidir}/docs/getting_started/tests {posargs} + lint-opentelemetry-getting-started: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/docs/getting_started + lint-opentelemetry-getting-started: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/docs/getting_started + lint-opentelemetry-getting-started: flake8 --config {toxinidir}/.flake8 {toxinidir}/docs/getting_started + lint-opentelemetry-getting-started: pylint {toxinidir}/docs/getting_started + + test-opentelemetry-opentracing-shim: pytest {toxinidir}/shim/opentelemetry-opentracing-shim/tests {posargs} + lint-opentelemetry-opentracing-shim: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/shim/opentelemetry-opentracing-shim + lint-opentelemetry-opentracing-shim: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/shim/opentelemetry-opentracing-shim + lint-opentelemetry-opentracing-shim: flake8 --config {toxinidir}/.flake8 {toxinidir}/shim/opentelemetry-opentracing-shim + lint-opentelemetry-opentracing-shim: pylint {toxinidir}/shim/opentelemetry-opentracing-shim/src/opentelemetry + lint-opentelemetry-opentracing-shim: pylint {toxinidir}/shim/opentelemetry-opentracing-shim/tests + + test-opentelemetry-opencensus-shim: pytest {toxinidir}/shim/opentelemetry-opencensus-shim/tests {posargs} + lint-opentelemetry-opencensus-shim: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/shim/opentelemetry-opencensus-shim + lint-opentelemetry-opencensus-shim: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/shim/opentelemetry-opencensus-shim + lint-opentelemetry-opencensus-shim: flake8 --config {toxinidir}/.flake8 {toxinidir}/shim/opentelemetry-opencensus-shim + lint-opentelemetry-opencensus-shim: pylint {toxinidir}/shim/opentelemetry-opencensus-shim/src/opentelemetry + lint-opentelemetry-opencensus-shim: pylint {toxinidir}/shim/opentelemetry-opencensus-shim/tests + + test-opentelemetry-exporter-opencensus: pytest {toxinidir}/exporter/opentelemetry-exporter-opencensus/tests {posargs} + lint-opentelemetry-exporter-opencensus: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-opencensus + lint-opentelemetry-exporter-opencensus: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-opencensus + lint-opentelemetry-exporter-opencensus: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-opencensus + lint-opentelemetry-exporter-opencensus: pylint {toxinidir}/exporter/opentelemetry-exporter-opencensus/src/opentelemetry + lint-opentelemetry-exporter-opencensus: pylint {toxinidir}/exporter/opentelemetry-exporter-opencensus/tests + + test-opentelemetry-exporter-otlp-proto-common: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/tests {posargs} + lint-opentelemetry-exporter-otlp-proto-common: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common + lint-opentelemetry-exporter-otlp-proto-common: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common + lint-opentelemetry-exporter-otlp-proto-common: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common + lint-opentelemetry-exporter-otlp-proto-common: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry + lint-opentelemetry-exporter-otlp-proto-common: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/tests + + test-opentelemetry-exporter-otlp-combined: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp/tests {posargs} + lint-opentelemetry-exporter-otlp-combined: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-otlp + lint-opentelemetry-exporter-otlp-combined: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-otlp + lint-opentelemetry-exporter-otlp-combined: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-otlp + lint-opentelemetry-exporter-otlp-combined: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp/src/opentelemetry + lint-opentelemetry-exporter-otlp-combined: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp/tests + + test-opentelemetry-exporter-otlp-proto-grpc: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/tests {posargs} + lint-opentelemetry-exporter-otlp-proto-grpc: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc + lint-opentelemetry-exporter-otlp-proto-grpc: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc + lint-opentelemetry-exporter-otlp-proto-grpc: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc + lint-opentelemetry-exporter-otlp-proto-grpc: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry + lint-opentelemetry-exporter-otlp-proto-grpc: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/tests + benchmark-opentelemetry-exporter-otlp-proto-grpc: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/benchmarks {posargs} --benchmark-json=exporter-otlp-proto-grpc-benchmark.json + + test-opentelemetry-exporter-otlp-proto-http: pytest {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/tests {posargs} + lint-opentelemetry-exporter-otlp-proto-http: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http + lint-opentelemetry-exporter-otlp-proto-http: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http + lint-opentelemetry-exporter-otlp-proto-http: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http + lint-opentelemetry-exporter-otlp-proto-http: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry + lint-opentelemetry-exporter-otlp-proto-http: pylint {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/tests + + test-opentelemetry-exporter-prometheus: pytest {toxinidir}/exporter/opentelemetry-exporter-prometheus/tests {posargs} + lint-opentelemetry-exporter-prometheus: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-prometheus + lint-opentelemetry-exporter-prometheus: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-prometheus + lint-opentelemetry-exporter-prometheus: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-prometheus + lint-opentelemetry-exporter-prometheus: pylint {toxinidir}/exporter/opentelemetry-exporter-prometheus/src/opentelemetry + lint-opentelemetry-exporter-prometheus: pylint {toxinidir}/exporter/opentelemetry-exporter-prometheus/tests + + test-opentelemetry-exporter-zipkin-combined: pytest {toxinidir}/exporter/opentelemetry-exporter-zipkin/tests {posargs} + lint-opentelemetry-exporter-zipkin-combined: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-zipkin + lint-opentelemetry-exporter-zipkin-combined: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-zipkin + lint-opentelemetry-exporter-zipkin-combined: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-zipkin + lint-opentelemetry-exporter-zipkin-combined: pylint {toxinidir}/exporter/opentelemetry-exporter-zipkin/src/opentelemetry + lint-opentelemetry-exporter-zipkin-combined: pylint {toxinidir}/exporter/opentelemetry-exporter-zipkin/tests + + test-opentelemetry-exporter-zipkin-proto-http: pytest {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/tests {posargs} + lint-opentelemetry-exporter-zipkin-proto-http: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http + lint-opentelemetry-exporter-zipkin-proto-http: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http + lint-opentelemetry-exporter-zipkin-proto-http: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http + lint-opentelemetry-exporter-zipkin-proto-http: pylint {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/src/opentelemetry + lint-opentelemetry-exporter-zipkin-proto-http: pylint {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/tests + + test-opentelemetry-exporter-zipkin-json: pytest {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/tests {posargs} + lint-opentelemetry-exporter-zipkin-json: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-zipkin-json + lint-opentelemetry-exporter-zipkin-json: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-zipkin-json + lint-opentelemetry-exporter-zipkin-json: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-zipkin-json + lint-opentelemetry-exporter-zipkin-json: pylint {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry + lint-opentelemetry-exporter-zipkin-json: pylint {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/tests + + test-opentelemetry-propagator-b3: pytest {toxinidir}/propagator/opentelemetry-propagator-b3/tests {posargs} + lint-opentelemetry-propagator-b3: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-b3 + lint-opentelemetry-propagator-b3: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-b3 + lint-opentelemetry-propagator-b3: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-b3 + lint-opentelemetry-propagator-b3: pylint {toxinidir}/propagator/opentelemetry-propagator-b3/src/opentelemetry + lint-opentelemetry-propagator-b3: pylint {toxinidir}/propagator/opentelemetry-propagator-b3/tests + benchmark-opentelemetry-propagator-b3: pytest {toxinidir}/propagator/opentelemetry-propagator-b3/benchmarks {posargs} --benchmark-json=propagator-b3-benchmark.json + + test-opentelemetry-propagator-jaeger: pytest {toxinidir}/propagator/opentelemetry-propagator-jaeger/tests {posargs} + lint-opentelemetry-propagator-jaeger: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-jaeger + lint-opentelemetry-propagator-jaeger: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-jaeger + lint-opentelemetry-propagator-jaeger: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-jaeger + lint-opentelemetry-propagator-jaeger: pylint {toxinidir}/propagator/opentelemetry-propagator-jaeger/src/opentelemetry + lint-opentelemetry-propagator-jaeger: pylint {toxinidir}/propagator/opentelemetry-propagator-jaeger/tests + + test-opentelemetry-test-utils: pytest {toxinidir}/tests/opentelemetry-test-utils/tests {posargs} + lint-opentelemetry-test-utils: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/tests/opentelemetry-test-utils + lint-opentelemetry-test-utils: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/tests/opentelemetry-test-utils + lint-opentelemetry-test-utils: flake8 --config {toxinidir}/.flake8 {toxinidir}/tests/opentelemetry-test-utils + lint-opentelemetry-test-utils: pylint {toxinidir}/tests/opentelemetry-test-utils/src/opentelemetry + lint-opentelemetry-test-utils: pylint {toxinidir}/tests/opentelemetry-test-utils/tests coverage: {toxinidir}/scripts/coverage.sh mypy: mypy --install-types --non-interactive --namespace-packages --explicit-package-bases opentelemetry-api/src/opentelemetry/ + mypy: mypy --install-types --non-interactive --namespace-packages --explicit-package-bases opentelemetry-semantic-conventions/src/opentelemetry/semconv/ ; For test code, we don't want to enforce the full mypy strictness mypy: mypy --install-types --non-interactive --namespace-packages --config-file=mypy-relaxed.ini opentelemetry-api/tests/ @@ -202,43 +341,25 @@ commands = ; implicit Any due to unfollowed import would result). mypyinstalled: mypy --install-types --non-interactive --namespace-packages opentelemetry-api/tests/mypysmoke.py --strict -[testenv:spellcheck] +[testenv:lint] basepython: python3 recreate = True deps = - codespell==2.2.6 + -r dev-requirements.txt commands = - codespell + black --config {toxinidir}/pyproject.toml {toxinidir} --diff --check + isort --settings-path {toxinidir}/.isort.cfg {toxinidir} --diff --check-only + flake8 --config {toxinidir}/.flake8 {toxinidir} -[testenv:lint] +[testenv:spellcheck] basepython: python3 recreate = True deps = - -r dev-requirements.txt - -commands_pre = - pip install -r {toxinidir}/opentelemetry-api/test-requirements.txt \ - -r {toxinidir}/opentelemetry-sdk/test-requirements.txt \ - -r {toxinidir}/opentelemetry-semantic-conventions/test-requirements.txt \ - -r {toxinidir}/opentelemetry-proto/test-requirements-0.txt \ - -r {toxinidir}/shim/opentelemetry-opentracing-shim/test-requirements.txt \ - -r {toxinidir}/shim/opentelemetry-opencensus-shim/test-requirements.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-opencensus/test-requirements.txt \ - -r {toxinidir}/tests/opentelemetry-test-utils/test-requirements.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-prometheus/test-requirements.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-otlp/test-requirements.txt \ - -r {toxinidir}/exporter/opentelemetry-exporter-zipkin/test-requirements.txt \ - -r {toxinidir}/propagator/opentelemetry-propagator-b3/test-requirements.txt \ - -r {toxinidir}/propagator/opentelemetry-propagator-jaeger/test-requirements.txt + codespell==2.2.6 commands = - python scripts/eachdist.py lint --check-only + codespell [testenv:docs] basepython: python3