From d60f9a159fc3d6c3cc04eaf4d6ab567d175eb151 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:36:08 -0500 Subject: [PATCH 01/31] Bump actions/checkout from 3 to 4 (#220) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- .github/workflows/cpp_format_tools.yml | 2 +- .github/workflows/markdown.yml | 2 +- .github/workflows/protobuf-dockerimage.yml | 2 +- .github/workflows/schema_tools.yml | 2 +- .github/workflows/semconvgen.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cpp_format_tools.yml b/.github/workflows/cpp_format_tools.yml index b4c94ea3..c833c331 100644 --- a/.github/workflows/cpp_format_tools.yml +++ b/.github/workflows/cpp_format_tools.yml @@ -13,7 +13,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build the Docker image run: docker build cpp_format_tools/. -t cpp_format_tools diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index 6e75c60a..250bd8de 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: install markdownlint run: sudo npm install -g markdownlint-cli diff --git a/.github/workflows/protobuf-dockerimage.yml b/.github/workflows/protobuf-dockerimage.yml index fdb85216..ca101943 100644 --- a/.github/workflows/protobuf-dockerimage.yml +++ b/.github/workflows/protobuf-dockerimage.yml @@ -17,7 +17,7 @@ jobs: TARGETARCH: [amd64] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build the Docker image run: docker build protobuf/. -t build-protobuf env: diff --git a/.github/workflows/schema_tools.yml b/.github/workflows/schema_tools.yml index 5844fade..193c96d9 100644 --- a/.github/workflows/schema_tools.yml +++ b/.github/workflows/schema_tools.yml @@ -13,7 +13,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build the Docker image run: docker build schemas/. -t build-tool-schemas diff --git a/.github/workflows/semconvgen.yml b/.github/workflows/semconvgen.yml index 9d227904..f0aba77e 100644 --- a/.github/workflows/semconvgen.yml +++ b/.github/workflows/semconvgen.yml @@ -16,7 +16,7 @@ jobs: run: working-directory: semantic-conventions/ steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.x' @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-latest needs: tests steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - name: Build the wheel run: | From 4a04fcad1a8fe36dfadf31ec47ccdb564cee4096 Mon Sep 17 00:00:00 2001 From: Kenny Guo <110429254+kennykguo@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:38:17 -0500 Subject: [PATCH 02/31] Update README.md (#252) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Will Hegedus Co-authored-by: Jesse <83730324+dev-jesse@users.noreply.github.com> Co-authored-by: Josh Suereth --- semantic-conventions/README.md | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index 9d1bc5a7..b62da331 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -92,31 +92,13 @@ semantic conventions that have the tag `network`. The image supports [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) templates to generate code from the models. -For example, opentelemetry-java [generates typed constants for semantic conventions](https://github.com/open-telemetry/opentelemetry-java/blob/main/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java) -using [this template](https://github.com/open-telemetry/opentelemetry-java/blob/main/buildscripts/semantic-convention/templates/SemanticAttributes.java.j2). +For example, opentelemetry-java generates typed constants for semantic conventions. Refer to https://github.com/open-telemetry/semantic-conventions-java for all semantic conventions. The commands used to generate that are -[here in the opentelemetry-java repo](https://github.com/open-telemetry/opentelemetry-java/blob/main/buildscripts/semantic-convention/generate.sh). -Note especially the `docker run` commands. For example to generate the aforementioned `SemanticAttributes.java`, -the following command is used: - -```bash -docker run --rm \ - -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/trace:/source \ - -v ${SCRIPT_DIR}/templates:/templates \ - -v ${ROOT_DIR}/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/:/output \ - otel/semconvgen:$GENERATOR_VERSION \ - --yaml-root /source \ - code \ - --template /templates/SemanticAttributes.java.j2 \ - --output /output/SemanticAttributes.java \ - -Dclass=SemanticAttributes \ - -DschemaUrl=$SCHEMA_URL \ - -Dpkg=io.opentelemetry.semconv.trace.attributes -``` +[here in the semantic-conventions-java repo](https://github.com/open-telemetry/semantic-conventions-java/blob/2be178a7fd62d1073fa9b4f0f0520772a6496e0b/build.gradle.kts#L96-L141) By default, all models are fed into the specified template at once, i.e. only a single file is generated. -This is helpful to generate constants for the semantic attributes, [example from opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java/tree/main/buildscripts/semantic-convention). +This is helpful to generate constants for the semantic attributes, [example from opentelemetry-java](https://github.com/open-telemetry/semantic-conventions-java#generating-semantic-conventions). If the parameter `--file-per-group {pattern}` is set, a single yaml model is fed into the template and the value of `pattern` is resolved from the model and attached as prefix to the output argument. From e106f1ffebc7d6c9040d8b5e5bd9b0744fa4bb35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 17:58:09 -0500 Subject: [PATCH 03/31] Bump go.opentelemetry.io/otel/schema from 0.0.4 to 0.0.7 in /schemas (#219) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- schemas/go.mod | 3 +-- schemas/go.sum | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/schemas/go.mod b/schemas/go.mod index b3306fad..62661150 100644 --- a/schemas/go.mod +++ b/schemas/go.mod @@ -5,12 +5,11 @@ go 1.17 require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/stretchr/testify v1.8.4 - go.opentelemetry.io/otel/schema v0.0.4 + go.opentelemetry.io/otel/schema v0.0.7 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/schemas/go.sum b/schemas/go.sum index e37f0773..3c8b670a 100644 --- a/schemas/go.sum +++ b/schemas/go.sum @@ -1,4 +1,3 @@ -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -11,15 +10,12 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -go.opentelemetry.io/otel/schema v0.0.4 h1:xgqNjF5c5oy7F1PDm4q6a6wDUJTm+po4jEiXmcN5ncI= -go.opentelemetry.io/otel/schema v0.0.4/go.mod h1:LBBdyW+43YB5XmeQtH4b2ET5k0hx7dh3yJgRGY4Qw+A= +go.opentelemetry.io/otel/schema v0.0.7 h1:UslTvUtbFGmaxlpL1Z+aROrjsP7BRWt06Xxm5Ng/kAU= +go.opentelemetry.io/otel/schema v0.0.7/go.mod h1:jFb7hFFzdtEQ8R8HdbDGy4KuBctXNZwH1XJBP470kH4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From b3c1a54132e216ccece970ab801136ee6cea973e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 11:38:07 -0500 Subject: [PATCH 04/31] Bump pytest from 6.2.5 to 8.0.1 in /semantic-conventions (#265) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index 5add5f42..08878037 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,6 +1,6 @@ black==22.3.0 mypy==0.910 -pytest==6.2.5 +pytest==8.0.1 flake8==7.0.0 pylint==3.0.2 isort==5.12.0 From 6c80918abc054f370abf73da03ebba07bd4f7630 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 11:42:22 -0500 Subject: [PATCH 05/31] Bump docker/login-action from 2 to 3 (#221) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- .github/workflows/cpp_format_tools.yml | 2 +- .github/workflows/schema_tools.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cpp_format_tools.yml b/.github/workflows/cpp_format_tools.yml index c833c331..de41e921 100644 --- a/.github/workflows/cpp_format_tools.yml +++ b/.github/workflows/cpp_format_tools.yml @@ -20,7 +20,7 @@ jobs: - name: Login to GitHub Package Registry if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/schema_tools.yml b/.github/workflows/schema_tools.yml index 193c96d9..472fc259 100644 --- a/.github/workflows/schema_tools.yml +++ b/.github/workflows/schema_tools.yml @@ -20,7 +20,7 @@ jobs: - name: Login to GitHub Package Registry if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From fb8d90315a90d07dd36a39a87e0ed865c537f6ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 10:16:14 +0100 Subject: [PATCH 06/31] Bump isort from 5.12.0 to 5.13.2 in /semantic-conventions (#269) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index 08878037..de0bb2a6 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -3,4 +3,4 @@ mypy==0.910 pytest==8.0.1 flake8==7.0.0 pylint==3.0.2 -isort==5.12.0 +isort==5.13.2 From b008e6288a662ddb53473069fca4742edd5d06a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 10:24:10 +0100 Subject: [PATCH 07/31] Bump pylint from 3.0.2 to 3.0.3 in /semantic-conventions (#268) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index de0bb2a6..4b496dc3 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -2,5 +2,5 @@ black==22.3.0 mypy==0.910 pytest==8.0.1 flake8==7.0.0 -pylint==3.0.2 +pylint==3.0.3 isort==5.13.2 From c9eb885545bf3574f554c8fb8525570e1e5314e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:22:48 -0500 Subject: [PATCH 08/31] Bump golang from 1.20-alpine to 1.22-alpine in /schemas (#261) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- schemas/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/Dockerfile b/schemas/Dockerfile index 5a42d837..7634547a 100644 --- a/schemas/Dockerfile +++ b/schemas/Dockerfile @@ -1,6 +1,6 @@ ## Build ## -FROM golang:1.20-alpine AS build +FROM golang:1.22-alpine AS build WORKDIR /app From 1325b9cca50fc375ad2de6989ea6b9a577ad6004 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Sat, 24 Feb 2024 12:18:49 -0800 Subject: [PATCH 09/31] Add backward compatibility check mode (#271) --- semantic-conventions/CHANGELOG.md | 2 + semantic-conventions/README.md | 33 ++- semantic-conventions/dev-requirements.txt | 2 +- semantic-conventions/mypy.ini | 4 + semantic-conventions/setup.cfg | 1 + .../src/opentelemetry/semconv/main.py | 112 ++++++++-- .../semconv/model/semantic_attribute.py | 17 +- .../semconv/model/semantic_convention.py | 28 +-- .../semconv/templating/compatibility.py | 204 +++++++++++++++++ .../vnext.yaml | 24 ++ .../vprev.yaml | 23 ++ .../compat/attribute_type_changed/vnext.yaml | 25 +++ .../compat/attribute_type_changed/vprev.yaml | 23 ++ .../compat/enum_member_removed/vnext.yaml | 17 ++ .../compat/enum_member_removed/vprev.yaml | 17 ++ .../data/compat/enum_type_changed/vnext.yaml | 17 ++ .../data/compat/enum_type_changed/vprev.yaml | 17 ++ .../data/compat/enum_value_changed/vnext.yaml | 17 ++ .../data/compat/enum_value_changed/vprev.yaml | 17 ++ .../compat/metric_attribute_added/vnext.yaml | 30 +++ .../compat/metric_attribute_added/vprev.yaml | 29 +++ .../metric_instrument_changed/vnext.yaml | 23 ++ .../metric_instrument_changed/vprev.yaml | 23 ++ .../metric_stable_to_experimental/vnext.yaml | 23 ++ .../metric_stable_to_experimental/vprev.yaml | 23 ++ .../compat/metric_unit_changed/vnext.yaml | 23 ++ .../compat/metric_unit_changed/vprev.yaml | 23 ++ .../data/compat/removed_attribute/vnext.yaml | 6 + .../data/compat/removed_attribute/vprev.yaml | 22 ++ .../src/tests/data/compat/success/vnext.yaml | 60 +++++ .../src/tests/data/compat/success/vprev.yaml | 50 +++++ .../src/tests/data/jinja/metrics/semconv.yml | 30 +++ .../semconv/templating/test_compatibility.py | 208 ++++++++++++++++++ 33 files changed, 1134 insertions(+), 39 deletions(-) create mode 100644 semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py create mode 100644 semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/attribute_type_changed/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_attribute_added/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_attribute_added/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_instrument_changed/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_instrument_changed/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_unit_changed/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/metric_unit_changed/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/removed_attribute/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/compat/success/vnext.yaml create mode 100644 semantic-conventions/src/tests/data/compat/success/vprev.yaml create mode 100644 semantic-conventions/src/tests/data/jinja/metrics/semconv.yml create mode 100644 semantic-conventions/src/tests/semconv/templating/test_compatibility.py diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index 8b74cb31..cbd1ff8f 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -6,6 +6,8 @@ Please update the changelog as part of any significant pull request. - BREAKING: Make stability and deprecation independent properties. ([#244](https://github.com/open-telemetry/build-tools/pull/244)) +- Add backward-compatibility check mode. + ([#271](https://github.com/open-telemetry/build-tools/pull/271)) ## v0.23.0 diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index b62da331..9826abcb 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -85,8 +85,8 @@ convention that have the tag `network`. `` will print the constraints and attributes of both `http` and `http.server` semantic conventions that have the tag `network`. -`` will print a table describing a single metric -`http.server.active_requests`. +`` will print a table describing a single metric +`http.server.active_requests`. ## Code Generator @@ -116,3 +116,32 @@ comma using the `--parameters [{key=value},]+` or `-D` flag. The image also supports customising [Whitespace Control in Jinja templates](https://jinja.palletsprojects.com/en/3.1.x/templates/#whitespace-control) via the additional flag `--trim-whitespace`. Providing the flag will enable both `lstrip_blocks` and `trim_blocks`. + +## Version compatibility check + +You can check compatibility between the local one specified with `--yaml-root` and sepcific OpenTelemetry semantic convention version using the following command: + +```bash +docker run --rm otel/semconvgen --yaml-root {yaml_folder} compatibility --previous-version {semconv version} +``` + +The `{semconv version}` (e.g. `1.24.0`) is the previously released version of semantic conventions. + +Following checks are performed + +- On all attributes and metrics (experimental and stable): + - attributes and metrics must not be removed. + +- On stable attributes and attribute templates: + - stability must not be changed + - the type of attribute must not be changed + - enum attribute: type of value must not be changed + - enum attribute: members must not be removed (changing `id` field is allowed, as long as `value` does not change) +- On stable metrics: + - stability must not be changed + - instrument and unit must not be changed + - new attributes should not be added. + This check does not take into account opt-in attributes. Adding new attributes to metric is not always breaking, + so it's considered non-critical and it's possible to suppress it with `--ignore-warnings` + + diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index 4b496dc3..6ec71734 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -3,4 +3,4 @@ mypy==0.910 pytest==8.0.1 flake8==7.0.0 pylint==3.0.3 -isort==5.13.2 +isort==5.13.2 \ No newline at end of file diff --git a/semantic-conventions/mypy.ini b/semantic-conventions/mypy.ini index 9ecdc1d5..a8dff7d7 100644 --- a/semantic-conventions/mypy.ini +++ b/semantic-conventions/mypy.ini @@ -5,3 +5,7 @@ ignore_missing_imports = True [mypy-mistune.*] ignore_missing_imports = True + +[mypy-requests.*] +ignore_missing_imports = True + diff --git a/semantic-conventions/setup.cfg b/semantic-conventions/setup.cfg index ce15e71c..0d1cc511 100644 --- a/semantic-conventions/setup.cfg +++ b/semantic-conventions/setup.cfg @@ -40,6 +40,7 @@ install_requires = ruamel.yaml~=0.16 Jinja2~=3.0 mistune==2.0.0a6 + requests==2.31.0 [options.packages.find] where = src diff --git a/semantic-conventions/src/opentelemetry/semconv/main.py b/semantic-conventions/src/opentelemetry/semconv/main.py index ce144d94..461d0c28 100644 --- a/semantic-conventions/src/opentelemetry/semconv/main.py +++ b/semantic-conventions/src/opentelemetry/semconv/main.py @@ -16,25 +16,33 @@ import argparse import glob +import os import sys +import tempfile +import zipfile from typing import List +import requests + from opentelemetry.semconv.model.semantic_convention import ( CONVENTION_CLS_BY_GROUP_TYPE, SemanticConventionSet, ) from opentelemetry.semconv.templating.code import CodeRenderer +from opentelemetry.semconv.templating.compatibility import CompatibilityChecker from opentelemetry.semconv.templating.markdown import MarkdownRenderer from opentelemetry.semconv.templating.markdown.options import MarkdownOptions -def parse_semconv(args, parser) -> SemanticConventionSet: - semconv = SemanticConventionSet(args.debug) - find_yaml(args) - for file in sorted(args.files): +def parse_semconv( + yaml_root: str, exclude: str, debug: bool, parser +) -> SemanticConventionSet: + semconv = SemanticConventionSet(debug) + files = find_yaml(yaml_root, exclude) + for file in sorted(files): if not file.endswith(".yaml") and not file.endswith(".yml"): parser.error(f"{file} is not a yaml file.") - semconv.parse(file) + semconv.parse(file, False) semconv.finish() if semconv.has_error(): sys.exit(1) @@ -64,8 +72,8 @@ def main(): parser = setup_parser() args = parser.parse_args() check_args(args, parser) - semconv = parse_semconv(args, parser) - semconv_filter = parse_only_filter(args, parser) + semconv = parse_semconv(args.yaml_root, args.exclude, args.debug, parser) + semconv_filter = parse_only_filter(args.only, parser) filter_semconv(semconv, semconv_filter) if len(semconv.models) == 0: parser.error("No semantic convention model found!") @@ -76,6 +84,8 @@ def main(): renderer.render(semconv, args.template, args.output, args.pattern) elif args.flavor == "markdown": process_markdown(semconv, args) + elif args.flavor == "compatibility": + check_compatibility(semconv, args, parser) def process_markdown(semconv, args): @@ -92,16 +102,32 @@ def process_markdown(semconv, args): md_renderer.render_md() -def find_yaml(args): - if args.yaml_root is not None: - exclude = set( - exclude_file_list(args.yaml_root if args.yaml_root else "", args.exclude) +def check_compatibility(semconv, args, parser): + prev_semconv_path = download_previous_version(args.previous_version) + prev_semconv = parse_semconv(prev_semconv_path, args.exclude, args.debug, parser) + compatibility_checker = CompatibilityChecker(semconv, prev_semconv) + problems = compatibility_checker.check() + + if any(problems): + print(f"Found {len(problems)} compatibility issues:") + for problem in sorted(str(p) for p in problems): + print(f"\t{problem}") + + if not args.ignore_warnings or ( + args.ignore_warnings and any(problem.critical for problem in problems) + ): + sys.exit(1) + + +def find_yaml(yaml_root: str, exclude: str) -> List[str]: + if yaml_root is not None: + excluded_files = set(exclude_file_list(yaml_root if yaml_root else "", exclude)) + yaml_files = set(glob.glob(f"{yaml_root}/**/*.yaml", recursive=True)).union( + set(glob.glob(f"{yaml_root}/**/*.yml", recursive=True)) ) - yaml_files = set( - glob.glob(f"{args.yaml_root}/**/*.yaml", recursive=True) - ).union(set(glob.glob(f"{args.yaml_root}/**/*.yml", recursive=True))) - file_names = yaml_files - exclude - args.files.extend(file_names) + return list(yaml_files - excluded_files) + + return [] def check_args(arguments, parser): @@ -110,11 +136,11 @@ def check_args(arguments, parser): parser.error("Either --yaml-root or YAML_FILE must be present") -def parse_only_filter(arguments, parser): - if not arguments.only: - return None +def parse_only_filter(only: str, parser) -> List[str]: + if not only: + return [] - types = [t.strip() for t in arguments.only.split(",")] + types = [t.strip() for t in only.split(",")] unknown_types = [t for t in types if t not in CONVENTION_CLS_BY_GROUP_TYPE.keys()] if unknown_types: parser.error( @@ -188,6 +214,12 @@ def add_md_parser(subparsers): required=False, action="store_true", ) + parser.add_argument( + "--check-compat", + help="Check backward compatibility with previous version of semantic conventions.", + type=str, + required=False, + ) parser.add_argument( "--md-use-badges", help="Use stability badges instead of labels for attributes.", @@ -216,6 +248,23 @@ def add_md_parser(subparsers): ) +def add_compat_check_parser(subparsers): + parser = subparsers.add_parser("compatibility") + parser.add_argument( + "--previous-version", + help="Check backward compatibility with specified older version of semantic conventions.", + type=str, + required=True, + ) + parser.add_argument( + "--ignore-warnings", + help="Ignore non-critical compatibility problems.", + required=False, + default=False, + action="store_true", + ) + + def setup_parser(): parser = argparse.ArgumentParser( description="Process Semantic Conventions yaml files." @@ -258,9 +307,32 @@ def setup_parser(): subparsers = parser.add_subparsers(dest="flavor") add_code_parser(subparsers) add_md_parser(subparsers) + add_compat_check_parser(subparsers) return parser +def download_previous_version(version: str) -> str: + filename = f"v{version}.zip" + tmppath = tempfile.mkdtemp() + path_to_zip = os.path.join(tmppath, filename) + path_to_semconv = os.path.join(tmppath, f"v{version}") + + semconv_vprev = ( + f"https://github.com/open-telemetry/semantic-conventions/archive/{filename}" + ) + + response = requests.get(semconv_vprev, allow_redirects=True, timeout=30) + response.raise_for_status() + + with open(path_to_zip, "wb") as zip_file: + zip_file.write(response.content) + + with zipfile.ZipFile(path_to_zip, "r") as zip_ref: + zip_ref.extractall(path_to_semconv) + + return os.path.join(path_to_semconv, f"semantic-conventions-{version}", "model") + + if __name__ == "__main__": main() diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py index e27f654a..edde7808 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py @@ -81,7 +81,9 @@ def is_enum(self): return isinstance(self.attr_type, EnumAttributeType) @staticmethod - def parse(prefix, yaml_attributes) -> "Dict[str, SemanticAttribute]": + def parse( + prefix, yaml_attributes, strict_validation=True + ) -> "Dict[str, SemanticAttribute]": """This method parses the yaml representation for semantic attributes creating the respective SemanticAttribute objects. """ @@ -177,7 +179,7 @@ def parse(prefix, yaml_attributes) -> "Dict[str, SemanticAttribute]": tag = attribute.get("tag", "").strip() stability = SemanticAttribute.parse_stability( - attribute.get("stability"), position_data + attribute.get("stability"), position_data, strict_validation ) deprecated = SemanticAttribute.parse_deprecated( attribute.get("deprecated"), position_data @@ -280,7 +282,7 @@ def parse_attribute(attribute): return attr_type, str(brief), examples @staticmethod - def parse_stability(stability, position_data): + def parse_stability(stability, position_data, strict_validation=True): if stability is None: return StabilityLevel.EXPERIMENTAL @@ -291,6 +293,15 @@ def parse_stability(stability, position_data): val = stability_value_map.get(stability) if val is not None: return val + + # TODO: remove this branch - it's necessary for now to allow back-compat checks against old spec versions + # where we used 'deprecated' as stability level + if not strict_validation and stability == "deprecated": + print( + 'WARNING: Using "deprecated" as stability level is no longer supported. Use "experimental" instead.' + ) + return StabilityLevel.EXPERIMENTAL + msg = f"Value '{stability}' is not allowed as a stability marker" raise ValidationError.from_yaml_pos(position_data["stability"], msg) diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py index fa6977a9..af51a6e0 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py @@ -59,15 +59,15 @@ def parse_semantic_convention_type(type_value): return CONVENTION_CLS_BY_GROUP_TYPE.get(type_value) -def parse_semantic_convention_groups(yaml_file): +def parse_semantic_convention_groups(yaml_file, strict_validation=True): yaml = YAML().load(yaml_file) models = [] for group in yaml["groups"]: - models.append(SemanticConvention(group)) + models.append(SemanticConvention(group, strict_validation)) return models -def SemanticConvention(group): +def SemanticConvention(group, strict_validation=True): type_value = group.get("type") if type_value is None: line = group.lc.data["id"][0] + 1 @@ -85,7 +85,7 @@ def SemanticConvention(group): # First, validate that the correct fields are available in the yaml convention_type.validate_keys(group) - model = convention_type(group) + model = convention_type(group, strict_validation) # Also, validate that the value of the fields is acceptable model.validate_values() return model @@ -134,7 +134,7 @@ def _get_attributes(self, templates: Optional[bool]): key=lambda attr: attr.fqn, ) - def __init__(self, group): + def __init__(self, group, strict_validation=True): super().__init__(group) self.semconv_id = self.id @@ -142,7 +142,7 @@ def __init__(self, group): self.prefix = group.get("prefix", "").strip() position_data = group.lc.data self.stability = SemanticAttribute.parse_stability( - group.get("stability"), position_data + group.get("stability"), position_data, strict_validation ) self.deprecated = SemanticAttribute.parse_deprecated( group.get("deprecated"), position_data @@ -151,7 +151,7 @@ def __init__(self, group): self.events = group.get("events", ()) self.constraints = parse_constraints(group.get("constraints", ())) self.attrs_by_name = SemanticAttribute.parse( - self.prefix, group.get("attributes") + self.prefix, group.get("attributes"), strict_validation ) def contains_attribute(self, attr: "SemanticAttribute"): @@ -198,7 +198,7 @@ class SpanSemanticConvention(BaseSemanticConvention): "span_kind", ) - def __init__(self, group): + def __init__(self, group, strict_validation=True): super().__init__(group) self.span_kind = SpanKind.parse(group.get("span_kind")) if self.span_kind is None: @@ -212,7 +212,7 @@ class EventSemanticConvention(BaseSemanticConvention): allowed_keys = BaseSemanticConvention.allowed_keys + ("name",) - def __init__(self, group): + def __init__(self, group, strict_validation=True): super().__init__(group) self.name = group.get("name", self.prefix) if not self.name: @@ -231,7 +231,7 @@ class UnitSemanticConvention(BaseSemanticConvention): "members", ) - def __init__(self, group): + def __init__(self, group, strict_validation=True): super().__init__(group) self.members = UnitMember.parse(group.get("members")) @@ -260,7 +260,7 @@ class MetricSemanticConvention(MetricGroupSemanticConvention): canonical_instrument_name_by_yaml_name.keys() ) - def __init__(self, group): + def __init__(self, group, strict_validation=True): super().__init__(group) self.metric_name = group.get("metric_name") self.unit = group.get("unit") @@ -292,10 +292,12 @@ class SemanticConventionSet: models: typing.Dict[str, BaseSemanticConvention] = field(default_factory=dict) errors: bool = False - def parse(self, file): + def parse(self, file, strict_validation=True): with open(file, "r", encoding="utf-8") as yaml_file: try: - semconv_models = parse_semantic_convention_groups(yaml_file) + semconv_models = parse_semantic_convention_groups( + yaml_file, strict_validation + ) for model in semconv_models: if model.semconv_id in self.models: self.errors = True diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py b/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py new file mode 100644 index 00000000..0a28366f --- /dev/null +++ b/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py @@ -0,0 +1,204 @@ +from opentelemetry.semconv.model.semantic_attribute import ( + EnumAttributeType, + EnumMember, + RequirementLevel, + SemanticAttribute, + StabilityLevel, +) +from opentelemetry.semconv.model.semantic_convention import ( + MetricSemanticConvention, + SemanticConventionSet, +) + + +class Problem: + signal: str + name: str + message: str + critical: bool + + def __init__(self, signal: str, name: str, message: str, critical: bool = True): + self.signal = signal + self.name = name + self.message = message + self.critical = critical + + def __str__(self): + return f"{self.signal} '{self.name}' {self.message}" + + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.__dict__ == other.__dict__ + + return False + + def __ne__(self, other): + return not self.__eq__(other) + + +class CompatibilityChecker: + previous_version: str + + def __init__( + self, + current_semconv: SemanticConventionSet, + previous_semconv: SemanticConventionSet, + ): + self.current_semconv = current_semconv + self.previous_semconv = previous_semconv + + def check(self) -> list[Problem]: + problems = [] # type: list[Problem] + for semconv in self.previous_semconv.models.values(): + for prev_attr in semconv.attributes_and_templates: + if ( + prev_attr.is_local + and prev_attr.attr_id is not None + and prev_attr.ref is None + ): + self._check_attribute(prev_attr, problems) + if isinstance(semconv, MetricSemanticConvention): + self._check_metric(semconv, problems) + return problems + + def _check_attribute(self, prev: SemanticAttribute, problems: list[Problem]): + cur = self.current_semconv._lookup_attribute(prev.fqn) + if cur is None: + problems.append(Problem("attribute", prev.fqn, "was removed")) + return + + if prev.stability == StabilityLevel.STABLE: + if cur.stability != prev.stability: + problems.append( + Problem( + "attribute", + prev.fqn, + f"stability changed from '{prev.stability}' to '{cur.stability}'", + ) + ) + + if isinstance(prev.attr_type, EnumAttributeType): + if not isinstance(cur.attr_type, EnumAttributeType): + problems.append( + Problem( + "attribute", + prev.fqn, + f"type changed from '{prev.attr_type}' to '{cur.attr_type}'", + ) + ) + else: + # enum type change inevitably causes some values to be removed + # which will be reported in _check_member method as well. + # keeping this check to provide more detailed error message + if cur.attr_type.enum_type != prev.attr_type.enum_type: + problems.append( + Problem( + "attribute", + prev.fqn, + f"enum type changed from '{prev.attr_type.enum_type}' to '{cur.attr_type.enum_type}'", + ) + ) + for member in prev.attr_type.members: + self._check_member( + prev.fqn, member, cur.attr_type.members, problems + ) + elif cur.attr_type != prev.attr_type: + problems.append( + Problem( + "attribute", + prev.fqn, + f"type changed from '{prev.attr_type}' to '{cur.attr_type}'", + ) + ) + + def _check_member( + self, + fqn: str, + prev: EnumMember, + members: list[EnumMember], + problems: list[Problem], + ): + for member in members: + if prev.member_id == member.member_id: + if prev.value != member.value: + member_value = ( + f'"{member.value}"' + if isinstance(member.value, str) + else member.value + ) + problems.append( + Problem( + "enum attribute member", + f"{fqn}.{prev.member_id}", + f"value changed from '{prev.value}' to '{member_value}'", + ) + ) + return + problems.append( + Problem("enum attribute member", f"{fqn}.{prev.member_id}", "was removed") + ) + + def _check_metric(self, prev: MetricSemanticConvention, problems: list[Problem]): + for cur in self.current_semconv.models.values(): + if ( + isinstance(cur, MetricSemanticConvention) + and cur.metric_name == prev.metric_name + ): + if prev.stability == StabilityLevel.STABLE: + if cur.stability != prev.stability: + problems.append( + Problem( + "metric", + prev.metric_name, + f"stability changed from '{prev.stability}' to '{cur.stability}'", + ) + ) + if cur.unit != prev.unit: + problems.append( + Problem( + "metric", + prev.metric_name, + f"unit changed from '{prev.unit}' to '{cur.unit}'", + ) + ) + if cur.instrument != prev.instrument: + problems.append( + Problem( + "metric", + prev.metric_name, + f"instrument changed from '{prev.instrument}' to '{cur.instrument}'", + ) + ) + self._check_metric_attributes(prev, cur, problems) + return + + problems.append(Problem("metric", prev.metric_name, "was removed")) + + def _check_metric_attributes( + self, + prev: MetricSemanticConvention, + cur: MetricSemanticConvention, + problems: list[Problem], + ): + if prev.stability == StabilityLevel.STABLE: + prev_default_attributes = [ + attr.fqn + for attr in prev.attributes + if attr.requirement_level != RequirementLevel.OPT_IN + ] + cur_default_attributes = [ + attr.fqn + for attr in cur.attributes + if attr.requirement_level != RequirementLevel.OPT_IN + ] + if prev_default_attributes != cur_default_attributes: + # Adding attributes to metrics could be fine if it does not increase number of time series, + # so we do not consider it as critical problem. + problems.append( + Problem( + "metric", + prev.metric_name, + f"attributes changed from '{prev_default_attributes}' to '{cur_default_attributes}'", + False, + ) + ) diff --git a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml new file mode 100644 index 00000000..a26c943f --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml @@ -0,0 +1,24 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "First attribute." + note: "First attribute note." + examples: ["first"] + stability: stable + - id: second_attr + type: int + brief: "Second attribute." + note: "Second attribute note." + stability: experimental + examples: [2] + - id: fifth_attr_template + type: template[string[]] + brief: "Request headers." + note: "Request headers note." + examples: '`first.fifth_attr.bar=["foo"]`' diff --git a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml new file mode 100644 index 00000000..74f0d577 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + - id: second_attr + type: int + brief: "second attribute" + note: "second attribute note" + stability: stable + examples: 2 + - id: fifth_attr_template + type: template[string[]] + brief: "request headers" + examples: '`first.fifth_attr.foo=["bar"]`' + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/attribute_type_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/attribute_type_changed/vnext.yaml new file mode 100644 index 00000000..bbfd801a --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/attribute_type_changed/vnext.yaml @@ -0,0 +1,25 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" + attributes: + - id: first_attr + type: int + brief: "First attribute." + note: "First attribute note." + examples: [1] + stability: stable + - id: second_attr + type: string + brief: "Second attribute." + note: "Second attribute note." + stability: stable + examples: ["two"] + - id: fifth_attr_template + type: template[int[]] + brief: "Request headers." + note: "Request headers note." + examples: '`first.fifth_attr.bar=[42]`' + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml new file mode 100644 index 00000000..74f0d577 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + - id: second_attr + type: int + brief: "second attribute" + note: "second attribute note" + stability: stable + examples: 2 + - id: fifth_attr_template + type: template[string[]] + brief: "request headers" + examples: '`first.fifth_attr.foo=["bar"]`' + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml new file mode 100644 index 00000000..9098298c --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml @@ -0,0 +1,17 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" + attributes: + - id: third_attr + type: + members: + - id: enum_two + brief: "enum two" + value: "two" + brief: "third attribute" + note: "third attribute note" + examples: ["two"] + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml new file mode 100644 index 00000000..ab72dfa0 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml @@ -0,0 +1,17 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: third_attr + type: + members: + - id: enum_one + brief: "enum one" + value: "one" + brief: "third attribute" + note: "third attribute note" + examples: ["one"] + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml new file mode 100644 index 00000000..6875fb50 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml @@ -0,0 +1,17 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" + attributes: + - id: third_attr + type: + members: + - id: enum_one + brief: "enum one" + value: 1 + brief: "third attribute" + note: "third attribute note" + examples: [1] + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml new file mode 100644 index 00000000..ab72dfa0 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml @@ -0,0 +1,17 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: third_attr + type: + members: + - id: enum_one + brief: "enum one" + value: "one" + brief: "third attribute" + note: "third attribute note" + examples: ["one"] + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml new file mode 100644 index 00000000..88f07223 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml @@ -0,0 +1,17 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" + attributes: + - id: third_attr + type: + members: + - id: enum_one + brief: "enum one" + value: "1" + brief: "third attribute" + note: "third attribute note" + examples: ["one"] + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml new file mode 100644 index 00000000..ab72dfa0 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml @@ -0,0 +1,17 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: third_attr + type: + members: + - id: enum_one + brief: "enum one" + value: "one" + brief: "third attribute" + note: "third attribute note" + examples: ["one"] + stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/metric_attribute_added/vnext.yaml b/semantic-conventions/src/tests/data/compat/metric_attribute_added/vnext.yaml new file mode 100644 index 00000000..7e2fc969 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_attribute_added/vnext.yaml @@ -0,0 +1,30 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: second_attr + type: int + brief: "second attribute" + note: "second attribute note" + stability: stable + examples: 2 + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "Metric one." + note: "Metric one note." + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.first_attr + - ref: first.second_attr \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/metric_attribute_added/vprev.yaml b/semantic-conventions/src/tests/data/compat/metric_attribute_added/vprev.yaml new file mode 100644 index 00000000..b7819edf --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_attribute_added/vprev.yaml @@ -0,0 +1,29 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: second_attr + type: int + brief: "second attribute" + note: "second attribute note" + stability: stable + examples: 2 + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "metric one" + note: "metric one note" + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/metric_instrument_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/metric_instrument_changed/vnext.yaml new file mode 100644 index 00000000..ae373320 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_instrument_changed/vnext.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "Metric one." + note: "Metric one note." + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/metric_instrument_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/metric_instrument_changed/vprev.yaml new file mode 100644 index 00000000..deeb61b5 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_instrument_changed/vprev.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "metric one" + note: "metric one note" + stability: stable + unit: "s" + instrument: counter + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vnext.yaml b/semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vnext.yaml new file mode 100644 index 00000000..22f8d3f3 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vnext.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "Metric one." + note: "Metric one note." + stability: experimental + unit: "s" + instrument: histogram + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vprev.yaml b/semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vprev.yaml new file mode 100644 index 00000000..5bfd15b0 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_stable_to_experimental/vprev.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "metric one" + note: "metric one note" + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/metric_unit_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/metric_unit_changed/vnext.yaml new file mode 100644 index 00000000..ae373320 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_unit_changed/vnext.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "Metric one." + note: "Metric one note." + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/metric_unit_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/metric_unit_changed/vprev.yaml new file mode 100644 index 00000000..acaed738 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/metric_unit_changed/vprev.yaml @@ -0,0 +1,23 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + stability: stable + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "metric one" + note: "metric one note" + stability: stable + unit: "ms" + instrument: histogram + attributes: + - ref: first.first_attr diff --git a/semantic-conventions/src/tests/data/compat/removed_attribute/vnext.yaml b/semantic-conventions/src/tests/data/compat/removed_attribute/vnext.yaml new file mode 100644 index 00000000..d6f58e86 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/removed_attribute/vnext.yaml @@ -0,0 +1,6 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" diff --git a/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml b/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml new file mode 100644 index 00000000..5d674714 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml @@ -0,0 +1,22 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + - id: second_attr + type: int + brief: "second attribute" + note: "second attribute note" + stability: stable + examples: 2 + - id: fifth_attr_template + type: template[string[]] + brief: "request headers" + examples: '`first.fifth_attr.foo=["bar"]`' diff --git a/semantic-conventions/src/tests/data/compat/success/vnext.yaml b/semantic-conventions/src/tests/data/compat/success/vnext.yaml new file mode 100644 index 00000000..388e6efc --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/success/vnext.yaml @@ -0,0 +1,60 @@ +groups: + - id: first + type: attribute_group + brief: "First group." + note: "First group note." + prefix: "first" + attributes: + - id: first_attr + type: int # was an experimental attribute, type can change + brief: "First attribute." + note: "First attribute note." + stability: stable + examples: [1] + - id: second_attr + type: int + brief: "Second attribute." + note: "Second attribute note." + stability: stable + examples: [2] + - id: third_attr + type: + members: + - id: enum_one + brief: "Enum one." + value: "one" + - id: enum_two + brief: "Enum two." + value: "two" + brief: "Third attribute." + note: "Third attribute note." + examples: ["two"] + stability: stable + - id: forth_attr + type: boolean + brief: "forth attribute" + note: "forth attribute note" + examples: [True] + stability: stable + - id: fifth_attr_template + type: template[string[]] + brief: "Request headers." + note: "Request headers note." + examples: '`first.fifth_attr.bar=["foo"]`' + stability: stable + + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "Metric one." + note: "Metric one note." + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.second_attr + requirement_level: required + - ref: first.third_attr + requirement_level: recommended + - ref: first.forth_attr + requirement_level: opt_in \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/success/vprev.yaml b/semantic-conventions/src/tests/data/compat/success/vprev.yaml new file mode 100644 index 00000000..8fc72dc2 --- /dev/null +++ b/semantic-conventions/src/tests/data/compat/success/vprev.yaml @@ -0,0 +1,50 @@ +groups: + - id: first + type: attribute_group + brief: "first group" + note: "first group note" + prefix: "first" + attributes: + - id: first_attr + type: string + brief: "first attribute" + note: "first attribute note" + examples: "first example" + - id: second_attr + type: int + brief: "second attribute" + note: "second attribute note" + stability: stable + examples: 2 + - id: third_attr + type: + members: + - id: enum_one + brief: "enum one" + value: "one" + - id: enum_two + brief: "enum two" + value: "two" + brief: "third attribute" + note: "third attribute note" + examples: ["one"] + stability: stable + - id: fifth_attr_template + type: template[string[]] + brief: "request headers" + examples: '`first.fifth_attr.foo=["bar"]`' + stability: stable + + - id: metric_one + type: metric + metric_name: "metric_one" + brief: "metric one" + note: "metric one note" + stability: stable + unit: "s" + instrument: histogram + attributes: + - ref: first.second_attr + requirement_level: required + - ref: first.third_attr + requirement_level: recommended diff --git a/semantic-conventions/src/tests/data/jinja/metrics/semconv.yml b/semantic-conventions/src/tests/data/jinja/metrics/semconv.yml new file mode 100644 index 00000000..3d2c670b --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/metrics/semconv.yml @@ -0,0 +1,30 @@ +groups: + - id: first_group_id + type: attribute_group + brief: first description + prefix: first + attributes: + - id: attr_one + type: boolean + brief: short description of attr_one + + - id: first_metric_id + brief: first metric description + metric_name: first.metric + instrument: counter + type: metric + unit: "{one}" + stability: stable + extends: first_group_id + + - id: second_group_id + brief: second metric description + metric_name: second_group.metric + type: metric + instrument: histogram + unit: "s" + prefix: second_group + attributes: + - id: attr_two + type: int + brief: short description of attr_two diff --git a/semantic-conventions/src/tests/semconv/templating/test_compatibility.py b/semantic-conventions/src/tests/semconv/templating/test_compatibility.py new file mode 100644 index 00000000..2497fdd5 --- /dev/null +++ b/semantic-conventions/src/tests/semconv/templating/test_compatibility.py @@ -0,0 +1,208 @@ +# 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 os +import unittest +from pathlib import Path + +from opentelemetry.semconv.model.semantic_convention import SemanticConventionSet +from opentelemetry.semconv.templating.compatibility import CompatibilityChecker, Problem + + +class TestCompatibility(unittest.TestCase): + def testSuccess(self): + cur = self.parse_semconv("compat/success/vnext.yaml") + prev = self.parse_semconv("compat/success/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + self.assert_errors([], problems) + + def testRemovedAttribute(self): + cur = self.parse_semconv("compat/removed_attribute/vnext.yaml") + prev = self.parse_semconv("compat/removed_attribute/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + + expected_errors = [ + Problem("attribute", "first.first_attr", "was removed"), + Problem("attribute", "first.second_attr", "was removed"), + Problem("attribute", "first.fifth_attr_template", "was removed"), + ] + self.assert_errors(expected_errors, problems) + + def testAttributeStableToExperimental(self): + cur = self.parse_semconv("compat/attribute_stable_to_experimental/vnext.yaml") + prev = self.parse_semconv("compat/attribute_stable_to_experimental/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "attribute", + "first.second_attr", + "stability changed from 'StabilityLevel.STABLE' to 'StabilityLevel.EXPERIMENTAL'", + ), + Problem( + "attribute", + "first.fifth_attr_template", + "stability changed from 'StabilityLevel.STABLE' to 'StabilityLevel.EXPERIMENTAL'", + ), + ] + self.assert_errors(expected_errors, problems) + + def testMetricStableToExperimental(self): + cur = self.parse_semconv("compat/metric_stable_to_experimental/vnext.yaml") + prev = self.parse_semconv("compat/metric_stable_to_experimental/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "metric", + "metric_one", + "stability changed from 'StabilityLevel.STABLE' to 'StabilityLevel.EXPERIMENTAL'", + ) + ] + self.assert_errors(expected_errors, problems) + + def testMetricInstrumentChanged(self): + cur = self.parse_semconv("compat/metric_instrument_changed/vnext.yaml") + prev = self.parse_semconv("compat/metric_instrument_changed/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "metric", + "metric_one", + "instrument changed from 'counter' to 'histogram'", + ) + ] + self.assert_errors(expected_errors, problems) + + def testMetricUnitChanged(self): + cur = self.parse_semconv("compat/metric_unit_changed/vnext.yaml") + prev = self.parse_semconv("compat/metric_unit_changed/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem("metric", "metric_one", "unit changed from 'ms' to 's'") + ] + self.assert_errors(expected_errors, problems) + + def testMetricAttributeAdded(self): + cur = self.parse_semconv("compat/metric_attribute_added/vnext.yaml") + prev = self.parse_semconv("compat/metric_attribute_added/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "metric", + "metric_one", + "attributes changed from '['first.first_attr']' to '['first.first_attr', 'first.second_attr']'", + critical=False, + ) + ] + self.assert_errors(expected_errors, problems) + + def testTypeChanged(self): + cur = self.parse_semconv("compat/attribute_type_changed/vnext.yaml") + prev = self.parse_semconv("compat/attribute_type_changed/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "attribute", "first.second_attr", "type changed from 'int' to 'string'" + ), + Problem( + "attribute", + "first.fifth_attr_template", + "type changed from 'template[string[]]' to 'template[int[]]'", + ), + ] + self.assert_errors(expected_errors, problems) + + def testEnumTypeChanged(self): + cur = self.parse_semconv("compat/enum_type_changed/vnext.yaml") + prev = self.parse_semconv("compat/enum_type_changed/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "attribute", + "first.third_attr", + "enum type changed from 'string' to 'int'", + ), + Problem( + "enum attribute member", + "first.third_attr.enum_one", + "value changed from 'one' to '1'", + ), + ] + self.assert_errors(expected_errors, problems) + + def testEnumValueChanged(self): + cur = self.parse_semconv("compat/enum_value_changed/vnext.yaml") + prev = self.parse_semconv("compat/enum_value_changed/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "enum attribute member", + "first.third_attr.enum_one", + "value changed from 'one' to '\"1\"'", + ) + ] + self.assert_errors(expected_errors, problems) + + def testEnumMemberRemoved(self): + cur = self.parse_semconv("compat/enum_member_removed/vnext.yaml") + prev = self.parse_semconv("compat/enum_member_removed/vprev.yaml") + checker = CompatibilityChecker(cur, prev) + problems = checker.check() + expected_errors = [ + Problem( + "enum attribute member", + "first.third_attr.enum_one", + "was removed", + ) + ] + self.assert_errors(expected_errors, problems) + + def parse_semconv( + self, + input_dir: str, + ) -> SemanticConventionSet: + + semconv = SemanticConventionSet(debug=True) + + dirpath = Path(self.get_file_path(input_dir)) + if dirpath.is_dir(): + for fname in dirpath.glob("*.yaml"): + print("Parsing", fname) + semconv.parse(fname) + else: + semconv.parse(dirpath) + + assert not semconv.has_error() + semconv.finish() + return semconv + + _TEST_DIR = os.path.dirname(__file__) + + def get_file_path(self, filename): + return os.path.join(self._TEST_DIR, "..", "..", "data", filename) + + def assert_errors(self, expected: list[Problem], actual: list[Problem]): + assert len(expected) == len(actual) + for a in actual: + print(a) + assert a in expected From e966e83e4b6b1b0d2971c1cdb2d1af266dfb8c56 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 26 Feb 2024 00:57:12 -0800 Subject: [PATCH 10/31] Add link to requirement levels on Markdown table headers (#222) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- semantic-conventions/CHANGELOG.md | 2 + .../semconv/templating/markdown/__init__.py | 38 ++++++++++------ .../data/markdown/attribute_group/expected.md | 6 +-- .../markdown/attribute_templates/expected.md | 10 ++--- .../data/markdown/deprecated/expected.md | 22 +++++----- .../tests/data/markdown/deprecated/input.md | 10 ++--- .../src/tests/data/markdown/empty/expected.md | 16 +++---- .../src/tests/data/markdown/empty/input.md | 16 +++---- .../tests/data/markdown/enum_int/expected.md | 4 +- .../src/tests/data/markdown/event/expected.md | 6 +-- .../data/markdown/event_noprefix/expected.md | 4 +- .../data/markdown/event_renamed/expected.md | 4 +- .../data/markdown/example_array/expected.md | 4 +- .../markdown/extend_constraint/expected.md | 44 +++++++++---------- .../data/markdown/extend_constraint/input.md | 44 +++++++++---------- .../markdown/extend_grandparent/expected.md | 12 ++--- .../tests/data/markdown/include/expected.md | 20 ++++----- .../data/markdown/metrics_tables/expected.md | 10 ++--- .../data/markdown/missing_end_tag/input.md | 10 ++--- .../tests/data/markdown/multiple/expected.md | 36 +++++++-------- .../src/tests/data/markdown/multiple/input.md | 10 ++--- .../data/markdown/multiple_enum/expected.md | 34 +++++++------- .../data/markdown/parameter_empty/http.md | 8 ++-- .../data/markdown/parameter_full/expected.md | 22 +++++----- .../data/markdown/parameter_full/http.md | 8 ++-- .../parameter_remove_constraint/expected.md | 16 +++---- .../parameter_remove_constraint/input.md | 16 +++---- .../data/markdown/parameter_tag/expected.md | 12 ++--- .../markdown/parameter_tag_empty/expected.md | 16 +++---- .../src/tests/data/markdown/ref/expected.md | 10 ++--- .../data/markdown/ref_extends/expected.md | 8 ++-- .../markdown/sampling_relevant/expected.md | 22 +++++----- .../src/tests/data/markdown/scope/expected.md | 4 +- .../tests/data/markdown/single/expected.md | 18 ++++---- .../src/tests/data/markdown/single/input.md | 10 ++--- .../tests/data/markdown/sorting/expected.md | 14 +++--- .../data/markdown/spec_version/expected.md | 7 +++ .../tests/data/markdown/spec_version/input.md | 4 ++ .../markdown/spec_version/spec_version.yaml | 12 +++++ .../markdown/stability/badges_expected.md | 10 ++--- .../markdown/stability/labels_expected.md | 10 ++--- .../data/markdown/wrong_semconv_id/input.md | 10 ++--- 42 files changed, 317 insertions(+), 282 deletions(-) create mode 100644 semantic-conventions/src/tests/data/markdown/spec_version/expected.md create mode 100644 semantic-conventions/src/tests/data/markdown/spec_version/input.md create mode 100644 semantic-conventions/src/tests/data/markdown/spec_version/spec_version.yaml diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index cbd1ff8f..7048798e 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -8,6 +8,8 @@ Please update the changelog as part of any significant pull request. ([#244](https://github.com/open-telemetry/build-tools/pull/244)) - Add backward-compatibility check mode. ([#271](https://github.com/open-telemetry/build-tools/pull/271)) +- Add link to requirement levels definition from Markdown table title. + ([#222](https://github.com/open-telemetry/build-tools/pull/222)) ## v0.23.0 diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py index 3590502c..20537ced 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py @@ -39,6 +39,10 @@ from opentelemetry.semconv.model.utils import ID_RE from opentelemetry.semconv.templating.markdown.options import MarkdownOptions +_REQUIREMENT_LEVEL_URL = ( + "https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/" +) + class RenderContext: def __init__(self): @@ -80,10 +84,6 @@ class MarkdownRenderer: ] prelude = "\n" - table_headers = "| Attribute | Type | Description | Examples | Requirement Level |\n|---|---|---|---|---|\n" - table_headers_omitting_req_level = ( - "| Attribute | Type | Description | Examples |\n|---|---|---|---|\n" - ) def __init__( self, md_folder, semconvset: SemanticConventionSet, options=MarkdownOptions() @@ -100,6 +100,16 @@ def __init__( # that contains it self.filename_for_attr_fqn = self._create_attribute_location_dict() + req_level = f"[Requirement Level]({_REQUIREMENT_LEVEL_URL})" + + self.table_headers = ( + f"| Attribute | Type | Description | Examples | {req_level} |" + "\n|---|---|---|---|---|\n" + ) + self.table_headers_omitting_req_level = ( + "| Attribute | Type | Description | Examples |\n|---|---|---|---|\n" + ) + def to_markdown_attr( self, attribute: SemanticAttribute, @@ -169,14 +179,14 @@ def to_markdown_attr( def derive_requirement_level(self, attribute: SemanticAttribute): if attribute.requirement_level == RequirementLevel.REQUIRED: - required = "Required" + required = "`Required`" elif attribute.requirement_level == RequirementLevel.CONDITIONALLY_REQUIRED: if len(attribute.requirement_level_msg) < self.options.break_count: - required = "Conditionally Required: " + attribute.requirement_level_msg + required = "`Conditionally Required` " + attribute.requirement_level_msg else: # We put the condition in the notes after the table self.render_ctx.add_note(attribute.requirement_level_msg) - required = f"Conditionally Required: [{len(self.render_ctx.notes)}]" + required = f"`Conditionally Required` [{len(self.render_ctx.notes)}]" elif attribute.requirement_level == RequirementLevel.OPT_IN: required = "Opt-In" else: # attribute.requirement_level == Required.RECOMMENDED or None @@ -188,20 +198,20 @@ def derive_requirement_level(self, attribute: SemanticAttribute): required = "See below" else: if not attribute.requirement_level_msg: - required = "Recommended" + required = "`Recommended`" elif len(attribute.requirement_level_msg) < self.options.break_count: - required = "Recommended: " + attribute.requirement_level_msg + required = "`Recommended` " + attribute.requirement_level_msg else: # We put the condition in the notes after the table self.render_ctx.add_note(attribute.requirement_level_msg) - required = f"Recommended: [{len(self.render_ctx.notes)}]" + required = f"`Recommended` [{len(self.render_ctx.notes)}]" return required def write_table_header(self, output: io.StringIO): if self.render_ctx.is_omit_requirement_level: - output.write(MarkdownRenderer.table_headers_omitting_req_level) + output.write(self.table_headers_omitting_req_level) else: - output.write(MarkdownRenderer.table_headers) + output.write(self.table_headers) def to_markdown_attribute_table( self, semconv: BaseSemanticConvention, output: io.StringIO @@ -322,8 +332,8 @@ def to_markdown_enum(self, output: io.StringIO): if enum.custom_values: output.write( "has the following list of well-known values." - + " If one of them applies, then the respective value MUST be used," - + " otherwise a custom value MAY be used." + + " If one of them applies, then the respective value MUST be used;" + + " otherwise, a custom value MAY be used." ) else: output.write("MUST be one of the following:") diff --git a/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md b/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md index 82b4e34e..51fe266d 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md +++ b/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md @@ -1,8 +1,8 @@ # Attribute Group Example -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `foo.bar` | string | Attribute 1 | `baz` | Recommended: if available | -| `foo.qux` | int | Attribute 2 | `42` | Conditionally Required: if available | +| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | +| `foo.qux` | int | Attribute 2 | `42` | `Conditionally Required` if available | diff --git a/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md b/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md index f304d72a..9a8be2b5 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md +++ b/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md @@ -1,10 +1,10 @@ # Custom HTTP Semantic Conventions -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `custom_http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | Recommended | -| `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `general.some_general_attribute.` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | Recommended | -| `referenced_http.request.referenced.header.` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | Recommended | +| `custom_http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | +| `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `general.some_general_attribute.` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | `Recommended` | +| `referenced_http.request.referenced.header.` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/expected.md b/semantic-conventions/src/tests/data/markdown/deprecated/expected.md index 988ac7c8..964e9d05 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/expected.md +++ b/semantic-conventions/src/tests/data/markdown/deprecated/expected.md @@ -2,21 +2,21 @@ -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.flavor` | string | **Deprecated. Use attribute `flavor_new` instead.**
Kind of HTTP protocol used [1] | `1.0` | Recommended | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | Recommended | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Recommended | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent | -| `http.status_text` | string | **Deprecated: Use attribute `status_description` instead.**
[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | Recommended | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Recommended | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | +| `http.flavor` | string | **Deprecated. Use attribute `flavor_new` instead.**
Kind of HTTP protocol used [1] | `1.0` | `Recommended` | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | +| `http.status_text` | string | **Deprecated: Use attribute `status_description` instead.**
[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | **[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. -`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/input.md b/semantic-conventions/src/tests/data/markdown/deprecated/input.md index 06fd8ea2..4e6e41b1 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/input.md +++ b/semantic-conventions/src/tests/data/markdown/deprecated/input.md @@ -3,17 +3,17 @@ -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/empty/expected.md b/semantic-conventions/src/tests/data/markdown/empty/expected.md index e7874380..0b063ae1 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/expected.md +++ b/semantic-conventions/src/tests/data/markdown/empty/expected.md @@ -70,17 +70,17 @@ Note that the items marked with [1] are different from the mapping defined in th -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. @@ -183,11 +183,11 @@ If the route does not include the application root, it SHOULD be prepended to th If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | | `http.server_name` | The primary server name of the matched virtual host. This should be obtained via configuration. If no such configuration can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). | [1] | -| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | Recommended | -| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | Recommended | +| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | `Recommended` | +| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | `Recommended` | [HTTP request line]: https://tools.ietf.org/html/rfc7230#section-3.1.1 [HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4 diff --git a/semantic-conventions/src/tests/data/markdown/empty/input.md b/semantic-conventions/src/tests/data/markdown/empty/input.md index e7874380..0b063ae1 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/input.md +++ b/semantic-conventions/src/tests/data/markdown/empty/input.md @@ -70,17 +70,17 @@ Note that the items marked with [1] are different from the mapping defined in th -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. @@ -183,11 +183,11 @@ If the route does not include the application root, it SHOULD be prepended to th If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | | `http.server_name` | The primary server name of the matched virtual host. This should be obtained via configuration. If no such configuration can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). | [1] | -| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | Recommended | -| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | Recommended | +| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | `Recommended` | +| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | `Recommended` | [HTTP request line]: https://tools.ietf.org/html/rfc7230#section-3.1.1 [HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4 diff --git a/semantic-conventions/src/tests/data/markdown/enum_int/expected.md b/semantic-conventions/src/tests/data/markdown/enum_int/expected.md index 8238900f..e8361396 100644 --- a/semantic-conventions/src/tests/data/markdown/enum_int/expected.md +++ b/semantic-conventions/src/tests/data/markdown/enum_int/expected.md @@ -1,9 +1,9 @@ # RPC.GRPC with int enum -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `16` | Required | +| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `16` | `Required` | `rpc.grpc.status_code` MUST be one of the following: diff --git a/semantic-conventions/src/tests/data/markdown/event/expected.md b/semantic-conventions/src/tests/data/markdown/event/expected.md index 41274345..ed3e9f0e 100644 --- a/semantic-conventions/src/tests/data/markdown/event/expected.md +++ b/semantic-conventions/src/tests/data/markdown/event/expected.md @@ -3,11 +3,11 @@ The event name MUST be `exception`. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `exception.escaped` | boolean | 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. [1] | | Recommended | +| `exception.escaped` | boolean | 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. [1] | | `Recommended` | | `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | -| `exception.stacktrace` | string | A stacktrace. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | +| `exception.stacktrace` | string | A stacktrace. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | | `exception.type` | string | The type of the exception. | `java.net.ConnectException`; `OSError` | See below | **[1]:** An exception is considered to have escaped. diff --git a/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md b/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md index f0beeb52..1cb8695e 100644 --- a/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md +++ b/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md @@ -3,7 +3,7 @@ The event name MUST be `myname`. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `attr` | boolean | attrbrief | | Recommended | +| `attr` | boolean | attrbrief | | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md b/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md index b96e5e6b..dd574537 100644 --- a/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md +++ b/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md @@ -3,7 +3,7 @@ The event name MUST be `myname`. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `myprefix.attr` | boolean | attrbrief | | Recommended | +| `myprefix.attr` | boolean | attrbrief | | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/example_array/expected.md b/semantic-conventions/src/tests/data/markdown/example_array/expected.md index b63a1b4a..4c1609f2 100644 --- a/semantic-conventions/src/tests/data/markdown/example_array/expected.md +++ b/semantic-conventions/src/tests/data/markdown/example_array/expected.md @@ -1,7 +1,7 @@ # Common Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.method` | string[] | HTTP request method. | `[GET, POST, HEAD]` | Required | +| `http.method` | string[] | HTTP request method. | `[GET, POST, HEAD]` | `Required` | \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md b/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md index 66372a62..414f25f8 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md @@ -34,15 +34,15 @@ These attributes will usually be the same for all operations performed over the Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | | `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | Conditionally Required: [2] | -| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | Conditionally Required: [3] | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Conditionally Required` [2] | +| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | **[1]:** It is recommended to remove embedded credentials. @@ -55,7 +55,7 @@ Some database systems may allow a connection to switch to a different `db.user`, * `net.peer.name` * `net.peer.ip` -`db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| @@ -125,10 +125,10 @@ When additional attributes are added that only apply to a specific DBMS, its ide ### Connection-level attributes for specific technologies -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | Recommended | +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | **[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). @@ -139,11 +139,11 @@ These attributes may be different for each operation performed, even if the same Usually only one `db.name` will be used per connection though. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`; `main` | Conditionally Required: [2] | -| `db.operation` | string | 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`. [3] | `findAndModify`; `HMSET` | Conditionally Required: if `db.statement` is not applicable. | -| `db.statement` | string | The database statement being executed. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Conditionally Required: if applicable. | +| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`; `main` | `Conditionally Required` [2] | +| `db.operation` | string | 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`. [3] | `findAndModify`; `HMSET` | `Conditionally Required` if `db.statement` is not applicable. | +| `db.statement` | string | The database statement being executed. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | **[1]:** In some SQL databases, the database name to be used is called "schema name". @@ -169,33 +169,33 @@ For example, when retrieving a document, `db.operation` would be set to (literal #### Cassandra -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | Required | +| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | `Required` | #### Apache HBase -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | Required | +| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | `Required` | #### Redis -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.redis.database_index` | int | 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. | `0`; `1`; `15` | Conditionally Required: if other than the default database (`0`). | +| `db.redis.database_index` | int | 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. | `0`; `1`; `15` | `Conditionally Required` if other than the default database (`0`). | #### MongoDB -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`; `products` | Required | +| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`; `products` | `Required` | ## Examples diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md b/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md index f979a83a..28049197 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md @@ -34,19 +34,19 @@ These attributes will usually be the same for all operations performed over the Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | -| `db.user` | string | Username for accessing the database. | `readonly_user`
`reporting_user` | Recommended | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | +| `db.user` | string | Username for accessing the database. | `readonly_user`
`reporting_user` | `Recommended` | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | Conditional
See below. | | `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | Conditional
See below. | -| `net.peer.port` | int | Remote port number. | `80`
`8080`
`443` | Conditionally Required: [2] | -| `net.transport` | string enum | Transport protocol used. See note below. | `IP.TCP` | Conditionally Required: [3] | +| `net.peer.port` | int | Remote port number. | `80`
`8080`
`443` | `Conditionally Required` [2] | +| `net.transport` | string enum | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | **[1]:** It is recommended to remove embedded credentials. -**[2]:** Conditionally Required: if using a port other than the default port for this DBMS. +**[2]:** Conditionally Required if using a port other than the default port for this DBMS. **[3]:** Recommended in general, required for in-process databases (`"inproc"`). @@ -55,7 +55,7 @@ At least one of the following is required: * `net.peer.name` * `net.peer.ip` -`db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| @@ -125,10 +125,10 @@ When additional attributes are added that only apply to a specific DBMS, its ide ### Connection-level attributes for specific technologies -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | Recommended | -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`
`com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`
`com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | **[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). @@ -139,11 +139,11 @@ These attributes may be different for each operation performed, even if the same Usually only one `db.name` will be used per connection though. -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`
`main` | Conditionally Required: [2] | -| `db.statement` | string | The database statement being executed. [3] | `SELECT * FROM wuser_table`
`SET mykey "WuValue"` | Conditional
Conditionally Required: if applicable. | -| `db.operation` | string | 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`. [4] | `findAndModify`
`HMSET` | Conditional
Conditionally Required: if `db.statement` is not applicable. | +| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`
`main` | `Conditionally Required` [2] | +| `db.statement` | string | The database statement being executed. [3] | `SELECT * FROM wuser_table`
`SET mykey "WuValue"` | Conditional
Conditionally Required if applicable. | +| `db.operation` | string | 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`. [4] | `findAndModify`
`HMSET` | Conditional
Conditionally Required if `db.statement` is not applicable. | **[1]:** In some SQL databases, the database name to be used is called "schema name". @@ -169,23 +169,23 @@ For example, when retrieving a document, `db.operation` would be set to (literal #### Cassandra -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | Required | +| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | `Required` | #### Apache HBase -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | Required | +| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | `Required` | #### Redis -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| | `db.redis.database_index` | int | 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. | `0`
`1`
`15` | Conditional [1] | @@ -195,9 +195,9 @@ For example, when retrieving a document, `db.operation` would be set to (literal #### MongoDB -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`
`products` | Required | +| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`
`products` | `Required` | ## Examples diff --git a/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md b/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md index 3964e411..40906dce 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md +++ b/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md @@ -1,10 +1,10 @@ ## DB spans -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.foo.bar` | string | Some property. | `baz` | Recommended | -| `db.name` | string | Database name. | `the_shop` | Recommended | +| `db.foo.bar` | string | Some property. | `baz` | `Recommended` | +| `db.name` | string | Database name. | `the_shop` | `Recommended` | ## DB metrics @@ -16,8 +16,8 @@ -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.foo.bar` | string | Some property. | `baz` | Recommended | -| `db.name` | string | Database name. | `the_shop` | Recommended | +| `db.foo.bar` | string | Some property. | `baz` | `Recommended` | +| `db.name` | string | Database name. | `the_shop` | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/include/expected.md b/semantic-conventions/src/tests/data/markdown/include/expected.md index d29c6fff..7102b13e 100644 --- a/semantic-conventions/src/tests/data/markdown/include/expected.md +++ b/semantic-conventions/src/tests/data/markdown/include/expected.md @@ -1,21 +1,21 @@ # Test Markdown -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | -| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | Required | +| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | +| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | | `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | See below | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `http.recommended_attribute` | string | brief | `foo` | Recommended: short note | -| `http.recommended_attribute_long_note` | string | brief | `bar` | Recommended: [1] | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `http.recommended_attribute` | string | brief | `foo` | `Recommended` short note | +| `http.recommended_attribute_long_note` | string | brief | `bar` | `Recommended` [1] | | `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | -| [`http.server_name`](input_http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | Conditionally Required: [3] | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended | +| [`http.server_name`](input_http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | **[1]:** some very long note that should be written under the semconv table diff --git a/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md b/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md index fccac598..253863ba 100644 --- a/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md +++ b/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md @@ -11,10 +11,10 @@ **Attributes for `foo.size`** -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent. | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | **`foo.active_eggs`** @@ -26,9 +26,9 @@ **Attributes for `foo.active_eggs`** -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `bar.egg.type` | string | Type of egg. [1] | `chicken`; `emu`; `dragon` | Conditionally Required: if available to instrumentation. | +| `bar.egg.type` | string | Type of egg. [1] | `chicken`; `emu`; `dragon` | `Conditionally Required` if available to instrumentation. | | `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Opt-In | **[1]:** Some notes on attribute diff --git a/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md b/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md index 738dbd13..8b5289a6 100644 --- a/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md +++ b/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md @@ -3,17 +3,17 @@ -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/multiple/expected.md b/semantic-conventions/src/tests/data/markdown/multiple/expected.md index 24b84332..a3fd8769 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/expected.md +++ b/semantic-conventions/src/tests/data/markdown/multiple/expected.md @@ -2,29 +2,29 @@ -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | Recommended | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Recommended | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | Recommended | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Recommended | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | Recommended | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Recommended | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | Recommended | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Recommended | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/multiple/input.md b/semantic-conventions/src/tests/data/markdown/multiple/input.md index 5364018f..45ae85c2 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/input.md +++ b/semantic-conventions/src/tests/data/markdown/multiple/input.md @@ -3,17 +3,17 @@ -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md b/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md index 96781fc4..c3780d61 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md +++ b/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md @@ -2,30 +2,30 @@ -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `net.host.carrier.icc` | string | host.carrier.icc | `DE` | Recommended | -| `net.host.carrier.mcc` | string | host.carrier.mcc | `310` | Recommended | -| `net.host.carrier.mnc` | string | host.carrier.mnc | `001` | Recommended | -| `net.host.carrier.name` | string | host.carrier.name | `sprint` | Recommended | -| `net.host.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell connection, but it could be used for describing details about a wifi connection. | `2G` | Recommended | -| `net.host.connection.type` | string | unavailable | `wifi` | Recommended | -| `net.host.ip` | string | Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. | `192.168.0.1` | Recommended | -| `net.host.name` | string | Local hostname or similar, see note below. | `localhost` | Recommended | -| `net.host.port` | int | Like `net.peer.port` but for the host port. | `35555` | Recommended | -| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | Recommended | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | Recommended | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | Recommended | -| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | Recommended | - -`net.host.connection.subtype` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +| `net.host.carrier.icc` | string | host.carrier.icc | `DE` | `Recommended` | +| `net.host.carrier.mcc` | string | host.carrier.mcc | `310` | `Recommended` | +| `net.host.carrier.mnc` | string | host.carrier.mnc | `001` | `Recommended` | +| `net.host.carrier.name` | string | host.carrier.name | `sprint` | `Recommended` | +| `net.host.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell connection, but it could be used for describing details about a wifi connection. | `2G` | `Recommended` | +| `net.host.connection.type` | string | unavailable | `wifi` | `Recommended` | +| `net.host.ip` | string | Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. | `192.168.0.1` | `Recommended` | +| `net.host.name` | string | Local hostname or similar, see note below. | `localhost` | `Recommended` | +| `net.host.port` | int | Like `net.peer.port` but for the host port. | `35555` | `Recommended` | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | +| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Recommended` | + +`net.host.connection.subtype` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| | `1G` | 1G | | `2G` | 2G | -`net.host.connection.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`net.host.connection.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| diff --git a/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md b/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md index e3d08f12..de3e6daa 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md @@ -1,11 +1,11 @@ # General -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | Conditionally Required: [2] | -| `http.route` | String | The matched route (path template). | `/users/:userID?` | Recommended | -| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | Recommended | +| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | +| `http.route` | String | The matched route (path template). | `/users/:userID?` | `Recommended` | +| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | **[1]:** http.url is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md index 1ff9a1c2..52f04e18 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md @@ -1,21 +1,21 @@ # Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | -| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | Required | -| [`http.client_ip`](http.md) | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [1] | `83.164.160.102` | Recommended | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | Conditionally Required: | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| [`http.route`](http.md) | string | The matched route (path template). | `/users/:userID?` | Recommended | +| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | +| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | +| [`http.client_ip`](http.md) | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [1] | `83.164.160.102` | `Recommended` | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| [`http.route`](http.md) | string | The matched route (path template). | `/users/:userID?` | `Recommended` | | `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | -| [`http.server_name`](http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | Conditionally Required: [3] | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended | +| [`http.server_name`](http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | **[1]:** This is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/http.md b/semantic-conventions/src/tests/data/markdown/parameter_full/http.md index eea49b57..b634120b 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/http.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/http.md @@ -1,11 +1,11 @@ # General -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | Conditionally Required: [2] | -| `http.route` | String | The matched route (path template). | `/users/:userID?` | Recommended | -| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | Recommended | +| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | +| `http.route` | String | The matched route (path template). | `/users/:userID?` | `Recommended` | +| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | **[1]:** http.url is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md index f37e496b..6d062e68 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md @@ -1,18 +1,18 @@ # DB -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | -| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | Required | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | Recommended | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | Recommended | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | Recommended | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | +| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | **[1]:** It is recommended to remove embedded credentials. -`db.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`db.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md index 4051b754..aa49e453 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md @@ -1,15 +1,15 @@ # DB -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.type` | String | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | Required | -| `db.connection_string` | String | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | -| `db.user` | String | Username for accessing the database. | `readonly_user`
`reporting_user` | Recommended | -| [net.peer.ip](general.md) | String | None | `127.0.0.1` | Recommended | -| [net.peer.name](general.md) | String | None | `example.com` | Recommended | -| [net.peer.port](general.md) | int | None | `80`
`8080`
`443` | Recommended | -| [net.transport](general.md) | Enum | None | `IP.TCP` | Recommended | +| `db.type` | String | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | +| `db.connection_string` | String | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | +| `db.user` | String | Username for accessing the database. | `readonly_user`
`reporting_user` | `Recommended` | +| [net.peer.ip](general.md) | String | None | `127.0.0.1` | `Recommended` | +| [net.peer.name](general.md) | String | None | `example.com` | `Recommended` | +| [net.peer.port](general.md) | int | None | `80`
`8080`
`443` | `Recommended` | +| [net.transport](general.md) | Enum | None | `IP.TCP` | `Recommended` | **[1]:** It is recommended to remove embedded credentials. diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md index 9332a6f9..bf1dd634 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md @@ -1,14 +1,14 @@ # DB -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | -| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | Required | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | +| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | | `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | Recommended | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | **[1]:** It is recommended to remove embedded credentials. @@ -17,7 +17,7 @@ * `net.peer.name` * `net.peer.ip` -`db.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`db.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md index 59acab51..6197be43 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md @@ -1,14 +1,14 @@ # DB -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `db.dbms` | string | An identifier for the DBMS (database management system) product | `mssql` | Conditionally Required: for `db.type="sql"` | -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | Recommended | -| `db.name` | string | If no tech-specific attribute is defined below, 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). [2] | `customers`; `master` | Conditionally Required: [3] | -| `db.operation` | string | The type of operation that is executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`. While it would semantically make sense to set this, e.g., to a SQL keyword like `SELECT` or `INSERT`, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property (the back end can do that if required). | `findAndModify` | Conditionally Required: if `db.statement` is not applicable. | -| `db.statement` | string | A database statement for the given database type. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Conditionally Required: if applicable. | +| `db.dbms` | string | An identifier for the DBMS (database management system) product | `mssql` | `Conditionally Required` for `db.type="sql"` | +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | +| `db.name` | string | If no tech-specific attribute is defined below, 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). [2] | `customers`; `master` | `Conditionally Required` [3] | +| `db.operation` | string | The type of operation that is executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`. While it would semantically make sense to set this, e.g., to a SQL keyword like `SELECT` or `INSERT`, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property (the back end can do that if required). | `findAndModify` | `Conditionally Required` if `db.statement` is not applicable. | +| `db.statement` | string | A database statement for the given database type. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | **[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). @@ -23,7 +23,7 @@ * `net.peer.name` * `net.peer.ip` -`db.dbms` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. +`db.dbms` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | |---|---| diff --git a/semantic-conventions/src/tests/data/markdown/ref/expected.md b/semantic-conventions/src/tests/data/markdown/ref/expected.md index 9f3a16e9..ad50fff0 100644 --- a/semantic-conventions/src/tests/data/markdown/ref/expected.md +++ b/semantic-conventions/src/tests/data/markdown/ref/expected.md @@ -1,13 +1,13 @@ # Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| | [`net.peer.name`](input_general.md) | string | override brief. [1] | `example.com` | Opt-In | -| [`net.peer.port`](input_general.md) | int | It describes the server port the client is connecting to | `80`; `8080`; `443` | Required | -| [`net.sock.peer.addr`](input_general.md) | string | Remote socket peer address. | `127.0.0.1`; `/tmp/mysql.sock` | Required | -| [`net.sock.peer.port`](input_general.md) | int | Remote socket peer port. | `16456` | Conditionally Required: | -| `rpc.service` | string | The service name, must be equal to the $service part in the span name. | `EchoService` | Required | +| [`net.peer.port`](input_general.md) | int | It describes the server port the client is connecting to | `80`; `8080`; `443` | `Required` | +| [`net.sock.peer.addr`](input_general.md) | string | Remote socket peer address. | `127.0.0.1`; `/tmp/mysql.sock` | `Required` | +| [`net.sock.peer.port`](input_general.md) | int | Remote socket peer port. | `16456` | `Conditionally Required` | +| `rpc.service` | string | The service name, must be equal to the $service part in the span name. | `EchoService` | `Required` | **[1]:** override note. diff --git a/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md b/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md index 82b59bbc..e08408c3 100644 --- a/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md +++ b/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md @@ -1,9 +1,9 @@ # Spans -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | Required | +| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | `Required` | **[1]:** Note on the overridden attribute definition. @@ -21,9 +21,9 @@ The following attributes can be important for making sampling decisions and SHOU -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | Required | +| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | `Required` | **[1]:** Note on the overridden attribute definition. diff --git a/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md b/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md index e00b6a84..ed838467 100644 --- a/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md +++ b/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md @@ -1,18 +1,18 @@ # Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.host` | string | . | `.` | Recommended | -| `http.method` | string | . | `GET` | Required | -| `http.scheme` | string | . | `http` | Recommended | -| `http.status_code` | int | . | | Conditionally Required: | -| `http.target` | string | . | `.` | Recommended | -| `http.url` | string | . [1] | `.` | Recommended | -| `http.user_agent` | string | . | `.` | Recommended | -| [`net.peer.ip`](span-general.md) | string | . | `.` | Recommended | -| [`net.peer.name`](span-general.md) | string | . | `.` | Recommended | -| [`net.peer.port`](span-general.md) | int | . | | Recommended | +| `http.host` | string | . | `.` | `Recommended` | +| `http.method` | string | . | `GET` | `Required` | +| `http.scheme` | string | . | `http` | `Recommended` | +| `http.status_code` | int | . | | `Conditionally Required` | +| `http.target` | string | . | `.` | `Recommended` | +| `http.url` | string | . [1] | `.` | `Recommended` | +| `http.user_agent` | string | . | `.` | `Recommended` | +| [`net.peer.ip`](span-general.md) | string | . | `.` | `Recommended` | +| [`net.peer.name`](span-general.md) | string | . | `.` | `Recommended` | +| [`net.peer.port`](span-general.md) | int | . | | `Recommended` | **[1]:** `http.url` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case the attribute's value should be `https://www.example.com/`. diff --git a/semantic-conventions/src/tests/data/markdown/scope/expected.md b/semantic-conventions/src/tests/data/markdown/scope/expected.md index 9707b860..e6ff24f9 100644 --- a/semantic-conventions/src/tests/data/markdown/scope/expected.md +++ b/semantic-conventions/src/tests/data/markdown/scope/expected.md @@ -1,7 +1,7 @@ # Instrumentation Scope Semantic Conventions -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `short_name` | string | The single-word name for the instrumentation scope. | `mylibrary` | Recommended | +| `short_name` | string | The single-word name for the instrumentation scope. | `mylibrary` | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/single/expected.md b/semantic-conventions/src/tests/data/markdown/single/expected.md index f10e136d..7bee2d95 100644 --- a/semantic-conventions/src/tests/data/markdown/single/expected.md +++ b/semantic-conventions/src/tests/data/markdown/single/expected.md @@ -2,16 +2,16 @@ -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | Conditionally Required: | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Recommended | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | Recommended | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Recommended | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/single/input.md b/semantic-conventions/src/tests/data/markdown/single/input.md index 06fd8ea2..4e6e41b1 100644 --- a/semantic-conventions/src/tests/data/markdown/single/input.md +++ b/semantic-conventions/src/tests/data/markdown/single/input.md @@ -3,17 +3,17 @@ -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/sorting/expected.md b/semantic-conventions/src/tests/data/markdown/sorting/expected.md index f9a8e1f7..7e699905 100644 --- a/semantic-conventions/src/tests/data/markdown/sorting/expected.md +++ b/semantic-conventions/src/tests/data/markdown/sorting/expected.md @@ -1,12 +1,12 @@ # Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| `aaa.aaa` | string | the 1st attribute | `aaa` | Recommended | -| `mmm.bbb` | string | the 2nd attribute | `bbb` | Recommended | -| `mmm.ccc.` | string | the 3rd attribute | ``mmm.ccc="ccc"`` | Recommended | -| `nnn.nnn` | string | the 4th attribute | `nnn` | Recommended | -| `zzz.xxx` | string | the 5th attribute | `xxx` | Recommended | -| `zzz.yyy` | string | the 6th attribute | `yyy` | Recommended | +| `aaa.aaa` | string | the 1st attribute | `aaa` | `Recommended` | +| `mmm.bbb` | string | the 2nd attribute | `bbb` | `Recommended` | +| `mmm.ccc.` | string | the 3rd attribute | ``mmm.ccc="ccc"`` | `Recommended` | +| `nnn.nnn` | string | the 4th attribute | `nnn` | `Recommended` | +| `zzz.xxx` | string | the 5th attribute | `xxx` | `Recommended` | +| `zzz.yyy` | string | the 6th attribute | `yyy` | `Recommended` | diff --git a/semantic-conventions/src/tests/data/markdown/spec_version/expected.md b/semantic-conventions/src/tests/data/markdown/spec_version/expected.md new file mode 100644 index 00000000..3ba03a0a --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/spec_version/expected.md @@ -0,0 +1,7 @@ +# Attribute Group Example + + +| Attribute | [Type](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/common/README.md#attribute) | Description | Examples | [Requirement Level](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/common/attribute-requirement-level.md) | +|---|---|---|---|---| +| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | + diff --git a/semantic-conventions/src/tests/data/markdown/spec_version/input.md b/semantic-conventions/src/tests/data/markdown/spec_version/input.md new file mode 100644 index 00000000..b4f62f61 --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/spec_version/input.md @@ -0,0 +1,4 @@ +# Attribute Group Example + + + diff --git a/semantic-conventions/src/tests/data/markdown/spec_version/spec_version.yaml b/semantic-conventions/src/tests/data/markdown/spec_version/spec_version.yaml new file mode 100644 index 00000000..e637f192 --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/spec_version/spec_version.yaml @@ -0,0 +1,12 @@ +groups: + - id: attributes + prefix: "foo" + type: attribute_group + brief: Attribute group + attributes: + - id: bar + type: string + requirement_level: + recommended: if available + brief: Attribute 1 + examples: ['baz'] diff --git a/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md index de1439da..8c53eba4 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md +++ b/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md @@ -1,10 +1,10 @@ # Common Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| [`test.def_stability`](labels_expected.md) | boolean | | | Required | -| [`test.deprecated_attr`](labels_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | Required | -| [`test.exp_attr`](labels_expected.md) | boolean | | | Required | -| [`test.stable_attr`](labels_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | Required | +| [`test.def_stability`](labels_expected.md) | boolean | | | `Required` | +| [`test.deprecated_attr`](labels_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](labels_expected.md) | boolean | | | `Required` | +| [`test.stable_attr`](labels_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | diff --git a/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md b/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md index ab7f6194..d6edf766 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md +++ b/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md @@ -1,10 +1,10 @@ # Common Attributes -| Attribute | Type | Description | Examples | Requirement Level | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | |---|---|---|---|---| -| [`test.def_stability`](labels_expected.md) | boolean | | | Required | -| [`test.deprecated_attr`](labels_expected.md) | boolean | **Deprecated: Removed.**
| | Required | -| [`test.exp_attr`](labels_expected.md) | boolean | | | Required | -| [`test.stable_attr`](labels_expected.md) | boolean | | | Required | +| [`test.def_stability`](labels_expected.md) | boolean | | | `Required` | +| [`test.deprecated_attr`](labels_expected.md) | boolean | **Deprecated: Removed.**
| | `Required` | +| [`test.exp_attr`](labels_expected.md) | boolean | | | `Required` | +| [`test.stable_attr`](labels_expected.md) | boolean | | | `Required` | diff --git a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md index f316463a..30656e50 100644 --- a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md +++ b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md @@ -3,17 +3,17 @@ -| Attribute name | Notes and examples | Required? | +| Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Required | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended | +| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. From 0331720083c5a0f4dd1d113e9cb499611c42e9c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:18:31 -0500 Subject: [PATCH 11/31] Bump pytest from 8.0.1 to 8.0.2 in /semantic-conventions (#273) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Josh Suereth --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index 6ec71734..5d2c3f96 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,6 +1,6 @@ black==22.3.0 mypy==0.910 -pytest==8.0.1 +pytest==8.0.2 flake8==7.0.0 pylint==3.0.3 isort==5.13.2 \ No newline at end of file From ca02f82a2af66901f01028c0d2a28e871cc2b5e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:52:21 -0500 Subject: [PATCH 12/31] Bump pylint from 3.0.3 to 3.1.0 in /semantic-conventions (#274) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index 5d2c3f96..cfae1c8e 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -2,5 +2,5 @@ black==22.3.0 mypy==0.910 pytest==8.0.2 flake8==7.0.0 -pylint==3.0.3 +pylint==3.1.0 isort==5.13.2 \ No newline at end of file From 50add91d560aa40adb5d323ee594260c9113d6fd Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 27 Feb 2024 04:01:32 -0800 Subject: [PATCH 13/31] Make stability required, fix ref and extends, render badges on metrics (#272) --- .../semconv/model/semantic_attribute.py | 10 +- .../semconv/model/semantic_convention.py | 7 +- .../semconv/templating/markdown/__init__.py | 44 +++--- .../vnext.yaml | 1 + .../vprev.yaml | 1 + .../compat/attribute_type_changed/vprev.yaml | 1 + .../data/compat/removed_attribute/vprev.yaml | 2 + .../src/tests/data/compat/success/vprev.yaml | 1 + .../attribute_group/attribute_group.yaml | 6 +- .../attribute_templates.yaml | 4 + .../data/markdown/deprecated/general.yaml | 10 ++ .../tests/data/markdown/deprecated/http.yaml | 10 ++ .../tests/data/markdown/empty/general.yaml | 10 ++ .../src/tests/data/markdown/empty/http.yaml | 8 ++ .../tests/data/markdown/empty_table/faas.yaml | 2 + .../data/markdown/empty_table/general.yaml | 10 ++ .../tests/data/markdown/empty_table/http.yaml | 11 ++ .../src/tests/data/markdown/enum_int/rpc.yaml | 1 + .../src/tests/data/markdown/event/event.yaml | 4 + .../data/markdown/event_noprefix/event.yaml | 1 + .../data/markdown/event_renamed/event.yaml | 1 + .../data/markdown/example_array/http.yaml | 1 + .../markdown/extend_constraint/database.yaml | 12 ++ .../markdown/extend_constraint/general.yaml | 10 ++ .../markdown/extend_grandparent/database.yaml | 3 + .../src/tests/data/markdown/include/faas.yaml | 2 + .../tests/data/markdown/include/general.yaml | 9 ++ .../src/tests/data/markdown/include/http.yaml | 17 ++- .../data/markdown/metrics_tables/expected.md | 2 +- .../markdown/missing_end_tag/general.yaml | 9 ++ .../data/markdown/missing_end_tag/http.yaml | 9 ++ .../tests/data/markdown/multiple/general.yaml | 9 ++ .../tests/data/markdown/multiple/http.yaml | 9 ++ .../data/markdown/multiple_enum/general.yaml | 16 +++ .../markdown/omit_requirement_level/http.yaml | 3 + .../data/markdown/parameter_empty/faas.yaml | 2 + .../markdown/parameter_empty/general.yaml | 9 ++ .../data/markdown/parameter_empty/http.yaml | 11 ++ .../data/markdown/parameter_full/faas.yaml | 2 + .../data/markdown/parameter_full/general.yaml | 9 ++ .../data/markdown/parameter_full/http.yaml | 11 ++ .../parameter_remove_constraint/database.yaml | 14 +- .../parameter_remove_constraint/general.yaml | 9 ++ .../data/markdown/parameter_tag/database.yaml | 14 +- .../data/markdown/parameter_tag/general.yaml | 9 ++ .../parameter_tag_empty/database.yaml | 14 +- .../markdown/parameter_tag_empty/general.yaml | 9 ++ .../parameter_tag_no_attr/database.yaml | 1 + .../data/markdown/parameter_wrong/faas.yaml | 2 + .../markdown/parameter_wrong/general.yaml | 9 ++ .../data/markdown/parameter_wrong/http.yaml | 11 ++ .../parameter_wrong_duplicate/faas.yaml | 2 + .../parameter_wrong_duplicate/general.yaml | 9 ++ .../parameter_wrong_duplicate/http.yaml | 11 ++ .../markdown/parameter_wrong_syntax/faas.yaml | 2 + .../parameter_wrong_syntax/general.yaml | 9 ++ .../markdown/parameter_wrong_syntax/http.yaml | 11 ++ .../src/tests/data/markdown/ref/general.yaml | 12 ++ .../src/tests/data/markdown/ref/http.yaml | 11 ++ .../src/tests/data/markdown/ref/rpc.yaml | 1 + .../tests/data/markdown/ref_extends/http.yaml | 1 + .../data/markdown/ref_extends/server.yaml | 1 + .../markdown/sampling_relevant/general.yaml | 3 + .../data/markdown/sampling_relevant/http.yaml | 7 + .../src/tests/data/markdown/scope/scope.yaml | 1 + .../tests/data/markdown/single/general.yaml | 9 ++ .../src/tests/data/markdown/single/http.yaml | 11 ++ .../tests/data/markdown/sorting/input.yaml | 6 + .../markdown/stability/all_badges_expected.md | 44 ++++++ .../markdown/stability/badges_expected.md | 10 -- .../tests/data/markdown/stability/input.md | 16 ++- .../markdown/stability/labels_expected.md | 10 -- .../data/markdown/stability/stability.yaml | 44 +++++- .../stability/stable_badges_expected.md | 44 ++++++ .../markdown/wrong_semconv_id/general.yaml | 9 ++ .../data/markdown/wrong_semconv_id/http.yaml | 11 ++ .../attribute_templates.yml | 5 +- .../tests/data/yaml/attribute_templates.yml | 3 + .../src/tests/data/yaml/basic_example.yml | 2 + .../src/tests/data/yaml/cloud.yaml | 4 + .../src/tests/data/yaml/database.yaml | 5 + .../src/tests/data/yaml/deprecated/http.yaml | 43 ++---- .../deprecated/deprecation_boolean.yaml | 1 + .../deprecated/deprecation_empty_string.yaml | 1 + .../errors/deprecated/deprecation_number.yaml | 1 + .../extends_overrides_deprecation.yaml | 20 +++ .../deprecated/multiple_deprecations.yaml | 14 ++ .../deprecated/ref_overrides_deprecation.yaml | 18 +++ .../data/yaml/errors/empty/empty_enum.yaml | 3 +- .../errors/empty/empty_example_boolean.yaml | 1 + .../empty/empty_example_boolean_array.yaml | 3 +- .../yaml/errors/empty/empty_example_enum.yaml | 1 + .../errors/empty/empty_example_string.yaml | 1 + .../tests/data/yaml/errors/empty_type.yaml | 3 +- .../enum/enum_member_with_extra_keys.yaml | 3 +- .../errors/enum/enum_with_double_values.yaml | 1 + .../errors/enum/enum_with_extra_keys.yaml | 3 +- .../yaml/errors/events/missing_event.yaml | 2 + .../yaml/errors/events/nameless_event.yaml | 1 + .../yaml/errors/events/no_event_type.yaml | 2 + .../yaml/errors/examples/example.types.yaml | 5 + .../yaml/errors/examples/example_bool.yaml | 1 + .../errors/examples/example_bool_array.yaml | 1 + .../errors/examples/example_number_array.yaml | 3 +- .../examples/example_number_array_single.yaml | 3 +- .../examples/example_single_string.yaml | 1 + .../yaml/errors/examples/example_string.yaml | 1 + .../errors/examples/example_string_array.yaml | 1 + .../errors/examples/example_wrong_type.yaml | 1 + .../tests/data/yaml/errors/id_clash/http.yaml | 6 +- .../yaml/errors/id_clash/httpInherited.yaml | 3 + .../yaml/errors/id_clash/resource2_faas.yaml | 4 + .../yaml/errors/id_clash/resource_faas.yaml | 4 + .../data/yaml/errors/id_clash/span_faas.yaml | 4 + .../tests/data/yaml/errors/invalid_type.yaml | 1 + .../data/yaml/errors/missing_attr_type.yaml | 1 + .../data/yaml/errors/missing_semconv_id.yaml | 1 + .../data/yaml/errors/resource_spankind.yaml | 1 + .../stability/extends_override_stability.yaml | 16 +++ .../stability/missing_stability_value.yaml | 8 ++ .../stability/multiple_stability_values.yaml | 10 ++ .../stability/ref_override_stability.yaml | 15 ++ .../data/yaml/errors/validate_anyof.yaml | 1 + ...g_conditionally_required_no_condition.yaml | 1 + .../data/yaml/errors/wrong_double_type.yaml | 1 + ...ong_multiple_requirement_level_values.yaml | 3 +- .../wrong_multiple_requirement_levels.yaml | 1 + .../data/yaml/errors/wrong_requirement.yaml | 1 + .../data/yaml/errors/wrong_sampling.yaml | 1 + .../src/tests/data/yaml/event.yaml | 29 +++- .../src/tests/data/yaml/extends/http.yaml | 1 + .../src/tests/data/yaml/faas.yaml | 8 ++ .../src/tests/data/yaml/general.yaml | 10 ++ .../src/tests/data/yaml/http.yaml | 10 ++ .../tests/data/yaml/imported-inherited.yaml | 8 ++ .../src/tests/data/yaml/links.yaml | 5 + .../src/tests/data/yaml/metrics.yaml | 11 +- .../tests/data/yaml/numeric_attributes.yml | 2 + .../src/tests/data/yaml/rpc.yaml | 1 + .../src/tests/data/yaml/scope.yaml | 1 + .../tests/data/yaml/semantic_attributes.yml | 3 + .../yaml/semantic_attributes_deprecated.yml | 1 + .../src/tests/data/yaml/span_event.yaml | 2 + .../src/tests/data/yaml/stability.yaml | 61 +++----- .../tests/semconv/model/test_correct_parse.py | 132 ++++++++++++++---- .../semconv/model/test_error_detection.py | 58 +++++++- .../tests/semconv/templating/test_markdown.py | 17 ++- semantic-conventions/syntax.md | 15 +- 148 files changed, 1117 insertions(+), 186 deletions(-) create mode 100644 semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md delete mode 100644 semantic-conventions/src/tests/data/markdown/stability/badges_expected.md delete mode 100644 semantic-conventions/src/tests/data/markdown/stability/labels_expected.md create mode 100644 semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md create mode 100644 semantic-conventions/src/tests/data/yaml/errors/deprecated/extends_overrides_deprecation.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/deprecated/multiple_deprecations.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/deprecated/ref_overrides_deprecation.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/extends_override_stability.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_value.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/ref_override_stability.yaml diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py index edde7808..5d1c1b49 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py @@ -128,6 +128,12 @@ def parse( if "type" in attribute: msg = f"Ref attribute '{ref}' must not declare a type" raise ValidationError.from_yaml_pos(position, msg) + if "stability" in attribute: + msg = f"Ref attribute '{ref}' must not override stability" + raise ValidationError.from_yaml_pos(position, msg) + if "deprecated" in attribute: + msg = f"Ref attribute '{ref}' must not override deprecation status" + raise ValidationError.from_yaml_pos(position, msg) brief = attribute.get("brief") examples = attribute.get("examples") ref = ref.strip() @@ -224,7 +230,7 @@ def parse( @staticmethod def parse_attribute(attribute): - check_no_missing_keys(attribute, ["type", "brief"]) + check_no_missing_keys(attribute, ["type", "brief", "stability"]) attr_val = attribute["type"] try: attr_type = EnumAttributeType.parse(attr_val) @@ -284,7 +290,7 @@ def parse_attribute(attribute): @staticmethod def parse_stability(stability, position_data, strict_validation=True): if stability is None: - return StabilityLevel.EXPERIMENTAL + return None stability_value_map = { "experimental": StabilityLevel.EXPERIMENTAL, diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py index af51a6e0..932cd578 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py @@ -104,6 +104,7 @@ class BaseSemanticConvention(ValidatableYamlNode): "extends", "attributes", "constraints", + "deprecated", ) GROUP_TYPE_NAME: str @@ -268,11 +269,11 @@ def __init__(self, group, strict_validation=True): self.validate() def validate(self): - val_tuple = (self.metric_name, self.unit, self.instrument) + val_tuple = (self.metric_name, self.unit, self.instrument, self.stability) if not all(val_tuple): raise ValidationError.from_yaml_pos( self._position, - "All of metric_name, units, and instrument must be defined", + "All of metric_name, units, instrument, and stability must be defined", ) if self.instrument not in self.allowed_instruments: @@ -483,6 +484,8 @@ def _fill_inherited_attribute(self, attr, semconv): def _merge_attribute(self, child, parent): child.attr_type = parent.attr_type + child.stability = parent.stability + child.deprecated = parent.deprecated if not child.brief: child.brief = parent.brief if not child.requirement_level: diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py index 20537ced..bbd9f3e4 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py @@ -124,25 +124,7 @@ def to_markdown_attr( if isinstance(attribute.attr_type, EnumAttributeType) else AttributeType.get_instantiated_type(attribute.attr_type) ) - description = "" - if attribute.deprecated and self.options.enable_deprecated: - if "deprecated" in attribute.deprecated.lower(): - description = f"**{attribute.deprecated}**
" - else: - deprecated_msg = self.options.deprecated_md_snippet().format( - attribute.deprecated - ) - description = f"{deprecated_msg}
" - elif ( - attribute.stability == StabilityLevel.STABLE and self.options.enable_stable - ): - description = f"{self.options.stable_md_snippet()}
" - elif ( - attribute.stability == StabilityLevel.EXPERIMENTAL - and self.options.enable_experimental - ): - description = f"{self.options.experimental_md_snippet()}
" - description += attribute.brief + description = self._description_with_badge(attribute) + attribute.brief if attribute.note: self.render_ctx.add_note(attribute.note) description += f" [{len(self.render_ctx.notes)}]" @@ -258,7 +240,7 @@ def to_markdown_metric_table( "| -------- | --------------- | ----------- | -------------- |\n" ) - description = semconv.brief + description = self._description_with_badge(semconv) + semconv.brief if semconv.note: self.render_ctx.add_note(semconv.note) description += f" [{len(self.render_ctx.notes)}]" @@ -544,3 +526,25 @@ def _render_group(self, semconv, parameters, output): self.to_markdown_unit_table(semconv.members, output) output.write("") + + def _description_with_badge( + self, item: typing.Union[SemanticAttribute | BaseSemanticConvention] + ): + description = "" + if item.deprecated and self.options.enable_deprecated: + if "deprecated" in item.deprecated.lower(): + description = f"**{item.deprecated}**
" + else: + deprecated_msg = self.options.deprecated_md_snippet().format( + item.deprecated + ) + description = f"{deprecated_msg}
" + elif item.stability == StabilityLevel.STABLE and self.options.enable_stable: + description = f"{self.options.stable_md_snippet()}
" + elif ( + item.stability == StabilityLevel.EXPERIMENTAL + and self.options.enable_experimental + ): + description = f"{self.options.experimental_md_snippet()}
" + + return description diff --git a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml index a26c943f..d83717a1 100644 --- a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml @@ -22,3 +22,4 @@ groups: brief: "Request headers." note: "Request headers note." examples: '`first.fifth_attr.bar=["foo"]`' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml index 74f0d577..4664a214 100644 --- a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml @@ -10,6 +10,7 @@ groups: brief: "first attribute" note: "first attribute note" examples: "first example" + stability: experimental - id: second_attr type: int brief: "second attribute" diff --git a/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml index 74f0d577..4664a214 100644 --- a/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml @@ -10,6 +10,7 @@ groups: brief: "first attribute" note: "first attribute note" examples: "first example" + stability: experimental - id: second_attr type: int brief: "second attribute" diff --git a/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml b/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml index 5d674714..5d3189d3 100644 --- a/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml @@ -10,6 +10,7 @@ groups: brief: "first attribute" note: "first attribute note" examples: "first example" + stability: experimental - id: second_attr type: int brief: "second attribute" @@ -20,3 +21,4 @@ groups: type: template[string[]] brief: "request headers" examples: '`first.fifth_attr.foo=["bar"]`' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/success/vprev.yaml b/semantic-conventions/src/tests/data/compat/success/vprev.yaml index 8fc72dc2..0c3ca727 100644 --- a/semantic-conventions/src/tests/data/compat/success/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/success/vprev.yaml @@ -10,6 +10,7 @@ groups: brief: "first attribute" note: "first attribute note" examples: "first example" + stability: experimental - id: second_attr type: int brief: "second attribute" diff --git a/semantic-conventions/src/tests/data/markdown/attribute_group/attribute_group.yaml b/semantic-conventions/src/tests/data/markdown/attribute_group/attribute_group.yaml index 9aee0e17..5b2fab95 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_group/attribute_group.yaml +++ b/semantic-conventions/src/tests/data/markdown/attribute_group/attribute_group.yaml @@ -6,10 +6,11 @@ groups: attributes: - id: bar type: string - requirement_level: + requirement_level: recommended: if available brief: Attribute 1 examples: ['baz'] + stability: experimental - id: derived_attributes type: attribute_group @@ -19,10 +20,11 @@ groups: attributes: - id: qux type: int - requirement_level: + requirement_level: conditionally_required: if available brief: Attribute 2 examples: [42] + stability: experimental - id: span_attribute_group prefix: "" diff --git a/semantic-conventions/src/tests/data/markdown/attribute_templates/attribute_templates.yaml b/semantic-conventions/src/tests/data/markdown/attribute_templates/attribute_templates.yaml index ebaa1644..8bec259c 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_templates/attribute_templates.yaml +++ b/semantic-conventions/src/tests/data/markdown/attribute_templates/attribute_templates.yaml @@ -14,12 +14,14 @@ groups: HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. examples: '`http.request.header.content_type=["application/json"]`' + stability: experimental - id: request.method type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] + stability: experimental - ref: referenced_http.request.referenced.header - id: referenced_http_id type: span @@ -31,6 +33,7 @@ groups: brief: > This is a referenced attribute. examples: '`http.request.header.content_type=["application/json"]`' + stability: experimental - id: general type: span prefix: general @@ -41,3 +44,4 @@ groups: brief: > This is a general attribute. examples: '`some_general_attribute.some_key="abc"`' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml b/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml index 32cc7f48..907fd00a 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml @@ -6,6 +6,7 @@ groups: These attributes may be used for any network related operation. attributes: - id: transport + stability: experimental type: allow_custom_values: false members: @@ -36,28 +37,34 @@ groups: Transport protocol used. See note below. examples: 'IP.TCP' - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -68,16 +75,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml b/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml index b41ca89e..4f668d6d 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml @@ -8,43 +8,51 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: "if and only if one was received/sent" brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' deprecated: Use attribute `status_description` instead. examples: ['OK'] - id: flavor + stability: experimental type: # Default value: `true`. If false, it helps the code gen tool to # encode checks that only accept the listed values. @@ -72,6 +80,7 @@ groups: is `QUIC`, in which case `IP.UDP` is assumed. examples: ['1.0'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -95,6 +104,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > diff --git a/semantic-conventions/src/tests/data/markdown/empty/general.yaml b/semantic-conventions/src/tests/data/markdown/empty/general.yaml index 32cc7f48..907fd00a 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty/general.yaml @@ -6,6 +6,7 @@ groups: These attributes may be used for any network related operation. attributes: - id: transport + stability: experimental type: allow_custom_values: false members: @@ -36,28 +37,34 @@ groups: Transport protocol used. See note below. examples: 'IP.TCP' - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -68,16 +75,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/empty/http.yaml b/semantic-conventions/src/tests/data/markdown/empty/http.yaml index 66cc08b1..96300950 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty/http.yaml @@ -8,6 +8,7 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false @@ -20,30 +21,36 @@ groups: Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. See note [1] examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: "if and only if one was received/sent" brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -67,6 +74,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > diff --git a/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml b/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml index 8c3288cc..648eb26e 100644 --- a/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml b/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml index 32cc7f48..907fd00a 100644 --- a/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml @@ -6,6 +6,7 @@ groups: These attributes may be used for any network related operation. attributes: - id: transport + stability: experimental type: allow_custom_values: false members: @@ -36,28 +37,34 @@ groups: Transport protocol used. See note below. examples: 'IP.TCP' - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -68,16 +75,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/empty_table/http.yaml b/semantic-conventions/src/tests/data/markdown/empty_table/http.yaml index c27fcba5..c754967f 100644 --- a/semantic-conventions/src/tests/data/markdown/empty_table/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty_table/http.yaml @@ -8,42 +8,50 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -67,6 +75,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -81,11 +90,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml b/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml index 601d05a2..1c13a243 100644 --- a/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml +++ b/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml @@ -5,6 +5,7 @@ groups: brief: 'Tech-specific attributes for gRPC.' attributes: - id: status_code + stability: experimental type: members: - id: ok diff --git a/semantic-conventions/src/tests/data/markdown/event/event.yaml b/semantic-conventions/src/tests/data/markdown/event/event.yaml index e90e4a21..ba74c1ae 100644 --- a/semantic-conventions/src/tests/data/markdown/event/event.yaml +++ b/semantic-conventions/src/tests/data/markdown/event/event.yaml @@ -7,15 +7,18 @@ groups: report a single exception associated with a span. attributes: - id: type + stability: experimental type: string brief: > The type of the exception. examples: ["java.net.ConnectException","OSError"] - id: message + stability: experimental type: string brief: The exception message. examples: ["Division by zero","Can't convert 'int' object to str implicitly"] - id: stacktrace + stability: experimental type: string brief: > A stacktrace. @@ -24,6 +27,7 @@ groups: at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)' - id: escaped + stability: experimental type: boolean brief: > SHOULD be set to true if the exception event is recorded at a point where diff --git a/semantic-conventions/src/tests/data/markdown/event_noprefix/event.yaml b/semantic-conventions/src/tests/data/markdown/event_noprefix/event.yaml index 3e41bf3c..ff215b42 100644 --- a/semantic-conventions/src/tests/data/markdown/event_noprefix/event.yaml +++ b/semantic-conventions/src/tests/data/markdown/event_noprefix/event.yaml @@ -7,3 +7,4 @@ groups: - id: attr type: boolean brief: attrbrief + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/event_renamed/event.yaml b/semantic-conventions/src/tests/data/markdown/event_renamed/event.yaml index f90d2e53..5b79be99 100644 --- a/semantic-conventions/src/tests/data/markdown/event_renamed/event.yaml +++ b/semantic-conventions/src/tests/data/markdown/event_renamed/event.yaml @@ -8,3 +8,4 @@ groups: - id: attr type: boolean brief: attrbrief + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/example_array/http.yaml b/semantic-conventions/src/tests/data/markdown/example_array/http.yaml index 2f90ce2d..4c884123 100644 --- a/semantic-conventions/src/tests/data/markdown/example_array/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/example_array/http.yaml @@ -8,6 +8,7 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string[] requirement_level: required sampling_relevant: false diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml b/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml index a9427dc7..a64b6d85 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml @@ -8,6 +8,7 @@ groups: span_kind: client attributes: - id: system + stability: experimental tag: connection-level brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. requirement_level: required @@ -144,6 +145,7 @@ groups: value: 'neo4j' brief: 'Neo4j' - id: connection_string + stability: experimental tag: connection-level type: string brief: > @@ -151,12 +153,14 @@ groups: note: It is recommended to remove embedded credentials. examples: 'Server=(localdb)\v11.0;Integrated Security=true;' - id: user + stability: experimental tag: connection-level type: string brief: > Username for accessing the database. examples: ['readonly_user', 'reporting_user'] - id: mssql.instance_name + stability: experimental tag: connection-level-tech-specific type: string note: > @@ -167,12 +171,14 @@ groups: connecting to. This name is used to determine the port of a named instance. examples: 'MSSQLSERVER' - id: jdbc.driver_classname + stability: experimental tag: connection-level-tech-specific type: string brief: > The fully-qualified class name of the JDBC driver used to connect. examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - id: name + stability: experimental tag: call-level type: string requirement_level: @@ -185,6 +191,7 @@ groups: In some SQL databases, the database name to be used is called "schema name". examples: [ 'customers', 'main' ] - id: statement + stability: experimental tag: call-level type: string requirement_level: @@ -194,6 +201,7 @@ groups: note: The value may be sanitized to exclude sensitive information. examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] - id: operation + stability: experimental tag: call-level type: string requirement_level: @@ -231,6 +239,7 @@ groups: Call-level attributes for Cassandra attributes: - id: keyspace + stability: experimental type: string requirement_level: required brief: > @@ -245,6 +254,7 @@ groups: Call-level attributes for Apache HBase attributes: - id: namespace + stability: experimental type: string requirement_level: required brief: > @@ -260,6 +270,7 @@ groups: Call-level attributes for Redis attributes: - id: database_index + stability: experimental type: int requirement_level: conditionally_required: if other than the default database (`0`). @@ -276,6 +287,7 @@ groups: Call-level attributes for MongoDB attributes: - id: collection + stability: experimental type: string requirement_level: required brief: > diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml b/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml index 32cc7f48..907fd00a 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml @@ -6,6 +6,7 @@ groups: These attributes may be used for any network related operation. attributes: - id: transport + stability: experimental type: allow_custom_values: false members: @@ -36,28 +37,34 @@ groups: Transport protocol used. See note below. examples: 'IP.TCP' - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -68,16 +75,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/extend_grandparent/database.yaml b/semantic-conventions/src/tests/data/markdown/extend_grandparent/database.yaml index af4aaa1d..ef74b20f 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_grandparent/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/extend_grandparent/database.yaml @@ -5,6 +5,7 @@ groups: brief: These attributes describe database calls. attributes: - id: name + stability: experimental brief: Database name. type: string examples: [ 'the_shop' ] @@ -16,6 +17,7 @@ groups: extends: database.common_attributes attributes: - id: bar + stability: experimental brief: Some property. type: string examples: [ 'baz' ] @@ -28,6 +30,7 @@ groups: - id: database.foo.duration.metric type: metric + stability: experimental metric_name: db.foo.duration instrument: histogram unit: s diff --git a/semantic-conventions/src/tests/data/markdown/include/faas.yaml b/semantic-conventions/src/tests/data/markdown/include/faas.yaml index bfca14c3..b9d592b1 100644 --- a/semantic-conventions/src/tests/data/markdown/include/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/include/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/include/general.yaml b/semantic-conventions/src/tests/data/markdown/include/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/include/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/include/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/include/http.yaml b/semantic-conventions/src/tests/data/markdown/include/http.yaml index 65ed4497..2bd266f2 100644 --- a/semantic-conventions/src/tests/data/markdown/include/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/include/http.yaml @@ -8,56 +8,66 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: "if and only if one was received/sent" brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string requirement_level: recommended brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] - id: recommended_attribute + stability: experimental brief: brief type: string - requirement_level: + requirement_level: recommended: short note examples: foo - id: recommended_attribute_long_note + stability: experimental brief: brief type: string - requirement_level: + requirement_level: recommended: some very long note that should be written under the semconv table examples: bar @@ -81,6 +91,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -93,7 +104,7 @@ groups: This is an example - of note - - with list + - with list examples: ['example.com'] constraints: - any_of: diff --git a/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md b/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md index 253863ba..8074bd93 100644 --- a/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md +++ b/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md @@ -21,7 +21,7 @@ | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `foo.active_eggs` | UpDownCounter | `{cartons}` | Measures how many eggs are currently active. | +| `foo.active_eggs` | UpDownCounter | `{cartons}` | **Deprecated: Removed.**
Measures how many eggs are currently active. | **Attributes for `foo.active_eggs`** diff --git a/semantic-conventions/src/tests/data/markdown/missing_end_tag/general.yaml b/semantic-conventions/src/tests/data/markdown/missing_end_tag/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/missing_end_tag/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/missing_end_tag/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/missing_end_tag/http.yaml b/semantic-conventions/src/tests/data/markdown/missing_end_tag/http.yaml index c9e672bd..de43aad4 100644 --- a/semantic-conventions/src/tests/data/markdown/missing_end_tag/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/missing_end_tag/http.yaml @@ -8,42 +8,50 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: "if and only if one was received/sent" brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -67,6 +75,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > diff --git a/semantic-conventions/src/tests/data/markdown/multiple/general.yaml b/semantic-conventions/src/tests/data/markdown/multiple/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/multiple/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/multiple/http.yaml b/semantic-conventions/src/tests/data/markdown/multiple/http.yaml index c9e672bd..de43aad4 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/multiple/http.yaml @@ -8,42 +8,50 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: "if and only if one was received/sent" brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -67,6 +75,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > diff --git a/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml b/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml index ea444b9e..650de793 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml @@ -6,6 +6,7 @@ groups: These attributes may be used for any network related operation. attributes: - id: transport + stability: experimental type: allow_custom_values: false members: @@ -36,6 +37,7 @@ groups: Transport protocol used. See note below. examples: 'IP.TCP' - id: host.connection.type + stability: experimental type: allow_custom_values: true members: @@ -51,6 +53,7 @@ groups: brief: 'unavailable' examples: 'wifi' - id: host.connection.subtype + stability: experimental type: allow_custom_values: true members: @@ -65,44 +68,54 @@ groups: brief: 'This describes more details regarding the connection.type. It may be the type of cell connection, but it could be used for describing details about a wifi connection.' examples: '2G' - id: host.carrier.name + stability: experimental type: string brief: "host.carrier.name" examples: "sprint" - id: host.carrier.mcc + stability: experimental type: string brief: "host.carrier.mcc" examples: "310" - id: host.carrier.mnc + stability: experimental type: string brief: "host.carrier.mnc" examples: "001" - id: host.carrier.icc + stability: experimental type: string brief: "host.carrier.icc" examples: "DE" - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -113,16 +126,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/omit_requirement_level/http.yaml b/semantic-conventions/src/tests/data/markdown/omit_requirement_level/http.yaml index 0186d65e..7db0d45c 100644 --- a/semantic-conventions/src/tests/data/markdown/omit_requirement_level/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/omit_requirement_level/http.yaml @@ -8,18 +8,21 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] diff --git a/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml index 8c3288cc..648eb26e 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/parameter_empty/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_empty/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_empty/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_empty/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_empty/http.yaml b/semantic-conventions/src/tests/data/markdown/parameter_empty/http.yaml index 211caf66..c7281bd6 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_empty/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_empty/http.yaml @@ -8,42 +8,50 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -67,6 +75,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -81,11 +90,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml index 1fd67a8d..0fb1cad4 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_full/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/http.yaml b/semantic-conventions/src/tests/data/markdown/parameter_full/http.yaml index 1b732061..f3fbdb4b 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml index 673ccd69..ebad25df 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml @@ -9,6 +9,7 @@ groups: span_kind: client attributes: - id: type + stability: experimental tag: connection-level type: allow_custom_values: true @@ -39,6 +40,7 @@ groups: Database type. For any SQL database, "sql". For others, the lower-case database category. - id: dbms + stability: experimental type: allow_custom_values: true members: @@ -146,6 +148,7 @@ groups: brief: > An identifier for the DBMS (database management system) product - id: connection_string + stability: experimental tag: connection-level type: string note: 'It is recommended to remove embedded credentials.' @@ -153,12 +156,14 @@ groups: The connection string used to connect to the database. examples: 'Server=(localdb)\v11.0;Integrated Security=true;' - id: user + stability: experimental tag: connection-level type: string brief: > Username for accessing the database. examples: ['readonly_user', 'reporting_user'] - id: mssql.instance_name + stability: experimental type: string note: > If setting a `db.mssql.instance_name`, `net.peer.port` is no longer @@ -168,11 +173,13 @@ groups: connecting to. This name is used to determine the port of a named instance. examples: 'MSSQLSERVER' - id: jdbc.driver_classname + stability: experimental type: string brief: > The fully-qualified class name of the JDBC driver used to connect. examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - id: name + stability: experimental type: string requirement_level: conditionally_required: > @@ -186,6 +193,7 @@ groups: Redis does not have a database name to used here. examples: [ 'customers', 'master' ] - id: statement + stability: experimental type: string requirement_level: conditionally_required: if applicable. @@ -194,6 +202,7 @@ groups: A database statement for the given database type. examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] - id: operation + stability: experimental type: string requirement_level: conditionally_required: if `db.statement` is not applicable. @@ -222,6 +231,7 @@ groups: Call-level attributes for Cassandra attributes: - id: keyspace + stability: experimental type: string requirement_level: required brief: > @@ -235,6 +245,7 @@ groups: Call-level attributes for Apache HBase attributes: - id: namespace + stability: experimental type: string requirement_level: required brief: > @@ -249,8 +260,9 @@ groups: Call-level attributes for MongoDB attributes: - id: collection + stability: experimental type: string requirement_level: required brief: > The collection being accessed within the database stated in `db.name`. - examples: [ 'customers', 'products' ] + examples: [ 'customers', 'products' ] diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/general.yaml index 1340605b..56bbfd48 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml index 54011f6f..36240552 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml @@ -9,6 +9,7 @@ groups: span_kind: client attributes: - id: type + stability: experimental tag: connection-level type: allow_custom_values: true @@ -39,6 +40,7 @@ groups: Database type. For any SQL database, "sql". For others, the lower-case database category. - id: dbms + stability: experimental type: allow_custom_values: true members: @@ -146,6 +148,7 @@ groups: brief: > An identifier for the DBMS (database management system) product - id: connection_string + stability: experimental tag: connection-level type: string note: 'It is recommended to remove embedded credentials.' @@ -153,12 +156,14 @@ groups: The connection string used to connect to the database. examples: 'Server=(localdb)\v11.0;Integrated Security=true;' - id: user + stability: experimental tag: connection-level type: string brief: > Username for accessing the database. examples: ['readonly_user', 'reporting_user'] - id: mssql.instance_name + stability: experimental type: string note: > If setting a `db.mssql.instance_name`, `net.peer.port` is no longer @@ -168,11 +173,13 @@ groups: connecting to. This name is used to determine the port of a named instance. examples: 'MSSQLSERVER' - id: jdbc.driver_classname + stability: experimental type: string brief: > The fully-qualified class name of the JDBC driver used to connect. examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - id: name + stability: experimental type: string requirement_level: conditionally_required: > @@ -186,6 +193,7 @@ groups: Redis does not have a database name to used here. examples: [ 'customers', 'master' ] - id: statement + stability: experimental type: string requirement_level: conditionally_required: if applicable. @@ -194,6 +202,7 @@ groups: A database statement for the given database type. examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] - id: operation + stability: experimental type: string requirement_level: conditionally_required: if `db.statement` is not applicable. @@ -222,6 +231,7 @@ groups: Call-level attributes for Cassandra attributes: - id: keyspace + stability: experimental type: string requirement_level: required brief: > @@ -235,6 +245,7 @@ groups: Call-level attributes for Apache HBase attributes: - id: namespace + stability: experimental type: string requirement_level: required brief: > @@ -249,8 +260,9 @@ groups: Call-level attributes for MongoDB attributes: - id: collection + stability: experimental type: string requirement_level: required brief: > The collection being accessed within the database stated in `db.name`. - examples: [ 'customers', 'products' ] + examples: [ 'customers', 'products' ] diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml index 00d3136f..7bb4e580 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml @@ -9,6 +9,7 @@ groups: span_kind: client attributes: - id: type + stability: experimental tag: connection-level type: allow_custom_values: true @@ -39,6 +40,7 @@ groups: Database type. For any SQL database, "sql". For others, the lower-case database category. - id: dbms + stability: experimental type: allow_custom_values: true members: @@ -146,6 +148,7 @@ groups: brief: > An identifier for the DBMS (database management system) product - id: connection_string + stability: experimental tag: connection-level type: string note: 'It is recommended to remove embedded credentials.' @@ -153,12 +156,14 @@ groups: The connection string used to connect to the database. examples: 'Server=(localdb)\v11.0;Integrated Security=true;' - id: user + stability: experimental tag: connection-level type: string brief: > Username for accessing the database. examples: ['readonly_user', 'reporting_user'] - id: mssql.instance_name + stability: experimental type: string note: > If setting a `db.mssql.instance_name`, `net.peer.port` is no longer @@ -168,11 +173,13 @@ groups: connecting to. This name is used to determine the port of a named instance. examples: 'MSSQLSERVER' - id: jdbc.driver_classname + stability: experimental type: string brief: > The fully-qualified class name of the JDBC driver used to connect. examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - id: name + stability: experimental type: string requirement_level: conditionally_required: > @@ -186,6 +193,7 @@ groups: Redis does not have a database name to used here. examples: [ 'customers', 'master' ] - id: statement + stability: experimental type: string requirement_level: conditionally_required: if applicable. @@ -194,6 +202,7 @@ groups: A database statement for the given database type. examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] - id: operation + stability: experimental type: string requirement_level: conditionally_required: if `db.statement` is not applicable. @@ -221,6 +230,7 @@ groups: Call-level attributes for Cassandra attributes: - id: keyspace + stability: experimental type: string requirement_level: required brief: > @@ -234,6 +244,7 @@ groups: Call-level attributes for Apache HBase attributes: - id: namespace + stability: experimental type: string requirement_level: required brief: > @@ -248,8 +259,9 @@ groups: Call-level attributes for MongoDB attributes: - id: collection + stability: experimental type: string requirement_level: required brief: > The collection being accessed within the database stated in `db.name`. - examples: [ 'customers', 'products' ] + examples: [ 'customers', 'products' ] diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/general.yaml index c4ecd8bc..8ff48838 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_no_attr/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag_no_attr/database.yaml index 8caf272d..05e2239f 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_no_attr/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_no_attr/database.yaml @@ -6,6 +6,7 @@ groups: span_kind: client attributes: - id: type + stability: experimental tag: connection-level type: boolean requirement_level: required diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong/faas.yaml index 8c3288cc..648eb26e 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong/http.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong/http.yaml index 1b732061..f3fbdb4b 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/faas.yaml index 1fd67a8d..0fb1cad4 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/http.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/http.yaml index 1b732061..f3fbdb4b 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong_duplicate/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/faas.yaml index 1fd67a8d..0fb1cad4 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/general.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/http.yaml b/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/http.yaml index 1b732061..f3fbdb4b 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_wrong_syntax/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/ref/general.yaml b/semantic-conventions/src/tests/data/markdown/ref/general.yaml index 4472178f..a1ebb62a 100644 --- a/semantic-conventions/src/tests/data/markdown/ref/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/ref/general.yaml @@ -6,43 +6,52 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' - id: sock.peer.name + stability: experimental type: string brief: Remote socket peer name. requirement_level: recommended: If available and different than `net.peer.name` and if `net.sock.peer.addr` is set. examples: proxy.example.com - id: sock.peer.addr + stability: experimental type: string brief: > Remote socket peer address. examples: ['127.0.0.1', '/tmp/mysql.sock' ] - id: sock.peer.port + stability: experimental type: int brief: Remote socket peer port. requirement_level: @@ -55,16 +64,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/ref/http.yaml b/semantic-conventions/src/tests/data/markdown/ref/http.yaml index 1b732061..f3fbdb4b 100644 --- a/semantic-conventions/src/tests/data/markdown/ref/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/ref/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/ref/rpc.yaml b/semantic-conventions/src/tests/data/markdown/ref/rpc.yaml index 58e932b2..a41dc390 100644 --- a/semantic-conventions/src/tests/data/markdown/ref/rpc.yaml +++ b/semantic-conventions/src/tests/data/markdown/ref/rpc.yaml @@ -5,6 +5,7 @@ groups: brief: 'This document defines semantic conventions for remote procedure calls.' attributes: - id: service + stability: experimental type: string requirement_level: required brief: 'The service name, must be equal to the $service part in the span name.' diff --git a/semantic-conventions/src/tests/data/markdown/ref_extends/http.yaml b/semantic-conventions/src/tests/data/markdown/ref_extends/http.yaml index 89cd5a5e..347a75f1 100644 --- a/semantic-conventions/src/tests/data/markdown/ref_extends/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/ref_extends/http.yaml @@ -19,6 +19,7 @@ groups: - id: http.client.request.duration.metric type: metric + stability: experimental metric_name: http.client.request.duration brief: "Measures request duration." instrument: histogram diff --git a/semantic-conventions/src/tests/data/markdown/ref_extends/server.yaml b/semantic-conventions/src/tests/data/markdown/ref_extends/server.yaml index 0b25c86f..a6e144b4 100644 --- a/semantic-conventions/src/tests/data/markdown/ref_extends/server.yaml +++ b/semantic-conventions/src/tests/data/markdown/ref_extends/server.yaml @@ -5,6 +5,7 @@ groups: brief: 'This document defines semantic conventions for common server attributes.' attributes: - id: address + stability: experimental type: string brief: 'Domain name. (original brief)' examples: 'foo' diff --git a/semantic-conventions/src/tests/data/markdown/sampling_relevant/general.yaml b/semantic-conventions/src/tests/data/markdown/sampling_relevant/general.yaml index 016be000..a256ef13 100644 --- a/semantic-conventions/src/tests/data/markdown/sampling_relevant/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/sampling_relevant/general.yaml @@ -6,14 +6,17 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: . examples: '.' - id: peer.port + stability: experimental type: int brief: . examples: [] - id: peer.name + stability: experimental type: string brief: . examples: '.' diff --git a/semantic-conventions/src/tests/data/markdown/sampling_relevant/http.yaml b/semantic-conventions/src/tests/data/markdown/sampling_relevant/http.yaml index 4fb47954..808799dd 100644 --- a/semantic-conventions/src/tests/data/markdown/sampling_relevant/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/sampling_relevant/http.yaml @@ -4,12 +4,14 @@ groups: brief: 'This document defines semantic conventions for HTTP client and server Spans.' attributes: - id: method + stability: experimental type: string requirement_level: required brief: . sampling_relevant: true examples: ["GET"] - id: url + stability: experimental type: string brief: . note: > @@ -18,27 +20,32 @@ groups: sampling_relevant: true examples: ['.'] - id: target + stability: experimental type: string brief: . sampling_relevant: true examples: ['.'] - id: host + stability: experimental type: string brief: . sampling_relevant: true examples: ['.'] - id: scheme + stability: experimental type: string brief: . sampling_relevant: true examples: ["http"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: brief: . examples: [] - id: user_agent + stability: experimental type: string brief: . examples: ['.'] diff --git a/semantic-conventions/src/tests/data/markdown/scope/scope.yaml b/semantic-conventions/src/tests/data/markdown/scope/scope.yaml index 12036dbf..ab0c8ce0 100644 --- a/semantic-conventions/src/tests/data/markdown/scope/scope.yaml +++ b/semantic-conventions/src/tests/data/markdown/scope/scope.yaml @@ -6,6 +6,7 @@ groups: Instrumentation Scope attributes attributes: - id: short_name + stability: experimental type: string requirement_level: recommended brief: > diff --git a/semantic-conventions/src/tests/data/markdown/single/general.yaml b/semantic-conventions/src/tests/data/markdown/single/general.yaml index fba8c3bf..bebaef5d 100644 --- a/semantic-conventions/src/tests/data/markdown/single/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/single/general.yaml @@ -6,27 +6,33 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -37,16 +43,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/single/http.yaml b/semantic-conventions/src/tests/data/markdown/single/http.yaml index 1b732061..f3fbdb4b 100644 --- a/semantic-conventions/src/tests/data/markdown/single/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/single/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/markdown/sorting/input.yaml b/semantic-conventions/src/tests/data/markdown/sorting/input.yaml index 50260364..a33ec950 100644 --- a/semantic-conventions/src/tests/data/markdown/sorting/input.yaml +++ b/semantic-conventions/src/tests/data/markdown/sorting/input.yaml @@ -5,10 +5,12 @@ groups: brief: 'Attributes that appear last.' attributes: - id: yyy + stability: experimental type: string brief: 'the 6th attribute' examples: 'yyy' - id: xxx + stability: experimental type: string brief: 'the 5th attribute' examples: 'xxx' @@ -19,6 +21,7 @@ groups: brief: 'Attributes that appear first.' attributes: - id: aaa + stability: experimental type: string brief: 'the 1st attribute' examples: 'aaa' @@ -29,6 +32,7 @@ groups: brief: 'Attributes that appear after `mmm`.' attributes: - id: nnn + stability: experimental type: string brief: 'the 4th attribute' examples: 'nnn' @@ -40,10 +44,12 @@ groups: extends: nnn attributes: - id: ccc + stability: experimental type: template[string] brief: the 3rd attribute examples: '`mmm.ccc="ccc"`' - id: bbb + stability: experimental type: string brief: the 2nd attribute examples: 'bbb' diff --git a/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md new file mode 100644 index 00000000..856f8a0c --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md @@ -0,0 +1,44 @@ + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | +|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | +|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | +|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | + + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `stable_metric` | Histogram | `s` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
stable_metric | + + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `experimental_metric` | Counter | `{e}` | ![Experimental](https://img.shields.io/badge/-experimental-blue)
experimental_metric | + + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `deprecated_metric` | UpDownCounter | `{d}` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
deprecated_metric | + \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md deleted file mode 100644 index 8c53eba4..00000000 --- a/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md +++ /dev/null @@ -1,10 +0,0 @@ -# Common Attributes - - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.def_stability`](labels_expected.md) | boolean | | | `Required` | -| [`test.deprecated_attr`](labels_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](labels_expected.md) | boolean | | | `Required` | -| [`test.stable_attr`](labels_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | - diff --git a/semantic-conventions/src/tests/data/markdown/stability/input.md b/semantic-conventions/src/tests/data/markdown/stability/input.md index 0109ba90..f699ebb8 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/input.md +++ b/semantic-conventions/src/tests/data/markdown/stability/input.md @@ -1,5 +1,17 @@ -# Common Attributes - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md b/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md deleted file mode 100644 index d6edf766..00000000 --- a/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md +++ /dev/null @@ -1,10 +0,0 @@ -# Common Attributes - - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.def_stability`](labels_expected.md) | boolean | | | `Required` | -| [`test.deprecated_attr`](labels_expected.md) | boolean | **Deprecated: Removed.**
| | `Required` | -| [`test.exp_attr`](labels_expected.md) | boolean | | | `Required` | -| [`test.stable_attr`](labels_expected.md) | boolean | | | `Required` | - diff --git a/semantic-conventions/src/tests/data/markdown/stability/stability.yaml b/semantic-conventions/src/tests/data/markdown/stability/stability.yaml index 14ed4783..6ad528db 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/stability.yaml +++ b/semantic-conventions/src/tests/data/markdown/stability/stability.yaml @@ -14,13 +14,53 @@ groups: requirement_level: required stability: stable brief: "" - - id: deprecated_attr + - id: deprecated_stable_attr type: boolean requirement_level: required stability: stable deprecated: "Removed." brief: "" - - id: def_stability + - id: deprecated_experimental_attr type: boolean requirement_level: required + stability: experimental + deprecated: "Removed." brief: "" + - id: ref_test + brief: 'ref_test' + attributes: + - ref: test.exp_attr + - ref: test.stable_attr + - ref: test.deprecated_stable_attr + - ref: test.deprecated_experimental_attr + - id: extends_test + brief: 'extends_test' + extends: test + - id: stable_metric + type: metric + brief: 'stable_metric' + stability: stable + metric_name: stable_metric + instrument: histogram + unit: "s" + attributes: + - ref: test.stable_attr + - id: experimental_metric + type: metric + brief: 'experimental_metric' + stability: experimental + metric_name: experimental_metric + instrument: counter + unit: "{e}" + attributes: + - ref: test.exp_attr + - id: deprecated_metric + type: metric + brief: 'deprecated_metric' + stability: stable + deprecated: "Removed." + metric_name: deprecated_metric + instrument: updowncounter + unit: "{d}" + attributes: + - ref: test.deprecated_experimental_attr \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md new file mode 100644 index 00000000..b1e779ad --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md @@ -0,0 +1,44 @@ + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | +|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | +|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | +|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | + + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `stable_metric` | Histogram | `s` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
stable_metric | + + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `experimental_metric` | Counter | `{e}` | experimental_metric | + + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `deprecated_metric` | UpDownCounter | `{d}` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
deprecated_metric | + \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/general.yaml b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/general.yaml index fed550d4..22af26ac 100644 --- a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/general.yaml @@ -6,28 +6,34 @@ groups: These attributes may be used for any network related operation. attributes: - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -38,16 +44,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/http.yaml b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/http.yaml index aa650b1a..11802496 100644 --- a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/http.yaml @@ -8,22 +8,26 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). @@ -32,20 +36,24 @@ groups: requirement_level: conditionally_required: . - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: if and only if one was received/sent. brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -69,6 +77,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > @@ -83,11 +92,13 @@ groups: It is thus preferred to supply the raw data that is available. examples: ['example.com'] - id: route + stability: experimental type: string brief: > The matched route (path template). examples: '/users/:userID?' - id: client_ip + stability: experimental type: string sampling_relevant: false brief: > diff --git a/semantic-conventions/src/tests/data/yaml/attr_templates_code/attribute_templates.yml b/semantic-conventions/src/tests/data/yaml/attr_templates_code/attribute_templates.yml index d56a0bba..355db758 100644 --- a/semantic-conventions/src/tests/data/yaml/attr_templates_code/attribute_templates.yml +++ b/semantic-conventions/src/tests/data/yaml/attr_templates_code/attribute_templates.yml @@ -1,9 +1,10 @@ -groups: +groups: - id: test type: attribute_group brief: 'brief' attributes: - id: attribute_template_one + stability: experimental tag: tag-one type: template[string] brief: > @@ -11,6 +12,7 @@ groups: the first attribute template examples: 'This is a good example of the first attribute template' - id: attribute_template_two + stability: experimental tag: tag-two type: template[int] brief: > @@ -18,6 +20,7 @@ groups: the second attribute template. It's a number. examples: [1000, 10, 1] - id: attribute_three + stability: experimental tag: tag-three type: boolean brief: > diff --git a/semantic-conventions/src/tests/data/yaml/attribute_templates.yml b/semantic-conventions/src/tests/data/yaml/attribute_templates.yml index d9ec04c8..05fe20e5 100644 --- a/semantic-conventions/src/tests/data/yaml/attribute_templates.yml +++ b/semantic-conventions/src/tests/data/yaml/attribute_templates.yml @@ -1,5 +1,6 @@ attributes: - id: attribute_template_one + stability: experimental tag: tag-one type: template[string] brief: > @@ -7,6 +8,7 @@ attributes: the first attribute template examples: 'This is a good example of the first attribute template' - id: attribute_template_two + stability: experimental tag: tag-two type: template[int] brief: > @@ -14,6 +16,7 @@ attributes: the second attribute template. It's a number. examples: [1000, 10, 1] - id: attribute_three + stability: experimental tag: tag-three type: boolean brief: > diff --git a/semantic-conventions/src/tests/data/yaml/basic_example.yml b/semantic-conventions/src/tests/data/yaml/basic_example.yml index dc6274bc..e252f90d 100644 --- a/semantic-conventions/src/tests/data/yaml/basic_example.yml +++ b/semantic-conventions/src/tests/data/yaml/basic_example.yml @@ -6,6 +6,7 @@ groups: span_kind: server attributes: - id: attr_one + stability: experimental type: boolean brief: short description - id: second_group_id @@ -16,6 +17,7 @@ groups: extends: first_group_id attributes: - id: attr_two + stability: experimental type: string brief: short description examples: ['example_one', 'example_two'] \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/cloud.yaml b/semantic-conventions/src/tests/data/yaml/cloud.yaml index 3befe01d..a376ff21 100644 --- a/semantic-conventions/src/tests/data/yaml/cloud.yaml +++ b/semantic-conventions/src/tests/data/yaml/cloud.yaml @@ -6,6 +6,7 @@ groups: Attributes for a cloud infrastructure (e.g. GCP, Azure, AWS). attributes: - id: provider + stability: experimental type: allow_custom_values: true members: @@ -18,16 +19,19 @@ groups: brief: > Name of the cloud provider. - id: account.id + stability: experimental type: string brief: > The cloud account id used to identify different entities. examples: ['opentelemetry-user'] - id: region + stability: experimental type: string brief: > A specific geographical location where different entities can run. examples: ['us-central1'] - id: zone + stability: experimental type: string brief: > Zones are a sub set of the region connected through low-latency links. diff --git a/semantic-conventions/src/tests/data/yaml/database.yaml b/semantic-conventions/src/tests/data/yaml/database.yaml index 8112fd7c..31e7119f 100644 --- a/semantic-conventions/src/tests/data/yaml/database.yaml +++ b/semantic-conventions/src/tests/data/yaml/database.yaml @@ -7,6 +7,7 @@ groups: span_kind: client attributes: - id: type + stability: experimental type: string requirement_level: required brief: > @@ -14,6 +15,7 @@ groups: For others, the lower-case database category. examples: ['cassandra', 'hbase', 'redis'] - id: instance + stability: experimental type: string requirement_level: required brief: > @@ -22,6 +24,7 @@ groups: the instance name is "customers" examples: ['customers'] - id: statement + stability: experimental type: string requirement_level: required brief: > @@ -30,11 +33,13 @@ groups: sensitive information. examples: ['SELECT * FROM wuser_table', "SET mykey 'WuValue'"] - id: url + stability: experimental type: string requirement_level: required brief: 'JDBC substring' examples: ['mysql://db.example.com:3306'] - id: user + stability: experimental type: string brief: 'Username for accessing database.' examples: ['readonly_user','reporting_user'] diff --git a/semantic-conventions/src/tests/data/yaml/deprecated/http.yaml b/semantic-conventions/src/tests/data/yaml/deprecated/http.yaml index 7e68b2e3..e5c9b3e2 100644 --- a/semantic-conventions/src/tests/data/yaml/deprecated/http.yaml +++ b/semantic-conventions/src/tests/data/yaml/deprecated/http.yaml @@ -8,44 +8,29 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string - requirement_level: required - sampling_relevant: false deprecated: Use attribute `nonDepecrated`. brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string deprecated: Use attribute `nonDepecrated`. - brief: > - Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. - Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. + brief: "" examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - - id: host - type: string - brief: > - The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). - When the header is empty or not present, this attribute should be the same. - examples: ['www.example.org'] - - id: scheme - type: string - brief: 'The URI scheme identifying the used protocol.' - examples: ["http", "https"] - - id: status_code - type: int - requirement_level: - conditionally_required: "if and only if one was received/sent" - brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' - examples: [200] - - id: status_text - type: string - brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' - examples: ['OK'] - - id: user_agent - type: string - brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' - examples: ['CERN-LineMode/2.15 libwww/2.17b3'] \ No newline at end of file + - id: http.client + type: span + brief: "" + attributes: + - ref: http.method + - id: http.server + type: span + brief: "" + extends: http + diff --git a/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_boolean.yaml b/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_boolean.yaml index 7cd09130..ef346145 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_boolean.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_boolean.yaml @@ -10,3 +10,4 @@ groups: deprecated: 99 brief: 'test' examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_empty_string.yaml b/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_empty_string.yaml index 9de2d8a7..9dd7cd7b 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_empty_string.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_empty_string.yaml @@ -10,3 +10,4 @@ groups: deprecated: '' brief: 'test' examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_number.yaml b/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_number.yaml index 17897012..58bd4e7b 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_number.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/deprecated/deprecation_number.yaml @@ -10,3 +10,4 @@ groups: deprecated: True brief: 'test' examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/deprecated/extends_overrides_deprecation.yaml b/semantic-conventions/src/tests/data/yaml/errors/deprecated/extends_overrides_deprecation.yaml new file mode 100644 index 00000000..c74ad8c1 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/deprecated/extends_overrides_deprecation.yaml @@ -0,0 +1,20 @@ +groups: + - id: test + type: span + prefix: test + brief: "" + span_kind: client + attributes: + - id: convention_version + type: boolean + brief: 'test' + examples: [true, false] + stability: experimental + deprecated: "parent description" + - id: test_child + type: span + brief: "" + extends: test + attributes: + - ref: test.convention_version + deprecated: "Removed" \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/deprecated/multiple_deprecations.yaml b/semantic-conventions/src/tests/data/yaml/errors/deprecated/multiple_deprecations.yaml new file mode 100644 index 00000000..b83ffe5b --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/deprecated/multiple_deprecations.yaml @@ -0,0 +1,14 @@ +groups: + - id: test + type: span + prefix: test + brief: 'This document defines semantic conventions for test.' + span_kind: client + attributes: + - id: convention_version + type: boolean + deprecated: "first" + deprecated: "second" + brief: 'test' + examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/deprecated/ref_overrides_deprecation.yaml b/semantic-conventions/src/tests/data/yaml/errors/deprecated/ref_overrides_deprecation.yaml new file mode 100644 index 00000000..f8adeac5 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/deprecated/ref_overrides_deprecation.yaml @@ -0,0 +1,18 @@ +groups: + - id: test + type: span + prefix: test + brief: "" + span_kind: client + attributes: + - id: convention_version + type: boolean + brief: 'test' + examples: [true, false] + stability: experimental + - id: test_child + type: span + brief: "" + attributes: + - ref: test.convention_version + deprecated: "Removed" diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_enum.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_enum.yaml index 4d6ce117..fea267cd 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_enum.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_enum.yaml @@ -10,4 +10,5 @@ groups: allow_custom_values: false members: requirement_level: required - brief: 'test' \ No newline at end of file + brief: 'test' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean.yaml index a85ed435..dcbe52d0 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean.yaml @@ -6,6 +6,7 @@ groups: span_kind: client attributes: - id: convention_version + stability: experimental type: boolean requirement_level: required brief: 'test' \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean_array.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean_array.yaml index 38641a9b..d5db6048 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean_array.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_boolean_array.yaml @@ -8,4 +8,5 @@ groups: - id: convention_version type: boolean[] requirement_level: required - brief: 'test' \ No newline at end of file + brief: 'test' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml index a51f1730..98743a36 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml @@ -6,6 +6,7 @@ groups: span_kind: client attributes: - id: type + stability: experimental type: allow_custom_values: false members: diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_string.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_string.yaml index 02bebc47..1db8c96a 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_string.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_string.yaml @@ -6,6 +6,7 @@ groups: span_kind: client attributes: - id: convention_version + stability: experimental type: string requirement_level: required brief: 'test' \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty_type.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty_type.yaml index 6c0127f0..25e91a44 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty_type.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty_type.yaml @@ -7,4 +7,5 @@ groups: attributes: - id: test requirement_level: required - brief: 'test.' \ No newline at end of file + brief: 'test.' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_member_with_extra_keys.yaml b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_member_with_extra_keys.yaml index 1576e509..c89b43b8 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_member_with_extra_keys.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_member_with_extra_keys.yaml @@ -13,4 +13,5 @@ groups: type: shouldnt value: yesyes requirement_level: required - brief: 'test' \ No newline at end of file + brief: 'test' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml index c9a7dc64..02b97e43 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml @@ -14,3 +14,4 @@ groups: requirement_level: required brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." examples: [0.0, 1.0] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_extra_keys.yaml b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_extra_keys.yaml index b58c12be..c12f662f 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_extra_keys.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_extra_keys.yaml @@ -11,4 +11,5 @@ groups: allow_custom_values: false members: requirement_level: required - brief: 'test' \ No newline at end of file + brief: 'test' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/events/missing_event.yaml b/semantic-conventions/src/tests/data/yaml/errors/events/missing_event.yaml index 3a1f1940..baa5688f 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/events/missing_event.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/events/missing_event.yaml @@ -8,6 +8,7 @@ groups: brief: example attributes: - id: flag + stability: experimental type: boolean brief: An attribute. @@ -17,5 +18,6 @@ groups: brief: example attributes: - id: flag + stability: experimental type: boolean brief: An attribute. diff --git a/semantic-conventions/src/tests/data/yaml/errors/events/nameless_event.yaml b/semantic-conventions/src/tests/data/yaml/errors/events/nameless_event.yaml index 60830869..241ab1e4 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/events/nameless_event.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/events/nameless_event.yaml @@ -4,5 +4,6 @@ groups: brief: eventbrief attributes: - id: eventattr + stability: experimental type: boolean brief: eventattrbrief diff --git a/semantic-conventions/src/tests/data/yaml/errors/events/no_event_type.yaml b/semantic-conventions/src/tests/data/yaml/errors/events/no_event_type.yaml index 4b3b6fd9..4c12f680 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/events/no_event_type.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/events/no_event_type.yaml @@ -7,6 +7,7 @@ groups: brief: example attributes: - id: flag + stability: experimental type: boolean brief: An attribute. @@ -16,5 +17,6 @@ groups: brief: example attributes: - id: flag + stability: experimental type: boolean brief: An attribute. diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example.types.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example.types.yaml index 96a9fe3e..31e0e0f1 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example.types.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example.types.yaml @@ -10,16 +10,19 @@ groups: requirement_level: required brief: 'test' examples: [1,asd] + stability: experimental - id: convention_version type: int[] requirement_level: required brief: 'test' examples: [1,3] + stability: experimental - id: url type: string requirement_level: required brief: 'test' examples: ['http://1.2.3.4:5678/'] + stability: experimental - id: value type: allow_custom_values: false @@ -29,8 +32,10 @@ groups: note: 'val' requirement_level: required brief: 'test.' + stability: experimental - id: flag requirement_level: conditionally_required type: boolean brief: 'test' examples: [true] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool.yaml index 3bda4789..20d74d4c 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool.yaml @@ -10,3 +10,4 @@ groups: requirement_level: required brief: 'test' examples: [true, false, yes] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool_array.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool_array.yaml index 75353d99..ceb99ebc 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool_array.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_bool_array.yaml @@ -10,3 +10,4 @@ groups: requirement_level: required brief: 'test' examples: [[true,false], [true, 1]] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array.yaml index ad9a95dd..5f42780a 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array.yaml @@ -9,4 +9,5 @@ groups: type: int[] requirement_level: required brief: 'test' - examples: [1, asd] \ No newline at end of file + examples: [1, asd] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array_single.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array_single.yaml index 6a7a08f5..36c6c9cd 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array_single.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_number_array_single.yaml @@ -9,4 +9,5 @@ groups: type: int[] requirement_level: required brief: 'test' - examples: 1 \ No newline at end of file + examples: 1 + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_single_string.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_single_string.yaml index a8b6b7c1..31c7f6e2 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_single_string.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_single_string.yaml @@ -10,3 +10,4 @@ groups: requirement_level: required brief: 'test' examples: "asd" + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_string.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_string.yaml index a9ca4b2a..6cf91562 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_string.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_string.yaml @@ -10,3 +10,4 @@ groups: requirement_level: required brief: 'test' examples: ["asd", 'dsa', 123] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_string_array.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_string_array.yaml index b427aa9c..0de6efc0 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_string_array.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_string_array.yaml @@ -10,3 +10,4 @@ groups: requirement_level: required brief: 'test' examples: [["",'',"'",'"'],["asd", 'dsa', 123]] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/examples/example_wrong_type.yaml b/semantic-conventions/src/tests/data/yaml/errors/examples/example_wrong_type.yaml index 8e0a8610..2ebc0794 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/examples/example_wrong_type.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/examples/example_wrong_type.yaml @@ -10,3 +10,4 @@ groups: requirement_level: required brief: 'test' examples: [1,asd] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/id_clash/http.yaml b/semantic-conventions/src/tests/data/yaml/errors/id_clash/http.yaml index fff4dfa0..9e7ffcc4 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/id_clash/http.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/id_clash/http.yaml @@ -9,15 +9,19 @@ groups: type: int brief: t examples: 3495 + stability: experimental - id: request_content_length_uncompressed type: int brief: t examples: 3495 + stability: experimental - id: request_content_length type: int brief: t examples: 3495 + stability: experimental - id: response_content_length_uncompressed type: int brief: t - examples: 3495 \ No newline at end of file + examples: 3495 + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/id_clash/httpInherited.yaml b/semantic-conventions/src/tests/data/yaml/errors/id_clash/httpInherited.yaml index 31976666..be4cbd56 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/id_clash/httpInherited.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/id_clash/httpInherited.yaml @@ -6,6 +6,7 @@ groups: note: t attributes: - id: request_content_length + stability: experimental type: int brief: t examples: 3495 @@ -17,12 +18,14 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string sampling_relevant: false brief: t note: t examples: ['example.com'] - id: request_content_length + stability: experimental type: int brief: t examples: 3495 \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource2_faas.yaml b/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource2_faas.yaml index b51e724e..5a3322fe 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource2_faas.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource2_faas.yaml @@ -6,23 +6,27 @@ groups: Attributes for a serverless instance. attributes: - id: name + stability: experimental type: string requirement_level: required brief: > The name of the function being executed. examples: ['my-function'] - id: id + stability: experimental type: string requirement_level: required brief: > The unique name of the function being executed. examples: ['arn:aws:lambda:us-west-2:123456789012:function:my-function'] - id: version + stability: experimental type: string brief: > The version examples: ['semver:2.0.0'] - id: instance + stability: experimental type: string brief: > The execution environment ID as a string. diff --git a/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource_faas.yaml b/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource_faas.yaml index d84b00af..1ed3fe6c 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource_faas.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/id_clash/resource_faas.yaml @@ -6,12 +6,14 @@ groups: Attributes for a serverless instance. attributes: - id: name + stability: experimental type: string requirement_level: required brief: > The name of the function being executed. examples: ['my-function'] - id: id + stability: experimental type: string requirement_level: required brief: > @@ -24,12 +26,14 @@ groups: field. examples: ['arn:aws:lambda:us-west-2:123456789012:function:my-function'] - id: version + stability: experimental type: string brief: > The version string of the function being executed as defined in [Version Attributes](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions#version-attributes). examples: ['semver:2.0.0'] - id: instance + stability: experimental type: string brief: > The execution environment ID as a string. diff --git a/semantic-conventions/src/tests/data/yaml/errors/id_clash/span_faas.yaml b/semantic-conventions/src/tests/data/yaml/errors/id_clash/span_faas.yaml index 91ac2be1..4496d5d1 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/id_clash/span_faas.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/id_clash/span_faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' @@ -39,6 +41,7 @@ groups: Semantic Convention for FaaS scheduled to be executed regularly. attributes: - id: time + stability: experimental type: string requirement_level: required brief: > @@ -47,6 +50,7 @@ groups: format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). examples: "2020-01-23T13:47:06Z" - id: cron + stability: experimental type: string brief: > A string containing the schedule period as diff --git a/semantic-conventions/src/tests/data/yaml/errors/invalid_type.yaml b/semantic-conventions/src/tests/data/yaml/errors/invalid_type.yaml index 169345ff..1e7a8f94 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/invalid_type.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/invalid_type.yaml @@ -5,6 +5,7 @@ groups: brief: 'This document defines semantic conventions for remote procedure calls.' attributes: - id: service + stability: experimental type: string requirement_level: required brief: 'The service name, must be equal to the $service part in the span name.' diff --git a/semantic-conventions/src/tests/data/yaml/errors/missing_attr_type.yaml b/semantic-conventions/src/tests/data/yaml/errors/missing_attr_type.yaml index 48cfaf6f..88b90434 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/missing_attr_type.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/missing_attr_type.yaml @@ -5,5 +5,6 @@ groups: span_kind: client attributes: - id: test + stability: experimental requirement_level: required brief: 'test.' \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/missing_semconv_id.yaml b/semantic-conventions/src/tests/data/yaml/errors/missing_semconv_id.yaml index 637db591..bf10dbb7 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/missing_semconv_id.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/missing_semconv_id.yaml @@ -5,6 +5,7 @@ groups: span_kind: client attributes: - id: test + stability: experimental type: allow_custom_values: false members: diff --git a/semantic-conventions/src/tests/data/yaml/errors/resource_spankind.yaml b/semantic-conventions/src/tests/data/yaml/errors/resource_spankind.yaml index 335f22c3..dd46b48a 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/resource_spankind.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/resource_spankind.yaml @@ -6,6 +6,7 @@ groups: brief: 'This document defines semantic conventions for remote procedure calls.' attributes: - id: service + stability: experimental type: string requirement_level: required brief: 'The service name, must be equal to the $service part in the span name.' diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/extends_override_stability.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/extends_override_stability.yaml new file mode 100644 index 00000000..38c61f21 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/extends_override_stability.yaml @@ -0,0 +1,16 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: test_attr + type: boolean + brief: "" + stability: experimental + - id: test_child_1 + type: attribute_group + brief: 'test child' + extends: test + attributes: + - ref: test_attr + stability: stable diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_value.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_value.yaml new file mode 100644 index 00000000..267e337d --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_value.yaml @@ -0,0 +1,8 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: test_attr + type: boolean + brief: "" diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values.yaml new file mode 100644 index 00000000..3cd56d87 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values.yaml @@ -0,0 +1,10 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: test_attr + type: boolean + stability: stable + stability: experimental + brief: "" diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/ref_override_stability.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/ref_override_stability.yaml new file mode 100644 index 00000000..d2fe1603 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/ref_override_stability.yaml @@ -0,0 +1,15 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: test_attr + type: boolean + brief: "" + stability: experimental + - id: test_child_1 + type: attribute_group + brief: 'test child' + attributes: + - ref: test_attr + stability: stable diff --git a/semantic-conventions/src/tests/data/yaml/errors/validate_anyof.yaml b/semantic-conventions/src/tests/data/yaml/errors/validate_anyof.yaml index 7996a33a..0ba2fb52 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/validate_anyof.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/validate_anyof.yaml @@ -9,6 +9,7 @@ groups: type: string brief: The version of the Node.js runtime. examples: [ '10.19.0' ] + stability: experimental constraints: - any_of: - 'messaging.node_version' diff --git a/semantic-conventions/src/tests/data/yaml/errors/wrong_conditionally_required_no_condition.yaml b/semantic-conventions/src/tests/data/yaml/errors/wrong_conditionally_required_no_condition.yaml index 5dd667c3..4791ea2a 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/wrong_conditionally_required_no_condition.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/wrong_conditionally_required_no_condition.yaml @@ -10,3 +10,4 @@ groups: brief: 'test' requirement_level: conditionally_required examples: [true, false] + stability: experimental diff --git a/semantic-conventions/src/tests/data/yaml/errors/wrong_double_type.yaml b/semantic-conventions/src/tests/data/yaml/errors/wrong_double_type.yaml index 2cd74fbf..f298330d 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/wrong_double_type.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/wrong_double_type.yaml @@ -6,6 +6,7 @@ groups: note: 'test' attributes: - id: one + stability: experimental type: double brief: it contains a float number. examples: [12, 1f, 1.0] \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_level_values.yaml b/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_level_values.yaml index 185e2f48..1596b947 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_level_values.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_level_values.yaml @@ -6,9 +6,10 @@ groups: span_kind: client attributes: - id: convention_version + stability: experimental type: boolean brief: 'test' - requirement_level: + requirement_level: recommended: recommended conditionally_required: condition examples: [true, false] diff --git a/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_levels.yaml b/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_levels.yaml index b47863e6..ebbb779e 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_levels.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/wrong_multiple_requirement_levels.yaml @@ -11,3 +11,4 @@ groups: requirement_level: required requirement_level: opt_in examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/wrong_requirement.yaml b/semantic-conventions/src/tests/data/yaml/errors/wrong_requirement.yaml index 78c4eb62..cfd873d4 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/wrong_requirement.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/wrong_requirement.yaml @@ -10,3 +10,4 @@ groups: requirement_level: maybe brief: 'test' examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/wrong_sampling.yaml b/semantic-conventions/src/tests/data/yaml/errors/wrong_sampling.yaml index 88764fcf..39c037da 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/wrong_sampling.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/wrong_sampling.yaml @@ -10,3 +10,4 @@ groups: brief: 'test' sampling_relevant: maybe examples: [true, false] + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/event.yaml b/semantic-conventions/src/tests/data/yaml/event.yaml index d0c69d06..38be388f 100644 --- a/semantic-conventions/src/tests/data/yaml/event.yaml +++ b/semantic-conventions/src/tests/data/yaml/event.yaml @@ -7,15 +7,18 @@ groups: report a single exception associated with a span. attributes: - id: type + stability: experimental type: string brief: > The type of the exception. examples: ["java.net.ConnectException","OSError"] - id: message + stability: experimental type: string brief: The exception message. examples: ["Division by zero","Can't convert 'int' object to str implicitly"] - id: stacktrace + stability: experimental type: string brief: > A stacktrace. @@ -24,6 +27,7 @@ groups: at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)' - id: escaped + stability: experimental type: boolean brief: > SHOULD be set to true if the exception event is recorded at a point where @@ -33,4 +37,27 @@ groups: constraints: - any_of: - "exception.type" - - "exception.message" \ No newline at end of file + - "exception.message" + - id: experimental_event + type: event + prefix: experimental_event + brief: "" + stability: experimental + attributes: + - id: foo + stability: experimental + type: string + brief: "" + examples: "foo" + - id: stable_event + type: event + prefix: stable_event + brief: "" + stability: stable + - id: deprecated_event + type: event + prefix: deprecated_event + brief: "" + stability: stable + deprecated: "Removed." + diff --git a/semantic-conventions/src/tests/data/yaml/extends/http.yaml b/semantic-conventions/src/tests/data/yaml/extends/http.yaml index ee4f7e50..9599946a 100644 --- a/semantic-conventions/src/tests/data/yaml/extends/http.yaml +++ b/semantic-conventions/src/tests/data/yaml/extends/http.yaml @@ -8,6 +8,7 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false diff --git a/semantic-conventions/src/tests/data/yaml/faas.yaml b/semantic-conventions/src/tests/data/yaml/faas.yaml index b56be7f4..2376f728 100644 --- a/semantic-conventions/src/tests/data/yaml/faas.yaml +++ b/semantic-conventions/src/tests/data/yaml/faas.yaml @@ -8,6 +8,7 @@ groups: serverless) with spans. attributes: - id: trigger + stability: experimental requirement_level: required brief: 'Type of the trigger on which the function is executed.' type: @@ -28,6 +29,7 @@ groups: - id: other value: 'other' - id: execution + stability: experimental type: string brief: "The execution id of the current function execution." examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' @@ -40,6 +42,7 @@ groups: source operation such as a database or filesystem read/write. attributes: - id: collection + stability: experimental type: string requirement_level: required brief: 'The name of the source on which the triggering operation was performed.' @@ -48,6 +51,7 @@ groups: and in Cosmos DB to the database name. examples: ['myBucketName', 'myDbName'] - id: operation + stability: experimental requirement_level: required type: allow_custom_values: true @@ -60,6 +64,7 @@ groups: value: 'delete' brief: 'Describes the type of the operation that was performed on the data.' - id: time + stability: experimental type: string requirement_level: required brief: > @@ -68,6 +73,7 @@ groups: format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). examples: "2020-01-23T13:47:06Z" - id: name + stability: experimental type: string brief: 'The document name/table subjected to the operation.' note: > @@ -96,6 +102,7 @@ groups: Semantic Convention for FaaS scheduled to be executed regularly. attributes: - id: time + stability: experimental type: string requirement_level: required brief: > @@ -104,6 +111,7 @@ groups: format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). examples: "2020-01-23T13:47:06Z" - id: cron + stability: experimental type: string brief: > A string containing the schedule period as diff --git a/semantic-conventions/src/tests/data/yaml/general.yaml b/semantic-conventions/src/tests/data/yaml/general.yaml index 5e91e7e6..75526142 100644 --- a/semantic-conventions/src/tests/data/yaml/general.yaml +++ b/semantic-conventions/src/tests/data/yaml/general.yaml @@ -6,6 +6,7 @@ groups: These attributes may be used for any network related operation. attributes: - id: transport + stability: experimental type: allow_custom_values: false members: @@ -36,28 +37,34 @@ groups: Transport protocol used. See note below. examples: 'ip.tcp' - id: peer.ip + stability: experimental type: string brief: > Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' - id: host.ip + stability: experimental type: string brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' examples: '192.168.0.1' - id: host.port + stability: experimental type: int brief: 'Like `net.peer.port` but for the host port.' examples: 35555 - id: host.name + stability: experimental type: string brief: 'Local hostname or similar, see note below.' examples: 'localhost' @@ -68,16 +75,19 @@ groups: These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - id: id + stability: experimental type: string brief: > Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. examples: 'username' - id: role + stability: experimental type: string brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope + stability: experimental type: string brief: > Scopes or granted authorities the client currently possesses extracted from token diff --git a/semantic-conventions/src/tests/data/yaml/http.yaml b/semantic-conventions/src/tests/data/yaml/http.yaml index 9eaf4e25..7b9c5746 100644 --- a/semantic-conventions/src/tests/data/yaml/http.yaml +++ b/semantic-conventions/src/tests/data/yaml/http.yaml @@ -8,42 +8,50 @@ groups: and various HTTP versions like 1.1, 2 and SPDY. attributes: - id: method + stability: experimental type: string requirement_level: required sampling_relevant: false brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] - id: url + stability: experimental type: string brief: > Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target + stability: experimental type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' examples: ['/path/12314/?q=ddds#123'] - id: host + stability: experimental type: string brief: > The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. examples: ['www.example.org'] - id: scheme + stability: experimental type: string brief: 'The URI scheme identifying the used protocol.' examples: ["http", "https"] - id: status_code + stability: experimental type: int requirement_level: conditionally_required: "if and only if one was received/sent" brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: status_text + stability: experimental type: string brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' examples: ['OK'] - id: flavor + stability: experimental type: # Default value: `true`. If false, it helps the code gen tool to # encode checks that only accept the listed values. @@ -70,6 +78,7 @@ groups: is `QUIC`, in which case `IP.UDP` is assumed. examples: ['1.0'] - id: user_agent + stability: experimental type: string brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' examples: ['CERN-LineMode/2.15 libwww/2.17b3'] @@ -93,6 +102,7 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - id: server_name + stability: experimental type: string requirement_level: conditionally_required: > diff --git a/semantic-conventions/src/tests/data/yaml/imported-inherited.yaml b/semantic-conventions/src/tests/data/yaml/imported-inherited.yaml index b0fa7b43..92e4cc09 100644 --- a/semantic-conventions/src/tests/data/yaml/imported-inherited.yaml +++ b/semantic-conventions/src/tests/data/yaml/imported-inherited.yaml @@ -6,6 +6,7 @@ groups: brief: 'Base' attributes: - id: service + stability: experimental type: string requirement_level: required brief: 'The service name, must be equal to the $service part in the span name.' @@ -22,16 +23,19 @@ groups: brief: 'imported' attributes: - id: peer.ip + stability: experimental type: string brief: > Remote examples: '127.0.0.1' - id: peer.port + stability: experimental type: int brief: 'Remote port number.' note: 'not override' examples: [80, 8080, 443] - id: peer.name + stability: experimental type: string brief: 'Remote hostname or similar, see note below.' examples: 'example.com' @@ -47,6 +51,7 @@ groups: requirement_level: required brief: 'override' - id: name + stability: experimental type: string requirement_level: required brief: 'Name' @@ -60,6 +65,7 @@ groups: brief: 'Imported' attributes: - id: method + stability: experimental type: string brief: 'HTTP Method' examples: 'example.com' @@ -72,6 +78,7 @@ groups: brief: 'Imported extends' attributes: - id: hostname + stability: experimental type: string brief: 'hostname' examples: 'example.com' @@ -84,6 +91,7 @@ groups: brief: 'Extends extends.' attributes: - id: zz.attr + stability: experimental type: string requirement_level: required brief: 'zz attr' diff --git a/semantic-conventions/src/tests/data/yaml/links.yaml b/semantic-conventions/src/tests/data/yaml/links.yaml index 2fc449e9..20ab67a2 100644 --- a/semantic-conventions/src/tests/data/yaml/links.yaml +++ b/semantic-conventions/src/tests/data/yaml/links.yaml @@ -6,17 +6,22 @@ groups: note: test attributes: - id: none + stability: experimental type: boolean brief: 'simple text' - id: single + stability: experimental type: boolean brief: 'text [eg](https://opentelemetry.io/)' - id: double + stability: experimental type: boolean brief: 'text1 [eg](https://opentelemetry.io/) text2 [eg](https://opentelemetry.io/) end' - id: start + stability: experimental type: boolean brief: '[eg](https://opentelemetry.io/) text' - id: multiple_end + stability: experimental type: boolean brief: 'text1 [eg](https://opentelemetry.io/) text2 [eg](https://opentelemetry.io/)' diff --git a/semantic-conventions/src/tests/data/yaml/metrics.yaml b/semantic-conventions/src/tests/data/yaml/metrics.yaml index 5d13f992..9ff2e70f 100644 --- a/semantic-conventions/src/tests/data/yaml/metrics.yaml +++ b/semantic-conventions/src/tests/data/yaml/metrics.yaml @@ -2,11 +2,13 @@ groups: - id: metric.foo prefix: bar type: metric_group + stability: experimental brief: "This document defines foo." note: > Details about foo. - attributes: + attributes: - id: egg.type + stability: experimental type: string brief: 'Type of egg.' examples: ["chicken", "emu", "dragon"] @@ -16,6 +18,7 @@ groups: - id: metric.foo.size prefix: foo type: metric + stability: stable metric_name: foo.size brief: "Measures the size of foo." instrument: histogram @@ -32,13 +35,15 @@ groups: - id: metric.foo.active_eggs prefix: foo type: metric + stability: experimental + deprecated: "Removed." metric_name: foo.active_eggs brief: "Measures how many eggs are currently active." instrument: updowncounter unit: "{cartons}" - attributes: + attributes: - ref: http.method requirement_level: opt_in - ref: bar.egg.type - requirement_level: + requirement_level: conditionally_required: "if available to instrumentation." diff --git a/semantic-conventions/src/tests/data/yaml/numeric_attributes.yml b/semantic-conventions/src/tests/data/yaml/numeric_attributes.yml index 5752370d..c54e2041 100644 --- a/semantic-conventions/src/tests/data/yaml/numeric_attributes.yml +++ b/semantic-conventions/src/tests/data/yaml/numeric_attributes.yml @@ -6,6 +6,7 @@ groups: note: 'test' attributes: - id: one + stability: experimental tag: tag-one type: int brief: > @@ -13,6 +14,7 @@ groups: the first attribute examples: 10 - id: two + stability: experimental tag: tag-two type: double brief: > diff --git a/semantic-conventions/src/tests/data/yaml/rpc.yaml b/semantic-conventions/src/tests/data/yaml/rpc.yaml index 7236bf2c..cc457595 100644 --- a/semantic-conventions/src/tests/data/yaml/rpc.yaml +++ b/semantic-conventions/src/tests/data/yaml/rpc.yaml @@ -5,6 +5,7 @@ groups: brief: 'This document defines semantic conventions for remote procedure calls.' attributes: - id: service + stability: experimental type: string requirement_level: required brief: 'The service name, must be equal to the $service part in the span name.' diff --git a/semantic-conventions/src/tests/data/yaml/scope.yaml b/semantic-conventions/src/tests/data/yaml/scope.yaml index ac691c9f..a9bc8c36 100644 --- a/semantic-conventions/src/tests/data/yaml/scope.yaml +++ b/semantic-conventions/src/tests/data/yaml/scope.yaml @@ -6,6 +6,7 @@ groups: Instrumentation Scope attributes attributes: - id: short_name + stability: experimental type: string requirement_level: recommended brief: > diff --git a/semantic-conventions/src/tests/data/yaml/semantic_attributes.yml b/semantic-conventions/src/tests/data/yaml/semantic_attributes.yml index b31f1ea7..55c0aea8 100644 --- a/semantic-conventions/src/tests/data/yaml/semantic_attributes.yml +++ b/semantic-conventions/src/tests/data/yaml/semantic_attributes.yml @@ -1,5 +1,6 @@ attributes: - id: attribute_one + stability: experimental tag: tag-one type: string brief: > @@ -7,6 +8,7 @@ attributes: the first attribute examples: 'This is a good example of the first attribute' - id: attribute_two + stability: experimental tag: tag-two type: int brief: > @@ -14,6 +16,7 @@ attributes: the second attribute. It's a number. examples: [1000, 10, 1] - id: attribute_three + stability: experimental tag: tag-three type: boolean brief: > diff --git a/semantic-conventions/src/tests/data/yaml/semantic_attributes_deprecated.yml b/semantic-conventions/src/tests/data/yaml/semantic_attributes_deprecated.yml index 962f42cc..c65f2ff1 100644 --- a/semantic-conventions/src/tests/data/yaml/semantic_attributes_deprecated.yml +++ b/semantic-conventions/src/tests/data/yaml/semantic_attributes_deprecated.yml @@ -1,5 +1,6 @@ attributes: - id: deprecated_attribute + stability: experimental tag: tag-one deprecated: don't use this one anymore type: boolean diff --git a/semantic-conventions/src/tests/data/yaml/span_event.yaml b/semantic-conventions/src/tests/data/yaml/span_event.yaml index 3a1f1940..baa5688f 100644 --- a/semantic-conventions/src/tests/data/yaml/span_event.yaml +++ b/semantic-conventions/src/tests/data/yaml/span_event.yaml @@ -8,6 +8,7 @@ groups: brief: example attributes: - id: flag + stability: experimental type: boolean brief: An attribute. @@ -17,5 +18,6 @@ groups: brief: example attributes: - id: flag + stability: experimental type: boolean brief: An attribute. diff --git a/semantic-conventions/src/tests/data/yaml/stability.yaml b/semantic-conventions/src/tests/data/yaml/stability.yaml index 48631cc7..726efada 100644 --- a/semantic-conventions/src/tests/data/yaml/stability.yaml +++ b/semantic-conventions/src/tests/data/yaml/stability.yaml @@ -1,8 +1,8 @@ groups: - - id: test + - id: test_1 type: span brief: 'test' - prefix: http_1 + prefix: test_1 attributes: - id: exp_attr type: boolean @@ -14,36 +14,28 @@ groups: requirement_level: required stability: stable brief: "" - - id: def_stability - type: boolean - requirement_level: required - brief: "" - - id: parent_default - type: span - brief: 'test' - prefix: http_2 - stability: experimental + - id: ref_test_1 + type: attribute_group + brief: 'ref_test' attributes: - - id: test_attr - type: boolean - requirement_level: required - brief: "" - - id: dep - type: boolean - requirement_level: required - deprecated: should not fail. - brief: "" + - ref: test_1.exp_attr + - ref: test_1.stable_attr + + - id: extends_test_1 + type: attribute_group + brief: 'extends_test' + extends: test_1 - id: not_fail type: span brief: 'test' - prefix: http_3 - stability: experimental + prefix: test_2 attributes: - id: test_attr type: boolean requirement_level: required + stability: experimental deprecated: should not fail. brief: "" - id: stable_deprecated_attr @@ -56,7 +48,7 @@ groups: - id: resource_test type: resource brief: 'test' - prefix: http_4 + prefix: test_3 attributes: - id: exp_attr type: boolean @@ -68,34 +60,15 @@ groups: requirement_level: required stability: stable brief: "" - - id: def_stability - type: boolean - requirement_level: required - brief: "" - - - id: resource_parent_default - type: resource - brief: 'test' - prefix: http_5 - stability: experimental - attributes: - - id: test_attr - type: boolean - requirement_level: required - brief: "" - - id: dep - type: boolean - requirement_level: required - deprecated: should not fail. - brief: "" - id: resource_not_fail type: resource brief: 'test' - prefix: http_6 + prefix: test_4 attributes: - id: test_attr type: boolean requirement_level: required + stability: experimental deprecated: should not fail. brief: "" \ No newline at end of file diff --git a/semantic-conventions/src/tests/semconv/model/test_correct_parse.py b/semantic-conventions/src/tests/semconv/model/test_correct_parse.py index e1d0f0f4..44604676 100644 --- a/semantic-conventions/src/tests/semconv/model/test_correct_parse.py +++ b/semantic-conventions/src/tests/semconv/model/test_correct_parse.py @@ -203,7 +203,7 @@ def test_metrics(self): semconv.parse(self.load_file("yaml/http.yaml")) metric_semconvs = cast( - List[MetricSemanticConvention], list(semconv.models.values())[:2] + List[MetricSemanticConvention], list(semconv.models.values()) ) expected = { @@ -211,6 +211,7 @@ def test_metrics(self): "prefix": "bar", "extends": "", "n_constraints": 0, + "stability": StabilityLevel.EXPERIMENTAL, "attributes": ["bar.egg.type"], } self.semantic_convention_check(metric_semconvs[0], expected) @@ -220,6 +221,7 @@ def test_metrics(self): "prefix": "foo", "extends": "", "n_constraints": 0, + "stability": StabilityLevel.STABLE, "metric_name": "foo.size", "unit": "{bars}", "instrument": "histogram", @@ -233,6 +235,26 @@ def test_metrics(self): self.assertEqual(metric_semconvs[1].instrument, expected["instrument"]) self.assertEqual(metric_semconvs[1].metric_name, expected["metric_name"]) + expected = { + "id": "metric.foo.active_eggs", + "prefix": "foo", + "extends": "", + "n_constraints": 0, + "stability": StabilityLevel.EXPERIMENTAL, + "metric_name": "foo.active_eggs", + "unit": "{cartons}", + "deprecated": "Removed.", + "instrument": "updowncounter", + "attributes": [ + "bar.egg.type", + "http.method", + ], + } + self.semantic_convention_check(metric_semconvs[2], expected) + self.assertEqual(metric_semconvs[2].unit, expected["unit"]) + self.assertEqual(metric_semconvs[2].instrument, expected["instrument"]) + self.assertEqual(metric_semconvs[2].metric_name, expected["metric_name"]) + def test_resource(self): semconv = SemanticConventionSet(debug=False) semconv.parse(self.load_file("yaml/cloud.yaml")) @@ -256,7 +278,7 @@ def test_event(self): semconv = SemanticConventionSet(debug=False) semconv.parse(self.load_file("yaml/event.yaml")) semconv.finish() - self.assertEqual(len(semconv.models), 1) + self.assertEqual(len(semconv.models), 4) event = list(semconv.models.values())[0] expected = { "id": "exception", @@ -281,22 +303,61 @@ def test_event(self): constraint.choice_list_attributes[choice_index][attr_index], ) + experimental_event = list(semconv.models.values())[1] + expected = { + "id": "experimental_event", + "prefix": "experimental_event", + "extends": "", + "n_constraints": 0, + "stability": StabilityLevel.EXPERIMENTAL, + "attributes": [ + "experimental_event.foo", + ], + } + self.semantic_convention_check(experimental_event, expected) + + stable_event = list(semconv.models.values())[2] + expected = { + "id": "stable_event", + "prefix": "stable_event", + "extends": "", + "n_constraints": 0, + "stability": StabilityLevel.STABLE, + "attributes": [], + } + self.semantic_convention_check(stable_event, expected) + + deprecated_event = list(semconv.models.values())[3] + expected = { + "id": "deprecated_event", + "prefix": "deprecated_event", + "extends": "", + "n_constraints": 0, + "stability": StabilityLevel.STABLE, + "deprecated": "Removed.", + "attributes": [], + } + self.semantic_convention_check(deprecated_event, expected) + def test_span_with_event(self): semconv = SemanticConventionSet(debug=False) semconv.parse(self.load_file("yaml/event.yaml")) semconv.parse(self.load_file("yaml/span_event.yaml")) semconv.finish() - self.assertEqual(len(semconv.models), 3) + self.assertEqual(len(semconv.models), 6) semconvs = list(semconv.models.values()) self.assertTrue(isinstance(semconvs[0], EventSemanticConvention)) - self.assertTrue(isinstance(semconvs[1], SpanSemanticConvention)) + self.assertTrue(isinstance(semconvs[1], EventSemanticConvention)) self.assertTrue(isinstance(semconvs[2], EventSemanticConvention)) - event_semconv = semconvs[1] - self.assertEqual(2, len(event_semconv.events)) - self.assertTrue(isinstance(event_semconv.events[0], EventSemanticConvention)) - self.assertTrue(isinstance(event_semconv.events[1], EventSemanticConvention)) - self.assertEqual("exception", event_semconv.events[0].semconv_id) - self.assertEqual("random.event", event_semconv.events[1].semconv_id) + self.assertTrue(isinstance(semconvs[3], EventSemanticConvention)) + self.assertTrue(isinstance(semconvs[4], SpanSemanticConvention)) + self.assertTrue(isinstance(semconvs[5], EventSemanticConvention)) + span_semconv = semconvs[4] + self.assertEqual(2, len(span_semconv.events)) + self.assertTrue(isinstance(span_semconv.events[0], EventSemanticConvention)) + self.assertTrue(isinstance(span_semconv.events[1], EventSemanticConvention)) + self.assertEqual("exception", span_semconv.events[0].semconv_id) + self.assertEqual("random.event", span_semconv.events[1].semconv_id) def test_rpc(self): semconv = SemanticConventionSet(debug=False) @@ -457,14 +518,27 @@ def test_deprecation(self): semconv = SemanticConventionSet(debug=False) semconv.parse(self.load_file("yaml/deprecated/http.yaml")) semconv.finish() - self.assertEqual(len(semconv.models), 1) + self.assertEqual(len(semconv.models), 3) - method_attr = list(semconv.models.values())[0].attrs_by_name["http.method"] - self.assertIsNotNone(method_attr.deprecated) + method_attr_original = list(semconv.models.values())[0].attrs_by_name[ + "http.method" + ] + self.assertIsNotNone(method_attr_original.deprecated) self.assertEqual( - method_attr.deprecated, + method_attr_original.deprecated, "Use attribute `nonDepecrated`.", ) + + method_attr_client = list(semconv.models.values())[1].attrs_by_name[ + "http.method" + ] + self.assertEqual(method_attr_client.deprecated, method_attr_original.deprecated) + + method_attr_server = list(semconv.models.values())[2].attrs_by_name[ + "http.method" + ] + self.assertEqual(method_attr_server.deprecated, method_attr_original.deprecated) + self.assertIsNone( list(semconv.models.values())[0].attrs_by_name["http.target"].deprecated ) @@ -476,37 +550,39 @@ def test_stability(self): self.assertEqual(len(semconv.models), 6) model = list(semconv.models.values())[0] - self.assertEqual(len(model.attributes_and_templates), 3) - self.assertEqual(model.stability, StabilityLevel.EXPERIMENTAL) + self.assertEqual(len(model.attributes_and_templates), 2) + self.assertIsNone(model.stability) attr = model.attributes_and_templates[0] - self.assertEqual(attr.attr_id, "def_stability") - self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL) - - attr = model.attributes_and_templates[1] self.assertEqual(attr.attr_id, "exp_attr") self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL) - attr = model.attributes_and_templates[2] + attr = model.attributes_and_templates[1] self.assertEqual(attr.attr_id, "stable_attr") self.assertEqual(attr.stability, StabilityLevel.STABLE) model = list(semconv.models.values())[1] self.assertEqual(len(model.attributes_and_templates), 2) - self.assertEqual(model.stability, StabilityLevel.EXPERIMENTAL) + self.assertIsNone(model.stability) attr = model.attributes_and_templates[0] - self.assertEqual(attr.attr_id, "dep") + self.assertEqual(attr.attr_id, "exp_attr") self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL) attr = model.attributes_and_templates[1] - self.assertEqual(attr.attr_id, "test_attr") - self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL) + self.assertEqual(attr.attr_id, "stable_attr") + self.assertEqual(attr.stability, StabilityLevel.STABLE) model = list(semconv.models.values())[2] - self.assertEqual(len(model.attributes_and_templates), 2) - self.assertEqual(model.stability, StabilityLevel.EXPERIMENTAL) + attr = model.attributes_and_templates[0] + self.assertEqual(attr.attr_id, "exp_attr") + self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL) + + attr = model.attributes_and_templates[1] + self.assertEqual(attr.attr_id, "stable_attr") + self.assertEqual(attr.stability, StabilityLevel.STABLE) + model = list(semconv.models.values())[3] attr = model.attributes_and_templates[0] self.assertEqual(attr.attr_id, "stable_deprecated_attr") self.assertEqual(attr.stability, StabilityLevel.STABLE) @@ -708,6 +784,8 @@ def test_inherited_imported(self): def semantic_convention_check(self, s, expected): self.assertEqual(expected["prefix"], s.prefix) + self.assertEqual(expected.get("stability"), s.stability) + self.assertEqual(expected.get("deprecated"), s.deprecated) self.assertEqual(expected["extends"], s.extends) self.assertEqual(expected["id"], s.semconv_id) self.assertEqual(len(expected["attributes"]), len(s.attributes)) diff --git a/semantic-conventions/src/tests/semconv/model/test_error_detection.py b/semantic-conventions/src/tests/semconv/model/test_error_detection.py index af1c9132..a37881e2 100644 --- a/semantic-conventions/src/tests/semconv/model/test_error_detection.py +++ b/semantic-conventions/src/tests/semconv/model/test_error_detection.py @@ -141,6 +141,28 @@ def test_invalid_stability(self): self.assertIn("is not allowed as a stability marker", msg) self.assertEqual(e.line, 10) + def test_multiple_stability_values(self): + with self.assertRaises(DuplicateKeyError): + self.open_yaml("yaml/errors/stability/multiple_stability_values.yaml") + + def test_missing_stability_value(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml("yaml/errors/stability/missing_stability_value.yaml") + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn("missing keys: ['stability']", msg) + self.assertEqual(e.line, 6) + + def test_ref_override_stability(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml("yaml/errors/stability/ref_override_stability.yaml") + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn("ref attribute 'test_attr' must not override stability", msg) + self.assertEqual(e.line, 14) + def test_invalid_semconv_stability_with_deprecated(self): with self.assertRaises(ValidationError) as ex: self.open_yaml("yaml/errors/stability/semconv_stability_deprecated.yaml") @@ -162,6 +184,34 @@ def test_invalid_deprecated_empty_string(self): ) self.assertEqual(e.line, 10) + def test_multiple_deprecations(self): + with self.assertRaises(DuplicateKeyError): + self.open_yaml("yaml/errors/deprecated/multiple_deprecations.yaml") + + def test_extends_overrides_deprecation(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml("yaml/errors/deprecated/extends_overrides_deprecation.yaml") + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn( + "ref attribute 'test.convention_version' must not override deprecation status", + msg, + ) + self.assertEqual(e.line, 19) + + def test_ref_overrides_deprecation(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml("yaml/errors/deprecated/ref_overrides_deprecation.yaml") + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn( + "ref attribute 'test.convention_version' must not override deprecation status", + msg, + ) + self.assertEqual(e.line, 17) + def test_invalid_deprecated_boolean(self): with self.assertRaises(ValidationError) as ex: self.open_yaml("yaml/errors/deprecated/deprecation_boolean.yaml") @@ -295,7 +345,7 @@ def test_example_wrong_double_type(self): self.assertIn("example with wrong type", msg) self.assertIn("expected double", msg) self.assertIn("is was ", msg) - self.assertEqual(e.line, 11) + self.assertEqual(e.line, 12) def test_examples_bool(self): with self.assertRaises(ValidationError) as ex: @@ -378,7 +428,7 @@ def test_attribute_id_clash(self): e = ex.exception msg = e.message.lower() self.assertIn("is already present at line 8", msg) - self.assertEqual(e.line, 16) + self.assertEqual(e.line, 18) def test_attribute_id_clash_inherited(self): semconv = SemanticConventionSet(debug=False) @@ -409,7 +459,7 @@ def test_validate_anyof_attributes(self): msg = e.message.lower() self.assertIn("any_of attribute", msg) self.assertIn("does not exists", msg) - self.assertEqual(e.line, 15) + self.assertEqual(e.line, 16) def test_missing_event(self): with self.assertRaises(ValidationError) as ex: @@ -459,7 +509,7 @@ def test_multiple_requirement_level_values(self): e = ex.exception msg = e.message.lower() self.assertIn("multiple requirement_level values are not allowed!", msg) - self.assertEqual(e.line, 11) + self.assertEqual(e.line, 12) def open_yaml(self, path): with open(self.load_file(path), encoding="utf-8") as file: diff --git a/semantic-conventions/src/tests/semconv/templating/test_markdown.py b/semantic-conventions/src/tests/semconv/templating/test_markdown.py index ed6adba4..abeac7fd 100644 --- a/semantic-conventions/src/tests/semconv/templating/test_markdown.py +++ b/semantic-conventions/src/tests/semconv/templating/test_markdown.py @@ -36,12 +36,23 @@ def testInclude(self): def testDeprecated(self): self.check("markdown/deprecated/") - def testStability(self): - self.check("markdown/stability/", expected_name="labels_expected.md") + def testStableBadges(self): self.check( "markdown/stability/", MarkdownOptions(enable_stable=True, use_badge=True), - expected_name="badges_expected.md", + expected_name="stable_badges_expected.md", + ) + + def testExperimentalAndStableBadges(self): + self.check( + "markdown/stability/", + MarkdownOptions( + enable_stable=True, + enable_experimental=True, + enable_deprecated=True, + use_badge=True, + ), + expected_name="all_badges_expected.md", ) def testSingle(self): diff --git a/semantic-conventions/syntax.md b/semantic-conventions/syntax.md index a422b309..3b1ba202 100644 --- a/semantic-conventions/syntax.md +++ b/semantic-conventions/syntax.md @@ -100,7 +100,6 @@ requirement_level ::= "required" | "recommended" [condition] # Default if not specified | "opt_in" -# EXPERIMENTAL: Using this is NOT ALLOWED in the specification currently. sampling_relevant ::= boolean examples ::= {} @@ -160,7 +159,6 @@ The field `semconv` represents a semantic convention and it is made by: It defaults to an empty string. - `extends`, optional string, reference another semantic convention `id`. It inherits the prefix, constraints, and all attributes defined in the specified semantic convention. -- `stability`, optional enum, specifies the stability of the semantic convention. Defaults to `experimental`. - `deprecated`, optional, when present marks the semantic convention as deprecated. The string provided as `` MUST specify why it's deprecated and/or what to use instead. - `attributes`, list of attributes that belong to the semantic convention. @@ -212,8 +210,8 @@ Attribute groups don't have any specific fields and follow the general `semconv` An attribute is defined by: -- `id`, string that uniquely identifies the attribute. -- `type`, either a string literal denoting the type as a primitive or an array type, a template type or an enum definition (See later). +- `id`, string that uniquely identifies the attribute. Required. +- `type`, either a string literal denoting the type as a primitive or an array type, a template type or an enum definition (See later). Required. The accepted string literals are: * _primitive and array types as string literals:_ * `"string"`: String attributes. @@ -225,8 +223,8 @@ An attribute is defined by: * `"double[]"`: Array of double attributes. * `"boolean[]"`: Array of booleans attributes. * _template type as string literal:_ `"template[]"` (See [below](#template-type)) - See the [specification of Attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute) for the definition of the value types. +- `stability`, enum - either `stable` or `experimental`, specifies the stability of the attribute. Required. - `ref`, optional string, reference an existing attribute, see [below](#ref). - `tag`, optional string, associates a tag ("sub-group") to the attribute. It carries no particular semantic meaning but can be used e.g. for filtering @@ -235,10 +233,10 @@ An attribute is defined by: Can be "required", "conditionally_required", "recommended" or "opt_in". When omitted, the attribute is "recommended". When set to "conditionally_required", the string provided as `` MUST specify the conditions under which the attribute is required. -- `sampling_relevant`, optional EXPERIMENTAL boolean, +- `sampling_relevant`, optional boolean, specifies if the attribute is (especially) relevant for sampling and thus should be set at span start. It defaults to `false`. -- `brief`, `note`, `stability`, `deprecated`, same meaning as for the whole +- `brief`, `note`, `deprecated`, same meaning as for the whole [semantic convention](#semantic-convention), but per attribute. - `examples`, sequence of example values for the attribute or single example value. They are required only for string and string array attributes. @@ -326,7 +324,7 @@ examples: #### Ref -`ref` MUST have an id of an existing attribute. When it is set, `id` and `type` MUST NOT be present. +`ref` MUST have an id of an existing attribute. When it is set, `id`, `type`, `stability`, and `deprecation` MUST NOT be present. `ref` is useful for specifying that an existing attribute of another semantic convention is part of the current semantic convention and inherit its `brief`, `note`, and `example` values. However, if these fields are present in the current attribute definition, they override the inherited values. @@ -354,6 +352,7 @@ groups: attributes: - id: http.request.header type: template[string[]] + stability: stable brief: > HTTP request headers, the key being the normalized HTTP header name (lowercase, with `-` characters replaced by `_`), the value being the header values. examples: ['http.request.header.content_type=["application/json"]', 'http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]'] From 9d242a93e482ed1aef1b526dd677e81e405657ea Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 27 Feb 2024 08:52:13 -0500 Subject: [PATCH 14/31] Remove C++ tools from build-tools in favor of their own repo. (#275) --- .github/dependabot.yml | 4 --- .github/workflows/cpp_format_tools.yml | 41 -------------------------- cpp_format_tools/Dockerfile | 20 ------------- cpp_format_tools/README.md | 16 ---------- cpp_format_tools/format.sh | 23 --------------- 5 files changed, 104 deletions(-) delete mode 100644 .github/workflows/cpp_format_tools.yml delete mode 100644 cpp_format_tools/Dockerfile delete mode 100644 cpp_format_tools/README.md delete mode 100755 cpp_format_tools/format.sh diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 61106e8d..e010892f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,10 +8,6 @@ updates: directory: "/protobuf" schedule: interval: "weekly" - - package-ecosystem: "docker" - directory: "/cpp_format_tools" - schedule: - interval: "weekly" - package-ecosystem: "docker" directory: "/schemas" schedule: diff --git a/.github/workflows/cpp_format_tools.yml b/.github/workflows/cpp_format_tools.yml deleted file mode 100644 index de41e921..00000000 --- a/.github/workflows/cpp_format_tools.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: C++ Format Tools Docker Image -on: - push: - tags: [ '**' ] - branches: [ main ] - pull_request: - branches: [ main ] - paths: - - .github/workflows/cpp_format_tools.yml - - cpp_format_tools/* - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Build the Docker image - run: docker build cpp_format_tools/. -t cpp_format_tools - - - name: Login to GitHub Package Registry - if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Push the Docker image - if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') - run: | - function tag_and_push { - docker tag cpp_format_tools "otel/cpp_format_tools:${1}" && docker push "otel/cpp_format_tools:${1}" - } - if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then - tag_and_push "latest" - elif [[ "${GITHUB_REF}" =~ refs/tags/v[0-9]+\.[0-9]+\.[0-9]+ ]]; then - TAG="${GITHUB_REF#"refs/tags/v"}" - tag_and_push "${TAG}" - else - tag_and_push "${GITHUB_REF#"refs/tags/"}" - fi diff --git a/cpp_format_tools/Dockerfile b/cpp_format_tools/Dockerfile deleted file mode 100644 index 13837aac..00000000 --- a/cpp_format_tools/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -ARG BUILDIFIER_VERSION=3.5.0 -ARG CLANG_VERSION=10.0.1-r0 -ARG CMAKE_FORMAT_VERSION=0.6.13 - -FROM alpine:3.13 -LABEL maintainer="The OpenTelemetry Authors" -RUN apk update - -ARG CLANG_VERSION -RUN apk add --no-cache clang=${CLANG_VERSION} python3 py3-pip git curl - -ARG CMAKE_FORMAT_VERSION -RUN pip3 install cmake_format==${CMAKE_FORMAT_VERSION} - -ARG BUILDIFIER_VERSION -RUN curl -L -o /usr/local/bin/buildifier https://github.com/bazelbuild/buildtools/releases/download/${BUILDIFIER_VERSION}/buildifier -RUN chmod +x /usr/local/bin/buildifier - -COPY format.sh / -ENTRYPOINT ["sh", "/format.sh"] diff --git a/cpp_format_tools/README.md b/cpp_format_tools/README.md deleted file mode 100644 index 2ac95296..00000000 --- a/cpp_format_tools/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# C++ Format Tools + Docker - -A lightweight Docker image, published as otel/cpp_format_tools to Docker Hub, -with all dependencies and tools built-in, to format C++ code. - -## What's included in the image - -- clang-format -- cmake-format -- buildifier - -## Usage - -```bash -docker run --rm --privileged=true --volume ${PWD}:/otel otel/cpp_format_tools -``` diff --git a/cpp_format_tools/format.sh b/cpp_format_tools/format.sh deleted file mode 100755 index 29d2d8ff..00000000 --- a/cpp_format_tools/format.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -set -e - -FIND="find /otel -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o -name out -prune -o -name .vs -prune -o" - -echo "Running sed: " -echo "-> Correct common miscapitalizations." -sed -i 's/Open[t]elemetry/OpenTelemetry/g' $($FIND -type f -print) -echo "-> No CRLF line endings, except Windows files." -sed -i 's/\r$//' $($FIND -name '*.ps1' -prune -o \ - -name '*.cmd' -prune -o -type f -print) -echo "-> No trailing spaces." -sed -i 's/ \+$//' $($FIND -type f -print) - -echo "Running clang-format $(clang-format --version 2>&1)." -clang-format -i -style=file $($FIND -name '*.cc' -print -o -name '*.h' -print) - -echo "Running cmake-format $(cmake-format --version 2>&1)." -cmake-format -i $($FIND -name 'CMakeLists.txt' -print -name '*.cmake' -print -name '*.cmake.in' -print) - -echo "Running buildifier" -buildifier $($FIND -name WORKSPACE -print -o -name BUILD -print -o -name '*.BUILD' -o -name '*.bzl' -print) From c21047b22ab1a141ffadc24d7baf60188c23b8bc Mon Sep 17 00:00:00 2001 From: Armin Ruech <7052238+arminru@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:40:16 +0100 Subject: [PATCH 15/31] Add changelog for #272 (#277) --- semantic-conventions/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index 7048798e..ca966272 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -4,6 +4,8 @@ Please update the changelog as part of any significant pull request. ## Unreleased +- BREAKING: Make stability required (also: fix ref and extends, render badges on metrics). + ([#272](https://github.com/open-telemetry/build-tools/pull/272)) - BREAKING: Make stability and deprecation independent properties. ([#244](https://github.com/open-telemetry/build-tools/pull/244)) - Add backward-compatibility check mode. From 29a0e97cdfb38f3573ec16a8ae83785c1d74d2b5 Mon Sep 17 00:00:00 2001 From: "James Hughes (Splunk)" Date: Tue, 5 Mar 2024 21:58:28 -0800 Subject: [PATCH 16/31] Update python version (#285) --- semantic-conventions/CHANGELOG.md | 2 ++ semantic-conventions/CONTRIBUTING.md | 3 ++- semantic-conventions/Dockerfile | 2 +- semantic-conventions/setup.cfg | 11 ++++++----- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index ca966272..38501e04 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -4,6 +4,8 @@ Please update the changelog as part of any significant pull request. ## Unreleased +- Change minimum support python version to 3.10 in setup.cfg and Dockerfile + ([#285](https://github.com/open-telemetry/build-tools/pull/285)) - BREAKING: Make stability required (also: fix ref and extends, render badges on metrics). ([#272](https://github.com/open-telemetry/build-tools/pull/272)) - BREAKING: Make stability and deprecation independent properties. diff --git a/semantic-conventions/CONTRIBUTING.md b/semantic-conventions/CONTRIBUTING.md index 5c3c0471..cbd95417 100644 --- a/semantic-conventions/CONTRIBUTING.md +++ b/semantic-conventions/CONTRIBUTING.md @@ -48,10 +48,11 @@ _Note:_ `venv` integrations exist for IDEs such as [PyCharm](https://www.jetbrai See the offical documents for creating and [using](https://docs.python.org/3/tutorial/venv.html) a [venv environment](https://docs.python.org/3/library/venv.html). All "python" commands listed in this document should be run in an activated `venv`. +**Note**, ensure the venv you create is using the earliest supported version of python as defined in `setup.cfg` ```bash # note that it's convention to not store your venv in your working directory, lest build tooling "pick up" venv configuration. -python3 -m venv ../semconvgen +python3.10 -m venv ../semconvgen source ../semconvgen/bin/activate # Run your pip/wheel commands as described elsewhere in this documentation here. # reset your environment by typing 'deactivate' or by exiting your TTY diff --git a/semantic-conventions/Dockerfile b/semantic-conventions/Dockerfile index 91326834..efda152b 100644 --- a/semantic-conventions/Dockerfile +++ b/semantic-conventions/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9.5-alpine3.12 +FROM python:3.10-alpine LABEL maintainer="The OpenTelemetry Authors" ADD *.whl /semconvgen/ WORKDIR /semconvgen diff --git a/semantic-conventions/setup.cfg b/semantic-conventions/setup.cfg index 0d1cc511..acf1b869 100644 --- a/semantic-conventions/setup.cfg +++ b/semantic-conventions/setup.cfg @@ -26,12 +26,13 @@ classifiers = License :: OSI Approved :: Apache Software License Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - 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 + Programming Language :: Python :: 3.13 [options] -python_requires = >=3.6 +# Ensure this remains synced with our Dockerfile +python_requires = >=3.10 package_dir= =src packages=find_namespace: From 213927e67ad8615be1117a47a3976f7c90e47e19 Mon Sep 17 00:00:00 2001 From: "James Hughes (Splunk)" Date: Wed, 6 Mar 2024 05:27:20 -0800 Subject: [PATCH 17/31] Make table generation conflicts easier to debug (with colors!) (#121) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- semantic-conventions/Dockerfile | 1 + semantic-conventions/README.md | 3 + .../semconv/templating/markdown/__init__.py | 13 +-- .../semconv/templating/markdown/utils.py | 87 +++++++++++++++++++ .../expected-no-colors.md | 18 ++++ .../expected-with-colors.md | 15 ++++ .../table_generation_conflict/input-1.md | 15 ++++ .../table_generation_conflict/input-2.md | 15 ++++ .../tests/semconv/templating/test_markdown.py | 76 +++++++++++++++- 9 files changed, 236 insertions(+), 7 deletions(-) create mode 100644 semantic-conventions/src/opentelemetry/semconv/templating/markdown/utils.py create mode 100644 semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-no-colors.md create mode 100644 semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-with-colors.md create mode 100644 semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-1.md create mode 100644 semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-2.md diff --git a/semantic-conventions/Dockerfile b/semantic-conventions/Dockerfile index efda152b..5be02c8e 100644 --- a/semantic-conventions/Dockerfile +++ b/semantic-conventions/Dockerfile @@ -7,4 +7,5 @@ RUN apk --update add --virtual build-dependencies build-base \ && pip install -U ./semconvgen-*.whl \ && apk del build-dependencies \ && rm *.whl +ENV COLORED_DIFF true ENTRYPOINT ["gen-semconv"] diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index 9826abcb..e76f01d2 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -117,6 +117,9 @@ The image also supports customising [Whitespace Control in Jinja templates](https://jinja.palletsprojects.com/en/3.1.x/templates/#whitespace-control) via the additional flag `--trim-whitespace`. Providing the flag will enable both `lstrip_blocks` and `trim_blocks`. +### Enabling/disabling support for colored diffs in error messages +The `COLORED_DIFF` environment variable is set in the `semantic-conventions` `Dockerfile`. When this environment varibale is set, errors related to reformatting tables will show a "colored diff" using standard ANSI control characters. While this should be supported natively in any modern terminal environment, you may unset this variable if issues arise. Doing so will enable a "fall back" of non-colored inline diffs showing what was "added" and what was "removed", followed by the exact tokens added/removed encased in single quotes. + ## Version compatibility check You can check compatibility between the local one specified with `--yaml-root` and sepcific OpenTelemetry semantic convention version using the following command: diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py index bbd9f3e4..2413d197 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py @@ -39,6 +39,8 @@ from opentelemetry.semconv.model.utils import ID_RE from opentelemetry.semconv.templating.markdown.options import MarkdownOptions +from .utils import VisualDiffer + _REQUIREMENT_LEVEL_URL = ( "https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/" ) @@ -392,12 +394,11 @@ def render_md(self): output = io.StringIO() self._render_single_file(content, md_filename, output) if self.options.check_only: - if content != output.getvalue(): - sys.exit( - "File " - + md_filename - + " contains a table that would be reformatted." - ) + output_value = output.getvalue() + if content != output_value: + diff = VisualDiffer.visual_diff(content, output_value) + err_msg = f"File {md_filename} contains a table that would be reformatted.\n{diff}" + sys.exit(err_msg) else: with open(md_filename, "w", encoding="utf-8") as md_file: md_file.write(output.getvalue()) diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/utils.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/utils.py new file mode 100644 index 00000000..3dd96556 --- /dev/null +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/utils.py @@ -0,0 +1,87 @@ +# 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 difflib +import os + + +class VisualDiffer: + """Colorize differential outputs, which can be useful in development of + semantic conventions + """ + + @staticmethod + def colorize_text(r: int, g: int, b: int, text: str): + """ + Colorize text according to ANSI standards + The way this works is we send out a control character, + then send the color information (the r,g,b parts), + then the normal text, then an escape char to end the coloring + + ## Breakdown of magic values + 33 (octal) == 1b (hexadecimal) == ESC control character + + ESC[38 => This sets foreground color + https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters + + ESC[38;2; => Set foreground color with 24-bit color mode + https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit + + ESC[0m => Resets foreground color (basically turn off "coloring mode") + + {r};{g};{b};m => Sets the color mode. "m" denotes the end of the escape sequence prefix + + For more information and colors, see + https://en.wikipedia.org/wiki/ANSI_escape_code#Colors + """ + escape_color_24bitmode = "\x1b[38;2" + reset_color = "\x1b[0m" + return f"{escape_color_24bitmode};{r};{g};{b}m{text}{reset_color}" + + @classmethod + def removed(cls, text: str) -> str: + return cls.colorize_text(255, 0, 0, text) + + @classmethod + def added(cls, text: str) -> str: + return cls.colorize_text(0, 255, 0, text) + + @classmethod + def visual_diff(cls, a: str, b: str): + """ + Prints git-like colored diff using ANSI terminal coloring. + Diff is "from a to b", that is, red text is text deleted in `a` + while green text is new to `b` + """ + if "true" != os.environ.get("COLORED_DIFF", "false").lower(): + return "".join(difflib.context_diff(a, b)) + + colored_diff = [] + diff_partitions = difflib.SequenceMatcher(None, a, b) + for operation, a_start, a_end, b_start, b_end in diff_partitions.get_opcodes(): + if operation == "equal": + colored_diff.append(a[a_start:a_end]) + elif operation == "insert": + colored_diff.append(cls.added(b[b_start:b_end])) + elif operation == "delete": + colored_diff.append(cls.removed(a[a_start:a_end])) + elif operation == "replace": + colored_diff.append(cls.added(b[b_start:b_end])) + colored_diff.append(cls.removed(a[a_start:a_end])) + else: + # Log.warn would be best here + raise ValueError( + f"Unhandled opcode from difflib in semantic conversion markdown renderer: {operation}" + ) + return "".join(colored_diff) diff --git a/semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-no-colors.md b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-no-colors.md new file mode 100644 index 00000000..b103057d --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-no-colors.md @@ -0,0 +1,18 @@ +*** +--- +*************** +*** 145,157 **** + A t r i b u t e- | --- 145,157 ---- + A t+ t r i b u t e | *************** +*** 176,181 **** +--- 176,182 ---- + o n + | E*************** +*** 243,248 **** +--- 244,250 ---- + - - -+ - | *************** +*** 280,292 **** + | ` b a r- .- f- o- o ` |--- 282,294 ---- + | `+ f+ o+ o+ . b a r ` |*************** +*** 311,316 **** +--- 313,319 ---- + s u m+ z | \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-with-colors.md b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-with-colors.md new file mode 100644 index 00000000..21e00a8d --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/expected-with-colors.md @@ -0,0 +1,15 @@ +# TestTable + +**Status**: [Experimental](../../../document-status.md) + +**type:** `foo.bar` + +**Description:** Test case + + + +| Attribute  | Type | Description  | Examples | Requirement Level | +| --------- | ------ | ------------ | -------- | ----------------- | +| `foo.bar.foo` | string | Lorem Ipsumz | no | Recommended | + + diff --git a/semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-1.md b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-1.md new file mode 100644 index 00000000..e1914d0f --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-1.md @@ -0,0 +1,15 @@ +# TestTable + +**Status**: [Experimental](../../../document-status.md) + +**type:** `foo.bar` + +**Description:** Test case + + + +| Atribute | Type | Description | Examples | Requirement Level | +| --------- | ------ | ----------- | -------- | ----------------- | +| `bar.foo` | string | Lorem Ipsum | no | Recommended | + + diff --git a/semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-2.md b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-2.md new file mode 100644 index 00000000..8d4bb918 --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/table_generation_conflict/input-2.md @@ -0,0 +1,15 @@ +# TestTable + +**Status**: [Experimental](../../../document-status.md) + +**type:** `foo.bar` + +**Description:** Test case + + + +| Attribute | Type | Description | Examples | Requirement Level | +| --------- | ------ | ------------ | -------- | ----------------- | +| `foo.bar` | string | Lorem Ipsumz | no | Recommended | + + diff --git a/semantic-conventions/src/tests/semconv/templating/test_markdown.py b/semantic-conventions/src/tests/semconv/templating/test_markdown.py index abeac7fd..0fd047d9 100644 --- a/semantic-conventions/src/tests/semconv/templating/test_markdown.py +++ b/semantic-conventions/src/tests/semconv/templating/test_markdown.py @@ -17,9 +17,10 @@ import unittest from pathlib import Path from typing import Optional, Sequence +from unittest.mock import patch from opentelemetry.semconv.model.semantic_convention import SemanticConventionSet -from opentelemetry.semconv.templating.markdown import MarkdownRenderer +from opentelemetry.semconv.templating.markdown import MarkdownRenderer, VisualDiffer from opentelemetry.semconv.templating.markdown.options import MarkdownOptions @@ -168,6 +169,79 @@ def test_attribute_templates(self): def test_sorting(self): self.check("markdown/sorting/") + def testVisualDiffer(self): + with open( + self.get_file_path("markdown/table_generation_conflict/input-1.md"), + encoding="utf8", + ) as fin: + sample_1 = fin.read() + with open( + self.get_file_path("markdown/table_generation_conflict/input-2.md"), + encoding="utf8", + ) as fin: + sample_2 = fin.read() + with open( + self.get_file_path( + "markdown/table_generation_conflict/expected-no-colors.md" + ), + encoding="utf8", + ) as fin: + expected = fin.read() + actual = VisualDiffer.visual_diff(sample_1, sample_2) + with open( + self.get_file_path( + "markdown/table_generation_conflict/expected-no-colors.md" + ), + "w+", + encoding="utf8", + ) as out: + out.writelines(actual) + self.assertEqual(expected, actual) + + @patch.dict(os.environ, {"COLORED_DIFF": "false"}) + def testVisualDifferExplicitNoColors(self): + with open( + self.get_file_path("markdown/table_generation_conflict/input-1.md"), + encoding="utf8", + ) as fin: + sample_1 = fin.read() + with open( + self.get_file_path("markdown/table_generation_conflict/input-2.md"), + encoding="utf8", + ) as fin: + sample_2 = fin.read() + with open( + self.get_file_path( + "markdown/table_generation_conflict/expected-no-colors.md" + ), + encoding="utf8", + ) as fin: + expected = fin.read() + actual = VisualDiffer.visual_diff(sample_1, sample_2) + self.assertEqual(expected, actual) + + @patch.dict(os.environ, {"COLORED_DIFF": "true"}) + def testColoredVisualDiffer(self): + with open( + self.get_file_path("markdown/table_generation_conflict/input-1.md"), + encoding="utf8", + ) as fin: + sample_1 = fin.read() + with open( + self.get_file_path("markdown/table_generation_conflict/input-2.md"), + encoding="utf8", + ) as fin: + sample_2 = fin.read() + with open( + self.get_file_path( + "markdown/table_generation_conflict/expected-with-colors.md", + ), + encoding="utf8", + ) as fin: + expected = fin.read() + actual = VisualDiffer.visual_diff(sample_1, sample_2) + self.assertEqual(expected, actual) + def check( self, input_dir: str, From fe157efee65725c2b4ce2e786994af951f4470bf Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 6 Mar 2024 10:26:46 -0800 Subject: [PATCH 18/31] Adds required stability property to enum members (#267) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- semantic-conventions/CHANGELOG.md | 2 + semantic-conventions/README.md | 9 +- semantic-conventions/semconv.schema.json | 14 +++ .../semconv/model/semantic_attribute.py | 29 ++++- .../semconv/templating/compatibility.py | 114 +++++++++++------- .../semconv/templating/markdown/__init__.py | 33 ++--- .../compat/enum_member_removed/vnext.yaml | 3 +- .../compat/enum_member_removed/vprev.yaml | 3 +- .../data/compat/enum_type_changed/vnext.yaml | 14 ++- .../data/compat/enum_type_changed/vprev.yaml | 14 ++- .../data/compat/enum_value_changed/vnext.yaml | 5 + .../data/compat/enum_value_changed/vprev.yaml | 5 + .../src/tests/data/compat/success/vnext.yaml | 4 +- .../src/tests/data/compat/success/vprev.yaml | 2 + .../data/markdown/deprecated/general.yaml | 7 ++ .../tests/data/markdown/deprecated/http.yaml | 5 + .../tests/data/markdown/empty/general.yaml | 7 ++ .../tests/data/markdown/empty_table/faas.yaml | 5 + .../data/markdown/empty_table/general.yaml | 7 ++ .../src/tests/data/markdown/enum_int/rpc.yaml | 17 +++ .../markdown/extend_constraint/database.yaml | 43 +++++++ .../markdown/extend_constraint/general.yaml | 7 ++ .../src/tests/data/markdown/include/faas.yaml | 5 + .../data/markdown/multiple_enum/general.yaml | 13 ++ .../data/markdown/parameter_empty/faas.yaml | 5 + .../data/markdown/parameter_full/faas.yaml | 5 + .../parameter_remove_constraint/database.yaml | 40 ++++++ .../data/markdown/parameter_tag/database.yaml | 40 ++++++ .../parameter_tag_empty/database.yaml | 40 ++++++ .../markdown/stability/all_badges_expected.md | 21 ++++ .../data/markdown/stability/stability.yaml | 26 +++- .../stability/stable_badges_expected.md | 21 ++++ .../src/tests/data/yaml/cloud.yaml | 3 + .../yaml/errors/empty/empty_example_enum.yaml | 1 + .../experimental_attr_stable_member.yaml | 14 +++ .../missing_stability_on_enum_member.yaml | 13 ++ ...tiple_stability_values_on_enum_member.yaml | 14 +++ ..._value.yaml => wrong_stability_value.yaml} | 0 .../wrong_stability_value_on_enum_member.yaml | 14 +++ .../src/tests/data/yaml/faas.yaml | 8 ++ .../src/tests/data/yaml/general.yaml | 7 ++ .../src/tests/data/yaml/http.yaml | 5 + .../semconv/model/test_error_detection.py | 42 ++++++- .../semconv/templating/test_compatibility.py | 5 + semantic-conventions/syntax.md | 4 +- 45 files changed, 629 insertions(+), 66 deletions(-) create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/experimental_attr_stable_member.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_on_enum_member.yaml create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values_on_enum_member.yaml rename semantic-conventions/src/tests/data/yaml/errors/stability/{wrong_value.yaml => wrong_stability_value.yaml} (100%) create mode 100644 semantic-conventions/src/tests/data/yaml/errors/stability/wrong_stability_value_on_enum_member.yaml diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index 38501e04..786f0f40 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -4,6 +4,8 @@ Please update the changelog as part of any significant pull request. ## Unreleased +- BREAKING: Add `stability` (required) and `deprecated` (optional) properties to `EnumMember` + ([#267](https://github.com/open-telemetry/build-tools/pull/267)) - Change minimum support python version to 3.10 in setup.cfg and Dockerfile ([#285](https://github.com/open-telemetry/build-tools/pull/285)) - BREAKING: Make stability required (also: fix ref and extends, render badges on metrics). diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index e76f01d2..e52a12a2 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -133,13 +133,18 @@ The `{semconv version}` (e.g. `1.24.0`) is the previously released version of se Following checks are performed - On all attributes and metrics (experimental and stable): - - attributes and metrics must not be removed. + - attributes and metrics must not be removed + - enum attribute members must not be removed - On stable attributes and attribute templates: - stability must not be changed - the type of attribute must not be changed - enum attribute: type of value must not be changed - - enum attribute: members must not be removed (changing `id` field is allowed, as long as `value` does not change) + +- On stable enum attribute members: + - stability must not be changed + - `id` and `value` must not be changed + - On stable metrics: - stability must not be changed - instrument and unit must not be changed diff --git a/semantic-conventions/semconv.schema.json b/semantic-conventions/semconv.schema.json index 7e51cca3..0e3a5050 100644 --- a/semantic-conventions/semconv.schema.json +++ b/semantic-conventions/semconv.schema.json @@ -259,6 +259,9 @@ "note": { "type": "string", "description": "longer description. It defaults to an empty string." + }, + "stability": { + "allOf": [{ "$ref": "#/definitions/StabilityLevel" }] } } } @@ -343,6 +346,14 @@ } ] }, + "StabilityLevel": { + "description": "specifies the stability level. Can be 'stable' or 'experimental' (the default).", + "type": "string", + "enum": [ + "stable", + "experimental" + ] + }, "Attribute": { "type": "object", "allOf": [ @@ -416,6 +427,9 @@ "deprecated": { "type": "string", "description": "specifies if the attribute is deprecated. The string provided as MUST specify why it's deprecated and/or what to use instead." + }, + "stability": { + "allOf": [{ "$ref": "#/definitions/StabilityLevel" }] } } }, diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py index 5d1c1b49..32996f9d 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py @@ -187,6 +187,17 @@ def parse( stability = SemanticAttribute.parse_stability( attribute.get("stability"), position_data, strict_validation ) + if stability == StabilityLevel.EXPERIMENTAL and isinstance( + attr_type, EnumAttributeType + ): + for member in attr_type.members: + if member.stability == StabilityLevel.STABLE: + msg = ( + f"Member '{member.member_id}' is marked as stable " + + "but it is not allowed on experimental attribute!" + ) + raise ValidationError.from_yaml_pos(position_data["type"], msg) + deprecated = SemanticAttribute.parse_deprecated( attribute.get("deprecated"), position_data ) @@ -482,7 +493,7 @@ def parse(attribute_type): attribute_type.lc.data["members"], "Enumeration without members!" ) - allowed_keys = ["id", "value", "brief", "note"] + allowed_keys = ["id", "value", "brief", "note", "stability", "deprecated"] mandatory_keys = ["id", "value"] for member in attribute_type["members"]: validate_values(member, allowed_keys, mandatory_keys) @@ -492,12 +503,26 @@ def parse(attribute_type): f"Invalid value used in enum: <{member['value']}>", ) validate_id(member["id"], member.lc.data["id"]) + + stability_str = member.get("stability") + if not stability_str: + raise ValidationError.from_yaml_pos( + member.lc.data["id"], + f"Enumeration member '{member['value']}' must have a stability level", + ) + + stability = SemanticAttribute.parse_stability(stability_str, member.lc.data) + deprecated = SemanticAttribute.parse_deprecated( + member.get("deprecated"), member.lc.data + ) members.append( EnumMember( member_id=member["id"], value=member["value"], brief=member.get("brief", member["id"]).strip(), note=member.get("note", "").strip(), + stability=stability, + deprecated=deprecated, ) ) enum_type = AttributeType.get_type(members[0].value) @@ -516,6 +541,8 @@ class EnumMember: value: str brief: str note: str + stability: StabilityLevel + deprecated: str class MdLink: diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py b/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py index 0a28366f..03d94da8 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/compatibility.py @@ -67,49 +67,66 @@ def _check_attribute(self, prev: SemanticAttribute, problems: list[Problem]): problems.append(Problem("attribute", prev.fqn, "was removed")) return + self._check_stability( + prev.stability, cur.stability, "attribute", prev.fqn, problems + ) if prev.stability == StabilityLevel.STABLE: - if cur.stability != prev.stability: + self._check_attribute_type(prev, cur, problems) + + if ( + isinstance(prev.attr_type, EnumAttributeType) + and + # this makes mypy happy, we already checked that type is the same for stable attributes + isinstance(cur.attr_type, EnumAttributeType) + ): + for member in prev.attr_type.members: + self._check_member(prev.fqn, member, cur.attr_type.members, problems) + + def _check_stability( + self, + prev: StabilityLevel, + cur: StabilityLevel, + signal: str, + fqn: str, + problems: list[Problem], + ): + if prev == StabilityLevel.STABLE and cur != prev: + problems.append( + Problem(signal, fqn, f"stability changed from '{prev}' to '{cur}'") + ) + + def _check_attribute_type( + self, prev: SemanticAttribute, cur: SemanticAttribute, problems: list[Problem] + ): + if isinstance(prev.attr_type, EnumAttributeType): + if not isinstance(cur.attr_type, EnumAttributeType): problems.append( Problem( "attribute", prev.fqn, - f"stability changed from '{prev.stability}' to '{cur.stability}'", + f"type changed from '{prev.attr_type}' to '{cur.attr_type}'", ) ) - - if isinstance(prev.attr_type, EnumAttributeType): - if not isinstance(cur.attr_type, EnumAttributeType): + else: + # enum type change inevitably causes some values to be removed + # which will be reported in _check_member method as well. + # keeping this check to provide more detailed error message + if cur.attr_type.enum_type != prev.attr_type.enum_type: problems.append( Problem( "attribute", prev.fqn, - f"type changed from '{prev.attr_type}' to '{cur.attr_type}'", + f"enum type changed from '{prev.attr_type.enum_type}' to '{cur.attr_type.enum_type}'", ) ) - else: - # enum type change inevitably causes some values to be removed - # which will be reported in _check_member method as well. - # keeping this check to provide more detailed error message - if cur.attr_type.enum_type != prev.attr_type.enum_type: - problems.append( - Problem( - "attribute", - prev.fqn, - f"enum type changed from '{prev.attr_type.enum_type}' to '{cur.attr_type.enum_type}'", - ) - ) - for member in prev.attr_type.members: - self._check_member( - prev.fqn, member, cur.attr_type.members, problems - ) - elif cur.attr_type != prev.attr_type: - problems.append( - Problem( - "attribute", - prev.fqn, - f"type changed from '{prev.attr_type}' to '{cur.attr_type}'", - ) + elif cur.attr_type != prev.attr_type: + problems.append( + Problem( + "attribute", + prev.fqn, + f"type changed from '{prev.attr_type}' to '{cur.attr_type}'", ) + ) def _check_member( self, @@ -118,8 +135,22 @@ def _check_member( members: list[EnumMember], problems: list[Problem], ): + found = False for member in members: if prev.member_id == member.member_id: + found = True + if prev.stability != StabilityLevel.STABLE: + # we allow stability and value changes for non-stable members + break + + self._check_stability( + prev.stability, + member.stability, + "enum attribute member", + f"{fqn}.{prev.member_id}", + problems, + ) + if prev.value != member.value: member_value = ( f'"{member.value}"' @@ -133,10 +164,12 @@ def _check_member( f"value changed from '{prev.value}' to '{member_value}'", ) ) - return - problems.append( - Problem("enum attribute member", f"{fqn}.{prev.member_id}", "was removed") - ) + if not found: + problems.append( + Problem( + "enum attribute member", f"{fqn}.{prev.member_id}", "was removed" + ) + ) def _check_metric(self, prev: MetricSemanticConvention, problems: list[Problem]): for cur in self.current_semconv.models.values(): @@ -145,14 +178,13 @@ def _check_metric(self, prev: MetricSemanticConvention, problems: list[Problem]) and cur.metric_name == prev.metric_name ): if prev.stability == StabilityLevel.STABLE: - if cur.stability != prev.stability: - problems.append( - Problem( - "metric", - prev.metric_name, - f"stability changed from '{prev.stability}' to '{cur.stability}'", - ) - ) + self._check_stability( + prev.stability, + cur.stability, + "metric", + prev.metric_name, + problems, + ) if cur.unit != prev.unit: problems.append( Problem( diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py index 2413d197..4accf983 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py @@ -126,7 +126,10 @@ def to_markdown_attr( if isinstance(attribute.attr_type, EnumAttributeType) else AttributeType.get_instantiated_type(attribute.attr_type) ) - description = self._description_with_badge(attribute) + attribute.brief + description = ( + self._description_with_badge(attribute.stability, attribute.deprecated) + + attribute.brief + ) if attribute.note: self.render_ctx.add_note(attribute.note) description += f" [{len(self.render_ctx.notes)}]" @@ -242,7 +245,10 @@ def to_markdown_metric_table( "| -------- | --------------- | ----------- | -------------- |\n" ) - description = self._description_with_badge(semconv) + semconv.brief + description = ( + self._description_with_badge(semconv.stability, semconv.deprecated) + + semconv.brief + ) if semconv.note: self.render_ctx.add_note(semconv.note) description += f" [{len(self.render_ctx.notes)}]" @@ -327,7 +333,10 @@ def to_markdown_enum(self, output: io.StringIO): counter = 1 notes = [] for member in enum.members: - description = member.brief + description = ( + self._description_with_badge(member.stability, member.deprecated) + + member.brief + ) if member.note: description += f" [{counter}]" counter += 1 @@ -528,22 +537,18 @@ def _render_group(self, semconv, parameters, output): output.write("") - def _description_with_badge( - self, item: typing.Union[SemanticAttribute | BaseSemanticConvention] - ): + def _description_with_badge(self, stability: StabilityLevel, deprecated: str): description = "" - if item.deprecated and self.options.enable_deprecated: - if "deprecated" in item.deprecated.lower(): - description = f"**{item.deprecated}**
" + if deprecated and self.options.enable_deprecated: + if "deprecated" in deprecated.lower(): + description = f"**{deprecated}**
" else: - deprecated_msg = self.options.deprecated_md_snippet().format( - item.deprecated - ) + deprecated_msg = self.options.deprecated_md_snippet().format(deprecated) description = f"{deprecated_msg}
" - elif item.stability == StabilityLevel.STABLE and self.options.enable_stable: + elif stability == StabilityLevel.STABLE and self.options.enable_stable: description = f"{self.options.stable_md_snippet()}
" elif ( - item.stability == StabilityLevel.EXPERIMENTAL + stability == StabilityLevel.EXPERIMENTAL and self.options.enable_experimental ): description = f"{self.options.experimental_md_snippet()}
" diff --git a/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml index 9098298c..2c6eb19d 100644 --- a/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml @@ -10,8 +10,9 @@ groups: members: - id: enum_two brief: "enum two" + stability: experimental value: "two" brief: "third attribute" note: "third attribute note" examples: ["two"] - stability: stable \ No newline at end of file + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml index ab72dfa0..9ec933d4 100644 --- a/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml @@ -10,8 +10,9 @@ groups: members: - id: enum_one brief: "enum one" + stability: experimental value: "one" brief: "third attribute" note: "third attribute note" examples: ["one"] - stability: stable \ No newline at end of file + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml index 6875fb50..362cfa36 100644 --- a/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_type_changed/vnext.yaml @@ -10,8 +10,20 @@ groups: members: - id: enum_one brief: "enum one" + stability: stable value: 1 brief: "third attribute" note: "third attribute note" - examples: [1] + examples: [3] + stability: stable + - id: forth_attr + type: + members: + - id: enum_two + brief: "enum two" + stability: experimental + value: 2 + brief: "forth attribute" + note: "forth attribute note" + examples: [2] stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml index ab72dfa0..61a24607 100644 --- a/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_type_changed/vprev.yaml @@ -10,8 +10,20 @@ groups: members: - id: enum_one brief: "enum one" + stability: stable value: "one" brief: "third attribute" note: "third attribute note" - examples: ["one"] + examples: ["three"] + stability: stable + - id: forth_attr + type: + members: + - id: enum_two + brief: "enum two" + stability: experimental + value: "one" + brief: "forth attribute" + note: "forth attribute note" + examples: ["four"] stability: stable \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml index 88f07223..c04605b5 100644 --- a/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_value_changed/vnext.yaml @@ -10,7 +10,12 @@ groups: members: - id: enum_one brief: "enum one" + stability: stable value: "1" + - id: enum_two + brief: "enum two" + stability: experimental + value: "_two_" brief: "third attribute" note: "third attribute note" examples: ["one"] diff --git a/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml index ab72dfa0..b6bd3281 100644 --- a/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_value_changed/vprev.yaml @@ -10,7 +10,12 @@ groups: members: - id: enum_one brief: "enum one" + stability: stable value: "one" + - id: enum_two + brief: "enum two" + stability: experimental + value: "two" brief: "third attribute" note: "third attribute note" examples: ["one"] diff --git a/semantic-conventions/src/tests/data/compat/success/vnext.yaml b/semantic-conventions/src/tests/data/compat/success/vnext.yaml index 388e6efc..1b762111 100644 --- a/semantic-conventions/src/tests/data/compat/success/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/success/vnext.yaml @@ -22,9 +22,11 @@ groups: members: - id: enum_one brief: "Enum one." - value: "one" + stability: stable + value: "_one_" - id: enum_two brief: "Enum two." + stability: stable value: "two" brief: "Third attribute." note: "Third attribute note." diff --git a/semantic-conventions/src/tests/data/compat/success/vprev.yaml b/semantic-conventions/src/tests/data/compat/success/vprev.yaml index 0c3ca727..79fc8d1d 100644 --- a/semantic-conventions/src/tests/data/compat/success/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/success/vprev.yaml @@ -22,9 +22,11 @@ groups: members: - id: enum_one brief: "enum one" + stability: experimental value: "one" - id: enum_two brief: "enum two" + stability: stable value: "two" brief: "third attribute" note: "third attribute note" diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml b/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml index 907fd00a..d0bc36ff 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/deprecated/general.yaml @@ -12,19 +12,25 @@ groups: members: - id: ip.tcp value: "IP.TCP" + stability: experimental - id: ip.udp value: "IP.UDP" + stability: experimental - id: ip value: "IP" + stability: experimental brief: 'Another IP-based protocol' - id: unix value: "Unix" + stability: experimental brief: 'Unix Domain socket. See below.' - id: pipe value: "pipe" + stability: experimental brief: 'Named or anonymous pipe. See note below.' - id: inproc value: "inproc" + stability: experimental brief: 'In-process communication.' note: > Signals that there is only in-process communication not using a "real" network protocol @@ -32,6 +38,7 @@ groups: attributes can be left out in that case. - id: other value: "other" + stability: experimental brief: 'Something else (non IP-based).' brief: > Transport protocol used. See note below. diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml b/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml index 4f668d6d..e0061b1d 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml @@ -61,18 +61,23 @@ groups: - id: http_1_0 value: '1.0' brief: 'HTTP 1.0' + stability: experimental - id: http_1_1 value: '1.1' brief: 'HTTP 1.1' + stability: experimental - id: http_2_0 value: '2.0' brief: 'HTTP 2' + stability: experimental - id: spdy value: 'SPDY' brief: 'SPDY protocol.' + stability: experimental - id: quic value: 'QUIC' brief: 'QUIC protocol.' + stability: experimental brief: 'Kind of HTTP protocol used' deprecated: Deprecated. Use attribute `flavor_new` instead. note: > diff --git a/semantic-conventions/src/tests/data/markdown/empty/general.yaml b/semantic-conventions/src/tests/data/markdown/empty/general.yaml index 907fd00a..71ebd125 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty/general.yaml @@ -12,25 +12,32 @@ groups: members: - id: ip.tcp value: "IP.TCP" + stability: experimental - id: ip.udp value: "IP.UDP" + stability: experimental - id: ip value: "IP" brief: 'Another IP-based protocol' + stability: experimental - id: unix value: "Unix" brief: 'Unix Domain socket. See below.' + stability: experimental - id: pipe value: "pipe" brief: 'Named or anonymous pipe. See note below.' + stability: experimental - id: inproc value: "inproc" brief: 'In-process communication.' + stability: experimental note: > Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. - id: other + stability: experimental value: "other" brief: 'Something else (non IP-based).' brief: > diff --git a/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml b/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml index 648eb26e..6e3ad387 100644 --- a/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty_table/faas.yaml @@ -17,17 +17,22 @@ groups: - id: datasource value: 'datasource' brief: 'A response to some data source operation such as a database or filesystem read/write.' + stability: experimental - id: http value: 'http' brief: 'To provide an answer to an inbound HTTP request' + stability: experimental - id: pubsub value: 'pubsub' brief: 'A function is set to be executed when messages are sent to a messaging system.' + stability: experimental - id: timer value: 'timer' brief: 'A function is scheduled to be executed regularly.' + stability: experimental - id: other value: 'other' + stability: experimental - id: execution stability: experimental type: string diff --git a/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml b/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml index 907fd00a..ba9318d2 100644 --- a/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/empty_table/general.yaml @@ -12,20 +12,26 @@ groups: members: - id: ip.tcp value: "IP.TCP" + stability: experimental - id: ip.udp value: "IP.UDP" + stability: experimental - id: ip value: "IP" brief: 'Another IP-based protocol' + stability: experimental - id: unix value: "Unix" brief: 'Unix Domain socket. See below.' + stability: experimental - id: pipe value: "pipe" brief: 'Named or anonymous pipe. See note below.' + stability: experimental - id: inproc value: "inproc" brief: 'In-process communication.' + stability: experimental note: > Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network @@ -33,6 +39,7 @@ groups: - id: other value: "other" brief: 'Something else (non IP-based).' + stability: experimental brief: > Transport protocol used. See note below. examples: 'IP.TCP' diff --git a/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml b/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml index 1c13a243..0a34a892 100644 --- a/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml +++ b/semantic-conventions/src/tests/data/markdown/enum_int/rpc.yaml @@ -10,38 +10,55 @@ groups: members: - id: ok value: 0 + stability: experimental - id: cancelled value: 1 + stability: experimental - id: unknown value: 2 + stability: experimental - id: invalid_argument value: 3 + stability: experimental - id: deadline_exceeded value: 4 + stability: experimental - id: not_found value: 5 + stability: experimental - id: already_exists value: 6 + stability: experimental - id: permission_denied value: 7 + stability: experimental - id: resource_exhausted value: 8 + stability: experimental - id: failed_precondition value: 9 + stability: experimental - id: aborted value: 10 + stability: experimental - id: out_of_range value: 11 + stability: experimental - id: unimplemented value: 12 + stability: experimental - id: internal value: 13 + stability: experimental - id: unavailable value: 14 + stability: experimental - id: data_loss value: 15 + stability: experimental - id: unauthenticated value: 16 + stability: experimental requirement_level: required brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." examples: [0, 1, 16] diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml b/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml index a64b6d85..ebfd1b70 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/database.yaml @@ -18,132 +18,175 @@ groups: - id: other_sql value: 'other_sql' brief: 'Some other SQL database. Fallback only. See notes.' + stability: experimental - id: mssql value: 'mssql' brief: 'Microsoft SQL Server' + stability: experimental - id: mysql value: 'mysql' brief: 'MySQL' + stability: experimental - id: oracle value: 'oracle' brief: 'Oracle Database' + stability: experimental - id: db2 value: 'db2' brief: 'IBM Db2' + stability: experimental - id: postgresql value: 'postgresql' brief: 'PostgreSQL' + stability: experimental - id: redshift value: 'redshift' brief: 'Amazon Redshift' + stability: experimental - id: hive value: 'hive' brief: 'Apache Hive' + stability: experimental - id: cloudscape value: 'cloudscape' brief: 'Cloudscape' + stability: experimental - id: hsqlsb value: 'hsqlsb' brief: 'HyperSQL DataBase' + stability: experimental - id: progress value: 'progress' brief: 'Progress Database' + stability: experimental - id: maxdb value: 'maxdb' brief: 'SAP MaxDB' + stability: experimental - id: hanadb value: 'hanadb' brief: 'SAP HANA' + stability: experimental - id: ingres value: 'ingres' brief: 'Ingres' + stability: experimental - id: firstsql value: 'firstsql' brief: 'FirstSQL' + stability: experimental - id: edb value: 'edb' brief: 'EnterpriseDB' + stability: experimental - id: cache value: 'cache' brief: 'InterSystems Caché' + stability: experimental - id: adabas value: 'adabas' brief: 'Adabas (Adaptable Database System)' + stability: experimental - id: firebird value: 'firebird' brief: 'Firebird' + stability: experimental - id: derby value: 'derby' brief: 'Apache Derby' + stability: experimental - id: filemaker value: 'filemaker' brief: 'FileMaker' + stability: experimental - id: informix value: 'informix' brief: 'Informix' + stability: experimental - id: instantdb value: 'instantdb' brief: 'InstantDB' + stability: experimental - id: interbase value: 'interbase' brief: 'InterBase' + stability: experimental - id: mariadb value: 'mariadb' brief: 'MariaDB' + stability: experimental - id: netezza value: 'netezza' brief: 'Netezza' + stability: experimental - id: pervasive value: 'pervasive' brief: 'Pervasive PSQL' + stability: experimental - id: pointbase value: 'pointbase' brief: 'PointBase' + stability: experimental - id: sqlite value: 'sqlite' brief: 'SQLite' + stability: experimental - id: sybase value: 'sybase' brief: 'Sybase' + stability: experimental - id: teradata value: 'teradata' brief: 'Teradata' + stability: experimental - id: vertica value: 'vertica' brief: 'Vertica' + stability: experimental - id: h2 value: 'h2' brief: 'H2' + stability: experimental - id: coldfusion value: 'coldfusion' brief: 'ColdFusion IMQ' + stability: experimental - id: cassandra value: 'cassandra' brief: 'Apache Cassandra' + stability: experimental - id: hbase value: 'hbase' brief: 'Apache HBase' + stability: experimental - id: mongodb value: 'mongodb' brief: 'MongoDB' + stability: experimental - id: redis value: 'redis' brief: 'Redis' + stability: experimental - id: couchbase value: 'couchbase' brief: 'Couchbase' + stability: experimental - id: couchdb value: 'couchdb' brief: 'CouchDB' + stability: experimental - id: cosmosdb value: 'cosmosdb' brief: 'Microsoft Azure Cosmos DB' + stability: experimental - id: dynamodb value: 'dynamodb' brief: 'Amazon DynamoDB' + stability: experimental - id: neo4j value: 'neo4j' brief: 'Neo4j' + stability: experimental - id: connection_string stability: experimental tag: connection-level diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml b/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml index 907fd00a..ba9318d2 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/general.yaml @@ -12,20 +12,26 @@ groups: members: - id: ip.tcp value: "IP.TCP" + stability: experimental - id: ip.udp value: "IP.UDP" + stability: experimental - id: ip value: "IP" brief: 'Another IP-based protocol' + stability: experimental - id: unix value: "Unix" brief: 'Unix Domain socket. See below.' + stability: experimental - id: pipe value: "pipe" brief: 'Named or anonymous pipe. See note below.' + stability: experimental - id: inproc value: "inproc" brief: 'In-process communication.' + stability: experimental note: > Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network @@ -33,6 +39,7 @@ groups: - id: other value: "other" brief: 'Something else (non IP-based).' + stability: experimental brief: > Transport protocol used. See note below. examples: 'IP.TCP' diff --git a/semantic-conventions/src/tests/data/markdown/include/faas.yaml b/semantic-conventions/src/tests/data/markdown/include/faas.yaml index b9d592b1..84607bbe 100644 --- a/semantic-conventions/src/tests/data/markdown/include/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/include/faas.yaml @@ -15,18 +15,23 @@ groups: allow_custom_values: false members: - id: datasource + stability: experimental value: 'datasource' brief: 'A response to some data source operation such as a database or filesystem read/write.' - id: http + stability: experimental value: 'http' brief: 'To provide an answer to an inbound HTTP request' - id: pubsub + stability: experimental value: 'pubsub' brief: 'A function is set to be executed when messages are sent to a messaging system.' - id: timer + stability: experimental value: 'timer' brief: 'A function is scheduled to be executed regularly.' - id: other + stability: experimental value: 'other' - id: execution stability: experimental diff --git a/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml b/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml index 650de793..2edca218 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml +++ b/semantic-conventions/src/tests/data/markdown/multiple_enum/general.yaml @@ -12,26 +12,33 @@ groups: members: - id: ip.tcp value: "IP.TCP" + stability: experimental - id: ip.udp value: "IP.UDP" + stability: experimental - id: ip value: "IP" brief: 'Another IP-based protocol' + stability: experimental - id: unix value: "Unix" brief: 'Unix Domain socket. See below.' + stability: experimental - id: pipe value: "pipe" brief: 'Named or anonymous pipe. See note below.' + stability: experimental - id: inproc value: "inproc" brief: 'In-process communication.' + stability: experimental note: > Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. - id: other value: "other" + stability: experimental brief: 'Something else (non IP-based).' brief: > Transport protocol used. See note below. @@ -43,13 +50,17 @@ groups: members: - id: wifi value: "wifi" + stability: experimental note: "Usually 802.11" - id: wired value: "wired" + stability: experimental - id: cell value: "cell" + stability: experimental - id: unavailable value: "unavailable" + stability: experimental brief: 'unavailable' examples: 'wifi' - id: host.connection.subtype @@ -61,10 +72,12 @@ groups: value: "1G" brief: > 1G + stability: experimental - id: gen2g value: "2G" brief: > 2G + stability: experimental brief: 'This describes more details regarding the connection.type. It may be the type of cell connection, but it could be used for describing details about a wifi connection.' examples: '2G' - id: host.carrier.name diff --git a/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml index 648eb26e..6e3ad387 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_empty/faas.yaml @@ -17,17 +17,22 @@ groups: - id: datasource value: 'datasource' brief: 'A response to some data source operation such as a database or filesystem read/write.' + stability: experimental - id: http value: 'http' brief: 'To provide an answer to an inbound HTTP request' + stability: experimental - id: pubsub value: 'pubsub' brief: 'A function is set to be executed when messages are sent to a messaging system.' + stability: experimental - id: timer value: 'timer' brief: 'A function is scheduled to be executed regularly.' + stability: experimental - id: other value: 'other' + stability: experimental - id: execution stability: experimental type: string diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml b/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml index 0fb1cad4..4064b531 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/faas.yaml @@ -17,17 +17,22 @@ groups: - id: datasource value: 'datasource' brief: 'A response to some data source operation such as a database or filesystem read/write.' + stability: experimental - id: http value: 'http' brief: 'To provide an answer to an inbound HTTP request' + stability: experimental - id: pubsub value: 'pubsub' brief: 'A function is set to be executed when messages are sent to a messaging system.' + stability: experimental - id: timer value: 'timer' brief: 'A function is scheduled to be executed regularly.' + stability: experimental - id: other value: 'other' + stability: experimental - id: execution stability: experimental type: string diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml index ebad25df..8972e112 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/database.yaml @@ -17,24 +17,31 @@ groups: - id: sql value: 'sql' brief: 'A SQL database' + stability: experimental - id: cassandra value: 'cassandra' brief: 'Apache Cassandra' + stability: experimental - id: hbase value: 'hbase' brief: 'Apache HBase' + stability: experimental - id: mongodb value: 'mongodb' brief: 'MongoDB' + stability: experimental - id: redis value: 'redis' brief: 'Redis' + stability: experimental - id: couchbase value: 'couchbase' brief: 'Couchbase' + stability: experimental - id: couchdb value: 'couchdb' brief: 'CouchDB' + stability: experimental requirement_level: required brief: > Database type. For any SQL database, "sql". @@ -47,102 +54,135 @@ groups: - id: mssql value: 'mssql' brief: 'Microsoft SQL Server' + stability: experimental - id: mysql value: 'mysql' brief: 'MySQL' + stability: experimental - id: oracle value: 'oracle' brief: 'Oracle' + stability: experimental - id: db2 value: 'db2' brief: 'IBM Db2' + stability: experimental - id: postgresql value: 'postgresql' brief: 'PostgreSQL' + stability: experimental - id: redshift value: 'redshift' brief: 'Amazon Redshift' + stability: experimental - id: hive value: 'hive' brief: 'Apache Hive' + stability: experimental - id: cloudscape value: 'cloudscape' brief: 'Cloudscape' + stability: experimental - id: hsqlsb value: 'hsqlsb' brief: 'HyperSQL DataBase' + stability: experimental - id: progress value: 'progress' brief: 'Progress Database' + stability: experimental - id: maxdb value: 'maxdb' brief: 'SAP MaxDB' + stability: experimental - id: hanadb value: 'hanadb' brief: 'SAP HANA' + stability: experimental - id: ingres value: 'ingres' brief: 'Ingres' + stability: experimental - id: firstsql value: 'firstsql' brief: 'FirstSQL' + stability: experimental - id: edb value: 'edb' brief: 'EnterpriseDB' + stability: experimental - id: cache value: 'cache' brief: 'InterSystems Caché' + stability: experimental - id: adabas value: 'adabas' brief: 'Adabas (Adaptable Database System)' + stability: experimental - id: firebird value: 'firebird' brief: 'Firebird' + stability: experimental - id: derby value: 'derby' brief: 'Apache Derby' + stability: experimental - id: filemaker value: 'filemaker' brief: 'FileMaker' + stability: experimental - id: informix value: 'informix' brief: 'Informix' + stability: experimental - id: instantdb value: 'instantdb' brief: 'InstantDB' + stability: experimental - id: interbase value: 'interbase' brief: 'InterBase' + stability: experimental - id: mariadb value: 'mariadb' brief: 'MariaDB' + stability: experimental - id: netezza value: 'netezza' brief: 'Netezza' + stability: experimental - id: pervasive value: 'pervasive' brief: 'Pervasive PSQL' + stability: experimental - id: pointbase value: 'pointbase' brief: 'PointBase' + stability: experimental - id: sqlite value: 'sqlite' brief: 'SQLite' + stability: experimental - id: sybase value: 'sybase' brief: 'Sybase' + stability: experimental - id: teradata value: 'teradata' brief: 'Teradata' + stability: experimental - id: vertica value: 'vertica' brief: 'Vertica' + stability: experimental - id: h2 value: 'h2' brief: 'H2' + stability: experimental - id: coldfusion value: 'coldfusion' brief: 'ColdFusion IMQ' + stability: experimental requirement_level: conditionally_required: for `db.type="sql"` brief: > diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml index 36240552..2ff73e47 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag/database.yaml @@ -17,24 +17,31 @@ groups: - id: sql value: 'sql' brief: 'A SQL database' + stability: experimental - id: cassandra value: 'cassandra' brief: 'Apache Cassandra' + stability: experimental - id: hbase value: 'hbase' brief: 'Apache HBase' + stability: experimental - id: mongodb value: 'mongodb' brief: 'MongoDB' + stability: experimental - id: redis value: 'redis' brief: 'Redis' + stability: experimental - id: couchbase value: 'couchbase' brief: 'Couchbase' + stability: experimental - id: couchdb value: 'couchdb' brief: 'CouchDB' + stability: experimental requirement_level: required brief: > Database type. For any SQL database, "sql". @@ -47,102 +54,135 @@ groups: - id: mssql value: 'mssql' brief: 'Microsoft SQL Server' + stability: experimental - id: mysql value: 'mysql' brief: 'MySQL' + stability: experimental - id: oracle value: 'oracle' brief: 'Oracle' + stability: experimental - id: db2 value: 'db2' brief: 'IBM Db2' + stability: experimental - id: postgresql value: 'postgresql' brief: 'PostgreSQL' + stability: experimental - id: redshift value: 'redshift' brief: 'Amazon Redshift' + stability: experimental - id: hive value: 'hive' brief: 'Apache Hive' + stability: experimental - id: cloudscape value: 'cloudscape' brief: 'Cloudscape' + stability: experimental - id: hsqlsb value: 'hsqlsb' brief: 'HyperSQL DataBase' + stability: experimental - id: progress value: 'progress' brief: 'Progress Database' + stability: experimental - id: maxdb value: 'maxdb' brief: 'SAP MaxDB' + stability: experimental - id: hanadb value: 'hanadb' brief: 'SAP HANA' + stability: experimental - id: ingres value: 'ingres' brief: 'Ingres' + stability: experimental - id: firstsql value: 'firstsql' brief: 'FirstSQL' + stability: experimental - id: edb value: 'edb' brief: 'EnterpriseDB' + stability: experimental - id: cache value: 'cache' brief: 'InterSystems Caché' + stability: experimental - id: adabas value: 'adabas' brief: 'Adabas (Adaptable Database System)' + stability: experimental - id: firebird value: 'firebird' brief: 'Firebird' + stability: experimental - id: derby value: 'derby' brief: 'Apache Derby' + stability: experimental - id: filemaker value: 'filemaker' brief: 'FileMaker' + stability: experimental - id: informix value: 'informix' brief: 'Informix' + stability: experimental - id: instantdb value: 'instantdb' brief: 'InstantDB' + stability: experimental - id: interbase value: 'interbase' brief: 'InterBase' + stability: experimental - id: mariadb value: 'mariadb' brief: 'MariaDB' + stability: experimental - id: netezza value: 'netezza' brief: 'Netezza' + stability: experimental - id: pervasive value: 'pervasive' brief: 'Pervasive PSQL' + stability: experimental - id: pointbase value: 'pointbase' brief: 'PointBase' + stability: experimental - id: sqlite value: 'sqlite' brief: 'SQLite' + stability: experimental - id: sybase value: 'sybase' brief: 'Sybase' + stability: experimental - id: teradata value: 'teradata' brief: 'Teradata' + stability: experimental - id: vertica value: 'vertica' brief: 'Vertica' + stability: experimental - id: h2 value: 'h2' brief: 'H2' + stability: experimental - id: coldfusion value: 'coldfusion' brief: 'ColdFusion IMQ' + stability: experimental requirement_level: recommended: for `db.type="sql"` brief: > diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml index 7bb4e580..356b7a74 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/database.yaml @@ -17,24 +17,31 @@ groups: - id: sql value: 'sql' brief: 'A SQL database' + stability: experimental - id: cassandra value: 'cassandra' brief: 'Apache Cassandra' + stability: experimental - id: hbase value: 'hbase' brief: 'Apache HBase' + stability: experimental - id: mongodb value: 'mongodb' brief: 'MongoDB' + stability: experimental - id: redis value: 'redis' brief: 'Redis' + stability: experimental - id: couchbase value: 'couchbase' brief: 'Couchbase' + stability: experimental - id: couchdb value: 'couchdb' brief: 'CouchDB' + stability: experimental requirement_level: required brief: > Database type. For any SQL database, "sql". @@ -47,102 +54,135 @@ groups: - id: mssql value: 'mssql' brief: 'Microsoft SQL Server' + stability: experimental - id: mysql value: 'mysql' brief: 'MySQL' + stability: experimental - id: oracle value: 'oracle' brief: 'Oracle' + stability: experimental - id: db2 value: 'db2' brief: 'IBM Db2' + stability: experimental - id: postgresql value: 'postgresql' brief: 'PostgreSQL' + stability: experimental - id: redshift value: 'redshift' brief: 'Amazon Redshift' + stability: experimental - id: hive value: 'hive' brief: 'Apache Hive' + stability: experimental - id: cloudscape value: 'cloudscape' brief: 'Cloudscape' + stability: experimental - id: hsqlsb value: 'hsqlsb' brief: 'HyperSQL DataBase' + stability: experimental - id: progress value: 'progress' brief: 'Progress Database' + stability: experimental - id: maxdb value: 'maxdb' brief: 'SAP MaxDB' + stability: experimental - id: hanadb value: 'hanadb' brief: 'SAP HANA' + stability: experimental - id: ingres value: 'ingres' brief: 'Ingres' + stability: experimental - id: firstsql value: 'firstsql' brief: 'FirstSQL' + stability: experimental - id: edb value: 'edb' brief: 'EnterpriseDB' + stability: experimental - id: cache value: 'cache' brief: 'InterSystems Caché' + stability: experimental - id: adabas value: 'adabas' brief: 'Adabas (Adaptable Database System)' + stability: experimental - id: firebird value: 'firebird' brief: 'Firebird' + stability: experimental - id: derby value: 'derby' brief: 'Apache Derby' + stability: experimental - id: filemaker value: 'filemaker' brief: 'FileMaker' + stability: experimental - id: informix value: 'informix' brief: 'Informix' + stability: experimental - id: instantdb value: 'instantdb' brief: 'InstantDB' + stability: experimental - id: interbase value: 'interbase' brief: 'InterBase' + stability: experimental - id: mariadb value: 'mariadb' brief: 'MariaDB' + stability: experimental - id: netezza value: 'netezza' brief: 'Netezza' + stability: experimental - id: pervasive value: 'pervasive' brief: 'Pervasive PSQL' + stability: experimental - id: pointbase value: 'pointbase' brief: 'PointBase' + stability: experimental - id: sqlite value: 'sqlite' brief: 'SQLite' + stability: experimental - id: sybase value: 'sybase' brief: 'Sybase' + stability: experimental - id: teradata value: 'teradata' brief: 'Teradata' + stability: experimental - id: vertica value: 'vertica' brief: 'Vertica' + stability: experimental - id: h2 value: 'h2' brief: 'H2' + stability: experimental - id: coldfusion value: 'coldfusion' brief: 'ColdFusion IMQ' + stability: experimental requirement_level: conditionally_required: for `db.type="sql"` brief: > diff --git a/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md index 856f8a0c..21578858 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md +++ b/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md @@ -5,6 +5,16 @@ | [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | | [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | | [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | + +`test.stable_enum_attr` MUST be one of the following: + +| Value | Description | +|---|---| +| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | +| `two` | ![Experimental](https://img.shields.io/badge/-experimental-blue)
member two | +| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | +| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | @@ -14,6 +24,7 @@ | [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | | [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | | [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | @@ -23,6 +34,16 @@ | [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | | [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | | [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | + +`test.stable_enum_attr` MUST be one of the following: + +| Value | Description | +|---|---| +| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | +| `two` | ![Experimental](https://img.shields.io/badge/-experimental-blue)
member two | +| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | +| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | diff --git a/semantic-conventions/src/tests/data/markdown/stability/stability.yaml b/semantic-conventions/src/tests/data/markdown/stability/stability.yaml index 6ad528db..357f09f2 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/stability.yaml +++ b/semantic-conventions/src/tests/data/markdown/stability/stability.yaml @@ -26,6 +26,29 @@ groups: stability: experimental deprecated: "Removed." brief: "" + - id: stable_enum_attr + brief: "" + stability: stable + type: + members: + - id: one + value: "one" + brief: 'member one' + stability: stable + - id: two + value: "two" + stability: experimental + brief: 'member two' + - id: three + value: "three" + stability: experimental + deprecated: "Removed." + brief: 'member three' + - id: four + value: "four" + stability: stable + deprecated: "Removed." + brief: 'member four' - id: ref_test brief: 'ref_test' attributes: @@ -33,6 +56,7 @@ groups: - ref: test.stable_attr - ref: test.deprecated_stable_attr - ref: test.deprecated_experimental_attr + - ref: test.stable_enum_attr - id: extends_test brief: 'extends_test' extends: test @@ -63,4 +87,4 @@ groups: instrument: updowncounter unit: "{d}" attributes: - - ref: test.deprecated_experimental_attr \ No newline at end of file + - ref: test.deprecated_experimental_attr diff --git a/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md index b1e779ad..42717ce6 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md +++ b/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md @@ -5,6 +5,16 @@ | [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | | [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | | [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | + +`test.stable_enum_attr` MUST be one of the following: + +| Value | Description | +|---|---| +| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | +| `two` | member two | +| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | +| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | @@ -14,6 +24,7 @@ | [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | | [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | | [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | @@ -23,6 +34,16 @@ | [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | | [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | | [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | + +`test.stable_enum_attr` MUST be one of the following: + +| Value | Description | +|---|---| +| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | +| `two` | member two | +| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | +| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | diff --git a/semantic-conventions/src/tests/data/yaml/cloud.yaml b/semantic-conventions/src/tests/data/yaml/cloud.yaml index a376ff21..8ea59ac8 100644 --- a/semantic-conventions/src/tests/data/yaml/cloud.yaml +++ b/semantic-conventions/src/tests/data/yaml/cloud.yaml @@ -12,10 +12,13 @@ groups: members: - id: aws value: 'aws' + stability: experimental - id: gcp value: 'gcp' + stability: experimental - id: azure value: 'azure' + stability: experimental brief: > Name of the cloud provider. - id: account.id diff --git a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml index 98743a36..8863addf 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/empty/empty_example_enum.yaml @@ -13,5 +13,6 @@ groups: - id: first value: 'first' note: 'first' + stability: experimental requirement_level: required brief: 'test' \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/experimental_attr_stable_member.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/experimental_attr_stable_member.yaml new file mode 100644 index 00000000..db06724c --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/experimental_attr_stable_member.yaml @@ -0,0 +1,14 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: enum_attr + brief: "" + stability: experimental + type: + members: + - id: one + value: "one" + brief: 'member one' + stability: stable diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_on_enum_member.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_on_enum_member.yaml new file mode 100644 index 00000000..79801692 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/missing_stability_on_enum_member.yaml @@ -0,0 +1,13 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: enum_attr + brief: "" + type: + members: + - id: one + value: "one" + brief: 'member one' + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values_on_enum_member.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values_on_enum_member.yaml new file mode 100644 index 00000000..c4659d30 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/multiple_stability_values_on_enum_member.yaml @@ -0,0 +1,14 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: enum_attr + brief: "" + type: + members: + - id: one + value: "one" + brief: 'member one' + stability: experimental + stability: stable diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/wrong_value.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/wrong_stability_value.yaml similarity index 100% rename from semantic-conventions/src/tests/data/yaml/errors/stability/wrong_value.yaml rename to semantic-conventions/src/tests/data/yaml/errors/stability/wrong_stability_value.yaml diff --git a/semantic-conventions/src/tests/data/yaml/errors/stability/wrong_stability_value_on_enum_member.yaml b/semantic-conventions/src/tests/data/yaml/errors/stability/wrong_stability_value_on_enum_member.yaml new file mode 100644 index 00000000..acf36479 --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/errors/stability/wrong_stability_value_on_enum_member.yaml @@ -0,0 +1,14 @@ +groups: + - id: test + type: attribute_group + brief: 'test' + attributes: + - id: enum_attr + brief: "" + type: + members: + - id: one + value: "one" + brief: 'member one' + stability: will_fail + stability: experimental \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/yaml/faas.yaml b/semantic-conventions/src/tests/data/yaml/faas.yaml index 2376f728..9dbe4721 100644 --- a/semantic-conventions/src/tests/data/yaml/faas.yaml +++ b/semantic-conventions/src/tests/data/yaml/faas.yaml @@ -15,18 +15,23 @@ groups: allow_custom_values: false members: - id: datasource + stability: experimental value: 'datasource' brief: 'A response to some data source operation such as a database or filesystem read/write.' - id: http + stability: experimental value: 'http' brief: 'To provide an answer to an inbound HTTP request' - id: pubsub + stability: experimental value: 'pubsub' brief: 'A function is set to be executed when messages are sent to a messaging system.' - id: timer + stability: experimental value: 'timer' brief: 'A function is scheduled to be executed regularly.' - id: other + stability: experimental value: 'other' - id: execution stability: experimental @@ -58,10 +63,13 @@ groups: members: - id: insert value: 'insert' + stability: experimental - id: edit value: 'edit' + stability: experimental - id: delete value: 'delete' + stability: experimental brief: 'Describes the type of the operation that was performed on the data.' - id: time stability: experimental diff --git a/semantic-conventions/src/tests/data/yaml/general.yaml b/semantic-conventions/src/tests/data/yaml/general.yaml index 75526142..9a707e13 100644 --- a/semantic-conventions/src/tests/data/yaml/general.yaml +++ b/semantic-conventions/src/tests/data/yaml/general.yaml @@ -12,20 +12,26 @@ groups: members: - id: ip.tcp value: "IP.TCP" + stability: experimental - id: ip.udp value: "IP.UDP" + stability: experimental - id: ip value: "IP" brief: 'Another IP-based protocol' + stability: experimental - id: unix value: "Unix" brief: 'Unix Domain socket. See below.' + stability: experimental - id: pipe value: "pipe" brief: 'Named or anonymous pipe. See note below.' + stability: experimental - id: inproc value: "inproc" brief: 'In-process communication.' + stability: experimental note: > Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network @@ -33,6 +39,7 @@ groups: - id: other value: "other" brief: 'Something else (non IP-based).' + stability: experimental brief: > Transport protocol used. See note below. examples: 'ip.tcp' diff --git a/semantic-conventions/src/tests/data/yaml/http.yaml b/semantic-conventions/src/tests/data/yaml/http.yaml index 7b9c5746..b1c9703f 100644 --- a/semantic-conventions/src/tests/data/yaml/http.yaml +++ b/semantic-conventions/src/tests/data/yaml/http.yaml @@ -58,18 +58,23 @@ groups: allow_custom_values: true members: - id: http_1_0 + stability: experimental value: '1.0' brief: 'HTTP 1.0' - id: http_1_1 + stability: experimental value: '1.1' brief: 'HTTP 1.1' - id: http_2_0 + stability: experimental value: '2.0' brief: 'HTTP 2' - id: spdy + stability: experimental value: 'SPDY' brief: 'SPDY protocol.' - id: quic + stability: experimental value: 'QUIC' brief: 'QUIC protocol.' brief: 'Kind of HTTP protocol used' diff --git a/semantic-conventions/src/tests/semconv/model/test_error_detection.py b/semantic-conventions/src/tests/semconv/model/test_error_detection.py index a37881e2..62dfe360 100644 --- a/semantic-conventions/src/tests/semconv/model/test_error_detection.py +++ b/semantic-conventions/src/tests/semconv/model/test_error_detection.py @@ -134,7 +134,7 @@ def test_invalid_key_in_constraint(self): def test_invalid_stability(self): with self.assertRaises(ValidationError) as ex: - self.open_yaml("yaml/errors/stability/wrong_value.yaml") + self.open_yaml("yaml/errors/stability/wrong_stability_value.yaml") self.fail() e = ex.exception msg = e.message.lower() @@ -172,6 +172,46 @@ def test_invalid_semconv_stability_with_deprecated(self): self.assertIn("value 'deprecated' is not allowed as a stability marker", msg) self.assertEqual(e.line, 6) + def test_wrong_stability_value_on_enum_member(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml( + "yaml/errors/stability/wrong_stability_value_on_enum_member.yaml" + ) + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn("value 'will_fail' is not allowed as a stability marker", msg) + self.assertEqual(e.line, 13) + + def test_missing_stability_value_on_enum_member(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml( + "yaml/errors/stability/missing_stability_on_enum_member.yaml" + ) + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn("enumeration member 'one' must have a stability level", msg) + self.assertEqual(e.line, 10) + + def test_multiple_stability_values_on_enum_member(self): + with self.assertRaises(DuplicateKeyError): + self.open_yaml( + "yaml/errors/stability/multiple_stability_values_on_enum_member.yaml" + ) + + def test_experimental_attr_stable_member(self): + with self.assertRaises(ValidationError) as ex: + self.open_yaml("yaml/errors/stability/experimental_attr_stable_member.yaml") + self.fail() + e = ex.exception + msg = e.message.lower() + self.assertIn( + "member 'one' is marked as stable but it is not allowed on experimental attribute!", + msg, + ) + self.assertEqual(e.line, 9) + def test_invalid_deprecated_empty_string(self): with self.assertRaises(ValidationError) as ex: self.open_yaml("yaml/errors/deprecated/deprecation_empty_string.yaml") diff --git a/semantic-conventions/src/tests/semconv/templating/test_compatibility.py b/semantic-conventions/src/tests/semconv/templating/test_compatibility.py index 2497fdd5..70db2e3e 100644 --- a/semantic-conventions/src/tests/semconv/templating/test_compatibility.py +++ b/semantic-conventions/src/tests/semconv/templating/test_compatibility.py @@ -146,6 +146,11 @@ def testEnumTypeChanged(self): "first.third_attr.enum_one", "value changed from 'one' to '1'", ), + Problem( + "attribute", + "first.forth_attr", + "enum type changed from 'string' to 'int'", + ), ] self.assert_errors(expected_errors, problems) diff --git a/semantic-conventions/syntax.md b/semantic-conventions/syntax.md index 3b1ba202..84a7544a 100644 --- a/semantic-conventions/syntax.md +++ b/semantic-conventions/syntax.md @@ -93,7 +93,7 @@ allow_custom_values := boolean members ::= member {member} -member ::= id value [brief] [note] +member ::= id value [brief] [note] [stability] [deprecated] requirement_level ::= "required" | "conditionally_required" @@ -376,6 +376,8 @@ An enum entry has the following fields: - `value`, string, int, or boolean; value of the enum entry. - `brief`, optional string, brief description of the enum entry value. It defaults to the value of `id`. - `note`, optional string, longer description. It defaults to an empty string. +- `stability`, required stability level. Attributes marked as experimental cannot have stable members. +- `deprecated`, optional string, similarly to semantic convention and attribute deprecation, marks specific member as deprecated. ### Constraints From 44712950437c8d1c831693c63a65f12b4f3834d7 Mon Sep 17 00:00:00 2001 From: "James Hughes (Splunk)" Date: Thu, 7 Mar 2024 05:31:15 -0800 Subject: [PATCH 19/31] smoke test the docker image (#286) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/workflows/semconvgen.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/semconvgen.yml b/.github/workflows/semconvgen.yml index f0aba77e..fcc3834d 100644 --- a/.github/workflows/semconvgen.yml +++ b/.github/workflows/semconvgen.yml @@ -39,7 +39,8 @@ jobs: run: pylint *.py src/ - name: Type checking (mypy) run: mypy src/ - + - name: Build the Docker image + run: pip wheel --no-deps . && docker build . -t semconvgen && docker run --rm semconvgen --help build-and-publish-docker: runs-on: ubuntu-latest From e154e07b2c1cfd3ef1c8e760f3df32399fa73cc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 21:04:21 -0700 Subject: [PATCH 20/31] Bump pytest from 8.0.2 to 8.1.1 in /semantic-conventions (#296) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index cfae1c8e..c81a89e9 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,6 +1,6 @@ black==22.3.0 mypy==0.910 -pytest==8.0.2 +pytest==8.1.1 flake8==7.0.0 pylint==3.1.0 isort==5.13.2 \ No newline at end of file From b6d52b9d58d35477ef5ee6c10081395bf7e34824 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 21:21:15 -0700 Subject: [PATCH 21/31] Bump black from 22.3.0 to 24.2.0 in /semantic-conventions (#264) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 2 +- semantic-conventions/setup.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index c81a89e9..efc47b8a 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,4 +1,4 @@ -black==22.3.0 +black==24.2.0 mypy==0.910 pytest==8.1.1 flake8==7.0.0 diff --git a/semantic-conventions/setup.py b/semantic-conventions/setup.py index b560307d..b7a54549 100644 --- a/semantic-conventions/setup.py +++ b/semantic-conventions/setup.py @@ -15,7 +15,7 @@ PUBLIC_VERSION = PACKAGE_INFO["__version__"] setuptools.setup( - version=PUBLIC_VERSION - if not VERSION_SUFFIX - else PUBLIC_VERSION + "+" + VERSION_SUFFIX + version=( + PUBLIC_VERSION if not VERSION_SUFFIX else PUBLIC_VERSION + "+" + VERSION_SUFFIX + ) ) From 0f96bd3cb5d1d3edb0dd5d296f5415f7495688c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 21:32:32 -0700 Subject: [PATCH 22/31] Bump mypy from 0.910 to 1.8.0 in /semantic-conventions (#250) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- semantic-conventions/dev-requirements.txt | 4 ++-- .../src/opentelemetry/semconv/model/constraints.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index efc47b8a..bb5fe10c 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,6 +1,6 @@ black==24.2.0 -mypy==0.910 +mypy==1.8.0 pytest==8.1.1 flake8==7.0.0 pylint==3.1.0 -isort==5.13.2 \ No newline at end of file +isort==5.13.2 diff --git a/semantic-conventions/src/opentelemetry/semconv/model/constraints.py b/semantic-conventions/src/opentelemetry/semconv/model/constraints.py index 2e44119c..9acf8c32 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/constraints.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/constraints.py @@ -13,7 +13,7 @@ # limitations under the License. from dataclasses import dataclass, replace -from typing import List, Tuple +from typing import Tuple from ruamel.yaml.comments import CommentedSeq @@ -52,7 +52,7 @@ def __eq__(self, other): def __hash__(self): return hash(self.choice_list_ids) - def add_attributes(self, attr: List[SemanticAttribute]): + def add_attributes(self, attr: Tuple[SemanticAttribute]): self.choice_list_attributes += (attr,) def inherit_anyof(self): From 631c556a48bff5b9b6a135362beb894e02e9e8c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:55:42 +0100 Subject: [PATCH 23/31] Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 in /schemas (#282) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- schemas/go.mod | 2 +- schemas/go.sum | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/schemas/go.mod b/schemas/go.mod index 62661150..66db1573 100644 --- a/schemas/go.mod +++ b/schemas/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/Masterminds/semver/v3 v3.2.1 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 go.opentelemetry.io/otel/schema v0.0.7 ) diff --git a/schemas/go.sum b/schemas/go.sum index 3c8b670a..aebb5cff 100644 --- a/schemas/go.sum +++ b/schemas/go.sum @@ -8,10 +8,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/otel/schema v0.0.7 h1:UslTvUtbFGmaxlpL1Z+aROrjsP7BRWt06Xxm5Ng/kAU= go.opentelemetry.io/otel/schema v0.0.7/go.mod h1:jFb7hFFzdtEQ8R8HdbDGy4KuBctXNZwH1XJBP470kH4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From 1b179519236d569ec1c6e5e6c6e362c72d1ecc67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:57:58 +0100 Subject: [PATCH 24/31] Bump python from 3.10-alpine to 3.12-alpine in /semantic-conventions (#297) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- semantic-conventions/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/Dockerfile b/semantic-conventions/Dockerfile index 5be02c8e..a20a98e0 100644 --- a/semantic-conventions/Dockerfile +++ b/semantic-conventions/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10-alpine +FROM python:3.12-alpine LABEL maintainer="The OpenTelemetry Authors" ADD *.whl /semconvgen/ WORKDIR /semconvgen From 3ff0eeb828d0e3bcb63b6cf4c548bc98951f0f4d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 13 Mar 2024 11:55:45 -0700 Subject: [PATCH 25/31] Add stability as a separate column in Markdown tables (#278) --- semantic-conventions/CHANGELOG.md | 2 + semantic-conventions/README.md | 3 + .../src/opentelemetry/semconv/main.py | 30 +-- .../semconv/templating/markdown/__init__.py | 76 +++--- .../semconv/templating/markdown/options.py | 28 +- .../data/markdown/attribute_group/expected.md | 8 +- .../markdown/attribute_templates/expected.md | 12 +- .../data/markdown/deprecated/expected.md | 36 +-- .../tests/data/markdown/deprecated/http.yaml | 2 +- .../tests/data/markdown/deprecated/input.md | 14 +- .../src/tests/data/markdown/empty/expected.md | 253 +----------------- .../src/tests/data/markdown/empty/input.md | 253 +----------------- .../tests/data/markdown/enum_int/expected.md | 44 +-- .../src/tests/data/markdown/event/expected.md | 12 +- .../data/markdown/event_noprefix/expected.md | 6 +- .../data/markdown/event_renamed/expected.md | 6 +- .../data/markdown/example_array/expected.md | 6 +- .../markdown/extend_constraint/expected.md | 150 +++++------ .../data/markdown/extend_constraint/input.md | 146 +++++----- .../markdown/extend_grandparent/expected.md | 22 +- .../tests/data/markdown/include/expected.md | 44 +-- .../data/markdown/metrics_tables/expected.md | 28 +- .../data/markdown/missing_end_tag/input.md | 19 +- .../tests/data/markdown/multiple/expected.md | 40 +-- .../src/tests/data/markdown/multiple/input.md | 6 +- .../data/markdown/multiple_enum/expected.md | 68 ++--- .../omit_requirement_level/expected.md | 10 +- .../data/markdown/parameter_empty/http.md | 10 +- .../data/markdown/parameter_full/expected.md | 44 +-- .../data/markdown/parameter_full/http.md | 10 +- .../parameter_remove_constraint/expected.md | 34 +-- .../parameter_remove_constraint/input.md | 36 +-- .../data/markdown/parameter_tag/expected.md | 34 +-- .../markdown/parameter_tag_empty/expected.md | 86 +++--- .../src/tests/data/markdown/ref/expected.md | 14 +- .../data/markdown/ref_extends/expected.md | 18 +- .../markdown/sampling_relevant/expected.md | 24 +- .../src/tests/data/markdown/scope/expected.md | 6 +- .../tests/data/markdown/single/expected.md | 20 +- .../src/tests/data/markdown/single/input.md | 6 +- .../tests/data/markdown/sorting/expected.md | 16 +- .../data/markdown/spec_version/expected.md | 2 +- .../markdown/stability/all_badges_expected.md | 84 +++--- .../stability/stable_badges_expected.md | 84 +++--- .../data/markdown/wrong_semconv_id/input.md | 6 +- .../tests/semconv/templating/test_markdown.py | 18 +- 46 files changed, 670 insertions(+), 1206 deletions(-) diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index 786f0f40..b919527b 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -8,6 +8,8 @@ Please update the changelog as part of any significant pull request. ([#267](https://github.com/open-telemetry/build-tools/pull/267)) - Change minimum support python version to 3.10 in setup.cfg and Dockerfile ([#285](https://github.com/open-telemetry/build-tools/pull/285)) +- BREAKING: Add dedicated column for stability to Markdown tables. + ([#278](https://github.com/open-telemetry/build-tools/pull/278)) - BREAKING: Make stability required (also: fix ref and extends, render badges on metrics). ([#272](https://github.com/open-telemetry/build-tools/pull/272)) - BREAKING: Make stability and deprecation independent properties. diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index e52a12a2..cad1bf5a 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -67,6 +67,9 @@ After `{semantic_convention_id}`, optional parameters enclosed in parentheses ca - `ref`: prints attributes that are referenced from another semantic convention; - `remove_constraint`: does not print additional constraints of the semantic convention. +By default markdown tables are rendered with stability badges (like ![Stable](https://img.shields.io/badge/-stable-lightgreen) or ![Experimental](https://img.shields.io/badge/-experimental-blue)) which can be disabled with `--md-disable-stable-badge`, `--md-disable-experimental-badge`, `--md-disable-deprecated-badge`. +When badges are disabled, the stability column contains plain text representation of stability or deprecation status. + ### Examples These examples assume that a semantic convention with the id `http.server` extends another semantic convention with the id `http`. diff --git a/semantic-conventions/src/opentelemetry/semconv/main.py b/semantic-conventions/src/opentelemetry/semconv/main.py index 461d0c28..c3f9b708 100644 --- a/semantic-conventions/src/opentelemetry/semconv/main.py +++ b/semantic-conventions/src/opentelemetry/semconv/main.py @@ -91,10 +91,9 @@ def main(): def process_markdown(semconv, args): options = MarkdownOptions( check_only=args.md_check, - enable_stable=args.md_stable, - enable_experimental=args.md_experimental, - enable_deprecated=args.md_enable_deprecated, - use_badge=args.md_use_badges, + disable_stable_badge=args.md_disable_stable, + disable_experimental_badge=args.md_disable_experimental, + disable_deprecated_badge=args.md_disable_deprecated, break_count=args.md_break_conditional, exclude_files=exclude_file_list(args.markdown_root, args.exclude), ) @@ -221,31 +220,26 @@ def add_md_parser(subparsers): required=False, ) parser.add_argument( - "--md-use-badges", - help="Use stability badges instead of labels for attributes.", + "--md-disable-stable-badge", + help="Removes badges from attributes marked as stable.", required=False, + default=False, action="store_true", ) parser.add_argument( - "--md-stable", - help="Add labels to attributes marked as stable.", + "--md-disable-experimental-badge", + help="Removes badges from attributes marked as experimental.", required=False, + default=False, action="store_true", ) parser.add_argument( - "--md-experimental", - help="Add labels to attributes marked as experimental.", + "--md-disable-deprecated-badge", + help="Removes badges from attributes marked as deprecated.", required=False, + default=False, action="store_true", ) - parser.add_argument( - "--md-disable-deprecated", - help="Removes deprecated notes of deprecated attributes.", - required=False, - default=True, - dest="md_enable_deprecated", - action="store_false", - ) def add_compat_check_parser(subparsers): diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py index 4accf983..360aa29d 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py @@ -41,8 +41,9 @@ from .utils import VisualDiffer +_OPENTELEMETRY_IO_SPEC_URL = "https://opentelemetry.io/docs/specs/" _REQUIREMENT_LEVEL_URL = ( - "https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/" + _OPENTELEMETRY_IO_SPEC_URL + "semconv/general/attribute-requirement-level/" ) @@ -105,11 +106,12 @@ def __init__( req_level = f"[Requirement Level]({_REQUIREMENT_LEVEL_URL})" self.table_headers = ( - f"| Attribute | Type | Description | Examples | {req_level} |" - "\n|---|---|---|---|---|\n" + f"| Attribute | Type | Description | Examples | {req_level} | Stability |" + "\n|---|---|---|---|---|---|\n" ) self.table_headers_omitting_req_level = ( - "| Attribute | Type | Description | Examples |\n|---|---|---|---|\n" + "| Attribute | Type | Description | Examples | Stability |" + "\n|---|---|---|---|---|\n" ) def to_markdown_attr( @@ -126,10 +128,7 @@ def to_markdown_attr( if isinstance(attribute.attr_type, EnumAttributeType) else AttributeType.get_instantiated_type(attribute.attr_type) ) - description = ( - self._description_with_badge(attribute.stability, attribute.deprecated) - + attribute.brief - ) + description = attribute.brief if attribute.note: self.render_ctx.add_note(attribute.note) description += f" [{len(self.render_ctx.notes)}]" @@ -156,12 +155,15 @@ def to_markdown_attr( else: examples = "; ".join(f"`{ex}`" for ex in example_list) + stability = self._render_stability(attribute) if self.render_ctx.is_omit_requirement_level: - output.write(f"| {name} | {attr_type} | {description} | {examples} |\n") + output.write( + f"| {name} | {attr_type} | {description} | {examples} | {stability} |\n" + ) else: required = self.derive_requirement_level(attribute) output.write( - f"| {name} | {attr_type} | {description} | {examples} | {required} |\n" + f"| {name} | {attr_type} | {description} | {examples} | {required} | {stability} |\n" ) def derive_requirement_level(self, attribute: SemanticAttribute): @@ -175,7 +177,7 @@ def derive_requirement_level(self, attribute: SemanticAttribute): self.render_ctx.add_note(attribute.requirement_level_msg) required = f"`Conditionally Required` [{len(self.render_ctx.notes)}]" elif attribute.requirement_level == RequirementLevel.OPT_IN: - required = "Opt-In" + required = "`Opt-In`" else: # attribute.requirement_level == Required.RECOMMENDED or None # check if there are any notes if ( @@ -240,21 +242,20 @@ def to_markdown_metric_table( instrument = MetricSemanticConvention.canonical_instrument_name_by_yaml_name[ semconv.instrument ] + output.write( - "| Name | Instrument Type | Unit (UCUM) | Description |\n" - "| -------- | --------------- | ----------- | -------------- |\n" + "| Name | Instrument Type | Unit (UCUM) | Description | Stability |\n" + "| -------- | --------------- | ----------- | -------------- | --------- |\n" ) - description = ( - self._description_with_badge(semconv.stability, semconv.deprecated) - + semconv.brief - ) + description = semconv.brief if semconv.note: self.render_ctx.add_note(semconv.note) description += f" [{len(self.render_ctx.notes)}]" + stability = self._render_stability(semconv) output.write( - f"| `{semconv.metric_name}` | {instrument} | `{semconv.unit}` | {description} |\n" + f"| `{semconv.metric_name}` | {instrument} | `{semconv.unit}` | {description} | {stability} |\n" ) self.to_markdown_notes(output) @@ -328,20 +329,18 @@ def to_markdown_enum(self, output: io.StringIO): else: output.write("MUST be one of the following:") output.write("\n\n") - output.write("| Value | Description |\n|---|---|") + output.write("| Value | Description | Stability |\n|---|---|---|") member: EnumMember counter = 1 notes = [] for member in enum.members: - description = ( - self._description_with_badge(member.stability, member.deprecated) - + member.brief - ) + description = member.brief if member.note: description += f" [{counter}]" counter += 1 notes.append(member.note) - output.write(f"\n| `{member.value}` | {description} |") + stability = self._render_stability(member) + output.write(f"\n| `{member.value}` | {description} | {stability} |") counter = 1 if not notes: output.write("\n") @@ -537,20 +536,15 @@ def _render_group(self, semconv, parameters, output): output.write("") - def _description_with_badge(self, stability: StabilityLevel, deprecated: str): - description = "" - if deprecated and self.options.enable_deprecated: - if "deprecated" in deprecated.lower(): - description = f"**{deprecated}**
" - else: - deprecated_msg = self.options.deprecated_md_snippet().format(deprecated) - description = f"{deprecated_msg}
" - elif stability == StabilityLevel.STABLE and self.options.enable_stable: - description = f"{self.options.stable_md_snippet()}
" - elif ( - stability == StabilityLevel.EXPERIMENTAL - and self.options.enable_experimental - ): - description = f"{self.options.experimental_md_snippet()}
" - - return description + def _render_stability( + self, + item: typing.Union[SemanticAttribute | BaseSemanticConvention | EnumMember], + ): + if item.deprecated: + return self.options.deprecated_md_snippet(item.deprecated) + if item.stability == StabilityLevel.STABLE: + return self.options.stable_md_snippet() + if item.stability == StabilityLevel.EXPERIMENTAL: + return self.options.experimental_md_snippet() + + raise ValueError(f"Unknown stability level {item.stability}") diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/options.py b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/options.py index 419ef8f1..af0cfce5 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/markdown/options.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/markdown/options.py @@ -19,24 +19,24 @@ @dataclass() class MarkdownOptions: check_only: bool = False - enable_stable: bool = False - enable_experimental: bool = False - enable_deprecated: bool = True - use_badge: bool = False + disable_stable_badge: bool = False + disable_experimental_badge: bool = False + disable_deprecated_badge: bool = False break_count: int = 50 exclude_files: List[str] = field(default_factory=list) def stable_md_snippet(self): - if self.use_badge: - return "![Stable](https://img.shields.io/badge/-stable-lightgreen)" - return "**Stable**" + if self.disable_stable_badge: + return "Stable" + return "![Stable](https://img.shields.io/badge/-stable-lightgreen)" def experimental_md_snippet(self): - if self.use_badge: - return "![Experimental](https://img.shields.io/badge/-experimental-blue)" - return "**Experimental**" + if self.disable_experimental_badge: + return "Experimental" + return "![Experimental](https://img.shields.io/badge/-experimental-blue)" - def deprecated_md_snippet(self): - if self.use_badge: - return "![Deprecated](https://img.shields.io/badge/-deprecated-red)" - return "**Deprecated: {}**" + def deprecated_md_snippet(self, deprecated_note: str): + if self.disable_deprecated_badge: + return f"Deprecated: {deprecated_note}" + + return f"![Deprecated](https://img.shields.io/badge/-deprecated-red)
{deprecated_note}" diff --git a/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md b/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md index 51fe266d..09b038e6 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md +++ b/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md @@ -1,8 +1,8 @@ # Attribute Group Example -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | -| `foo.qux` | int | Attribute 2 | `42` | `Conditionally Required` if available | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | Experimental | +| `foo.qux` | int | Attribute 2 | `42` | `Conditionally Required` if available | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md b/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md index 9a8be2b5..41599ce8 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md +++ b/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md @@ -1,10 +1,10 @@ # Custom HTTP Semantic Conventions -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `custom_http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | -| `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `general.some_general_attribute.` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | `Recommended` | -| `referenced_http.request.referenced.header.` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `custom_http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | Experimental | +| `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `general.some_general_attribute.` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | `Recommended` | Experimental | +| `referenced_http.request.referenced.header.` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/expected.md b/semantic-conventions/src/tests/data/markdown/deprecated/expected.md index 964e9d05..aac840f0 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/expected.md +++ b/semantic-conventions/src/tests/data/markdown/deprecated/expected.md @@ -2,29 +2,29 @@ -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.flavor` | string | **Deprecated. Use attribute `flavor_new` instead.**
Kind of HTTP protocol used [1] | `1.0` | `Recommended` | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | -| `http.status_text` | string | **Deprecated: Use attribute `status_description` instead.**
[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.flavor` | string | Kind of HTTP protocol used [1] | `1.0` | `Recommended` | Deprecated: Use attribute `flavor_new` instead. | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Deprecated: Use attribute `status_description` instead. | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | **[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. `http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `1.0` | HTTP 1.0 | -| `1.1` | HTTP 1.1 | -| `2.0` | HTTP 2 | -| `SPDY` | SPDY protocol. | -| `QUIC` | QUIC protocol. | +| Value | Description | Stability | +|---|---|---| +| `1.0` | HTTP 1.0 | Experimental | +| `1.1` | HTTP 1.1 | Experimental | +| `2.0` | HTTP 2 | Experimental | +| `SPDY` | SPDY protocol. | Experimental | +| `QUIC` | QUIC protocol. | Experimental | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml b/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml index e0061b1d..22cce227 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml +++ b/semantic-conventions/src/tests/data/markdown/deprecated/http.yaml @@ -79,7 +79,7 @@ groups: brief: 'QUIC protocol.' stability: experimental brief: 'Kind of HTTP protocol used' - deprecated: Deprecated. Use attribute `flavor_new` instead. + deprecated: Use attribute `flavor_new` instead. note: > If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/input.md b/semantic-conventions/src/tests/data/markdown/deprecated/input.md index 4e6e41b1..af396848 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/input.md +++ b/semantic-conventions/src/tests/data/markdown/deprecated/input.md @@ -2,19 +2,7 @@ - -| Attribute name | Notes and examples | `Required`? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | -| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | -| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | -| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | -| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | -| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | - +this will be removed It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/empty/expected.md b/semantic-conventions/src/tests/data/markdown/empty/expected.md index 0b063ae1..fa8888c3 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/expected.md +++ b/semantic-conventions/src/tests/data/markdown/empty/expected.md @@ -1,252 +1 @@ -# Semantic conventions for HTTP spans - -This document defines semantic conventions for HTTP client and server Spans. -They can be used for http and https schemes -and various HTTP versions like 1.1, 2 and SPDY. - - - - - -- [Name](#name) -- [Status](#status) -- [Common Attributes](#common-attributes) -- [HTTP client](#http-client) -- [HTTP server](#http-server) - * [HTTP server definitions](#http-server-definitions) - * [HTTP Server semantic conventions](#http-server-semantic-conventions) -- [HTTP client-server example](#http-client-server-example) - - - -## Name - -HTTP spans MUST follow the overall [guidelines for span names](../api.md#span). -Many REST APIs encode parameters into URI path, e.g. `/api/users/123` where `123` -is a user id, which creates high cardinality value space not suitable for span -names. In case of HTTP servers, these endpoints are often mapped by the server -frameworks to more concise _HTTP routes_, e.g. `/api/users/{user_id}`, which are -recommended as the low cardinality span names. However, the same approach usually -does not work for HTTP client spans, especially when instrumentation is provided -by a lower-level middleware that is not aware of the specifics of how the URIs -are formed. Therefore, HTTP client spans SHOULD be using conservative, low -cardinality names formed from the available parameters of an HTTP request, -such as `"HTTP {METHOD_NAME}"`. Instrumentation MUST NOT default to using URI -path as span name, but MAY provide hooks to allow custom logic to override the -default span name. - -## Status - -Implementations MUST set the [span status](../api.md#status) if the HTTP communication failed -or an HTTP error status code is returned (e.g. above 3xx). - -In the case of an HTTP redirect, the request should normally be considered successful, -unless the client aborts following redirects due to hitting some limit (redirect loop). -If following a (chain of) redirect(s) successfully, the status should be set according to the result of the final HTTP request. - -Don't set the span status description if the reason can be inferred from `http.status_code` and `http.status_text`. - -| HTTP code | Span status code | -|-------------------------|-----------------------| -| 100...299 | `Ok` | -| 3xx redirect codes | `DeadlineExceeded` in case of loop (see above) [1], otherwise `Ok` | -| 401 Unauthorized ⚠ | `Unauthenticated` ⚠ (Unauthorized actually means unauthenticated according to [RFC 7235][rfc-unauthorized]) | -| 403 Forbidden | `PermissionDenied` | -| 404 Not Found | `NotFound` | -| 429 Too Many Requests | `ResourceExhausted` | -| Other 4xx code | `InvalidArgument` [1] | -| 501 Not Implemented | `Unimplemented` | -| 503 Service Unavailable | `Unavailable` | -| 504 Gateway Timeout | `DeadlineExceeded` | -| Other 5xx code | `Internal` [1] | -| Any status code the client fails to interpret (e.g., 093 or 573) | `Unknown` | - -Note that the items marked with [1] are different from the mapping defined in the [OpenCensus semantic conventions][oc-http-status]. - -[oc-http-status]: https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/HTTP.md#mapping-from-http-status-codes-to-trace-status-codes -[rfc-unauthorized]: https://tools.ietf.org/html/rfc7235#section-3.1 - -## Common Attributes - - - -| Attribute name | Notes and examples | `Required`? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | -| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | -| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | -| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | -| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | -| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | - -It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. - -[network attributes]: span-general.md#general-network-connection-attributes -[HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 -[HTTP reason phrase]: https://tools.ietf.org/html/rfc7230#section-3.1.2 -[User-Agent]: https://tools.ietf.org/html/rfc7231#section-5.5.3 - -## HTTP client - -This span type represents an outbound HTTP request. - -For an HTTP client span, `SpanKind` MUST be `Client`. - -If set, `http.url` must be the originally requested URL, -before any HTTP-redirects that may happen when executing the request. - -One of the following sets of attributes is required (in order of usual preference unless for a particular web client/framework it is known that some other set is preferable for some reason; all strings must be non-empty): - -* `http.url` -* `http.scheme`, `http.host`, `http.target` -* `http.scheme`, `net.peer.name`, `net.peer.port`, `http.target` -* `http.scheme`, `net.peer.ip`, `net.peer.port`, `http.target` - -Note that in some cases `http.host` might be different -from the `net.peer.name` -used to look up the `net.peer.ip` that is actually connected to. -In that case it is strongly recommended to set the `net.peer.name` attribute in addition to `http.host`. - -For status, the following special cases have canonical error codes assigned: - -| Client error | Trace status code | -|-----------------------------|--------------------| -| DNS resolution failed | `Unknown` | -| Request cancelled by caller | `Cancelled` | -| URL cannot be parsed | `InvalidArgument` | -| Request timed out | `DeadlineExceeded` | - -This is not meant to be an exhaustive list -but if there is no clear mapping for some error conditions, -instrumentation developers are encouraged to use `Unknown` -and open a PR or issue in the specification repository. - -## HTTP server - -To understand the attributes defined in this section, it is helpful to read the "Definitions" subsection. - -### HTTP server definitions - -This section gives a short summary of some concepts -in web server configuration and web app deployment -that are relevant to tracing. - -Usually, on a physical host, reachable by one or multiple IP addresses, a single HTTP listener process runs. -If multiple processes are running, they must listen on distinct TCP/UDP ports so that the OS can route incoming TCP/UDP packets to the right one. - -Within a single server process, there can be multiple **virtual hosts**. -The [HTTP host header][] (in combination with a port number) is normally used to determine to which of them to route incoming HTTP requests. - -The host header value that matches some virtual host is called the virtual hosts's **server name**. If there are multiple aliases for the virtual host, one of them (often the first one listed in the configuration) is called the **primary server name**. See for example, the Apache [`ServerName`][ap-sn] or NGINX [`server_name`][nx-sn] directive or the CGI specification on `SERVER_NAME` ([RFC 3875][rfc-servername]). -In practice the HTTP host header is often ignored when just a single virtual host is configured for the IP. - -Within a single virtual host, some servers support the concepts of an **HTTP application** -(for example in Java, the Servlet JSR defines an application as -"a collection of servlets, HTML pages, classes, and other resources that make up a complete application on a Web server" --- SRV.9 in [JSR 53][]; -in a deployment of a Python application to Apache, the application would be the [PEP 3333][] conformant callable that is configured using the -[`WSGIScriptAlias` directive][modwsgisetup] of `mod_wsgi`). - -An application can be "mounted" under some **application root** -(also know as *[context root][]* *[context prefix][]*, or *[document base][]*) -which is a fixed path prefix of the URL that determines to which application a request is routed -(e.g., the server could be configured to route all requests that go to an URL path starting with `/webshop/` -at a particular virtual host -to the `com.example.webshop` web application). - -Some servers allow to bind the same HTTP application to multiple `(virtual host, application root)` pairs. - -> TODO: Find way to trace HTTP application and application root ([opentelemetry/opentelementry-specification#335][]) - -[PEP 3333]: https://www.python.org/dev/peps/pep-3333/ -[modwsgisetup]: https://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html -[context root]: https://docs.jboss.org/jbossas/guides/webguide/r2/en/html/ch06.html -[context prefix]: https://marc.info/?l=apache-cvs&m=130928191414740 -[document base]: http://tomcat.apache.org/tomcat-5.5-doc/config/context.html -[rfc-servername]: https://tools.ietf.org/html/rfc3875#section-4.1.14 -[ap-sn]: https://httpd.apache.org/docs/2.4/mod/core.html#servername -[nx-sn]: http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name -[JSR 53]: https://jcp.org/aboutJava/communityprocess/maintenance/jsr053/index2.html -[opentelemetry/opentelementry-specification#335]: https://github.com/open-telemetry/opentelemetry-specification/issues/335 - -### HTTP Server semantic conventions - -This span type represents an inbound HTTP request. - -For an HTTP server span, `SpanKind` MUST be `Server`. - -Given an inbound request for a route (e.g. `"/users/:userID?"`) the `name` attribute of the span SHOULD be set to this route. -If the route does not include the application root, it SHOULD be prepended to the span name. - -If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. - -| Attribute name | Notes and examples | `Required`? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.server_name` | The primary server name of the matched virtual host. This should be obtained via configuration. If no such configuration can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). | [1] | -| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | `Recommended` | -| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | `Recommended` | - -[HTTP request line]: https://tools.ietf.org/html/rfc7230#section-3.1.1 -[HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4 -[X-Forwarded-For]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For - -**[1]**: `http.url` is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. ). -It is thus preferred to supply the raw data that *is* available. -Namely, one of the following sets is required (in order of usual preference unless for a particular web server/framework it is known that some other set is preferable for some reason; all strings must be non-empty): - -* `http.scheme`, `http.host`, `http.target` -* `http.scheme`, `http.server_name`, `net.host.port`, `http.target` -* `http.scheme`, `net.host.name`, `net.host.port`, `http.target` -* `http.url` - -Of course, more than the required attributes can be supplied, but this is recommended only if they cannot be inferred from the sent ones. -For example, `http.server_name` has shown great value in practice, as bogus HTTP Host headers occur often in the wild. - -It is strongly recommended to set `http.server_name` to allow associating requests with some logical server entity. - -## HTTP client-server example - -As an example, if a browser request for `https://example.com:8080/webshop/articles/4?s=1` is invoked from a host with IP 192.0.2.4, we may have the following Span on the client side: - -Span name: `/webshop/articles/4` (NOTE: This is subject to change, see [open-telemetry/opentelemetry-specification#270][].) - -[open-telemetry/opentelemetry-specification#270]: https://github.com/open-telemetry/opentelemetry-specification/issues/270 - -| Attribute name | Value | -| :----------------- | :-------------------------------------------------------| -| `http.method` | `"GET"` | -| `http.flavor` | `"1.1"` | -| `http.url` | `"https://example.com:8080/webshop/articles/4?s=1"` | -| `net.peer.ip` | `"192.0.2.5"` | -| `http.status_code` | `200` | -| `http.status_text` | `"OK"` | - -The corresponding server Span may look like this: - -Span name: `/webshop/articles/:article_id`. - -| Attribute name | Value | -| :----------------- | :---------------------------------------------- | -| `http.method` | `"GET"` | -| `http.flavor` | `"1.1"` | -| `http.target` | `"/webshop/articles/4?s=1"` | -| `http.host` | `"example.com:8080"` | -| `http.server_name` | `"example.com"` | -| `host.port` | `8080` | -| `http.scheme` | `"https"` | -| `http.route` | `"/webshop/articles/:article_id"` | -| `http.status_code` | `200` | -| `http.status_text` | `"OK"` | -| `http.client_ip` | `"192.0.2.4"` | -| `net.peer.ip` | `"192.0.2.5"` (the client goes through a proxy) | -| `http.user_agent` | `"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"` | - -Note that following the recommendations above, `http.url` is not set in the above example. -If set, it would be -`"https://example.com:8080/webshop/articles/4?s=1"` -but due to `http.scheme`, `http.host` and `http.target` being set, it would be redundant. -As explained above, these separate values are preferred but if for some reason the URL is available but the other values are not, -URL can replace `http.scheme`, `http.host` and `http.target`. +This is an arbitrary markdown file that does not have any semantic conventions anchors. diff --git a/semantic-conventions/src/tests/data/markdown/empty/input.md b/semantic-conventions/src/tests/data/markdown/empty/input.md index 0b063ae1..fa8888c3 100644 --- a/semantic-conventions/src/tests/data/markdown/empty/input.md +++ b/semantic-conventions/src/tests/data/markdown/empty/input.md @@ -1,252 +1 @@ -# Semantic conventions for HTTP spans - -This document defines semantic conventions for HTTP client and server Spans. -They can be used for http and https schemes -and various HTTP versions like 1.1, 2 and SPDY. - - - - - -- [Name](#name) -- [Status](#status) -- [Common Attributes](#common-attributes) -- [HTTP client](#http-client) -- [HTTP server](#http-server) - * [HTTP server definitions](#http-server-definitions) - * [HTTP Server semantic conventions](#http-server-semantic-conventions) -- [HTTP client-server example](#http-client-server-example) - - - -## Name - -HTTP spans MUST follow the overall [guidelines for span names](../api.md#span). -Many REST APIs encode parameters into URI path, e.g. `/api/users/123` where `123` -is a user id, which creates high cardinality value space not suitable for span -names. In case of HTTP servers, these endpoints are often mapped by the server -frameworks to more concise _HTTP routes_, e.g. `/api/users/{user_id}`, which are -recommended as the low cardinality span names. However, the same approach usually -does not work for HTTP client spans, especially when instrumentation is provided -by a lower-level middleware that is not aware of the specifics of how the URIs -are formed. Therefore, HTTP client spans SHOULD be using conservative, low -cardinality names formed from the available parameters of an HTTP request, -such as `"HTTP {METHOD_NAME}"`. Instrumentation MUST NOT default to using URI -path as span name, but MAY provide hooks to allow custom logic to override the -default span name. - -## Status - -Implementations MUST set the [span status](../api.md#status) if the HTTP communication failed -or an HTTP error status code is returned (e.g. above 3xx). - -In the case of an HTTP redirect, the request should normally be considered successful, -unless the client aborts following redirects due to hitting some limit (redirect loop). -If following a (chain of) redirect(s) successfully, the status should be set according to the result of the final HTTP request. - -Don't set the span status description if the reason can be inferred from `http.status_code` and `http.status_text`. - -| HTTP code | Span status code | -|-------------------------|-----------------------| -| 100...299 | `Ok` | -| 3xx redirect codes | `DeadlineExceeded` in case of loop (see above) [1], otherwise `Ok` | -| 401 Unauthorized ⚠ | `Unauthenticated` ⚠ (Unauthorized actually means unauthenticated according to [RFC 7235][rfc-unauthorized]) | -| 403 Forbidden | `PermissionDenied` | -| 404 Not Found | `NotFound` | -| 429 Too Many Requests | `ResourceExhausted` | -| Other 4xx code | `InvalidArgument` [1] | -| 501 Not Implemented | `Unimplemented` | -| 503 Service Unavailable | `Unavailable` | -| 504 Gateway Timeout | `DeadlineExceeded` | -| Other 5xx code | `Internal` [1] | -| Any status code the client fails to interpret (e.g., 093 or 573) | `Unknown` | - -Note that the items marked with [1] are different from the mapping defined in the [OpenCensus semantic conventions][oc-http-status]. - -[oc-http-status]: https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/HTTP.md#mapping-from-http-status-codes-to-trace-status-codes -[rfc-unauthorized]: https://tools.ietf.org/html/rfc7235#section-3.1 - -## Common Attributes - - - -| Attribute name | Notes and examples | `Required`? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | -| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | -| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | -| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | -| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | -| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | - -It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. - -[network attributes]: span-general.md#general-network-connection-attributes -[HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 -[HTTP reason phrase]: https://tools.ietf.org/html/rfc7230#section-3.1.2 -[User-Agent]: https://tools.ietf.org/html/rfc7231#section-5.5.3 - -## HTTP client - -This span type represents an outbound HTTP request. - -For an HTTP client span, `SpanKind` MUST be `Client`. - -If set, `http.url` must be the originally requested URL, -before any HTTP-redirects that may happen when executing the request. - -One of the following sets of attributes is required (in order of usual preference unless for a particular web client/framework it is known that some other set is preferable for some reason; all strings must be non-empty): - -* `http.url` -* `http.scheme`, `http.host`, `http.target` -* `http.scheme`, `net.peer.name`, `net.peer.port`, `http.target` -* `http.scheme`, `net.peer.ip`, `net.peer.port`, `http.target` - -Note that in some cases `http.host` might be different -from the `net.peer.name` -used to look up the `net.peer.ip` that is actually connected to. -In that case it is strongly recommended to set the `net.peer.name` attribute in addition to `http.host`. - -For status, the following special cases have canonical error codes assigned: - -| Client error | Trace status code | -|-----------------------------|--------------------| -| DNS resolution failed | `Unknown` | -| Request cancelled by caller | `Cancelled` | -| URL cannot be parsed | `InvalidArgument` | -| Request timed out | `DeadlineExceeded` | - -This is not meant to be an exhaustive list -but if there is no clear mapping for some error conditions, -instrumentation developers are encouraged to use `Unknown` -and open a PR or issue in the specification repository. - -## HTTP server - -To understand the attributes defined in this section, it is helpful to read the "Definitions" subsection. - -### HTTP server definitions - -This section gives a short summary of some concepts -in web server configuration and web app deployment -that are relevant to tracing. - -Usually, on a physical host, reachable by one or multiple IP addresses, a single HTTP listener process runs. -If multiple processes are running, they must listen on distinct TCP/UDP ports so that the OS can route incoming TCP/UDP packets to the right one. - -Within a single server process, there can be multiple **virtual hosts**. -The [HTTP host header][] (in combination with a port number) is normally used to determine to which of them to route incoming HTTP requests. - -The host header value that matches some virtual host is called the virtual hosts's **server name**. If there are multiple aliases for the virtual host, one of them (often the first one listed in the configuration) is called the **primary server name**. See for example, the Apache [`ServerName`][ap-sn] or NGINX [`server_name`][nx-sn] directive or the CGI specification on `SERVER_NAME` ([RFC 3875][rfc-servername]). -In practice the HTTP host header is often ignored when just a single virtual host is configured for the IP. - -Within a single virtual host, some servers support the concepts of an **HTTP application** -(for example in Java, the Servlet JSR defines an application as -"a collection of servlets, HTML pages, classes, and other resources that make up a complete application on a Web server" --- SRV.9 in [JSR 53][]; -in a deployment of a Python application to Apache, the application would be the [PEP 3333][] conformant callable that is configured using the -[`WSGIScriptAlias` directive][modwsgisetup] of `mod_wsgi`). - -An application can be "mounted" under some **application root** -(also know as *[context root][]* *[context prefix][]*, or *[document base][]*) -which is a fixed path prefix of the URL that determines to which application a request is routed -(e.g., the server could be configured to route all requests that go to an URL path starting with `/webshop/` -at a particular virtual host -to the `com.example.webshop` web application). - -Some servers allow to bind the same HTTP application to multiple `(virtual host, application root)` pairs. - -> TODO: Find way to trace HTTP application and application root ([opentelemetry/opentelementry-specification#335][]) - -[PEP 3333]: https://www.python.org/dev/peps/pep-3333/ -[modwsgisetup]: https://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html -[context root]: https://docs.jboss.org/jbossas/guides/webguide/r2/en/html/ch06.html -[context prefix]: https://marc.info/?l=apache-cvs&m=130928191414740 -[document base]: http://tomcat.apache.org/tomcat-5.5-doc/config/context.html -[rfc-servername]: https://tools.ietf.org/html/rfc3875#section-4.1.14 -[ap-sn]: https://httpd.apache.org/docs/2.4/mod/core.html#servername -[nx-sn]: http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name -[JSR 53]: https://jcp.org/aboutJava/communityprocess/maintenance/jsr053/index2.html -[opentelemetry/opentelementry-specification#335]: https://github.com/open-telemetry/opentelemetry-specification/issues/335 - -### HTTP Server semantic conventions - -This span type represents an inbound HTTP request. - -For an HTTP server span, `SpanKind` MUST be `Server`. - -Given an inbound request for a route (e.g. `"/users/:userID?"`) the `name` attribute of the span SHOULD be set to this route. -If the route does not include the application root, it SHOULD be prepended to the span name. - -If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. - -| Attribute name | Notes and examples | `Required`? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.server_name` | The primary server name of the matched virtual host. This should be obtained via configuration. If no such configuration can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). | [1] | -| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | `Recommended` | -| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | `Recommended` | - -[HTTP request line]: https://tools.ietf.org/html/rfc7230#section-3.1.1 -[HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4 -[X-Forwarded-For]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For - -**[1]**: `http.url` is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. ). -It is thus preferred to supply the raw data that *is* available. -Namely, one of the following sets is required (in order of usual preference unless for a particular web server/framework it is known that some other set is preferable for some reason; all strings must be non-empty): - -* `http.scheme`, `http.host`, `http.target` -* `http.scheme`, `http.server_name`, `net.host.port`, `http.target` -* `http.scheme`, `net.host.name`, `net.host.port`, `http.target` -* `http.url` - -Of course, more than the required attributes can be supplied, but this is recommended only if they cannot be inferred from the sent ones. -For example, `http.server_name` has shown great value in practice, as bogus HTTP Host headers occur often in the wild. - -It is strongly recommended to set `http.server_name` to allow associating requests with some logical server entity. - -## HTTP client-server example - -As an example, if a browser request for `https://example.com:8080/webshop/articles/4?s=1` is invoked from a host with IP 192.0.2.4, we may have the following Span on the client side: - -Span name: `/webshop/articles/4` (NOTE: This is subject to change, see [open-telemetry/opentelemetry-specification#270][].) - -[open-telemetry/opentelemetry-specification#270]: https://github.com/open-telemetry/opentelemetry-specification/issues/270 - -| Attribute name | Value | -| :----------------- | :-------------------------------------------------------| -| `http.method` | `"GET"` | -| `http.flavor` | `"1.1"` | -| `http.url` | `"https://example.com:8080/webshop/articles/4?s=1"` | -| `net.peer.ip` | `"192.0.2.5"` | -| `http.status_code` | `200` | -| `http.status_text` | `"OK"` | - -The corresponding server Span may look like this: - -Span name: `/webshop/articles/:article_id`. - -| Attribute name | Value | -| :----------------- | :---------------------------------------------- | -| `http.method` | `"GET"` | -| `http.flavor` | `"1.1"` | -| `http.target` | `"/webshop/articles/4?s=1"` | -| `http.host` | `"example.com:8080"` | -| `http.server_name` | `"example.com"` | -| `host.port` | `8080` | -| `http.scheme` | `"https"` | -| `http.route` | `"/webshop/articles/:article_id"` | -| `http.status_code` | `200` | -| `http.status_text` | `"OK"` | -| `http.client_ip` | `"192.0.2.4"` | -| `net.peer.ip` | `"192.0.2.5"` (the client goes through a proxy) | -| `http.user_agent` | `"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"` | - -Note that following the recommendations above, `http.url` is not set in the above example. -If set, it would be -`"https://example.com:8080/webshop/articles/4?s=1"` -but due to `http.scheme`, `http.host` and `http.target` being set, it would be redundant. -As explained above, these separate values are preferred but if for some reason the URL is available but the other values are not, -URL can replace `http.scheme`, `http.host` and `http.target`. +This is an arbitrary markdown file that does not have any semantic conventions anchors. diff --git a/semantic-conventions/src/tests/data/markdown/enum_int/expected.md b/semantic-conventions/src/tests/data/markdown/enum_int/expected.md index e8361396..c481f605 100644 --- a/semantic-conventions/src/tests/data/markdown/enum_int/expected.md +++ b/semantic-conventions/src/tests/data/markdown/enum_int/expected.md @@ -1,29 +1,29 @@ # RPC.GRPC with int enum -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `16` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `16` | `Required` | Experimental | `rpc.grpc.status_code` MUST be one of the following: -| Value | Description | -|---|---| -| `0` | ok | -| `1` | cancelled | -| `2` | unknown | -| `3` | invalid_argument | -| `4` | deadline_exceeded | -| `5` | not_found | -| `6` | already_exists | -| `7` | permission_denied | -| `8` | resource_exhausted | -| `9` | failed_precondition | -| `10` | aborted | -| `11` | out_of_range | -| `12` | unimplemented | -| `13` | internal | -| `14` | unavailable | -| `15` | data_loss | -| `16` | unauthenticated | +| Value | Description | Stability | +|---|---|---| +| `0` | ok | Experimental | +| `1` | cancelled | Experimental | +| `2` | unknown | Experimental | +| `3` | invalid_argument | Experimental | +| `4` | deadline_exceeded | Experimental | +| `5` | not_found | Experimental | +| `6` | already_exists | Experimental | +| `7` | permission_denied | Experimental | +| `8` | resource_exhausted | Experimental | +| `9` | failed_precondition | Experimental | +| `10` | aborted | Experimental | +| `11` | out_of_range | Experimental | +| `12` | unimplemented | Experimental | +| `13` | internal | Experimental | +| `14` | unavailable | Experimental | +| `15` | data_loss | Experimental | +| `16` | unauthenticated | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/event/expected.md b/semantic-conventions/src/tests/data/markdown/event/expected.md index ed3e9f0e..a4606a7d 100644 --- a/semantic-conventions/src/tests/data/markdown/event/expected.md +++ b/semantic-conventions/src/tests/data/markdown/event/expected.md @@ -3,12 +3,12 @@ The event name MUST be `exception`. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `exception.escaped` | boolean | 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. [1] | | `Recommended` | -| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | -| `exception.stacktrace` | string | A stacktrace. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | -| `exception.type` | string | The type of the exception. | `java.net.ConnectException`; `OSError` | See below | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `exception.escaped` | boolean | 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. [1] | | `Recommended` | Experimental | +| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | Experimental | +| `exception.stacktrace` | string | A stacktrace. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | Experimental | +| `exception.type` | string | The type of the exception. | `java.net.ConnectException`; `OSError` | See below | Experimental | **[1]:** An exception is considered to have escaped. diff --git a/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md b/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md index 1cb8695e..dc6cfa03 100644 --- a/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md +++ b/semantic-conventions/src/tests/data/markdown/event_noprefix/expected.md @@ -3,7 +3,7 @@ The event name MUST be `myname`. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `attr` | boolean | attrbrief | | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `attr` | boolean | attrbrief | | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md b/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md index dd574537..9529c603 100644 --- a/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md +++ b/semantic-conventions/src/tests/data/markdown/event_renamed/expected.md @@ -3,7 +3,7 @@ The event name MUST be `myname`. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `myprefix.attr` | boolean | attrbrief | | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `myprefix.attr` | boolean | attrbrief | | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/example_array/expected.md b/semantic-conventions/src/tests/data/markdown/example_array/expected.md index 4c1609f2..042075d5 100644 --- a/semantic-conventions/src/tests/data/markdown/example_array/expected.md +++ b/semantic-conventions/src/tests/data/markdown/example_array/expected.md @@ -1,7 +1,7 @@ # Common Attributes -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.method` | string[] | HTTP request method. | `[GET, POST, HEAD]` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.method` | string[] | HTTP request method. | `[GET, POST, HEAD]` | `Required` | Experimental | \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md b/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md index 414f25f8..efa11282 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md @@ -34,15 +34,15 @@ These attributes will usually be the same for all operations performed over the Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | -| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Conditionally Required` [2] | -| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | Experimental | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | Experimental | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | Experimental | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | Experimental | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Conditionally Required` [2] | Experimental | +| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | Experimental | **[1]:** It is recommended to remove embedded credentials. @@ -57,51 +57,51 @@ Some database systems may allow a connection to switch to a different `db.user`, `db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `other_sql` | Some other SQL database. Fallback only. See notes. | -| `mssql` | Microsoft SQL Server | -| `mysql` | MySQL | -| `oracle` | Oracle Database | -| `db2` | IBM Db2 | -| `postgresql` | PostgreSQL | -| `redshift` | Amazon Redshift | -| `hive` | Apache Hive | -| `cloudscape` | Cloudscape | -| `hsqlsb` | HyperSQL DataBase | -| `progress` | Progress Database | -| `maxdb` | SAP MaxDB | -| `hanadb` | SAP HANA | -| `ingres` | Ingres | -| `firstsql` | FirstSQL | -| `edb` | EnterpriseDB | -| `cache` | InterSystems Caché | -| `adabas` | Adabas (Adaptable Database System) | -| `firebird` | Firebird | -| `derby` | Apache Derby | -| `filemaker` | FileMaker | -| `informix` | Informix | -| `instantdb` | InstantDB | -| `interbase` | InterBase | -| `mariadb` | MariaDB | -| `netezza` | Netezza | -| `pervasive` | Pervasive PSQL | -| `pointbase` | PointBase | -| `sqlite` | SQLite | -| `sybase` | Sybase | -| `teradata` | Teradata | -| `vertica` | Vertica | -| `h2` | H2 | -| `coldfusion` | ColdFusion IMQ | -| `cassandra` | Apache Cassandra | -| `hbase` | Apache HBase | -| `mongodb` | MongoDB | -| `redis` | Redis | -| `couchbase` | Couchbase | -| `couchdb` | CouchDB | -| `cosmosdb` | Microsoft Azure Cosmos DB | -| `dynamodb` | Amazon DynamoDB | -| `neo4j` | Neo4j | +| Value | Description | Stability | +|---|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | Experimental | +| `mssql` | Microsoft SQL Server | Experimental | +| `mysql` | MySQL | Experimental | +| `oracle` | Oracle Database | Experimental | +| `db2` | IBM Db2 | Experimental | +| `postgresql` | PostgreSQL | Experimental | +| `redshift` | Amazon Redshift | Experimental | +| `hive` | Apache Hive | Experimental | +| `cloudscape` | Cloudscape | Experimental | +| `hsqlsb` | HyperSQL DataBase | Experimental | +| `progress` | Progress Database | Experimental | +| `maxdb` | SAP MaxDB | Experimental | +| `hanadb` | SAP HANA | Experimental | +| `ingres` | Ingres | Experimental | +| `firstsql` | FirstSQL | Experimental | +| `edb` | EnterpriseDB | Experimental | +| `cache` | InterSystems Caché | Experimental | +| `adabas` | Adabas (Adaptable Database System) | Experimental | +| `firebird` | Firebird | Experimental | +| `derby` | Apache Derby | Experimental | +| `filemaker` | FileMaker | Experimental | +| `informix` | Informix | Experimental | +| `instantdb` | InstantDB | Experimental | +| `interbase` | InterBase | Experimental | +| `mariadb` | MariaDB | Experimental | +| `netezza` | Netezza | Experimental | +| `pervasive` | Pervasive PSQL | Experimental | +| `pointbase` | PointBase | Experimental | +| `sqlite` | SQLite | Experimental | +| `sybase` | Sybase | Experimental | +| `teradata` | Teradata | Experimental | +| `vertica` | Vertica | Experimental | +| `h2` | H2 | Experimental | +| `coldfusion` | ColdFusion IMQ | Experimental | +| `cassandra` | Apache Cassandra | Experimental | +| `hbase` | Apache HBase | Experimental | +| `mongodb` | MongoDB | Experimental | +| `redis` | Redis | Experimental | +| `couchbase` | Couchbase | Experimental | +| `couchdb` | CouchDB | Experimental | +| `cosmosdb` | Microsoft Azure Cosmos DB | Experimental | +| `dynamodb` | Amazon DynamoDB | Experimental | +| `neo4j` | Neo4j | Experimental | ### Notes on `db.system` @@ -125,10 +125,10 @@ When additional attributes are added that only apply to a specific DBMS, its ide ### Connection-level attributes for specific technologies -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | Experimental | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | Experimental | **[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). @@ -139,11 +139,11 @@ These attributes may be different for each operation performed, even if the same Usually only one `db.name` will be used per connection though. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`; `main` | `Conditionally Required` [2] | -| `db.operation` | string | 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`. [3] | `findAndModify`; `HMSET` | `Conditionally Required` if `db.statement` is not applicable. | -| `db.statement` | string | The database statement being executed. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`; `main` | `Conditionally Required` [2] | Experimental | +| `db.operation` | string | 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`. [3] | `findAndModify`; `HMSET` | `Conditionally Required` if `db.statement` is not applicable. | Experimental | +| `db.statement` | string | The database statement being executed. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | Experimental | **[1]:** In some SQL databases, the database name to be used is called "schema name". @@ -169,33 +169,33 @@ For example, when retrieving a document, `db.operation` would be set to (literal #### Cassandra -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | `Required` | Experimental | #### Apache HBase -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | `Required` | Experimental | #### Redis -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.redis.database_index` | int | 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. | `0`; `1`; `15` | `Conditionally Required` if other than the default database (`0`). | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.redis.database_index` | int | 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. | `0`; `1`; `15` | `Conditionally Required` if other than the default database (`0`). | Experimental | #### MongoDB -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`; `products` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`; `products` | `Required` | Experimental | ## Examples diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md b/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md index 28049197..ce07dbab 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/input.md @@ -34,15 +34,15 @@ These attributes will usually be the same for all operations performed over the Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | -| `db.user` | string | Username for accessing the database. | `readonly_user`
`reporting_user` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | Experimental | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | +| `db.user` | string | Username for accessing the database. | `readonly_user`
`reporting_user` | `Recommended` | Experimental | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | Conditional
See below. | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | Conditional
See below. | -| `net.peer.port` | int | Remote port number. | `80`
`8080`
`443` | `Conditionally Required` [2] | -| `net.transport` | string enum | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | Conditional
See below. | Experimental | +| `net.peer.port` | int | Remote port number. | `80`
`8080`
`443` | `Conditionally Required` [2] | Experimental | +| `net.transport` | string enum | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | Experimental | **[1]:** It is recommended to remove embedded credentials. @@ -57,51 +57,51 @@ At least one of the following is required: `db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `other_sql` | Some other SQL database. Fallback only. See notes. | -| `mssql` | Microsoft SQL Server | -| `mysql` | MySQL | -| `oracle` | Oracle Database | -| `db2` | IBM Db2 | -| `postgresql` | PostgreSQL | -| `redshift` | Amazon Redshift | -| `hive` | Apache Hive | -| `cloudscape` | Cloudscape | -| `hsqlsb` | HyperSQL DataBase | -| `progress` | Progress Database | -| `maxdb` | SAP MaxDB | -| `hanadb` | SAP HANA | -| `ingres` | Ingres | -| `firstsql` | FirstSQL | -| `edb` | EnterpriseDB | -| `cache` | InterSystems Caché | -| `adabas` | Adabas (Adaptable Database System) | -| `firebird` | Firebird | -| `derby` | Apache Derby | -| `filemaker` | FileMaker | -| `informix` | Informix | -| `instantdb` | InstantDB | -| `interbase` | InterBase | -| `mariadb` | MariaDB | -| `netezza` | Netezza | -| `pervasive` | Pervasive PSQL | -| `pointbase` | PointBase | -| `sqlite` | SQLite | -| `sybase` | Sybase | -| `teradata` | Teradata | -| `vertica` | Vertica | -| `h2` | H2 | -| `coldfusion` | ColdFusion IMQ | -| `cassandra` | Apache Cassandra | -| `hbase` | Apache HBase | -| `mongodb` | MongoDB | -| `redis` | Redis | -| `couchbase` | Couchbase | -| `couchdb` | CouchDB | -| `cosmosdb` | Microsoft Azure Cosmos DB | -| `dynamodb` | Amazon DynamoDB | -| `neo4j` | Neo4j | +| Value | Description | Stability | +|---|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | Experimental | +| `mssql` | Microsoft SQL Server | Experimental | +| `mysql` | MySQL | Experimental | +| `oracle` | Oracle Database | Experimental | +| `db2` | IBM Db2 | Experimental | +| `postgresql` | PostgreSQL | Experimental | +| `redshift` | Amazon Redshift | Experimental | +| `hive` | Apache Hive | Experimental | +| `cloudscape` | Cloudscape | Experimental | +| `hsqlsb` | HyperSQL DataBase | Experimental | +| `progress` | Progress Database | Experimental | +| `maxdb` | SAP MaxDB | Experimental | +| `hanadb` | SAP HANA | Experimental | +| `ingres` | Ingres | Experimental | +| `firstsql` | FirstSQL | Experimental | +| `edb` | EnterpriseDB | Experimental | +| `cache` | InterSystems Caché | Experimental | +| `adabas` | Adabas (Adaptable Database System) | Experimental | +| `firebird` | Firebird | Experimental | +| `derby` | Apache Derby | Experimental | +| `filemaker` | FileMaker | Experimental | +| `informix` | Informix | Experimental | +| `instantdb` | InstantDB | Experimental | +| `interbase` | InterBase | Experimental | +| `mariadb` | MariaDB | Experimental | +| `netezza` | Netezza | Experimental | +| `pervasive` | Pervasive PSQL | Experimental | +| `pointbase` | PointBase | Experimental | +| `sqlite` | SQLite | Experimental | +| `sybase` | Sybase | Experimental | +| `teradata` | Teradata | Experimental | +| `vertica` | Vertica | Experimental | +| `h2` | H2 | Experimental | +| `coldfusion` | ColdFusion IMQ | Experimental | +| `cassandra` | Apache Cassandra | Experimental | +| `hbase` | Apache HBase | Experimental | +| `mongodb` | MongoDB | Experimental | +| `redis` | Redis | Experimental | +| `couchbase` | Couchbase | Experimental | +| `couchdb` | CouchDB | Experimental | +| `cosmosdb` | Microsoft Azure Cosmos DB | Experimental | +| `dynamodb` | Amazon DynamoDB | Experimental | +| `neo4j` | Neo4j | Experimental | ### Notes on `db.system` @@ -125,10 +125,10 @@ When additional attributes are added that only apply to a specific DBMS, its ide ### Connection-level attributes for specific technologies -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`
`com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | Experimental | +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`
`com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | Experimental | **[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). @@ -139,11 +139,11 @@ These attributes may be different for each operation performed, even if the same Usually only one `db.name` will be used per connection though. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`
`main` | `Conditionally Required` [2] | -| `db.statement` | string | The database statement being executed. [3] | `SELECT * FROM wuser_table`
`SET mykey "WuValue"` | Conditional
Conditionally Required if applicable. | -| `db.operation` | string | 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`. [4] | `findAndModify`
`HMSET` | Conditional
Conditionally Required if `db.statement` is not applicable. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.name` | string | If no tech-specific attribute is defined, 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). [1] | `customers`
`main` | `Conditionally Required` [2] | Experimental | +| `db.statement` | string | The database statement being executed. [3] | `SELECT * FROM wuser_table`
`SET mykey "WuValue"` | Conditional
Conditionally Required if applicable. | Experimental | +| `db.operation` | string | 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`. [4] | `findAndModify`
`HMSET` | Conditional
Conditionally Required if `db.statement` is not applicable. | Experimental | **[1]:** In some SQL databases, the database name to be used is called "schema name". @@ -169,24 +169,24 @@ For example, when retrieving a document, `db.operation` would be set to (literal #### Cassandra -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.cassandra.keyspace` | string | The name of the keyspace being accessed. To be used instead of the generic `db.name` attribute. | `mykeyspace` | `Required` | Experimental | #### Apache HBase -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.hbase.namespace` | string | The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being accessed. To be used instead of the generic `db.name` attribute. | `default` | `Required` | Experimental | #### Redis -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| | `db.redis.database_index` | int | 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. | `0`
`1`
`15` | Conditional [1] | **[1]:** if other than the default database (`0`). @@ -195,9 +195,9 @@ For example, when retrieving a document, `db.operation` would be set to (literal #### MongoDB -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`
`products` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`
`products` | `Required` | Experimental | ## Examples diff --git a/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md b/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md index 40906dce..46fce809 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md +++ b/semantic-conventions/src/tests/data/markdown/extend_grandparent/expected.md @@ -1,23 +1,23 @@ ## DB spans -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.foo.bar` | string | Some property. | `baz` | `Recommended` | -| `db.name` | string | Database name. | `the_shop` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.foo.bar` | string | Some property. | `baz` | `Recommended` | Experimental | +| `db.name` | string | Database name. | `the_shop` | `Recommended` | Experimental | ## DB metrics -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.foo.duration` | Histogram | `s` | Measures the duration of database Foo calls. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.foo.duration` | Histogram | `s` | Measures the duration of database Foo calls. | Experimental | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.foo.bar` | string | Some property. | `baz` | `Recommended` | -| `db.name` | string | Database name. | `the_shop` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.foo.bar` | string | Some property. | `baz` | `Recommended` | Experimental | +| `db.name` | string | Database name. | `the_shop` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/include/expected.md b/semantic-conventions/src/tests/data/markdown/include/expected.md index 7102b13e..331d979f 100644 --- a/semantic-conventions/src/tests/data/markdown/include/expected.md +++ b/semantic-conventions/src/tests/data/markdown/include/expected.md @@ -1,21 +1,21 @@ # Test Markdown -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | -| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | See below | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `http.recommended_attribute` | string | brief | `foo` | `Recommended` short note | -| `http.recommended_attribute_long_note` | string | brief | `bar` | `Recommended` [1] | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | -| [`http.server_name`](input_http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | Experimental | +| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | See below | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.recommended_attribute` | string | brief | `foo` | `Recommended` short note | Experimental | +| `http.recommended_attribute_long_note` | string | brief | `bar` | `Recommended` [1] | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | Experimental | +| [`http.server_name`](input_http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | Experimental | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | **[1]:** some very long note that should be written under the semconv table @@ -35,11 +35,11 @@ `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write. | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system. | -| `timer` | A function is scheduled to be executed regularly. | -| `other` | other | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write. | Experimental | +| `http` | To provide an answer to an inbound HTTP request | Experimental | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system. | Experimental | +| `timer` | A function is scheduled to be executed regularly. | Experimental | +| `other` | other | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md b/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md index 8074bd93..a34ac25b 100644 --- a/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md +++ b/semantic-conventions/src/tests/data/markdown/metrics_tables/expected.md @@ -2,34 +2,34 @@ **`foo.size`** -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `foo.size` | Histogram | `{bars}` | Measures the size of foo. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `foo.size` | Histogram | `{bars}` | Measures the size of foo. [1] | Stable | **[1]:** Some notes on metric.foo.size **Attributes for `foo.size`** -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | Experimental | **`foo.active_eggs`** -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `foo.active_eggs` | UpDownCounter | `{cartons}` | **Deprecated: Removed.**
Measures how many eggs are currently active. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `foo.active_eggs` | UpDownCounter | `{cartons}` | Measures how many eggs are currently active. | Deprecated: Removed. | **Attributes for `foo.active_eggs`** -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `bar.egg.type` | string | Type of egg. [1] | `chicken`; `emu`; `dragon` | `Conditionally Required` if available to instrumentation. | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `bar.egg.type` | string | Type of egg. [1] | `chicken`; `emu`; `dragon` | `Conditionally Required` if available to instrumentation. | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Opt-In` | Experimental | **[1]:** Some notes on attribute diff --git a/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md b/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md index 8b5289a6..f3c75e9b 100644 --- a/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md +++ b/semantic-conventions/src/tests/data/markdown/missing_end_tag/input.md @@ -3,21 +3,4 @@ -| Attribute name | Notes and examples | `Required`? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | -| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | -| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | -| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | -| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | -| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | - -It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. - -[network attributes]: span-general.md#general-network-connection-attributes -[HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 -[HTTP reason phrase]: https://tools.ietf.org/html/rfc7230#section-3.1.2 -[User-Agent]: https://tools.ietf.org/html/rfc7231#section-5.5.3 +There is no end tag here - we expect an error to be raised \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/multiple/expected.md b/semantic-conventions/src/tests/data/markdown/multiple/expected.md index a3fd8769..8eacf0fa 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/expected.md +++ b/semantic-conventions/src/tests/data/markdown/multiple/expected.md @@ -2,29 +2,29 @@ -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/multiple/input.md b/semantic-conventions/src/tests/data/markdown/multiple/input.md index 45ae85c2..e44cb842 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/input.md +++ b/semantic-conventions/src/tests/data/markdown/multiple/input.md @@ -5,15 +5,15 @@ | Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | Experimental | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | | `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | Experimental | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md b/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md index c3780d61..d652b47f 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md +++ b/semantic-conventions/src/tests/data/markdown/multiple_enum/expected.md @@ -2,51 +2,51 @@ -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `net.host.carrier.icc` | string | host.carrier.icc | `DE` | `Recommended` | -| `net.host.carrier.mcc` | string | host.carrier.mcc | `310` | `Recommended` | -| `net.host.carrier.mnc` | string | host.carrier.mnc | `001` | `Recommended` | -| `net.host.carrier.name` | string | host.carrier.name | `sprint` | `Recommended` | -| `net.host.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell connection, but it could be used for describing details about a wifi connection. | `2G` | `Recommended` | -| `net.host.connection.type` | string | unavailable | `wifi` | `Recommended` | -| `net.host.ip` | string | Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. | `192.168.0.1` | `Recommended` | -| `net.host.name` | string | Local hostname or similar, see note below. | `localhost` | `Recommended` | -| `net.host.port` | int | Like `net.peer.port` but for the host port. | `35555` | `Recommended` | -| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | -| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `net.host.carrier.icc` | string | host.carrier.icc | `DE` | `Recommended` | Experimental | +| `net.host.carrier.mcc` | string | host.carrier.mcc | `310` | `Recommended` | Experimental | +| `net.host.carrier.mnc` | string | host.carrier.mnc | `001` | `Recommended` | Experimental | +| `net.host.carrier.name` | string | host.carrier.name | `sprint` | `Recommended` | Experimental | +| `net.host.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell connection, but it could be used for describing details about a wifi connection. | `2G` | `Recommended` | Experimental | +| `net.host.connection.type` | string | unavailable | `wifi` | `Recommended` | Experimental | +| `net.host.ip` | string | Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. | `192.168.0.1` | `Recommended` | Experimental | +| `net.host.name` | string | Local hostname or similar, see note below. | `localhost` | `Recommended` | Experimental | +| `net.host.port` | int | Like `net.peer.port` but for the host port. | `35555` | `Recommended` | Experimental | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | Experimental | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | Experimental | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | Experimental | +| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Recommended` | Experimental | `net.host.connection.subtype` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `1G` | 1G | -| `2G` | 2G | +| Value | Description | Stability | +|---|---|---| +| `1G` | 1G | Experimental | +| `2G` | 2G | Experimental | `net.host.connection.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `wifi` | wifi [1] | -| `wired` | wired | -| `cell` | cell | -| `unavailable` | unavailable | +| Value | Description | Stability | +|---|---|---| +| `wifi` | wifi [1] | Experimental | +| `wired` | wired | Experimental | +| `cell` | cell | Experimental | +| `unavailable` | unavailable | Experimental | **[1]:** Usually 802.11 `net.transport` MUST be one of the following: -| Value | Description | -|---|---| -| `IP.TCP` | ip.tcp | -| `IP.UDP` | ip.udp | -| `IP` | Another IP-based protocol | -| `Unix` | Unix Domain socket. See below. | -| `pipe` | Named or anonymous pipe. See note below. | -| `inproc` | In-process communication. [1] | -| `other` | Something else (non IP-based). | +| Value | Description | Stability | +|---|---|---| +| `IP.TCP` | ip.tcp | Experimental | +| `IP.UDP` | ip.udp | Experimental | +| `IP` | Another IP-based protocol | Experimental | +| `Unix` | Unix Domain socket. See below. | Experimental | +| `pipe` | Named or anonymous pipe. See note below. | Experimental | +| `inproc` | In-process communication. [1] | Experimental | +| `other` | Something else (non IP-based). | Experimental | **[1]:** Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. diff --git a/semantic-conventions/src/tests/data/markdown/omit_requirement_level/expected.md b/semantic-conventions/src/tests/data/markdown/omit_requirement_level/expected.md index ffa730ac..0d0e99cd 100644 --- a/semantic-conventions/src/tests/data/markdown/omit_requirement_level/expected.md +++ b/semantic-conventions/src/tests/data/markdown/omit_requirement_level/expected.md @@ -1,9 +1,9 @@ # Common Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Experimental | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md b/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md index de3e6daa..cfaaf1d4 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_empty/http.md @@ -1,11 +1,11 @@ # General -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | -| `http.route` | String | The matched route (path template). | `/users/:userID?` | `Recommended` | -| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | Experimental | +| `http.route` | String | The matched route (path template). | `/users/:userID?` | `Recommended` | Experimental | +| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | Experimental | **[1]:** http.url is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md index 52f04e18..34b5b5ea 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md @@ -1,21 +1,21 @@ # Attributes -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | -| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | -| [`http.client_ip`](http.md) | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [1] | `83.164.160.102` | `Recommended` | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| [`http.route`](http.md) | string | The matched route (path template). | `/users/:userID?` | `Recommended` | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | -| [`http.server_name`](http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | Experimental | +| `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | Experimental | +| [`http.client_ip`](http.md) | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [1] | `83.164.160.102` | `Recommended` | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| [`http.route`](http.md) | string | The matched route (path template). | `/users/:userID?` | `Recommended` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | Experimental | +| [`http.server_name`](http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | Experimental | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | Experimental | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | **[1]:** This is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. @@ -32,11 +32,11 @@ `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write. | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system. | -| `timer` | A function is scheduled to be executed regularly. | -| `other` | other | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write. | Experimental | +| `http` | To provide an answer to an inbound HTTP request | Experimental | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system. | Experimental | +| `timer` | A function is scheduled to be executed regularly. | Experimental | +| `other` | other | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/http.md b/semantic-conventions/src/tests/data/markdown/parameter_full/http.md index b634120b..01eab08d 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/http.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/http.md @@ -1,11 +1,11 @@ # General -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | -| `http.route` | String | The matched route (path template). | `/users/:userID?` | `Recommended` | -| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.server_name` | String | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | Experimental | +| `http.route` | String | The matched route (path template). | `/users/:userID?` | `Recommended` | Experimental | +| `http.client_ip` | String | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | Experimental | **[1]:** http.url is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md index 6d062e68..b9b93999 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md @@ -1,26 +1,26 @@ # DB -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | -| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | -| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | +| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | Experimental | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | Experimental | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | Experimental | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | Experimental | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | Experimental | **[1]:** It is recommended to remove embedded credentials. `db.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `sql` | A SQL database | -| `cassandra` | Apache Cassandra | -| `hbase` | Apache HBase | -| `mongodb` | MongoDB | -| `redis` | Redis | -| `couchbase` | Couchbase | -| `couchdb` | CouchDB | +| Value | Description | Stability | +|---|---|---| +| `sql` | A SQL database | Experimental | +| `cassandra` | Apache Cassandra | Experimental | +| `hbase` | Apache HBase | Experimental | +| `mongodb` | MongoDB | Experimental | +| `redis` | Redis | Experimental | +| `couchbase` | Couchbase | Experimental | +| `couchdb` | CouchDB | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md index aa49e453..2d4bffac 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/input.md @@ -1,28 +1,28 @@ # DB -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.type` | String | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | -| `db.connection_string` | String | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | -| `db.user` | String | Username for accessing the database. | `readonly_user`
`reporting_user` | `Recommended` | -| [net.peer.ip](general.md) | String | None | `127.0.0.1` | `Recommended` | -| [net.peer.name](general.md) | String | None | `example.com` | `Recommended` | -| [net.peer.port](general.md) | int | None | `80`
`8080`
`443` | `Recommended` | -| [net.transport](general.md) | Enum | None | `IP.TCP` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.type` | String | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | Experimental | +| `db.connection_string` | String | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | +| `db.user` | String | Username for accessing the database. | `readonly_user`
`reporting_user` | `Recommended` | Experimental | +| [net.peer.ip](general.md) | String | None | `127.0.0.1` | `Recommended` | Experimental | +| [net.peer.name](general.md) | String | None | `example.com` | `Recommended` | Experimental | +| [net.peer.port](general.md) | int | None | `80`
`8080`
`443` | `Recommended` | Experimental | +| [net.transport](general.md) | Enum | None | `IP.TCP` | `Recommended` | Experimental | **[1]:** It is recommended to remove embedded credentials. `db.type` MUST be one of the following: -| Value | Description | -|---|---| -| sql | A SQL database | -| cassandra | Apache Cassandra | -| hbase | Apache HBase | -| mongodb | MongoDB | -| redis | Redis | -| couchbase | Couchbase | -| couchdb | CouchDB | +| Value | Description | Stability | +|---|---|---| +| sql | A SQL database | Experimental | +| cassandra | Apache Cassandra | Experimental | +| hbase | Apache HBase | Experimental | +| mongodb | MongoDB | Experimental | +| redis | Redis | Experimental | +| couchbase | Couchbase | Experimental | +| couchdb | CouchDB | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md index bf1dd634..38ce374f 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md @@ -1,14 +1,14 @@ # DB -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | -| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | -| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | -| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | +| `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | Experimental | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | Experimental | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | Experimental | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | Experimental | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Recommended` | Experimental | **[1]:** It is recommended to remove embedded credentials. @@ -19,13 +19,13 @@ `db.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `sql` | A SQL database | -| `cassandra` | Apache Cassandra | -| `hbase` | Apache HBase | -| `mongodb` | MongoDB | -| `redis` | Redis | -| `couchbase` | Couchbase | -| `couchdb` | CouchDB | +| Value | Description | Stability | +|---|---|---| +| `sql` | A SQL database | Experimental | +| `cassandra` | Apache Cassandra | Experimental | +| `hbase` | Apache HBase | Experimental | +| `mongodb` | MongoDB | Experimental | +| `redis` | Redis | Experimental | +| `couchbase` | Couchbase | Experimental | +| `couchdb` | CouchDB | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md index 6197be43..bfdee699 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md @@ -1,14 +1,14 @@ # DB -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `db.dbms` | string | An identifier for the DBMS (database management system) product | `mssql` | `Conditionally Required` for `db.type="sql"` | -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | -| `db.name` | string | If no tech-specific attribute is defined below, 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). [2] | `customers`; `master` | `Conditionally Required` [3] | -| `db.operation` | string | The type of operation that is executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`. While it would semantically make sense to set this, e.g., to a SQL keyword like `SELECT` or `INSERT`, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property (the back end can do that if required). | `findAndModify` | `Conditionally Required` if `db.statement` is not applicable. | -| `db.statement` | string | A database statement for the given database type. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `db.dbms` | string | An identifier for the DBMS (database management system) product | `mssql` | `Conditionally Required` for `db.type="sql"` | Experimental | +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | Experimental | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | Experimental | +| `db.name` | string | If no tech-specific attribute is defined below, 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). [2] | `customers`; `master` | `Conditionally Required` [3] | Experimental | +| `db.operation` | string | The type of operation that is executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`. While it would semantically make sense to set this, e.g., to a SQL keyword like `SELECT` or `INSERT`, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property (the back end can do that if required). | `findAndModify` | `Conditionally Required` if `db.statement` is not applicable. | Experimental | +| `db.statement` | string | A database statement for the given database type. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | Experimental | **[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). @@ -25,39 +25,39 @@ `db.dbms` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | -|---|---| -| `mssql` | Microsoft SQL Server | -| `mysql` | MySQL | -| `oracle` | Oracle | -| `db2` | IBM Db2 | -| `postgresql` | PostgreSQL | -| `redshift` | Amazon Redshift | -| `hive` | Apache Hive | -| `cloudscape` | Cloudscape | -| `hsqlsb` | HyperSQL DataBase | -| `progress` | Progress Database | -| `maxdb` | SAP MaxDB | -| `hanadb` | SAP HANA | -| `ingres` | Ingres | -| `firstsql` | FirstSQL | -| `edb` | EnterpriseDB | -| `cache` | InterSystems Caché | -| `adabas` | Adabas (Adaptable Database System) | -| `firebird` | Firebird | -| `derby` | Apache Derby | -| `filemaker` | FileMaker | -| `informix` | Informix | -| `instantdb` | InstantDB | -| `interbase` | InterBase | -| `mariadb` | MariaDB | -| `netezza` | Netezza | -| `pervasive` | Pervasive PSQL | -| `pointbase` | PointBase | -| `sqlite` | SQLite | -| `sybase` | Sybase | -| `teradata` | Teradata | -| `vertica` | Vertica | -| `h2` | H2 | -| `coldfusion` | ColdFusion IMQ | +| Value | Description | Stability | +|---|---|---| +| `mssql` | Microsoft SQL Server | Experimental | +| `mysql` | MySQL | Experimental | +| `oracle` | Oracle | Experimental | +| `db2` | IBM Db2 | Experimental | +| `postgresql` | PostgreSQL | Experimental | +| `redshift` | Amazon Redshift | Experimental | +| `hive` | Apache Hive | Experimental | +| `cloudscape` | Cloudscape | Experimental | +| `hsqlsb` | HyperSQL DataBase | Experimental | +| `progress` | Progress Database | Experimental | +| `maxdb` | SAP MaxDB | Experimental | +| `hanadb` | SAP HANA | Experimental | +| `ingres` | Ingres | Experimental | +| `firstsql` | FirstSQL | Experimental | +| `edb` | EnterpriseDB | Experimental | +| `cache` | InterSystems Caché | Experimental | +| `adabas` | Adabas (Adaptable Database System) | Experimental | +| `firebird` | Firebird | Experimental | +| `derby` | Apache Derby | Experimental | +| `filemaker` | FileMaker | Experimental | +| `informix` | Informix | Experimental | +| `instantdb` | InstantDB | Experimental | +| `interbase` | InterBase | Experimental | +| `mariadb` | MariaDB | Experimental | +| `netezza` | Netezza | Experimental | +| `pervasive` | Pervasive PSQL | Experimental | +| `pointbase` | PointBase | Experimental | +| `sqlite` | SQLite | Experimental | +| `sybase` | Sybase | Experimental | +| `teradata` | Teradata | Experimental | +| `vertica` | Vertica | Experimental | +| `h2` | H2 | Experimental | +| `coldfusion` | ColdFusion IMQ | Experimental | \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/ref/expected.md b/semantic-conventions/src/tests/data/markdown/ref/expected.md index ad50fff0..2fade255 100644 --- a/semantic-conventions/src/tests/data/markdown/ref/expected.md +++ b/semantic-conventions/src/tests/data/markdown/ref/expected.md @@ -1,13 +1,13 @@ # Attributes -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`net.peer.name`](input_general.md) | string | override brief. [1] | `example.com` | Opt-In | -| [`net.peer.port`](input_general.md) | int | It describes the server port the client is connecting to | `80`; `8080`; `443` | `Required` | -| [`net.sock.peer.addr`](input_general.md) | string | Remote socket peer address. | `127.0.0.1`; `/tmp/mysql.sock` | `Required` | -| [`net.sock.peer.port`](input_general.md) | int | Remote socket peer port. | `16456` | `Conditionally Required` | -| `rpc.service` | string | The service name, must be equal to the $service part in the span name. | `EchoService` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`net.peer.name`](input_general.md) | string | override brief. [1] | `example.com` | `Opt-In` | Experimental | +| [`net.peer.port`](input_general.md) | int | It describes the server port the client is connecting to | `80`; `8080`; `443` | `Required` | Experimental | +| [`net.sock.peer.addr`](input_general.md) | string | Remote socket peer address. | `127.0.0.1`; `/tmp/mysql.sock` | `Required` | Experimental | +| [`net.sock.peer.port`](input_general.md) | int | Remote socket peer port. | `16456` | `Conditionally Required` | Experimental | +| `rpc.service` | string | The service name, must be equal to the $service part in the span name. | `EchoService` | `Required` | Experimental | **[1]:** override note. diff --git a/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md b/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md index e08408c3..1a795493 100644 --- a/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md +++ b/semantic-conventions/src/tests/data/markdown/ref_extends/expected.md @@ -1,9 +1,9 @@ # Spans -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | `Required` | Experimental | **[1]:** Note on the overridden attribute definition. @@ -15,15 +15,15 @@ The following attributes can be important for making sampling decisions and SHOU # Metrics -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.request.duration` | Histogram | `s` | Measures request duration. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.request.duration` | Histogram | `s` | Measures request duration. | Experimental | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | `Required` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`server.address`](input_server.md) | string | Server component of Host header. (overridden brief) [1] | `foo.io` | `Required` | Experimental | **[1]:** Note on the overridden attribute definition. diff --git a/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md b/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md index ed838467..1bf30abd 100644 --- a/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md +++ b/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md @@ -1,18 +1,18 @@ # Attributes -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.host` | string | . | `.` | `Recommended` | -| `http.method` | string | . | `GET` | `Required` | -| `http.scheme` | string | . | `http` | `Recommended` | -| `http.status_code` | int | . | | `Conditionally Required` | -| `http.target` | string | . | `.` | `Recommended` | -| `http.url` | string | . [1] | `.` | `Recommended` | -| `http.user_agent` | string | . | `.` | `Recommended` | -| [`net.peer.ip`](span-general.md) | string | . | `.` | `Recommended` | -| [`net.peer.name`](span-general.md) | string | . | `.` | `Recommended` | -| [`net.peer.port`](span-general.md) | int | . | | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.host` | string | . | `.` | `Recommended` | Experimental | +| `http.method` | string | . | `GET` | `Required` | Experimental | +| `http.scheme` | string | . | `http` | `Recommended` | Experimental | +| `http.status_code` | int | . | | `Conditionally Required` | Experimental | +| `http.target` | string | . | `.` | `Recommended` | Experimental | +| `http.url` | string | . [1] | `.` | `Recommended` | Experimental | +| `http.user_agent` | string | . | `.` | `Recommended` | Experimental | +| [`net.peer.ip`](span-general.md) | string | . | `.` | `Recommended` | Experimental | +| [`net.peer.name`](span-general.md) | string | . | `.` | `Recommended` | Experimental | +| [`net.peer.port`](span-general.md) | int | . | | `Recommended` | Experimental | **[1]:** `http.url` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case the attribute's value should be `https://www.example.com/`. diff --git a/semantic-conventions/src/tests/data/markdown/scope/expected.md b/semantic-conventions/src/tests/data/markdown/scope/expected.md index e6ff24f9..29209024 100644 --- a/semantic-conventions/src/tests/data/markdown/scope/expected.md +++ b/semantic-conventions/src/tests/data/markdown/scope/expected.md @@ -1,7 +1,7 @@ # Instrumentation Scope Semantic Conventions -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `short_name` | string | The single-word name for the instrumentation scope. | `mylibrary` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `short_name` | string | The single-word name for the instrumentation scope. | `mylibrary` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/single/expected.md b/semantic-conventions/src/tests/data/markdown/single/expected.md index 7bee2d95..212af0eb 100644 --- a/semantic-conventions/src/tests/data/markdown/single/expected.md +++ b/semantic-conventions/src/tests/data/markdown/single/expected.md @@ -2,16 +2,16 @@ -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | -| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | -| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | Experimental | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | Experimental | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/data/markdown/single/input.md b/semantic-conventions/src/tests/data/markdown/single/input.md index 4e6e41b1..8ad61ec5 100644 --- a/semantic-conventions/src/tests/data/markdown/single/input.md +++ b/semantic-conventions/src/tests/data/markdown/single/input.md @@ -5,15 +5,15 @@ | Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | Experimental | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | | `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | Experimental | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/sorting/expected.md b/semantic-conventions/src/tests/data/markdown/sorting/expected.md index 7e699905..f1f73b2a 100644 --- a/semantic-conventions/src/tests/data/markdown/sorting/expected.md +++ b/semantic-conventions/src/tests/data/markdown/sorting/expected.md @@ -1,12 +1,12 @@ # Attributes -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| `aaa.aaa` | string | the 1st attribute | `aaa` | `Recommended` | -| `mmm.bbb` | string | the 2nd attribute | `bbb` | `Recommended` | -| `mmm.ccc.` | string | the 3rd attribute | ``mmm.ccc="ccc"`` | `Recommended` | -| `nnn.nnn` | string | the 4th attribute | `nnn` | `Recommended` | -| `zzz.xxx` | string | the 5th attribute | `xxx` | `Recommended` | -| `zzz.yyy` | string | the 6th attribute | `yyy` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aaa.aaa` | string | the 1st attribute | `aaa` | `Recommended` | Experimental | +| `mmm.bbb` | string | the 2nd attribute | `bbb` | `Recommended` | Experimental | +| `mmm.ccc.` | string | the 3rd attribute | ``mmm.ccc="ccc"`` | `Recommended` | Experimental | +| `nnn.nnn` | string | the 4th attribute | `nnn` | `Recommended` | Experimental | +| `zzz.xxx` | string | the 5th attribute | `xxx` | `Recommended` | Experimental | +| `zzz.yyy` | string | the 6th attribute | `yyy` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/spec_version/expected.md b/semantic-conventions/src/tests/data/markdown/spec_version/expected.md index 3ba03a0a..cab51560 100644 --- a/semantic-conventions/src/tests/data/markdown/spec_version/expected.md +++ b/semantic-conventions/src/tests/data/markdown/spec_version/expected.md @@ -2,6 +2,6 @@ | Attribute | [Type](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/common/README.md#attribute) | Description | Examples | [Requirement Level](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/common/attribute-requirement-level.md) | -|---|---|---|---|---| +|---|---|---|---|---|---| | `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | diff --git a/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md index 21578858..de658878 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md +++ b/semantic-conventions/src/tests/data/markdown/stability/all_badges_expected.md @@ -1,65 +1,65 @@ -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | -| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | -| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | | `one` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `test.stable_enum_attr` MUST be one of the following: -| Value | Description | -|---|---| -| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | -| `two` | ![Experimental](https://img.shields.io/badge/-experimental-blue)
member two | -| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | -| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | +| Value | Description | Stability | +|---|---|---| +| `one` | member one | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `two` | member two | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `three` | member three | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| `four` | member four | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | -| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | -| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | | `one` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](stable_badges_expected.md) | boolean | ![Experimental](https://img.shields.io/badge/-experimental-blue)
| | `Required` | -| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | -| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | | `one` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `test.stable_enum_attr` MUST be one of the following: -| Value | Description | -|---|---| -| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | -| `two` | ![Experimental](https://img.shields.io/badge/-experimental-blue)
member two | -| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | -| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | +| Value | Description | Stability | +|---|---|---| +| `one` | member one | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `two` | member two | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `three` | member three | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| `four` | member four | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `stable_metric` | Histogram | `s` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
stable_metric | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `stable_metric` | Histogram | `s` | stable_metric | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `experimental_metric` | Counter | `{e}` | ![Experimental](https://img.shields.io/badge/-experimental-blue)
experimental_metric | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `experimental_metric` | Counter | `{e}` | experimental_metric | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `deprecated_metric` | UpDownCounter | `{d}` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
deprecated_metric | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `deprecated_metric` | UpDownCounter | `{d}` | deprecated_metric | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md index 42717ce6..4ee1e6db 100644 --- a/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md +++ b/semantic-conventions/src/tests/data/markdown/stability/stable_badges_expected.md @@ -1,65 +1,65 @@ -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | -| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | -| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | | | `Required` | Deprecated: Removed. | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | Deprecated: Removed. | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | Experimental | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | | `one` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `test.stable_enum_attr` MUST be one of the following: -| Value | Description | -|---|---| -| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | -| `two` | member two | -| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | -| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | +| Value | Description | Stability | +|---|---|---| +| `one` | member one | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `two` | member two | Experimental | +| `three` | member three | Deprecated: Removed. | +| `four` | member four | Deprecated: Removed. | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | -| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | -| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | | | `Required` | Deprecated: Removed. | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | Deprecated: Removed. | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | Experimental | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | | `one` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | -|---|---|---|---|---| -| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | `Required` | -| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | -| [`test.stable_attr`](stable_badges_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | `Required` | -| [`test.stable_enum_attr`](stable_badges_expected.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| `one` | `Recommended` | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`test.deprecated_experimental_attr`](stable_badges_expected.md) | boolean | | | `Required` | Deprecated: Removed. | +| [`test.deprecated_stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | Deprecated: Removed. | +| [`test.exp_attr`](stable_badges_expected.md) | boolean | | | `Required` | Experimental | +| [`test.stable_attr`](stable_badges_expected.md) | boolean | | | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`test.stable_enum_attr`](stable_badges_expected.md) | string | | `one` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `test.stable_enum_attr` MUST be one of the following: -| Value | Description | -|---|---| -| `one` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
member one | -| `two` | member two | -| `three` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member three | -| `four` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
member four | +| Value | Description | Stability | +|---|---|---| +| `one` | member one | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `two` | member two | Experimental | +| `three` | member three | Deprecated: Removed. | +| `four` | member four | Deprecated: Removed. | -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `stable_metric` | Histogram | `s` | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
stable_metric | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `stable_metric` | Histogram | `s` | stable_metric | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `experimental_metric` | Counter | `{e}` | experimental_metric | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `experimental_metric` | Counter | `{e}` | experimental_metric | Experimental | -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `deprecated_metric` | UpDownCounter | `{d}` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
deprecated_metric | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `deprecated_metric` | UpDownCounter | `{d}` | deprecated_metric | Deprecated: Removed. | \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md index 30656e50..a5f2b958 100644 --- a/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md +++ b/semantic-conventions/src/tests/data/markdown/wrong_semconv_id/input.md @@ -5,15 +5,15 @@ | Attribute name | Notes and examples | `Required`? | | :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | +| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` | Experimental | | `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | | `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | | `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | | `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | | `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. | -| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | +| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` | Experimental | | `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No | -| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | +| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` | Experimental | It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. diff --git a/semantic-conventions/src/tests/semconv/templating/test_markdown.py b/semantic-conventions/src/tests/semconv/templating/test_markdown.py index 0fd047d9..5c84c440 100644 --- a/semantic-conventions/src/tests/semconv/templating/test_markdown.py +++ b/semantic-conventions/src/tests/semconv/templating/test_markdown.py @@ -40,19 +40,16 @@ def testDeprecated(self): def testStableBadges(self): self.check( "markdown/stability/", - MarkdownOptions(enable_stable=True, use_badge=True), + MarkdownOptions( + disable_deprecated_badge=True, disable_experimental_badge=True + ), expected_name="stable_badges_expected.md", ) def testExperimentalAndStableBadges(self): self.check( "markdown/stability/", - MarkdownOptions( - enable_stable=True, - enable_experimental=True, - enable_deprecated=True, - use_badge=True, - ), + MarkdownOptions(), expected_name="all_badges_expected.md", ) @@ -245,7 +242,11 @@ def testColoredVisualDiffer(self): def check( self, input_dir: str, - options=MarkdownOptions(), + options=MarkdownOptions( + disable_experimental_badge=True, + disable_deprecated_badge=True, + disable_stable_badge=True, + ), *, expected_name="expected.md", extra_yaml_dirs: Sequence[str] = (), @@ -287,6 +288,7 @@ def do_render(): return ex.exception do_render() result = output.getvalue() + print(result) assert result == (dirpath / expected_name).read_text(encoding="utf-8") return None From 472bedb241f59fd3c8d51498bf5d7724da14a564 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Wed, 13 Mar 2024 22:34:21 +0100 Subject: [PATCH 26/31] Sort attribute tables by requirement level and attribute name (#260) Co-authored-by: Liudmila Molkova --- semantic-conventions/CHANGELOG.md | 2 + .../semconv/model/semantic_convention.py | 8 +- .../data/markdown/attribute_group/expected.md | 2 +- .../markdown/attribute_templates/expected.md | 2 +- .../data/markdown/deprecated/expected.md | 4 +- .../markdown/extend_constraint/expected.md | 12 +- .../tests/data/markdown/include/expected.md | 18 +-- .../tests/data/markdown/multiple/expected.md | 8 +- .../data/markdown/parameter_full/expected.md | 16 +-- .../parameter_remove_constraint/expected.md | 2 +- .../data/markdown/parameter_tag/expected.md | 2 +- .../markdown/parameter_tag_empty/expected.md | 16 +-- .../src/tests/data/markdown/ref/expected.md | 4 +- .../markdown/sampling_relevant/expected.md | 6 +- .../tests/data/markdown/single/expected.md | 4 +- .../tests/semconv/model/test_correct_parse.py | 124 +++++++++--------- 16 files changed, 118 insertions(+), 112 deletions(-) diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index b919527b..269a0cf5 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -18,6 +18,8 @@ Please update the changelog as part of any significant pull request. ([#271](https://github.com/open-telemetry/build-tools/pull/271)) - Add link to requirement levels definition from Markdown table title. ([#222](https://github.com/open-telemetry/build-tools/pull/222)) +- Sort attribute tables by requirement level and attribute name + ([#260](https://github.com/open-telemetry/build-tools/pull/260)) ## v0.23.0 diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py index 932cd578..54ed5c58 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py @@ -24,6 +24,7 @@ from opentelemetry.semconv.model.exceptions import ValidationError from opentelemetry.semconv.model.semantic_attribute import ( AttributeType, + RequirementLevel, SemanticAttribute, ) from opentelemetry.semconv.model.unit_member import UnitMember @@ -125,6 +126,11 @@ def _get_attributes(self, templates: Optional[bool]): if not hasattr(self, "attrs_by_name"): return [] + def comparison_key(attr): + if attr.requirement_level: + return attr.requirement_level.value, attr.fqn + return RequirementLevel.RECOMMENDED.value, attr.fqn + return sorted( [ attr @@ -132,7 +138,7 @@ def _get_attributes(self, templates: Optional[bool]): if templates is None or templates == AttributeType.is_template_type(attr.attr_type) ], - key=lambda attr: attr.fqn, + key=comparison_key, ) def __init__(self, group, strict_validation=True): diff --git a/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md b/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md index 09b038e6..e0f847c6 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md +++ b/semantic-conventions/src/tests/data/markdown/attribute_group/expected.md @@ -3,6 +3,6 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | Experimental | | `foo.qux` | int | Attribute 2 | `42` | `Conditionally Required` if available | Experimental | +| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md b/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md index 41599ce8..c0865815 100644 --- a/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md +++ b/semantic-conventions/src/tests/data/markdown/attribute_templates/expected.md @@ -3,8 +3,8 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `custom_http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | Experimental | | `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `custom_http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | Experimental | | `general.some_general_attribute.` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | `Recommended` | Experimental | | `referenced_http.request.referenced.header.` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/deprecated/expected.md b/semantic-conventions/src/tests/data/markdown/deprecated/expected.md index aac840f0..215a7d4a 100644 --- a/semantic-conventions/src/tests/data/markdown/deprecated/expected.md +++ b/semantic-conventions/src/tests/data/markdown/deprecated/expected.md @@ -4,11 +4,11 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | | `http.flavor` | string | Kind of HTTP protocol used [1] | `1.0` | `Recommended` | Deprecated: Use attribute `flavor_new` instead. | | `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | | `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | | `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Deprecated: Use attribute `status_description` instead. | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md b/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md index efa11282..d80bddae 100644 --- a/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md +++ b/semantic-conventions/src/tests/data/markdown/extend_constraint/expected.md @@ -36,19 +36,19 @@ Some database systems may allow a connection to switch to a different `db.user`, | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | Experimental | +| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Conditionally Required` [1] | Experimental | +| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [2] | Experimental | +| `db.connection_string` | string | The connection string used to connect to the database. [3] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | Experimental | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | Experimental | | `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | Experimental | -| `net.peer.port` | int | Remote port number. | `80`; `8080`; `443` | `Conditionally Required` [2] | Experimental | -| `net.transport` | string | Transport protocol used. See note below. | `IP.TCP` | `Conditionally Required` [3] | Experimental | -**[1]:** It is recommended to remove embedded credentials. +**[1]:** if using a port other than the default port for this DBMS. -**[2]:** if using a port other than the default port for this DBMS. +**[2]:** Recommended in general, required for in-process databases (`"inproc"`). -**[3]:** Recommended in general, required for in-process databases (`"inproc"`). +**[3]:** It is recommended to remove embedded credentials. **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/semantic-conventions/src/tests/data/markdown/include/expected.md b/semantic-conventions/src/tests/data/markdown/include/expected.md index 331d979f..b0462419 100644 --- a/semantic-conventions/src/tests/data/markdown/include/expected.md +++ b/semantic-conventions/src/tests/data/markdown/include/expected.md @@ -3,28 +3,28 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | Experimental | | `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | Experimental | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | See below | Experimental | | `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| [`http.server_name`](input_http.md) | string | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | See below | Experimental | | `http.recommended_attribute` | string | brief | `foo` | `Recommended` short note | Experimental | -| `http.recommended_attribute_long_note` | string | brief | `bar` | `Recommended` [1] | Experimental | +| `http.recommended_attribute_long_note` | string | brief | `bar` | `Recommended` [3] | Experimental | | `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | Experimental | -| [`http.server_name`](input_http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | Experimental | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | | `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | Experimental | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | Experimental | | `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | -**[1]:** some very long note that should be written under the semconv table - -**[2]:** This is an example +**[1]:** This is an example - of note - with list -**[3]:** This should be obtained via configuration. If this attribute can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). +**[2]:** This should be obtained via configuration. If this attribute can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). + +**[3]:** some very long note that should be written under the semconv table **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/semantic-conventions/src/tests/data/markdown/multiple/expected.md b/semantic-conventions/src/tests/data/markdown/multiple/expected.md index 8eacf0fa..3f8c1196 100644 --- a/semantic-conventions/src/tests/data/markdown/multiple/expected.md +++ b/semantic-conventions/src/tests/data/markdown/multiple/expected.md @@ -4,10 +4,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | | `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | | `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | | `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | @@ -17,10 +17,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | | `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | | `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | | `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md index 34b5b5ea..079264a5 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_full/expected.md @@ -3,25 +3,25 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | Experimental | | `faas.trigger` | string | Type of the trigger on which the function is executed. | `datasource` | `Required` | Experimental | -| [`http.client_ip`](http.md) | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [1] | `83.164.160.102` | `Recommended` | Experimental | -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | Experimental | | `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | Experimental | +| [`http.server_name`](http.md) | string | The primary server name of the matched virtual host. [1] | `example.com` | `Conditionally Required` [2] | Experimental | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | Experimental | +| `faas.execution` | string | The execution id of the current function execution. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | Experimental | +| [`http.client_ip`](http.md) | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [3] | `83.164.160.102` | `Recommended` | Experimental | | [`http.route`](http.md) | string | The matched route (path template). | `/users/:userID?` | `Recommended` | Experimental | | `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | See below | Experimental | -| [`http.server_name`](http.md) | string | The primary server name of the matched virtual host. [2] | `example.com` | `Conditionally Required` [3] | Experimental | -| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | Experimental | | `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | See below | Experimental | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | See below | Experimental | | `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` | Experimental | -**[1]:** This is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. +**[1]:** http.url is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. -**[2]:** http.url is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. +**[2]:** This should be obtained via configuration. If this attribute can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). -**[3]:** This should be obtained via configuration. If this attribute can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). +**[3]:** This is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md index b9b93999..7a6ef541 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_remove_constraint/expected.md @@ -3,8 +3,8 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | | `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | Experimental | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | Experimental | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | `Recommended` | Experimental | | `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md index 38ce374f..f79bb0e4 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag/expected.md @@ -3,8 +3,8 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | | `db.type` | string | Database type. For any SQL database, "sql". For others, the lower-case database category. | `sql` | `Required` | Experimental | +| `db.connection_string` | string | The connection string used to connect to the database. [1] | `Server=(localdb)\v11.0;Integrated Security=true;` | `Recommended` | Experimental | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | Experimental | | `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | See below | Experimental | | `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | See below | Experimental | diff --git a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md index bfdee699..05445f02 100644 --- a/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md +++ b/semantic-conventions/src/tests/data/markdown/parameter_tag_empty/expected.md @@ -4,19 +4,19 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | `db.dbms` | string | An identifier for the DBMS (database management system) product | `mssql` | `Conditionally Required` for `db.type="sql"` | Experimental | -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | Experimental | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [1] | `MSSQLSERVER` | `Recommended` | Experimental | -| `db.name` | string | If no tech-specific attribute is defined below, 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). [2] | `customers`; `master` | `Conditionally Required` [3] | Experimental | +| `db.name` | string | If no tech-specific attribute is defined below, 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). [1] | `customers`; `master` | `Conditionally Required` [2] | Experimental | | `db.operation` | string | The type of operation that is executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`. While it would semantically make sense to set this, e.g., to a SQL keyword like `SELECT` or `INSERT`, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property (the back end can do that if required). | `findAndModify` | `Conditionally Required` if `db.statement` is not applicable. | Experimental | -| `db.statement` | string | A database statement for the given database type. [4] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | Experimental | +| `db.statement` | string | A database statement for the given database type. [3] | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Conditionally Required` if applicable. | Experimental | +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the JDBC driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `Recommended` | Experimental | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/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. [4] | `MSSQLSERVER` | `Recommended` | Experimental | -**[1]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). +**[1]:** In some SQL databases, the database name to be used is called "schema name". Redis does not have a database name to used here. -**[2]:** In some SQL databases, the database name to be used is called "schema name". Redis does not have a database name to used here. +**[2]:** if applicable and no more-specific attribute is defined. -**[3]:** if applicable and no more-specific attribute is defined. +**[3]:** The value may be sanitized to exclude sensitive information. -**[4]:** The value may be sanitized to exclude sensitive information. +**[4]:** If setting a `db.mssql.instance_name`, `net.peer.port` is no longer required (but still recommended if non-standard). **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/semantic-conventions/src/tests/data/markdown/ref/expected.md b/semantic-conventions/src/tests/data/markdown/ref/expected.md index 2fade255..145d9267 100644 --- a/semantic-conventions/src/tests/data/markdown/ref/expected.md +++ b/semantic-conventions/src/tests/data/markdown/ref/expected.md @@ -3,11 +3,11 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`net.peer.name`](input_general.md) | string | override brief. [1] | `example.com` | `Opt-In` | Experimental | | [`net.peer.port`](input_general.md) | int | It describes the server port the client is connecting to | `80`; `8080`; `443` | `Required` | Experimental | | [`net.sock.peer.addr`](input_general.md) | string | Remote socket peer address. | `127.0.0.1`; `/tmp/mysql.sock` | `Required` | Experimental | -| [`net.sock.peer.port`](input_general.md) | int | Remote socket peer port. | `16456` | `Conditionally Required` | Experimental | | `rpc.service` | string | The service name, must be equal to the $service part in the span name. | `EchoService` | `Required` | Experimental | +| [`net.sock.peer.port`](input_general.md) | int | Remote socket peer port. | `16456` | `Conditionally Required` | Experimental | +| [`net.peer.name`](input_general.md) | string | override brief. [1] | `example.com` | `Opt-In` | Experimental | **[1]:** override note. diff --git a/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md b/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md index 1bf30abd..260fd99e 100644 --- a/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md +++ b/semantic-conventions/src/tests/data/markdown/sampling_relevant/expected.md @@ -3,10 +3,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `http.host` | string | . | `.` | `Recommended` | Experimental | | `http.method` | string | . | `GET` | `Required` | Experimental | -| `http.scheme` | string | . | `http` | `Recommended` | Experimental | | `http.status_code` | int | . | | `Conditionally Required` | Experimental | +| `http.host` | string | . | `.` | `Recommended` | Experimental | +| `http.scheme` | string | . | `http` | `Recommended` | Experimental | | `http.target` | string | . | `.` | `Recommended` | Experimental | | `http.url` | string | . [1] | `.` | `Recommended` | Experimental | | `http.user_agent` | string | . | `.` | `Recommended` | Experimental | @@ -18,8 +18,8 @@ The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): -* `http.host` * `http.method` +* `http.host` * `http.scheme` * `http.target` * `http.url` diff --git a/semantic-conventions/src/tests/data/markdown/single/expected.md b/semantic-conventions/src/tests/data/markdown/single/expected.md index 212af0eb..88ed09ac 100644 --- a/semantic-conventions/src/tests/data/markdown/single/expected.md +++ b/semantic-conventions/src/tests/data/markdown/single/expected.md @@ -4,10 +4,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | Experimental | | `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` | Experimental | -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Conditionally Required` | Experimental | | `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent. | Experimental | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` | Experimental | | `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` | Experimental | | `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` | Experimental | | `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` | Experimental | diff --git a/semantic-conventions/src/tests/semconv/model/test_correct_parse.py b/semantic-conventions/src/tests/semconv/model/test_correct_parse.py index 44604676..51ef2112 100644 --- a/semantic-conventions/src/tests/semconv/model/test_correct_parse.py +++ b/semantic-conventions/src/tests/semconv/model/test_correct_parse.py @@ -84,7 +84,7 @@ def test_faas(self): "prefix": "faas", "extends": "", "n_constraints": 0, - "attributes": ["faas.execution", "faas.trigger"], + "attributes": ["faas.trigger", "faas.execution"], } self.semantic_convention_check(list(semconv.models.values())[0], expected) expected = { @@ -94,9 +94,9 @@ def test_faas(self): "n_constraints": 0, "attributes": [ "faas.document.collection", - "faas.document.name", "faas.document.operation", "faas.document.time", + "faas.document.name", ], } self.semantic_convention_check(list(semconv.models.values())[1], expected) @@ -121,7 +121,7 @@ def test_faas(self): "prefix": "faas", "extends": "faas", "n_constraints": 0, - "attributes": ["faas.cron", "faas.time"], + "attributes": ["faas.time", "faas.cron"], } self.semantic_convention_check(list(semconv.models.values())[4], expected) @@ -166,11 +166,11 @@ def test_http(self): "extends": "", "n_constraints": 0, "attributes": [ + "http.method", + "http.status_code", "http.flavor", "http.host", - "http.method", "http.scheme", - "http.status_code", "http.status_text", "http.target", "http.url", @@ -429,11 +429,11 @@ def test_extends(self): "extends": "", "n_constraints": 0, "attributes": [ + "http.method", + "http.status_code", "http.flavor", "http.host", - "http.method", "http.scheme", - "http.status_code", "http.status_text", "http.target", "http.url", @@ -447,11 +447,11 @@ def test_extends(self): "extends": "http", "n_constraints": 1, "attributes": [ + "http.method", + "http.status_code", "http.flavor", "http.host", - "http.method", "http.scheme", - "http.status_code", "http.status_text", "http.target", "http.url", @@ -465,12 +465,12 @@ def test_extends(self): "extends": "http", "n_constraints": 1, "attributes": [ - "http.flavor", - "http.host", "http.method", - "http.scheme", "http.server_name", "http.status_code", + "http.flavor", + "http.host", + "http.scheme", "http.status_text", "http.target", "http.url", @@ -496,16 +496,14 @@ def test_include(self): "extends": "faas", "n_constraints": 2, "attributes": [ - # Parent - "faas.execution", - "faas.trigger", - # Include - "http.flavor", - "http.host", + "faas.trigger", # Parent "http.method", - "http.scheme", "http.server_name", "http.status_code", + "faas.execution", # Parent + "http.flavor", + "http.host", + "http.scheme", "http.status_text", "http.target", "http.url", @@ -667,61 +665,61 @@ def test_inherited_imported(self): self.assertEqual(models[2].semconv_id, "rpc") self.assertEqual(len(attrs), 4) - self.assertEqual(attrs[0].fqn, "net.peer.ip") - self.assertEqual(attrs[0].imported, True) + self.assertEqual(attrs[0].fqn, "rpc.service") + self.assertEqual(attrs[0].imported, False) self.assertEqual(attrs[0].inherited, False) self.assertEqual(attrs[0].ref, None) - self.assertEqual(attrs[1].fqn, "net.peer.name") + self.assertEqual(attrs[1].fqn, "net.peer.ip") self.assertEqual(attrs[1].imported, True) self.assertEqual(attrs[1].inherited, False) self.assertEqual(attrs[1].ref, None) - self.assertEqual(attrs[2].fqn, "net.peer.port") + self.assertEqual(attrs[2].fqn, "net.peer.name") self.assertEqual(attrs[2].imported, True) self.assertEqual(attrs[2].inherited, False) self.assertEqual(attrs[2].ref, None) - self.assertEqual(attrs[2].note, "not override") - self.assertEqual(attrs[3].fqn, "rpc.service") - self.assertEqual(attrs[3].imported, False) + self.assertEqual(attrs[3].fqn, "net.peer.port") + self.assertEqual(attrs[3].imported, True) self.assertEqual(attrs[3].inherited, False) self.assertEqual(attrs[3].ref, None) + self.assertEqual(attrs[3].note, "not override") # Extended - rpc.client attrs = models[3].attributes_and_templates self.assertEqual(models[3].semconv_id, "rpc.client") self.assertEqual(len(attrs), 6) - self.assertEqual(attrs[0].fqn, "http.method") - self.assertEqual(attrs[0].imported, True) + self.assertEqual(attrs[0].fqn, "net.peer.port") + self.assertEqual(attrs[0].imported, False) self.assertEqual(attrs[0].inherited, False) - self.assertEqual(attrs[0].ref, None) + self.assertEqual(attrs[0].ref, "net.peer.port") + self.assertEqual(attrs[0].brief, "override") + self.assertEqual(attrs[0].note, "not override") - self.assertEqual(attrs[1].fqn, "net.peer.ip") - self.assertEqual(attrs[1].imported, True) - self.assertEqual(attrs[1].inherited, True) + self.assertEqual(attrs[1].fqn, "rpc.client.name") + self.assertEqual(attrs[1].imported, False) + self.assertEqual(attrs[1].inherited, False) self.assertEqual(attrs[1].ref, None) - self.assertEqual(attrs[2].fqn, "net.peer.name") - self.assertEqual(attrs[2].imported, True) + self.assertEqual(attrs[2].fqn, "rpc.service") + self.assertEqual(attrs[2].imported, False) self.assertEqual(attrs[2].inherited, True) self.assertEqual(attrs[2].ref, None) - self.assertEqual(attrs[3].fqn, "net.peer.port") - self.assertEqual(attrs[3].imported, False) + self.assertEqual(attrs[3].fqn, "http.method") + self.assertEqual(attrs[3].imported, True) self.assertEqual(attrs[3].inherited, False) - self.assertEqual(attrs[3].ref, "net.peer.port") - self.assertEqual(attrs[3].brief, "override") - self.assertEqual(attrs[3].note, "not override") + self.assertEqual(attrs[3].ref, None) - self.assertEqual(attrs[4].fqn, "rpc.client.name") - self.assertEqual(attrs[4].imported, False) - self.assertEqual(attrs[4].inherited, False) + self.assertEqual(attrs[4].fqn, "net.peer.ip") + self.assertEqual(attrs[4].imported, True) + self.assertEqual(attrs[4].inherited, True) self.assertEqual(attrs[4].ref, None) - self.assertEqual(attrs[5].fqn, "rpc.service") - self.assertEqual(attrs[5].imported, False) + self.assertEqual(attrs[5].fqn, "net.peer.name") + self.assertEqual(attrs[5].imported, True) self.assertEqual(attrs[5].inherited, True) self.assertEqual(attrs[5].ref, None) @@ -740,40 +738,40 @@ def test_inherited_imported(self): self.assertEqual(models[5].semconv_id, "zz.rpc.client") self.assertEqual(len(attrs), 8) - self.assertEqual(attrs[0].fqn, "http.method") - self.assertEqual(attrs[0].imported, True) + self.assertEqual(attrs[0].fqn, "net.peer.port") + self.assertEqual(attrs[0].imported, False) self.assertEqual(attrs[0].inherited, True) - self.assertEqual(attrs[0].ref, None) + self.assertEqual(attrs[0].ref, "net.peer.port") + self.assertEqual(attrs[0].brief, "override") + self.assertEqual(attrs[0].note, "not override") - self.assertEqual(attrs[1].fqn, "net.peer.ip") - self.assertEqual(attrs[1].imported, True) + self.assertEqual(attrs[1].fqn, "rpc.client.name") + self.assertEqual(attrs[1].imported, False) self.assertEqual(attrs[1].inherited, True) self.assertEqual(attrs[1].ref, None) - self.assertEqual(attrs[2].fqn, "net.peer.name") - self.assertEqual(attrs[2].imported, True) - self.assertEqual(attrs[2].inherited, True) + self.assertEqual(attrs[2].fqn, "rpc.client.zz.attr") + self.assertEqual(attrs[2].imported, False) + self.assertEqual(attrs[2].inherited, False) self.assertEqual(attrs[2].ref, None) - self.assertEqual(attrs[3].fqn, "net.peer.port") + self.assertEqual(attrs[3].fqn, "rpc.service") self.assertEqual(attrs[3].imported, False) self.assertEqual(attrs[3].inherited, True) - self.assertEqual(attrs[3].ref, "net.peer.port") - self.assertEqual(attrs[3].brief, "override") - self.assertEqual(attrs[3].note, "not override") + self.assertEqual(attrs[3].ref, None) - self.assertEqual(attrs[4].fqn, "rpc.client.name") - self.assertEqual(attrs[4].imported, False) + self.assertEqual(attrs[4].fqn, "http.method") + self.assertEqual(attrs[4].imported, True) self.assertEqual(attrs[4].inherited, True) self.assertEqual(attrs[4].ref, None) - self.assertEqual(attrs[5].fqn, "rpc.client.zz.attr") - self.assertEqual(attrs[5].imported, False) - self.assertEqual(attrs[5].inherited, False) + self.assertEqual(attrs[5].fqn, "net.peer.ip") + self.assertEqual(attrs[5].imported, True) + self.assertEqual(attrs[5].inherited, True) self.assertEqual(attrs[5].ref, None) - self.assertEqual(attrs[6].fqn, "rpc.service") - self.assertEqual(attrs[6].imported, False) + self.assertEqual(attrs[6].fqn, "net.peer.name") + self.assertEqual(attrs[6].imported, True) self.assertEqual(attrs[6].inherited, True) self.assertEqual(attrs[6].ref, None) From 157bb4b8eb8aaa7c054155ec106e874056adf89e Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 15 Mar 2024 08:48:32 -0700 Subject: [PATCH 27/31] Merge code generation changes to main (#295) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Alexander Wert Co-authored-by: Josh Suereth Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/workflows/semconvgen.yml | 20 +- .gitignore | 3 + semantic-conventions/CHANGELOG.md | 12 + semantic-conventions/README.md | 354 ++++++++++++++++-- .../src/opentelemetry/semconv/main.py | 28 +- .../semconv/model/semantic_attribute.py | 6 + .../semconv/model/semantic_convention.py | 3 + .../opentelemetry/semconv/templating/code.py | 195 +++++++++- .../vnext.yaml | 2 +- .../compat/enum_member_removed/vnext.yaml | 2 +- .../compat/enum_member_removed/vprev.yaml | 2 +- .../data/compat/removed_attribute/vprev.yaml | 2 +- .../data/jinja/attribute_templates/template | 19 +- .../all/FifthAttributes.java | 27 ++ .../all/FirstAttributes.java | 18 + .../all/SecondAttributes.java | 8 + .../all/ThirdAttributes.java | 13 + .../group_by_root_namespace/attributes.yml | 94 +++++ .../attributes_and_metrics/First.java | 19 + .../attributes_and_metrics/SecondGroup.java | 19 + .../attributes_and_metrics/semconv.yml | 33 ++ .../attributes_and_metrics/template | 76 ++++ .../no_group_prefix/FooAttributes.java | 13 + .../no_group_prefix/OtherAttributes.java | 8 + .../attributes_no_group_prefix.yml | 23 ++ .../single_file/All.java | 34 ++ .../single_file/semconv.yml | 57 +++ .../single_file/template_single_file | 74 ++++ .../stable/ThirdAttributesStable.java | 8 + .../stable/template_only_stable | 49 +++ .../group_by_root_namespace/template_all | 57 +++ .../data/jinja/metrics/expected_metrics.java | 16 + .../tests/data/jinja/metrics/metrics_template | 12 + .../markdown/stability/badges_expected.md | 10 + .../markdown/stability/labels_expected.md | 10 + .../src/tests/data/yaml/metrics/metrics.yaml | 34 ++ .../src/tests/semconv/templating/test_code.py | 201 +++++++++- 37 files changed, 1481 insertions(+), 80 deletions(-) create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FifthAttributes.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FirstAttributes.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/SecondAttributes.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/ThirdAttributes.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes.yml create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/First.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/SecondGroup.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/semconv.yml create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/template create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/FooAttributes.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/OtherAttributes.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/attributes_no_group_prefix.yml create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/All.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/semconv.yml create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/template_single_file create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/ThirdAttributesStable.java create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/template_only_stable create mode 100644 semantic-conventions/src/tests/data/jinja/group_by_root_namespace/template_all create mode 100644 semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java create mode 100644 semantic-conventions/src/tests/data/jinja/metrics/metrics_template create mode 100644 semantic-conventions/src/tests/data/markdown/stability/badges_expected.md create mode 100644 semantic-conventions/src/tests/data/markdown/stability/labels_expected.md create mode 100644 semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml diff --git a/.github/workflows/semconvgen.yml b/.github/workflows/semconvgen.yml index fcc3834d..29d38234 100644 --- a/.github/workflows/semconvgen.yml +++ b/.github/workflows/semconvgen.yml @@ -2,9 +2,13 @@ name: Semantic Convention Generator on: push: tags: [ '**' ] - branches: [ main ] + branches: + - main + - 'feature/**' pull_request: - branches: [ main ] + branches: + - main + - 'feature/**' paths: - .github/workflows/semconvgen.yml - 'semantic-conventions/**' @@ -13,7 +17,7 @@ jobs: tests: runs-on: ubuntu-latest defaults: - run: + run: working-directory: semantic-conventions/ steps: - uses: actions/checkout@v4 @@ -69,3 +73,13 @@ jobs: else tag_and_push "${GITHUB_REF#"refs/tags/"}" fi + - name: Push the Dev Docker image + if: startsWith(github.ref, 'refs/heads/feature/') + run: | + echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + function tag_and_push { + docker tag semconvgen "otel/semconvgen:${1}" && docker push "otel/semconvgen:${1}" + } + TAG="${GITHUB_REF#"refs/heads/"}" + TAG="${TAG/"/"/"-"}" + tag_and_push "${TAG}" diff --git a/.gitignore b/.gitignore index 21e871b4..ff67d5cf 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ # Vim .swp + +# Python +*.whl diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index 269a0cf5..49ccc6f3 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -18,6 +18,18 @@ Please update the changelog as part of any significant pull request. ([#271](https://github.com/open-telemetry/build-tools/pull/271)) - Add link to requirement levels definition from Markdown table title. ([#222](https://github.com/open-telemetry/build-tools/pull/222)) +- Added code-generation mode that groups attributes by the root namespace and ability to write each group into individual file. + [BREAKING] The `--file-per-group ` that used to create multiple directories (like `output//file`) now generates + multiple files (`output/file`) instead. + ([#243](https://github.com/open-telemetry/build-tools/pull/243)) +- Update `semconvgen.yml` workflow to run on feature/* branches. + ([#256](https://github.com/open-telemetry/build-tools/pull/256)) +- Allow --output to be templatized when generating multiple files. + ([#263](https://github.com/open-telemetry/build-tools/pull/263)) +- Add `metrics` to the context of non-scoped code generation + ([#270](https://github.com/open-telemetry/build-tools/pull/270)) +- Add `enum_attributes` to the context, adds `print_member_value` helper + ([#266](https://github.com/open-telemetry/build-tools/pull/266)) - Sort attribute tables by requirement level and attribute name ([#260](https://github.com/open-telemetry/build-tools/pull/260)) diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index cad1bf5a..4be014a2 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -91,6 +91,38 @@ semantic conventions that have the tag `network`. `` will print a table describing a single metric `http.server.active_requests`. +## Version compatibility check + +You can check compatibility between the local one specified with `--yaml-root` and specific OpenTelemetry semantic convention version using the following command: + +```bash +docker run --rm otel/semconvgen --yaml-root {yaml_folder} compatibility --previous-version {semconv version} +``` + +The `{semconv version}` (e.g. `1.24.0`) is the previously released version of semantic conventions. + +The following checks are performed: + +- On all attributes and metrics (experimental and stable): + - attributes and metrics must not be removed + - enum attribute members must not be removed + +- On stable attributes and attribute templates: + - stability must not be changed + - the type of attribute must not be changed + - enum attribute: type of value must not be changed + +- On stable enum attribute members: + - stability must not be changed + - `id` and `value` must not be changed + +- On stable metrics: + - stability must not be changed + - instrument and unit must not be changed + - new attributes should not be added. + This check does not take into account opt-in attributes. Adding new attributes to metric is not always breaking, + so it's considered non-critical and it's possible to suppress it with `--ignore-warnings` + ## Code Generator The image supports [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) templates to generate code from the models. @@ -104,55 +136,331 @@ By default, all models are fed into the specified template at once, i.e. only a This is helpful to generate constants for the semantic attributes, [example from opentelemetry-java](https://github.com/open-telemetry/semantic-conventions-java#generating-semantic-conventions). If the parameter `--file-per-group {pattern}` is set, a single yaml model is fed into the template -and the value of `pattern` is resolved from the model and attached as prefix to the output argument. +and the value of `pattern` is resolved from the model and may be used in the output argument. This way, multiple files are generated. The value of `pattern` can be one of the following: - `semconv_id`: The id of the semantic convention. - `prefix`: The prefix with which all attributes starts with. - `extends`: The id of the parent semantic convention. +- `root_namespace`: The root namespace of attribute to group by. + +The `--output` parameter, when `--file-per-group` is used is evaluated as a template. The following variables are provided to output: + +- `prefix`: A prefix name for files, determined from the grouping. e.g. `http`, `database`, `user-agent`. +- `pascal_prefix`: A Pascal-case prefix name for files. e.g. `Http`, `Database`, `UserAgent`. +- `camel_prefix`: A camel-case prefix name for files. e.g. `http`, `database`, `userAgent`. +- `snake_prefix`: A snake-case prefix name for files. e.g. `http`, `database`, `user_agent`. + +For example, you could do the following: + +```bash +docker run --rm \ + -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/trace:/source \ + -v ${SCRIPT_DIR}/templates:/templates \ + -v ${ROOT_DIR}/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/:/output \ + otel/semconvgen:$GENERATOR_VERSION \ + --yaml-root /source \ + code \ + --template /templates/SemanticAttributes.java.j2 \ + --file-per-group root_namespace \ + --output "/output/{{pascal_prefix}}Attributes.java" \ + ...other parameters... +``` Finally, additional value can be passed to the template in form of `key=value` pairs separated by comma using the `--parameters [{key=value},]+` or `-D` flag. +Generating code from older versions of semantic conventions with new tooling is, in general, not supported. +However in some cases minor incompatibilities in semantic conventions can be ignored by setting `--strict-validation` flag to `false` + +```bash +docker run --rm \ + otel/semconvgen:$GENERATOR_VERSION \ + --yaml-root /source \ + `--strict-validation false` + code \ + ...other parameters... +``` + ### Customizing Jinja's Whitespace Control -The image also supports customising +The image also supports customizing [Whitespace Control in Jinja templates](https://jinja.palletsprojects.com/en/3.1.x/templates/#whitespace-control) via the additional flag `--trim-whitespace`. Providing the flag will enable both `lstrip_blocks` and `trim_blocks`. ### Enabling/disabling support for colored diffs in error messages The `COLORED_DIFF` environment variable is set in the `semantic-conventions` `Dockerfile`. When this environment varibale is set, errors related to reformatting tables will show a "colored diff" using standard ANSI control characters. While this should be supported natively in any modern terminal environment, you may unset this variable if issues arise. Doing so will enable a "fall back" of non-colored inline diffs showing what was "added" and what was "removed", followed by the exact tokens added/removed encased in single quotes. -## Version compatibility check +### Accessing Semantic Conventions in the template + +When the template is processed, it has access to a set of variables that depends on the `--file-per-group` value (or lack of it). +You can access properties of these variables and call Jinja or Python functions defined on them. + +#### Single file (no `--file-per-group` pattern is provided) + +Processes all parsed semantic conventions + +- `semconvs` - the dictionary containing parsed `BaseSemanticConvention` instances with semconv `id` as a key +- `attributes_and_templates` - the dictionary containing all attributes (including template ones) grouped by their root namespace. + Each element in the dictionary is a list of attributes that share the same root namespace. Attributes that don't have a namespace + appear under `""` key. Attributes and templates are sorted by attribute name. +- `attributes` - the list of all attributes from all parsed semantic conventions. Does not include template attributes. +- `attribute_templates` - the list of all attribute templates from all parsed semantic conventions. +- `metrics` - the list of all metric semantic conventions sorted by metric name. + +#### The `root_namespace` pattern + +Processes a single namespace and is called for each namespace detected. + +- `attributes_and_templates` - the list containing all attributes (including template ones) in the given root namespace. Attributes are sorted by their name. +- `enum_attributes` - the list containing all enum attributes in the given root namespace. Attributes are sorted by their name. +- `root_namespace` - the root namespace being processed. + +#### Other patterns + +Processes a single pattern value and is called for each distinct value. + +- `semconv` - the instance of parsed `BaseSemanticConvention` being processed. + +### Filtering and mapping + +Jinja templates has a notion of [filters](https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-filters) allowing to transform objects or filter lists. + +Semconvgen supports the following additional filters to simplify common operations in templates. + +#### `SemanticAttribute` operations + +1. `is_definition` - Checks if the attribute is the original definition of the attribute and not a reference. +2. `is_deprecated` - Checks if the attribute is deprecated. The same check can also be done with `(attribute.stability | string()) == "StabilityLevel.DEPRECATED"` +3. `is_experimental` - Checks if the attribute is experimental. The same check can also be done with `(attribute.stability | string()) == "StabilityLevel.EXPERIMENTAL"` +4. `is_stable` - Checks if the attribute is experimental. The same check can also be done with `(attribute.stability | string()) == "StabilityLevel.STABLE"` +5. `is_template` - Checks if the attribute is a template attribute. +6. `attribute | print_member_value(member)` - Applies to enum attributes only and takes `EnumMember` as a parameter. Prints value of a given enum member as a constant - strings are quoted, integers are printed as is. + +#### String operations + +1. `first_up` - Upper-cases the first character in the string. Does not modify anything else +2. `regex_replace(text, pattern, replace)` - Makes regex-based replace in `text` string using `pattern`` +3. `to_camelcase` - Converts a string to camel case (using `.` and `_` as words delimiter in the original string). + The first character of every word is upper-cased, other characters are lower-cased. E.g. `foo.bAR_baz` becomes `fooBarBaz` +4. `to_const_name` - Converts a string to Python or Java constant name (SNAKE_CASE) replacing `.` or `-` with `_`. E.g. + `foo.bAR-baz` becomes `FOO_BAR_BAZ`. +5. `to_doc_brief` - Trims whitespace and removes dot at the end. E.g. ` Hello world.\t` becomes `Hello world` + +#### `BaseSemanticConvention` operations -You can check compatibility between the local one specified with `--yaml-root` and sepcific OpenTelemetry semantic convention version using the following command: +1. `is_metric` - Checks if semantic convention describes a metric. + +### Examples + +#### Generate all attributes in files grouped by root namespace + +First, we should iterate over all attributes. +```jinja +{%- for attribute in attributes_and_templates %} +... +{%- endfor %} +``` + +Now, for each attribute we want to generate constant declaration like + +```python +SERVER_ADDRESS = "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. +""" + +we can achieve it with the following template: + +```jinja +{{attribute.fqn | to_const_name}} = "{{attribute.fqn}}" +""" +{{attribute.brief | to_doc_brief}}. +{%- if attribute.note %} +Note: {{attribute.note | to_doc_brief | indent}}. +{%- endif %} +""" +``` + +We should also annotate deprecated attributes and potentially generate template attributes differently. +Here's a full example: + +```jinja +{%- for attribute in attributes_and_templates %} + +{% if attribute | is_template %} +{{attribute.fqn | to_const_name}}_TEMPLATE = "{{attribute.fqn}}" +{%- else %} +{{attribute.fqn | to_const_name}} = "{{attribute.fqn}}" +{%- endif %} +""" +{{attribute.brief | to_doc_brief}}. +{%- if attribute.note %} +Note: {{attribute.note | to_doc_brief | indent}}. +{%- endif %} + +{%- if attribute | is_deprecated %} +Deprecated: {{attribute.deprecated | to_doc_brief}}. +{%- endif %} +""" + +{%- endfor %} +``` + +#### Filter attributes based on stability + +It's possible to split attributes into stable and unstable for example to ship them in different artifacts or namespaces. + +You can achieve it by running code generation twice with different filters and output destinations. + +Here's an example of how to keep one template file for both: + +```jinja +{%- set filtered_attributes = attributes_and_templates | select(filter) | list %} +{%- for attribute in attributes_and_templates %} +... +{%- endfor %} +``` + +Here we apply a Jinja test named `filter` which we can define in the generation script: ```bash -docker run --rm otel/semconvgen --yaml-root {yaml_folder} compatibility --previous-version {semconv version} +docker run --rm \ + -v ${SCRIPT_DIR}/semantic-conventions/model:/source \ + -v ${SCRIPT_DIR}/templates:/templates \ + -v ${ROOT_DIR}/opentelemetry-semantic-conventions/src/opentelemetry/semconv/:/output \ + otel/semconvgen:$OTEL_SEMCONV_GEN_IMG_VERSION \ + -f /source code \ + --template /templates/semantic_attributes.j2 \ + --output /output/{{snake_prefix}}_attributes.py \ + --file-per-group root_namespace \ + -Dfilter=is_stable ``` -The `{semconv version}` (e.g. `1.24.0`) is the previously released version of semantic conventions. +Here we run the generation with `filter` variable set to `is_stable`, which resolves to `attributes_and_templates | select("is_stable")` expression. +It will apply `is_stable` custom function to each attribute and collect only stable ones. -Following checks are performed +We can also generate experimental attributes by changing the destination path and filter value: -- On all attributes and metrics (experimental and stable): - - attributes and metrics must not be removed - - enum attribute members must not be removed +```bash +docker run --rm \ + -v ${SCRIPT_DIR}/semantic-conventions/model:/source \ + -v ${SCRIPT_DIR}/templates:/templates \ + -v ${ROOT_DIR}/opentelemetry-semantic-conventions/src/opentelemetry/semconv/:/output \ + otel/semconvgen:$OTEL_SEMCONV_GEN_IMG_VERSION \ + -f /source code \ + --template /templates/semantic_attributes.j2 \ + --output /output/experimental/{{snake_prefix}}_attributes.py \ + --file-per-group root_namespace \ + -Dfilter=is_experimental +``` -- On stable attributes and attribute templates: - - stability must not be changed - - the type of attribute must not be changed - - enum attribute: type of value must not be changed +#### Generate enum definitions -- On stable enum attribute members: - - stability must not be changed - - `id` and `value` must not be changed +Enum attribute members could be generated in the following way: -- On stable metrics: - - stability must not be changed - - instrument and unit must not be changed - - new attributes should not be added. - This check does not take into account opt-in attributes. Adding new attributes to metric is not always breaking, - so it's considered non-critical and it's possible to suppress it with `--ignore-warnings` +```jinja +{%- for attribute in enum_attributes %} + +{%- set class_name = attribute.fqn | to_camelcase(True) ~ "Values" %} +{%- set type = attribute.attr_type.enum_type %} +class {{class_name}}(Enum): + {%- for member in attribute.attr_type.members %} + {{ member.member_id | to_const_name }} = {{ attribute | print_member_value(member) }} + """{{member.brief | to_doc_brief}}.""" + {% endfor %} +{% endfor %} +``` + +resulting in en enum like this: + +```python +class NetworkTransportValues(Enum): + TCP = "tcp" + """TCP.""" + + UDP = "udp" + """UDP.""" + + PIPE = "pipe" + """Named or anonymous pipe.""" + + UNIX = "unix" + """Unix domain socket.""" +``` + +#### Exclude certain namespaces + +In some cases you might want to skip certain namespaces. For example, JVM attribute and metric definitions might not be very useful in Python application. + +You can create a list of excluded namespaces and pass it over to the template as parameter (or hardcode it): + +```jinja +{%- if root_namespace not in ("jvm", "dotnet") %} +... +{%- endif %} +``` + +If result of the rendering is empty string, code generator does not store it. + +#### Generate metric definitions + +You can generate metric names as constants, but could also generate method definitions that create instruments and populate name, description, and unit: + +```python +""" +Duration of HTTP client requests +""" +@staticmethod +def create_http_client_request_duration(meter: Meter) -> Histogram: + return meter.create_histogram( + name="http.client.request.duration", + description="Duration of HTTP client requests.", + unit="s", + ) +``` + +Since metric types (like `Histogram`) and factory methods (like `create_histogram`) depend on the language, it's necessary to define mappings in the template. + +For example, this is a macro rendering Python instrument type name based on the semantic convention type: + +```jinja +{%- macro to_python_instrument_type(instrument) -%} + {%- if instrument == "counter" -%} + Counter + {%- elif instrument == "histogram" -%} + Histogram + {%- elif instrument == "updowncounter" -%} + UpDownCounter + {%- elif instrument == "gauge" -%} + ObservableGauge + {%- endif -%} +{%- endmacro %} +``` + +We'd need a very similar one for factory method. + +This is the template that generates above metric definition: + +```java + """ + {{metric.brief | to_doc_brief}} + """ + @staticmethod + {%- if metric.instrument == "gauge" %} + def create_{{ metric.metric_name | replace(".", "_") }}(meter: Meter, callback: Sequence[Callable]) -> {{to_python_instrument_type(metric.instrument)}}: + {%- else %} + def create_{{ metric.metric_name | replace(".", "_") }}(meter: Meter) -> {{to_python_instrument_type(metric.instrument)}}: + {%- endif %} + return meter.create_{{to_python_instrument_factory(metric.instrument)}}( + name="{{ metric.metric_name }}", + {%- if metric.instrument == "gauge" %} + callback=callback, + {%- endif %} + description="{{ metric.brief }}", + unit="{{ metric.unit }}", + ) +``` diff --git a/semantic-conventions/src/opentelemetry/semconv/main.py b/semantic-conventions/src/opentelemetry/semconv/main.py index c3f9b708..aa1a3eea 100644 --- a/semantic-conventions/src/opentelemetry/semconv/main.py +++ b/semantic-conventions/src/opentelemetry/semconv/main.py @@ -35,14 +35,14 @@ def parse_semconv( - yaml_root: str, exclude: str, debug: bool, parser + yaml_root: str, exclude: str, debug: bool, strict_validation: bool, parser ) -> SemanticConventionSet: semconv = SemanticConventionSet(debug) files = find_yaml(yaml_root, exclude) for file in sorted(files): if not file.endswith(".yaml") and not file.endswith(".yml"): parser.error(f"{file} is not a yaml file.") - semconv.parse(file, False) + semconv.parse(file, strict_validation) semconv.finish() if semconv.has_error(): sys.exit(1) @@ -72,7 +72,9 @@ def main(): parser = setup_parser() args = parser.parse_args() check_args(args, parser) - semconv = parse_semconv(args.yaml_root, args.exclude, args.debug, parser) + semconv = parse_semconv( + args.yaml_root, args.exclude, args.debug, args.strict_validation, parser + ) semconv_filter = parse_only_filter(args.only, parser) filter_semconv(semconv, semconv_filter) if len(semconv.models) == 0: @@ -103,7 +105,9 @@ def process_markdown(semconv, args): def check_compatibility(semconv, args, parser): prev_semconv_path = download_previous_version(args.previous_version) - prev_semconv = parse_semconv(prev_semconv_path, args.exclude, args.debug, parser) + prev_semconv = parse_semconv( + prev_semconv_path, args.exclude, args.debug, args.strict_validation, parser + ) compatibility_checker = CompatibilityChecker(semconv, prev_semconv) problems = compatibility_checker.check() @@ -154,7 +158,8 @@ def add_code_parser(subparsers): parser.add_argument( "--output", "-o", - help="Specify the output file for the code generation.", + help="Specify the output file name for the code generation. " + "See also `--file-per-group` on how to generate multiple files.", type=str, required=True, ) @@ -168,8 +173,10 @@ def add_code_parser(subparsers): parser.add_argument( "--file-per-group", dest="pattern", - help="Each Semantic Convention is processed by the template and store in a different file. PATTERN is expected " - "to be the name of a SemanticConvention field and is prepended as a prefix to the output argument", + help="Semantic conventions are processed by the template and stored in a different file. " + "File names start with a 'pattern' and end with the name specified in the 'output' argument. " + "The 'pattern' can either match 'root_namespace' to group attributes by the root namespace or " + "match a name of Semantic Convention property which value will be used as a file name prefix.", type=str, ) parser.add_argument( @@ -298,6 +305,13 @@ def setup_parser(): nargs="*", help="YAML file containing a Semantic Convention", ) + parser.add_argument( + "--strict-validation", + help="Fail on non-critical yaml validation issues.", + required=False, + default=True, + action="store_false", + ) subparsers = parser.add_subparsers(dest="flavor") add_code_parser(subparsers) add_md_parser(subparsers) diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py index 32996f9d..9a53ed7e 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py @@ -59,6 +59,7 @@ class SemanticAttribute: sampling_relevant: bool note: str position: List[int] + root_namespace: str inherited: bool = False imported: bool = False @@ -211,6 +212,10 @@ def parse( fqn = fqn.strip() parsed_brief = TextWithLinks(brief.strip() if brief else "") parsed_note = TextWithLinks(note.strip()) + + namespaces = fqn.split(".") + root_namespace = namespaces[0] if len(namespaces) > 1 else "" + attr = SemanticAttribute( fqn=fqn, attr_id=attr_id, @@ -226,6 +231,7 @@ def parse( sampling_relevant=sampling_relevant, note=parsed_note, position=position, + root_namespace=root_namespace, ) if attr.fqn in attributes: position = position_data[list(attribute)[0]] diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py index 54ed5c58..b9893945 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py @@ -272,6 +272,9 @@ def __init__(self, group, strict_validation=True): self.metric_name = group.get("metric_name") self.unit = group.get("unit") self.instrument = group.get("instrument") + + namespaces = self.metric_name.split(".") + self.root_namespace = namespaces[0] if len(namespaces) > 1 else "" self.validate() def validate(self): diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/code.py b/semantic-conventions/src/opentelemetry/semconv/templating/code.py index b8865291..721a8462 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/code.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/code.py @@ -21,12 +21,17 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape from opentelemetry.semconv.model.semantic_attribute import ( + AttributeType, + EnumAttributeType, + EnumMember, RequirementLevel, SemanticAttribute, + StabilityLevel, TextWithLinks, ) from opentelemetry.semconv.model.semantic_convention import ( BaseSemanticConvention, + MetricSemanticConvention, SemanticConventionSet, ) from opentelemetry.semconv.model.utils import ID_RE @@ -122,6 +127,15 @@ def to_doc_brief(doc_string: typing.Optional[str]) -> str: return doc_string +def print_member_value(attr: SemanticAttribute, member: EnumMember) -> str: + if ( + isinstance(attr.attr_type, EnumAttributeType) + and attr.attr_type.enum_type == "string" + ): + return f'"{member.value}"' + return str(member.value) + + def to_html_links(doc_string: typing.Optional[typing.Union[str, TextWithLinks]]) -> str: if doc_string is None: return "" @@ -160,10 +174,43 @@ def to_camelcase(name: str, first_upper=False) -> str: return first + "".join(word.capitalize() for word in rest) +def to_snake_case(name): + name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name) + name = re.sub("__([A-Z])", r"_\1", name) + name = re.sub("([a-z0-9])([A-Z])", r"\1_\2", name) + return name.lower() + + +def first_up(name: str) -> str: + return name[0].upper() + name[1:] + + +def is_stable(obj: typing.Union[SemanticAttribute, BaseSemanticConvention]) -> bool: + return obj.stability == StabilityLevel.STABLE + + def is_deprecated(obj: typing.Union[SemanticAttribute, BaseSemanticConvention]) -> bool: return obj.deprecated is not None +def is_experimental( + obj: typing.Union[SemanticAttribute, BaseSemanticConvention] +) -> bool: + return obj.stability is None or obj.stability == StabilityLevel.EXPERIMENTAL + + +def is_definition(attribute: SemanticAttribute) -> bool: + return attribute.is_local and attribute.ref is None + + +def is_template(attribute: SemanticAttribute) -> bool: + return AttributeType.is_template_type(str(attribute.attr_type)) + + +def is_metric(semconv: BaseSemanticConvention) -> bool: + return isinstance(semconv, MetricSemanticConvention) + + class CodeRenderer: pattern = f"{{{ID_RE.pattern}}}" @@ -196,6 +243,8 @@ def get_data_single_file( "semconvs": semconvset.models, "attributes": semconvset.attributes(), "attribute_templates": semconvset.attribute_templates(), + "attributes_and_templates": self._grouped_attribute_definitions(semconvset), + "metrics": self._all_metrics_definitions(semconvset), } data.update(self.parameters) return data @@ -214,20 +263,43 @@ def setup_environment(env: Environment, trim_whitespace: bool): env.filters["to_const_name"] = to_const_name env.filters["merge"] = merge env.filters["to_camelcase"] = to_camelcase + env.filters["first_up"] = first_up env.filters["to_html_links"] = to_html_links env.filters["regex_replace"] = regex_replace env.filters["render_markdown"] = render_markdown + env.filters["print_member_value"] = print_member_value env.filters["is_deprecated"] = is_deprecated + env.filters["is_definition"] = is_definition + env.filters["is_stable"] = is_stable + env.filters["is_experimental"] = is_experimental + env.filters["is_template"] = is_template + env.filters["is_metric"] = is_metric + env.tests["is_stable"] = is_stable + env.tests["is_experimental"] = is_experimental env.tests["is_deprecated"] = is_deprecated + env.tests["is_definition"] = is_definition + env.tests["is_template"] = is_template + env.tests["is_metric"] = is_metric env.trim_blocks = trim_whitespace env.lstrip_blocks = trim_whitespace @staticmethod - def prefix_output_file(file_name, pattern, semconv): - basename = os.path.basename(file_name) - dirname = os.path.dirname(file_name) - value = getattr(semconv, pattern) - return os.path.join(dirname, to_camelcase(value, True), basename) + def prefix_output_file(env, file_name, prefix): + # We treat incoming file names as a pattern. + # We allow will give them access to the same jinja model as file creation + # and we'll make sure a few things are available there, specifically: + # pascal case, camel case and snake case + data = { + "prefix": prefix, + "pascal_prefix": to_camelcase(prefix, True), + "camel_prefix": to_camelcase(prefix, False), + "snake_prefix": to_snake_case(prefix), + } + template = env.from_string(file_name) + full_name = template.render(data) + dirname = os.path.dirname(full_name) + basename = os.path.basename(full_name) + return os.path.join(dirname, basename) def render( self, @@ -243,19 +315,106 @@ def render( autoescape=select_autoescape([""]), ) self.setup_environment(env, self.trim_whitespace) - if pattern: - for semconv in semconvset.models.values(): - output_name = self.prefix_output_file(output_file, pattern, semconv) - data = self.get_data_multiple_files(semconv, template_path) - template = env.get_template(file_name, globals=data) - template.globals["now"] = datetime.datetime.utcnow() - template.globals["version"] = os.environ.get("ARTIFACT_VERSION", "dev") - template.globals["RequirementLevel"] = RequirementLevel - template.stream(data).dump(output_name) + if pattern == "root_namespace": + self._render_group_by_root_namespace( + semconvset, template_path, file_name, output_file, env + ) + elif pattern is not None: + self._render_by_pattern( + semconvset, template_path, file_name, output_file, pattern, env + ) else: data = self.get_data_single_file(semconvset, template_path) template = env.get_template(file_name, globals=data) - template.globals["now"] = datetime.datetime.utcnow() - template.globals["version"] = os.environ.get("ARTIFACT_VERSION", "dev") - template.globals["RequirementLevel"] = RequirementLevel - template.stream(data).dump(output_file) + self._write_template_to_file(template, data, output_file) + + def _render_by_pattern( + self, + semconvset: SemanticConventionSet, + template_path: str, + file_name: str, + output_file: str, + pattern: str, + env: Environment, + ): + for semconv in semconvset.models.values(): + prefix = getattr(semconv, pattern) + output_name = self.prefix_output_file(env, output_file, prefix) + data = self.get_data_multiple_files(semconv, template_path) + template = env.get_template(file_name, globals=data) + self._write_template_to_file(template, data, output_name) + + def _render_group_by_root_namespace( + self, + semconvset: SemanticConventionSet, + template_path: str, + file_name: str, + output_file: str, + env: Environment, + ): + attribute_and_templates = self._grouped_attribute_definitions(semconvset) + metrics = self._grouped_metric_definitions(semconvset) + for ns, attribute_and_templates in attribute_and_templates.items(): + sanitized_ns = ns if ns != "" else "other" + output_name = self.prefix_output_file(env, output_file, sanitized_ns) + + data = { + "template": template_path, + "attributes_and_templates": attribute_and_templates, + "enum_attributes": [a for a in attribute_and_templates if a.is_enum], + "metrics": metrics.get(ns) or [], + "root_namespace": sanitized_ns, + } + data.update(self.parameters) + + template = env.get_template(file_name, globals=data) + self._write_template_to_file(template, data, output_name) + + def _grouped_attribute_definitions(self, semconvset): + grouped_attributes = {} + for semconv in semconvset.models.values(): + for attr in semconv.attributes_and_templates: + if not is_definition(attr): # skip references + continue + if attr.root_namespace not in grouped_attributes: + grouped_attributes[attr.root_namespace] = [] + grouped_attributes[attr.root_namespace].append(attr) + + for ns in grouped_attributes: + grouped_attributes[ns] = sorted(grouped_attributes[ns], key=lambda a: a.fqn) + return grouped_attributes + + def _grouped_metric_definitions(self, semconvset): + grouped_metrics = {} + for semconv in semconvset.models.values(): + if not is_metric(semconv): + continue + + if semconv.root_namespace not in grouped_metrics: + grouped_metrics[semconv.root_namespace] = [] + + grouped_metrics[semconv.root_namespace].append(semconv) + + for ns in grouped_metrics: + grouped_metrics[ns] = sorted( + grouped_metrics[ns], key=lambda a: a.metric_name + ) + return grouped_metrics + + def _all_metrics_definitions(self, semconvset): + all_metrics = [] + for semconv in semconvset.models.values(): + if is_metric(semconv): + all_metrics.append(semconv) + + return sorted(all_metrics, key=lambda a: a.metric_name) + + def _write_template_to_file(self, template, data, output_name): + template.globals["now"] = datetime.datetime.utcnow() + template.globals["version"] = os.environ.get("ARTIFACT_VERSION", "dev") + template.globals["RequirementLevel"] = RequirementLevel + + content = template.render(data) + if content != "": + with open(output_name, "w", encoding="utf-8") as f: + f.write(content) diff --git a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml index d83717a1..de6b05df 100644 --- a/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml @@ -22,4 +22,4 @@ groups: brief: "Request headers." note: "Request headers note." examples: '`first.fifth_attr.bar=["foo"]`' - stability: experimental \ No newline at end of file + stability: experimental diff --git a/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml b/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml index 2c6eb19d..3b07b235 100644 --- a/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_member_removed/vnext.yaml @@ -15,4 +15,4 @@ groups: brief: "third attribute" note: "third attribute note" examples: ["two"] - stability: experimental \ No newline at end of file + stability: experimental diff --git a/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml b/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml index 9ec933d4..db094829 100644 --- a/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/enum_member_removed/vprev.yaml @@ -15,4 +15,4 @@ groups: brief: "third attribute" note: "third attribute note" examples: ["one"] - stability: experimental \ No newline at end of file + stability: experimental diff --git a/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml b/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml index 5d3189d3..c78f2a4f 100644 --- a/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml +++ b/semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml @@ -21,4 +21,4 @@ groups: type: template[string[]] brief: "request headers" examples: '`first.fifth_attr.foo=["bar"]`' - stability: experimental \ No newline at end of file + stability: experimental diff --git a/semantic-conventions/src/tests/data/jinja/attribute_templates/template b/semantic-conventions/src/tests/data/jinja/attribute_templates/template index e32d00a3..c6b139df 100644 --- a/semantic-conventions/src/tests/data/jinja/attribute_templates/template +++ b/semantic-conventions/src/tests/data/jinja/attribute_templates/template @@ -25,22 +25,13 @@ {%- elif type == "double" -%} doubleKey {%- else -%} - {{lowerFirst(type)}}Key + {{ type | to_camelcase(False)}}Key {%- endif -%} {%- endmacro %} -{%- macro print_value(type, value) -%} - {{ "\"" if type == "String"}}{{value}}{{ "\"" if type == "String"}} -{%- endmacro %} -{%- macro upFirst(text) -%} - {{ text[0]|upper}}{{text[1:] }} -{%- endmacro %} -{%- macro lowerFirst(text) -%} - {{ text[0]|lower}}{{text[1:] }} -{%- endmacro %} package io.opentelemetry.instrumentation.api.attributetemplates; class AttributesTemplate { -{%- for attribute_template in attribute_templates if attribute_template.is_local and not attribute_template.ref %} +{%- for attribute_template in attribute_templates | select("is_definition") %} /** * {{attribute_template.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} @@ -57,9 +48,9 @@ class AttributesTemplate { {%- if attribute_template | is_deprecated %} @Deprecated {%- endif %} - public static final AttributeKey<{{upFirst(to_java_return_type(attribute_template.instantiated_type | string))}}> {{attribute_template.fqn | to_const_name}} = {{to_java_key_type(attribute_template.instantiated_type | string)}}("{{attribute_template.fqn}}"); + public static final AttributeKey<{{ to_java_return_type(attribute_template.instantiated_type | string) | to_camelcase(True)}}> {{attribute_template.fqn | to_const_name}} = {{to_java_key_type(attribute_template.instantiated_type | string)}}("{{attribute_template.fqn}}"); {%- endfor %} -{%- for attribute in attributes if attribute.is_local and not attribute.ref %} +{%- for attribute in attributes | select("is_definition") %} /** * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} @@ -76,6 +67,6 @@ class AttributesTemplate { {%- if attribute | is_deprecated %} @Deprecated {%- endif %} - public static final AttributeKey<{{upFirst(to_java_return_type(attribute.instantiated_type | string))}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + public static final AttributeKey<{{ to_java_return_type(attribute.instantiated_type | string) | to_camelcase(True)}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); {%- endfor %} } diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FifthAttributes.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FifthAttributes.java new file mode 100644 index 00000000..490a7aa3 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FifthAttributes.java @@ -0,0 +1,27 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class FifthAttributes { + /** + * short description of attr_five_int + */ + public static final AttributeKey FIFTH_ATTR_FIVE_INT = enumKey("fifth.attr_five_int"); + + /** + * short description of attr_five_string + */ + public static final AttributeKey FIFTH_ATTR_FIVE_STRING = enumKey("fifth.attr_five_string"); + public static final class FifthAttrFiveIntValues { + /** First enum2 value.*/ + public static final long ENUM2_ONE = 1; + /** Second enum2 value.*/ + public static final long ENUM2_TWO = 2; + } + + public static final class FifthAttrFiveStringValues { + /** First enum1 value.*/ + public static final String ENUM1_ONE = "one"; + /** Second enum1 value.*/ + public static final String ENUM1_TWO = "two"; + } + +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FirstAttributes.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FirstAttributes.java new file mode 100644 index 00000000..0d15179f --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/FirstAttributes.java @@ -0,0 +1,18 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class FirstAttributes { + /** + * short description of attr_one_a + */ + public static final AttributeKey FIRST_ATTR_ONE_A = longKey("first.attr_one_a"); + + /** + * this is the description of attribute template + */ + public static final AttributeKeyTemplate FIRST_ATTR_TEMPLATE_ONE = stringKey("first.attr_template_one"); + + /** + * short description of last_attr + */ + public static final AttributeKey FIRST_LAST_ATTR = booleanKey("first.last_attr"); +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/SecondAttributes.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/SecondAttributes.java new file mode 100644 index 00000000..abc59440 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/SecondAttributes.java @@ -0,0 +1,8 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class SecondAttributes { + /** + * short description of attr_two + */ + public static final AttributeKey SECOND_ATTR_TWO = stringKey("second.attr_two"); +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/ThirdAttributes.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/ThirdAttributes.java new file mode 100644 index 00000000..e4a9bca1 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/all/ThirdAttributes.java @@ -0,0 +1,13 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class ThirdAttributes { + /** + * this is the description of attribute template + */ + public static final AttributeKeyTemplate THIRD_ATTR_TEMPLATE_THREE = stringKey("third.attr_template_three"); + + /** + * short description of attr_three + */ + public static final AttributeKey THIRD_ATTR_THREE = stringKey("third.attr_three"); +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes.yml b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes.yml new file mode 100644 index 00000000..72415d1a --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes.yml @@ -0,0 +1,94 @@ +groups: + - id: first_group_id + type: attribute_group + brief: first description + prefix: first + attributes: + - id: last_attr # intentionally out of alphabetical order to test sorting + type: boolean + stability: experimental + brief: short description of last_attr + - id: attr_template_one + type: template[string] + stability: experimental + brief: > + this is the description of attribute template + examples: 'example' + + - id: second_group_id + brief: second description + prefix: second + span_kind: client + extends: first_group_id + attributes: + - id: attr_two + type: string + stability: experimental + brief: short description of attr_two + examples: ['example_one', 'example_two'] + - id: first_group_part_two + type: resource + brief: first_a description + prefix: first + attributes: + - id: attr_one_a + type: int + stability: experimental + brief: short description of attr_one_a + - ref: second.attr_two + - ref: third.attr_template_three + - id: third_group_id + brief: third description + prefix: third + attributes: + - id: attr_three + type: string + brief: short description of attr_three + examples: "3" + stability: stable + - id: attr_template_three + type: template[string] + stability: experimental + brief: > + this is the description of attribute template + examples: 'example' + - id: forth_group_id + brief: forth description + attributes: + - id: attr_four + type: string + stability: experimental + brief: short description of attr_four + examples: "4" + - id: fifth_group_id + brief: fifth description + prefix: fifth + attributes: + - id: attr_five_string + stability: experimental + type: + members: + - id: enum1_one + value: "one" + stability: experimental + brief: "First enum1 value" + - id: enum1_two + value: "two" + stability: experimental + brief: "Second enum1 value" + brief: short description of attr_five_string + examples: one + - id: attr_five_int + stability: experimental + type: + members: + - id: enum2_one + value: 1 + stability: experimental + brief: "First enum2 value" + - id: enum2_two + value: 2 + stability: experimental + brief: "Second enum2 value" + brief: short description of attr_five_int + examples: 1 diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/First.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/First.java new file mode 100644 index 00000000..7ec15b57 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/First.java @@ -0,0 +1,19 @@ +package io.opentelemetry.instrumentation.api.semconv; + +import io.opentelemetry.api.metrics.Meter; + +class First { + /** + * short description of attr_one + */ + public static final AttributeKey FIRST_ATTR_ONE = booleanKey("first.attr_one"); + /** + * first metric description + * Experimental: False + */ + public static final LongCounterBuilder createFirstMetric(Meter meter) { + return meter.counterBuilder("first.metric") + .setDescription("first metric description") + .setUnit("{one}"); + } +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/SecondGroup.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/SecondGroup.java new file mode 100644 index 00000000..20fbc0ed --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/SecondGroup.java @@ -0,0 +1,19 @@ +package io.opentelemetry.instrumentation.api.semconv; + +import io.opentelemetry.api.metrics.Meter; + +class SecondGroup { + /** + * short description of attr_two + */ + public static final AttributeKey SECOND_GROUP_ATTR_TWO = longKey("second_group.attr_two"); + /** + * second metric description + * Experimental: True + */ + public static final DoubleHistogramBuilder createSecondGroupMetric(Meter meter) { + return meter.histogramBuilder("second_group.metric") + .setDescription("second metric description") + .setUnit("s"); + } +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/semconv.yml b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/semconv.yml new file mode 100644 index 00000000..16f47c9e --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/semconv.yml @@ -0,0 +1,33 @@ +groups: + - id: first_group_id + type: attribute_group + brief: first description + prefix: first + attributes: + - id: attr_one + type: boolean + stability: experimental + brief: short description of attr_one + + - id: first_metric_id + brief: first metric description + metric_name: first.metric + instrument: counter + type: metric + unit: "{one}" + stability: stable + extends: first_group_id + + - id: second_group_id + brief: second metric description + metric_name: second_group.metric + stability: experimental + type: metric + instrument: histogram + unit: "s" + prefix: second_group + attributes: + - id: attr_two + type: int + stability: experimental + brief: short description of attr_two diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/template b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/template new file mode 100644 index 00000000..f1cacd96 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/attributes_and_metrics/template @@ -0,0 +1,76 @@ +{%- macro to_java_return_type(type) -%} + {%- if type == "string" -%} + String + {%- elif type == "string[]" -%} + List + {%- elif type == "boolean" -%} + boolean + {%- elif type == "int" -%} + long + {%- elif type == "double" -%} + double + {%- else -%} + {{type}} + {%- endif -%} +{%- endmacro %} +{%- macro to_java_key_type(type) -%} + {%- if type == "string" -%} + stringKey + {%- elif type == "string[]" -%} + stringArrayKey + {%- elif type == "boolean" -%} + booleanKey + {%- elif type == "int" -%} + longKey + {%- elif type == "double" -%} + doubleKey + {%- else -%} + {{ type | to_camelcase(False)}}Key + {%- endif -%} +{%- endmacro %} +{%- macro to_java_instrument_builder_factory(instrument) -%} + {%- if instrument == "counter" -%} + counterBuilder + {%- elif instrument == "histogram" -%} + histogramBuilder + {%- elif instrument == "updowncounter" -%} + upDownCounterBuilder + {%- elif instrument == "gauge" -%} + gaugeBuilder + {%- endif -%} +{%- endmacro %} +{%- macro to_java_instrument_builder_type(instrument) -%} + {%- if instrument == "counter" -%} + LongCounterBuilder + {%- elif instrument == "histogram" -%} + DoubleHistogramBuilder + {%- elif instrument == "updowncounter" -%} + LongUpDownCounterBuilder + {%- elif instrument == "gauge" -%} + DoubleGaugeBuilder + {%- endif -%} +{%- endmacro %} +package io.opentelemetry.instrumentation.api.semconv; + +import io.opentelemetry.api.metrics.Meter; + +class {{ root_namespace | to_camelcase(True) }} { +{%- for attribute in attributes_and_templates %} + + /** + * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} + */ + public static final AttributeKey<{{ to_java_return_type(attribute.instantiated_type | string) | first_up }}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); +{% endfor %} +{%- for metric in metrics %} + /** + * {{metric.brief | to_doc_brief}} + * Experimental: {{ metric | is_experimental }} + */ + public static final {{ to_java_instrument_builder_type(metric.instrument) }} create{{metric.metric_name | to_camelcase(True)}}(Meter meter) { + return meter.{{to_java_instrument_builder_factory(metric.instrument)}}("{{ metric.metric_name }}") + .setDescription("{{ metric.brief }}") + .setUnit("{{ metric.unit }}"); + } +{% endfor %} +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/FooAttributes.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/FooAttributes.java new file mode 100644 index 00000000..b09c7dc5 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/FooAttributes.java @@ -0,0 +1,13 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class FooAttributes { + /** + * short description of attr_one + */ + public static final AttributeKey FOO_ATTR_ONE = booleanKey("foo.attr_one"); + + /** + * short description of foo.attr_two + */ + public static final AttributeKey FOO_ATTR_TWO = stringKey("foo.attr_two"); +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/OtherAttributes.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/OtherAttributes.java new file mode 100644 index 00000000..9a7b38b2 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/OtherAttributes.java @@ -0,0 +1,8 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class OtherAttributes { + /** + * short description of bar_attr + */ + public static final AttributeKey BAR_ATTR = stringKey("bar_attr"); +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/attributes_no_group_prefix.yml b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/attributes_no_group_prefix.yml new file mode 100644 index 00000000..eb58fd47 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/no_group_prefix/attributes_no_group_prefix.yml @@ -0,0 +1,23 @@ +groups: + - id: group_with_prefix + type: attribute_group + brief: description + prefix: foo + attributes: + - id: attr_one + type: boolean + stability: experimental + brief: short description of attr_one + - id: group_with_no_prefix + brief: description + attributes: + - id: foo.attr_two + type: string + stability: experimental + brief: short description of foo.attr_two + examples: "foo" + - id: bar_attr + type: string + stability: experimental + brief: short description of bar_attr + examples: "bar" \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/All.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/All.java new file mode 100644 index 00000000..cd1cabeb --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/All.java @@ -0,0 +1,34 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class AllAttributes { + class FirstAttributes { + /** + * short description of attr_one + */ + public static final AttributeKey FIRST_ATTR_ONE = booleanKey("first.attr_one"); + + /** + * short description of attr_one_a + */ + public static final AttributeKey FIRST_ATTR_ONE_A = longKey("first.attr_one_a"); + + /** + * this is the description of attribute template + */ + public static final AttributeKeyTemplate FIRST_ATTR_TEMPLATE_ONE = stringKey("first.attr_template_one"); + } + class SecondAttributes { + /** + * short description of attr_two + */ + public static final AttributeKey SECOND_ATTR_TWO = stringKey("second.attr_two"); + } + /** + * short description of attr_four + */ + public static final AttributeKey ATTR_FOUR = stringKey("attr_four"); + /** + * first metric description + */ + public static final String FIRST_METRIC_NAME = "first.metric.name"; +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/semconv.yml b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/semconv.yml new file mode 100644 index 00000000..cdd432bc --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/semconv.yml @@ -0,0 +1,57 @@ +groups: + - id: first_group_id + type: attribute_group + brief: first description + prefix: first + attributes: + - id: attr_one + type: boolean + stability: experimental + brief: short description of attr_one + - id: attr_template_one + type: template[string] + stability: experimental + brief: > + this is the description of attribute template + examples: 'example' + + - id: second_group_id + brief: second description + prefix: second + span_kind: client + extends: first_group_id + attributes: + - id: attr_two + type: string + stability: experimental + brief: short description of attr_two + examples: ['example_one', 'example_two'] + + - id: first_group_part_two + type: resource + brief: first_a description + prefix: first + attributes: + - id: attr_one_a + type: int + stability: experimental + brief: short description of attr_one_a + - ref: second.attr_two + + - id: forth_group_id + brief: forth description + attributes: + - id: attr_four + type: string + stability: experimental + brief: short description of attr_four + examples: "4" + + - id: first_metric_id + brief: first metric description + metric_name: first.metric.name + stability: experimental + instrument: counter + type: metric + unit: "{one}" + extends: first_group_id diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/template_single_file b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/template_single_file new file mode 100644 index 00000000..98ff6d26 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/single_file/template_single_file @@ -0,0 +1,74 @@ +{%- macro to_java_return_type(type) -%} + {%- if type == "string" -%} + String + {%- elif type == "string[]" -%} + List + {%- elif type == "boolean" -%} + boolean + {%- elif type == "int" -%} + long + {%- elif type == "double" -%} + double + {%- else -%} + {{type}} + {%- endif -%} +{%- endmacro %} +{%- macro to_java_key_type(type) -%} + {%- if type == "string" -%} + stringKey + {%- elif type == "string[]" -%} + stringArrayKey + {%- elif type == "boolean" -%} + booleanKey + {%- elif type == "int" -%} + longKey + {%- elif type == "double" -%} + doubleKey + {%- else -%} + {{ type | to_camelcase(False)}}Key + {%- endif -%} +{%- endmacro %} +package io.opentelemetry.instrumentation.api.semconv; + +class AllAttributes { +{%- for root_ns in attributes_and_templates %} + + {% if root_ns != "" %} + class {{root_ns | first_up}}Attributes { + {%- for attribute in attributes_and_templates[root_ns] %} + + /** + * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} + */ + {% if attribute | is_template %} + public static final AttributeKeyTemplate<{{ to_java_return_type(attribute.instantiated_type | string) | first_up}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% else %} + public static final AttributeKey<{{ to_java_return_type(attribute.instantiated_type | string) | first_up }}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% endif %} + + {%- endfor %} + } + {%- endif %} +{%- endfor %} +{# non-namespaced attributes #} +{%- for attribute in attributes_and_templates[""] %} + /** + * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} + */ + {% if attribute | is_template %} + public static final AttributeKeyTemplate<{{ to_java_return_type(attribute.instantiated_type | string) | first_up}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% else %} + public static final AttributeKey<{{ to_java_return_type(attribute.instantiated_type | string) | first_up }}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% endif %} + +{%- endfor %} +{%- for id in semconvs %} +{%- if semconvs[id] | is_metric %} +{% set metric = semconvs[id] %} + /** + * {{metric.brief | to_doc_brief}} + */ + public static final String {{metric.metric_name | to_const_name}} = "{{metric.metric_name}}"; +{% endif %} +{% endfor %} +} diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/ThirdAttributesStable.java b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/ThirdAttributesStable.java new file mode 100644 index 00000000..ece8c736 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/ThirdAttributesStable.java @@ -0,0 +1,8 @@ +package io.opentelemetry.instrumentation.api.semconv; + +class ThirdAttributes { + /** + * short description of attr_three + */ + public static final AttributeKey THIRD_ATTR_THREE = stringKey("third.attr_three"); +} diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/template_only_stable b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/template_only_stable new file mode 100644 index 00000000..60d75caa --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/stable/template_only_stable @@ -0,0 +1,49 @@ +{%- macro to_java_return_type(type) -%} + {%- if type == "string" -%} + String + {%- elif type == "string[]" -%} + List + {%- elif type == "boolean" -%} + boolean + {%- elif type == "int" -%} + long + {%- elif type == "double" -%} + double + {%- else -%} + {{type}} + {%- endif -%} +{%- endmacro %} +{%- macro to_java_key_type(type) -%} + {%- if type == "string" -%} + stringKey + {%- elif type == "string[]" -%} + stringArrayKey + {%- elif type == "boolean" -%} + booleanKey + {%- elif type == "int" -%} + longKey + {%- elif type == "double" -%} + doubleKey + {%- else -%} + {{ type | to_camelcase(False)}}Key + {%- endif -%} +{%- endmacro %} +{%- set stable_attributes_and_templates = attributes_and_templates | select("is_stable") | list %} + +{%- if stable_attributes_and_templates | count > 0 %} +package io.opentelemetry.instrumentation.api.semconv; + +class {{ root_namespace | to_camelcase(True) }}Attributes { +{%- for attribute in stable_attributes_and_templates %} + + /** + * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} + */ + {% if attribute | is_template %} + public static final AttributeKeyTemplate<{{ to_java_return_type(attribute.instantiated_type | string) | first_up}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% else %} + public static final AttributeKey<{{ to_java_return_type(attribute.instantiated_type | string) | first_up }}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% endif %} +{% endfor %} +} +{% endif %} diff --git a/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/template_all b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/template_all new file mode 100644 index 00000000..adc735eb --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/group_by_root_namespace/template_all @@ -0,0 +1,57 @@ +{%- macro to_java_return_type(type) -%} + {%- if type == "string" -%} + String + {%- elif type == "string[]" -%} + List + {%- elif type == "boolean" -%} + boolean + {%- elif type == "int" -%} + long + {%- elif type == "double" -%} + double + {%- else -%} + {{type}} + {%- endif -%} +{%- endmacro %} +{%- macro to_java_key_type(type) -%} + {%- if type == "string" -%} + stringKey + {%- elif type == "string[]" -%} + stringArrayKey + {%- elif type == "boolean" -%} + booleanKey + {%- elif type == "int" -%} + longKey + {%- elif type == "double" -%} + doubleKey + {%- else -%} + {{ type | to_camelcase(False)}}Key + {%- endif -%} +{%- endmacro %} +package io.opentelemetry.instrumentation.api.semconv; + +class {{ root_namespace | to_camelcase(True) }}Attributes { +{%- for attribute in attributes_and_templates %} + + /** + * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} + */ + {% if attribute | is_template %} + public static final AttributeKeyTemplate<{{ to_java_return_type(attribute.instantiated_type | string) | first_up}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% else %} + public static final AttributeKey<{{ to_java_return_type(attribute.instantiated_type | string) | first_up }}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}"); + {% endif %} +{% endfor %} + +{%- for attribute in enum_attributes %} + {% set type = to_java_return_type(attribute.attr_type.enum_type) %} + public static final class {{attribute.fqn | to_camelcase(True) ~ "Values"}} { + {% for member in attribute.attr_type.members %} + /** {{member.brief | to_doc_brief}}.*/ + {% set value = attribute | print_member_value(member) %} + public static final {{ type }} {{ member.member_id | to_const_name }} = {{ value }}; + {% endfor %} + } + +{% endfor %} +} diff --git a/semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java b/semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java new file mode 100644 index 00000000..86727325 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java @@ -0,0 +1,16 @@ +class AllMetrics { + /** + * first metric description + * Unit: {one} + * Instrument: counter + * Experimental: False + */ + public static final String FIRST_METRIC = "first.metric"; + /** + * second metric description + * Unit: s + * Instrument: histogram + * Experimental: True + */ + public static final String SECOND_GROUP_METRIC = "second_group.metric"; +} diff --git a/semantic-conventions/src/tests/data/jinja/metrics/metrics_template b/semantic-conventions/src/tests/data/jinja/metrics/metrics_template new file mode 100644 index 00000000..9941bb9f --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/metrics/metrics_template @@ -0,0 +1,12 @@ +class AllMetrics { +{%- for metric in metrics %} + /** + * {{metric.brief | to_doc_brief}} + * Unit: {{ metric.unit }} + * Instrument: {{ metric.instrument }} + * Experimental: {{ metric | is_experimental }} + */ + public static final String {{ metric.metric_name | to_const_name }} = "{{metric.metric_name}}"; +{%- endfor %} +} + diff --git a/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md b/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md new file mode 100644 index 00000000..de1439da --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/stability/badges_expected.md @@ -0,0 +1,10 @@ +# Common Attributes + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`test.def_stability`](labels_expected.md) | boolean | | | Required | +| [`test.deprecated_attr`](labels_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
| | Required | +| [`test.exp_attr`](labels_expected.md) | boolean | | | Required | +| [`test.stable_attr`](labels_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
| | Required | + diff --git a/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md b/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md new file mode 100644 index 00000000..ab7f6194 --- /dev/null +++ b/semantic-conventions/src/tests/data/markdown/stability/labels_expected.md @@ -0,0 +1,10 @@ +# Common Attributes + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`test.def_stability`](labels_expected.md) | boolean | | | Required | +| [`test.deprecated_attr`](labels_expected.md) | boolean | **Deprecated: Removed.**
| | Required | +| [`test.exp_attr`](labels_expected.md) | boolean | | | Required | +| [`test.stable_attr`](labels_expected.md) | boolean | | | Required | + diff --git a/semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml b/semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml new file mode 100644 index 00000000..6a02479b --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml @@ -0,0 +1,34 @@ +groups: + - id: first_group_id + type: attribute_group + stability: experimental + brief: first description + prefix: first + attributes: + - id: attr_one + type: boolean + stability: experimental + brief: short description of attr_one + + - id: first_metric_id + brief: first metric description + metric_name: first.metric + instrument: counter + type: metric + unit: "{one}" + stability: stable + extends: first_group_id + + - id: second_group_id + brief: second metric description + metric_name: second_group.metric + stability: experimental + type: metric + instrument: histogram + unit: "s" + prefix: second_group + attributes: + - id: attr_two + type: int + stability: experimental + brief: short description of attr_two diff --git a/semantic-conventions/src/tests/semconv/templating/test_code.py b/semantic-conventions/src/tests/semconv/templating/test_code.py index 643505c9..034d2b95 100644 --- a/semantic-conventions/src/tests/semconv/templating/test_code.py +++ b/semantic-conventions/src/tests/semconv/templating/test_code.py @@ -1,4 +1,5 @@ -import io +import os +import tempfile from opentelemetry.semconv.model.semantic_convention import SemanticConventionSet from opentelemetry.semconv.templating.code import CodeRenderer @@ -12,15 +13,34 @@ def test_codegen_units(test_file_path, read_test_file): template_path = test_file_path("jinja", "metrics", "units_template") renderer = CodeRenderer({}, trim_whitespace=False) - output = io.StringIO() - renderer.render(semconv, template_path, output, None) - result = output.getvalue() + filename = os.path.join(tempfile.mkdtemp(), "Attributes.java") + renderer.render(semconv, template_path, filename, None) + with open(filename, "r", encoding="utf-8") as f: + result = f.read() expected = read_test_file("jinja", "metrics", "expected.java") assert result == expected +def test_codegen_metrics_all(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + semconv.parse(test_file_path("yaml", "metrics", "metrics.yaml")) + semconv.finish() + + template_path = test_file_path("jinja", "metrics", "metrics_template") + renderer = CodeRenderer({}, trim_whitespace=False) + + filename = os.path.join(tempfile.mkdtemp(), "AllMetrics.java") + renderer.render(semconv, template_path, filename, None) + with open(filename, "r", encoding="utf-8") as f: + result = f.read() + + expected = read_test_file("jinja", "metrics", "expected_metrics.java") + + assert result == expected + + def test_strip_blocks_enabled(test_file_path, read_test_file): """Tests that the Jinja whitespace control params are fed to the Jinja environment""" semconv = SemanticConventionSet(debug=False) @@ -32,9 +52,10 @@ def test_strip_blocks_enabled(test_file_path, read_test_file): ) renderer = CodeRenderer({}, trim_whitespace=True) - output = io.StringIO() - renderer.render(semconv, template_path, output, None) - result = output.getvalue() + filename = os.path.join(tempfile.mkdtemp(), "Attributes.java") + renderer.render(semconv, template_path, filename, None) + with open(filename, "r", encoding="utf-8") as f: + result = f.read() expected = read_test_file( "jinja", "metrics", "expected_trim_whitespace_enabled.java" @@ -53,10 +74,168 @@ def test_codegen_attribute_templates(test_file_path, read_test_file): template_path = test_file_path("jinja", "attribute_templates", "template") renderer = CodeRenderer({}, trim_whitespace=False) - output = io.StringIO() - renderer.render(semconv, template_path, output, None) - result = output.getvalue() - + filename = os.path.join(tempfile.mkdtemp(), "Attributes.java") + renderer.render(semconv, template_path, filename, None) + with open(filename, "r", encoding="utf-8") as f: + result = f.read() expected = read_test_file("jinja", "attribute_templates", "expected.java") assert result == expected + + +def test_codegen_attribute_root_ns(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + + semconv.parse(test_file_path("jinja", "group_by_root_namespace", "attributes.yml")) + semconv.finish() + + template_path = test_file_path("jinja", "group_by_root_namespace", "template_all") + renderer = CodeRenderer({}, trim_whitespace=True) + + test_path = os.path.join("group_by_root_namespace", "all") + tmppath = tempfile.mkdtemp() + renderer.render( + semconv, + template_path, + os.path.join(tmppath, "{{pascal_prefix}}Attributes.java"), + "root_namespace", + ) + + first = read_test_file("jinja", test_path, "FirstAttributes.java") + check_file(tmppath, "FirstAttributes.java", first) + + second = read_test_file("jinja", test_path, "SecondAttributes.java") + check_file(tmppath, "SecondAttributes.java", second) + + third = read_test_file("jinja", test_path, "ThirdAttributes.java") + check_file(tmppath, "ThirdAttributes.java", third) + + fifth = read_test_file("jinja", test_path, "FifthAttributes.java") + check_file(tmppath, "FifthAttributes.java", fifth) + + +def test_codegen_attribute_root_ns_snake_case_file(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + + semconv.parse(test_file_path("jinja", "group_by_root_namespace", "attributes.yml")) + semconv.finish() + + template_path = test_file_path("jinja", "group_by_root_namespace", "template_all") + renderer = CodeRenderer({}, trim_whitespace=True) + + test_path = os.path.join("group_by_root_namespace", "all") + tmppath = tempfile.mkdtemp() + renderer.render( + semconv, + template_path, + os.path.join(tmppath, "{{snake_prefix}}_attributes.java"), + "root_namespace", + ) + + first = read_test_file("jinja", test_path, "FirstAttributes.java") + check_file(tmppath, "first_attributes.java", first) + + second = read_test_file("jinja", test_path, "SecondAttributes.java") + check_file(tmppath, "second_attributes.java", second) + + third = read_test_file("jinja", test_path, "ThirdAttributes.java") + check_file(tmppath, "third_attributes.java", third) + + fifth = read_test_file("jinja", test_path, "FifthAttributes.java") + check_file(tmppath, "fifth_attributes.java", fifth) + + +def test_codegen_attribute_root_ns_stable(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + semconv.parse(test_file_path("jinja", "group_by_root_namespace", "attributes.yml")) + semconv.finish() + + test_path = os.path.join("group_by_root_namespace", "stable") + template_path = test_file_path("jinja", test_path, "template_only_stable") + renderer = CodeRenderer({}, trim_whitespace=True) + + tmppath = tempfile.mkdtemp() + renderer.render( + semconv, + template_path, + os.path.join(tmppath, "{{pascal_prefix}}Attributes.java"), + "root_namespace", + ) + + thirdStable = read_test_file("jinja", test_path, "ThirdAttributesStable.java") + check_file(tmppath, "ThirdAttributes.java", thirdStable) + assert not os.path.isfile(os.path.join(tmppath, "FirstAttributes.java")) + assert not os.path.isfile(os.path.join(tmppath, "SecondAttributes.java")) + + +def test_codegen_attribute_root_ns_no_group_prefix(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + + test_path = os.path.join("group_by_root_namespace", "no_group_prefix") + semconv.parse(test_file_path("jinja", test_path, "attributes_no_group_prefix.yml")) + semconv.finish() + + template_path = test_file_path("jinja", "group_by_root_namespace", "template_all") + renderer = CodeRenderer({}, trim_whitespace=True) + + tmppath = tempfile.mkdtemp() + renderer.render( + semconv, + template_path, + os.path.join(tmppath, "{{pascal_prefix}}Attributes.java"), + "root_namespace", + ) + + res = read_test_file("jinja", test_path, "FooAttributes.java") + check_file(tmppath, "FooAttributes.java", res) + + other = read_test_file("jinja", test_path, "OtherAttributes.java") + check_file(tmppath, "OtherAttributes.java", other) + + +def test_codegen_attribute_root_ns_single_file(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + + test_path = os.path.join("group_by_root_namespace", "single_file") + semconv.parse(test_file_path("jinja", test_path, "semconv.yml")) + semconv.finish() + + template_path = test_file_path("jinja", test_path, "template_single_file") + renderer = CodeRenderer({}, trim_whitespace=True) + + tmppath = tempfile.mkdtemp() + renderer.render(semconv, template_path, os.path.join(tmppath, "All.java"), None) + + result = read_test_file("jinja", test_path, "All.java") + check_file(tmppath, "All.java", result) + + +def test_codegen_attribute_root_ns_metrics(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + + test_path = os.path.join("group_by_root_namespace", "attributes_and_metrics") + semconv.parse(test_file_path("jinja", test_path, "semconv.yml")) + semconv.finish() + + template_path = test_file_path("jinja", test_path, "template") + renderer = CodeRenderer({}, trim_whitespace=True) + + tmppath = tempfile.mkdtemp() + renderer.render( + semconv, + template_path, + os.path.join(tmppath, "{{pascal_prefix}}.java"), + "root_namespace", + ) + + first = read_test_file("jinja", test_path, "First.java") + check_file(tmppath, "First.java", first) + + second = read_test_file("jinja", test_path, "SecondGroup.java") + check_file(tmppath, "SecondGroup.java", second) + + +def check_file(tmppath, actual_filename, expected_content): + with open(os.path.join(tmppath, actual_filename), "r", encoding="utf-8") as f: + actual = f.read() + assert actual == expected_content From 761b9f0d254f1feb61ecfeb9e3e4e304cd5c0c78 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 19 Mar 2024 11:28:07 -0700 Subject: [PATCH 28/31] Add flag to suppress validation errors to simplify codegen and back compat checks (#300) --- semantic-conventions/CHANGELOG.md | 4 + semantic-conventions/README.md | 10 +- .../src/opentelemetry/semconv/main.py | 38 +++-- .../semconv/model/constraints.py | 7 +- .../opentelemetry/semconv/model/exceptions.py | 14 +- .../semconv/model/semantic_attribute.py | 142 +++++++++--------- .../semconv/model/semantic_convention.py | 117 +++++++++------ .../semconv/model/unit_member.py | 10 +- .../src/opentelemetry/semconv/model/utils.py | 41 +++-- .../errors/enum/enum_with_double_values.yaml | 2 + .../semconv/model/test_error_detection.py | 32 ++-- .../semconv/model/test_semantic_attribute.py | 13 +- .../semconv/model/test_semantic_convention.py | 5 +- .../model/test_semantic_convention_units.py | 9 +- .../src/tests/semconv/model/test_utils.py | 18 ++- 15 files changed, 274 insertions(+), 188 deletions(-) diff --git a/semantic-conventions/CHANGELOG.md b/semantic-conventions/CHANGELOG.md index 49ccc6f3..42a3ecc0 100644 --- a/semantic-conventions/CHANGELOG.md +++ b/semantic-conventions/CHANGELOG.md @@ -32,6 +32,10 @@ Please update the changelog as part of any significant pull request. ([#266](https://github.com/open-telemetry/build-tools/pull/266)) - Sort attribute tables by requirement level and attribute name ([#260](https://github.com/open-telemetry/build-tools/pull/260)) +- Support suppressing all validation errors via flag that allows to + parse previous versions of semantic conventions for backward compatibility checks + and use code generation improvements on older semantic convention version. + ([#300](https://github.com/open-telemetry/build-tools/pull/300)) ## v0.23.0 diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index 4be014a2..81f91a23 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -123,6 +123,12 @@ The following checks are performed: This check does not take into account opt-in attributes. Adding new attributes to metric is not always breaking, so it's considered non-critical and it's possible to suppress it with `--ignore-warnings` +Previous versions of semantic conventions are not always compatible with newer versions of build-tools. You can suppress validation errors by adding `--continue-on-validation-errors` flag: + +```bash +docker run --rm otel/semconvgen --yaml-root {yaml_folder} --continue-on-validation-errors compatibility --previous-version {semconv version} +``` + ## Code Generator The image supports [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) templates to generate code from the models. @@ -171,13 +177,13 @@ Finally, additional value can be passed to the template in form of `key=value` p comma using the `--parameters [{key=value},]+` or `-D` flag. Generating code from older versions of semantic conventions with new tooling is, in general, not supported. -However in some cases minor incompatibilities in semantic conventions can be ignored by setting `--strict-validation` flag to `false` +However in some cases minor incompatibilities in semantic conventions can be suppressed by adding `--continue-on-validation-errors` flag: ```bash docker run --rm \ otel/semconvgen:$GENERATOR_VERSION \ --yaml-root /source \ - `--strict-validation false` + --continue-on-validation-errors \ code \ ...other parameters... ``` diff --git a/semantic-conventions/src/opentelemetry/semconv/main.py b/semantic-conventions/src/opentelemetry/semconv/main.py index aa1a3eea..fe5a5aea 100644 --- a/semantic-conventions/src/opentelemetry/semconv/main.py +++ b/semantic-conventions/src/opentelemetry/semconv/main.py @@ -28,6 +28,7 @@ CONVENTION_CLS_BY_GROUP_TYPE, SemanticConventionSet, ) +from opentelemetry.semconv.model.utils import ValidationContext from opentelemetry.semconv.templating.code import CodeRenderer from opentelemetry.semconv.templating.compatibility import CompatibilityChecker from opentelemetry.semconv.templating.markdown import MarkdownRenderer @@ -42,7 +43,7 @@ def parse_semconv( for file in sorted(files): if not file.endswith(".yaml") and not file.endswith(".yml"): parser.error(f"{file} is not a yaml file.") - semconv.parse(file, strict_validation) + semconv.parse(file, ValidationContext(file, strict_validation)) semconv.finish() if semconv.has_error(): sys.exit(1) @@ -73,7 +74,11 @@ def main(): args = parser.parse_args() check_args(args, parser) semconv = parse_semconv( - args.yaml_root, args.exclude, args.debug, args.strict_validation, parser + args.yaml_root, + args.exclude, + args.debug, + not args.continue_on_validation_errors, + parser, ) semconv_filter = parse_only_filter(args.only, parser) filter_semconv(semconv, semconv_filter) @@ -93,9 +98,9 @@ def main(): def process_markdown(semconv, args): options = MarkdownOptions( check_only=args.md_check, - disable_stable_badge=args.md_disable_stable, - disable_experimental_badge=args.md_disable_experimental, - disable_deprecated_badge=args.md_disable_deprecated, + disable_stable_badge=args.md_disable_stable_badge, + disable_experimental_badge=args.md_disable_experimental_badge, + disable_deprecated_badge=args.md_disable_deprecated_badge, break_count=args.md_break_conditional, exclude_files=exclude_file_list(args.markdown_root, args.exclude), ) @@ -106,7 +111,11 @@ def process_markdown(semconv, args): def check_compatibility(semconv, args, parser): prev_semconv_path = download_previous_version(args.previous_version) prev_semconv = parse_semconv( - prev_semconv_path, args.exclude, args.debug, args.strict_validation, parser + prev_semconv_path, + args.exclude, + args.debug, + not args.continue_on_validation_errors, + parser, ) compatibility_checker = CompatibilityChecker(semconv, prev_semconv) problems = compatibility_checker.check() @@ -220,12 +229,6 @@ def add_md_parser(subparsers): required=False, action="store_true", ) - parser.add_argument( - "--check-compat", - help="Check backward compatibility with previous version of semantic conventions.", - type=str, - required=False, - ) parser.add_argument( "--md-disable-stable-badge", help="Removes badges from attributes marked as stable.", @@ -306,11 +309,14 @@ def setup_parser(): help="YAML file containing a Semantic Convention", ) parser.add_argument( - "--strict-validation", - help="Fail on non-critical yaml validation issues.", + "--continue-on-validation-errors", + help="""Continue parsing on yaml validation issues. + Should not be used to generate or validate semantic conventions. + Useful when running backward compatibility checks or using newer + tooling version to generate code for released semantic conventions.""", required=False, - default=True, - action="store_false", + default=False, + action="store_true", ) subparsers = parser.add_subparsers(dest="flavor") add_code_parser(subparsers) diff --git a/semantic-conventions/src/opentelemetry/semconv/model/constraints.py b/semantic-conventions/src/opentelemetry/semconv/model/constraints.py index 9acf8c32..a483928d 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/constraints.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/constraints.py @@ -17,7 +17,6 @@ from ruamel.yaml.comments import CommentedSeq -from opentelemetry.semconv.model.exceptions import ValidationError from opentelemetry.semconv.model.semantic_attribute import SemanticAttribute from opentelemetry.semconv.model.utils import validate_values @@ -64,20 +63,20 @@ class Include: semconv_id: str -def parse_constraints(yaml_constraints): +def parse_constraints(yaml_constraints, validation_ctx): """This method parses the yaml representation for semantic convention attributes creating a list of Constraint objects. """ constraints = () allowed_keys = ("include", "any_of") for constraint in yaml_constraints: - validate_values(constraint, allowed_keys) + validate_values(constraint, allowed_keys, validation_ctx) if len(constraint.keys()) > 1: position = constraint.lc.data[list(constraint)[1]] msg = ( "Invalid entry in constraint array - multiple top-level keys in entry." ) - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, None) if "include" in constraint: constraints += (Include(constraint.get("include")),) elif "any_of" in constraint: diff --git a/semantic-conventions/src/opentelemetry/semconv/model/exceptions.py b/semantic-conventions/src/opentelemetry/semconv/model/exceptions.py index 354a3aa7..7e2dd06c 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/exceptions.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/exceptions.py @@ -19,19 +19,15 @@ class ValidationError(Exception): line -- line in the file where the error occurred column -- column in the file where the error occurred message -- reason of the error + fqn -- identifier of the node that contains the error """ - @classmethod - def from_yaml_pos(cls, pos, msg): - # the yaml parser starts counting from 0 - # while in document is usually reported starting from 1 - return cls(pos[0] + 1, pos[1] + 1, msg) - - def __init__(self, line, column, message): - super().__init__(line, column, message) + def __init__(self, line, column, message, fqn): + super().__init__(line, column, message, fqn) self.message = message self.line = line self.column = column + self.fqn = fqn def __str__(self): - return f"{self.message} - @{self.line}:{self.column}" + return f"{self.message} - @{self.line}:{self.column} ('{self.fqn}')" diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py index 9a53ed7e..233e2e64 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py @@ -20,7 +20,6 @@ from ruamel.yaml.comments import CommentedMap, CommentedSeq -from opentelemetry.semconv.model.exceptions import ValidationError from opentelemetry.semconv.model.utils import ( check_no_missing_keys, validate_id, @@ -83,7 +82,7 @@ def is_enum(self): @staticmethod def parse( - prefix, yaml_attributes, strict_validation=True + prefix, yaml_attributes, validation_ctx ) -> "Dict[str, SemanticAttribute]": """This method parses the yaml representation for semantic attributes creating the respective SemanticAttribute objects. @@ -106,18 +105,18 @@ def parse( return attributes for attribute in yaml_attributes: - validate_values(attribute, allowed_keys) + validate_values(attribute, allowed_keys, validation_ctx) attr_id = attribute.get("id") ref = attribute.get("ref") position_data = attribute.lc.data position = position_data[next(iter(attribute))] if attr_id is None and ref is None: msg = "At least one of id or ref is required." - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, attr_id) if attr_id is not None: - validate_id(attr_id, position_data["id"]) + validate_id(attr_id, position_data["id"], validation_ctx) attr_type, brief, examples = SemanticAttribute.parse_attribute( - attribute + attribute, validation_ctx ) if prefix: fqn = f"{prefix}.{attr_id}" @@ -127,14 +126,14 @@ def parse( # Ref attr_type = None if "type" in attribute: - msg = f"Ref attribute '{ref}' must not declare a type" - raise ValidationError.from_yaml_pos(position, msg) + msg = "Ref attribute must not declare a type" + validation_ctx.raise_or_warn(position, msg, ref) if "stability" in attribute: - msg = f"Ref attribute '{ref}' must not override stability" - raise ValidationError.from_yaml_pos(position, msg) + msg = "Ref attribute must not override stability" + validation_ctx.raise_or_warn(position, msg, ref) if "deprecated" in attribute: - msg = f"Ref attribute '{ref}' must not override deprecation status" - raise ValidationError.from_yaml_pos(position, msg) + msg = "Ref attribute must not override deprecation status" + validation_ctx.raise_or_warn(position, msg, ref) brief = attribute.get("brief") examples = attribute.get("examples") ref = ref.strip() @@ -154,7 +153,7 @@ def parse( if len(requirement_level_val) != 1: position = position_data["requirement_level"] msg = "Multiple requirement_level values are not allowed!" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, fqn) recommended_msg = requirement_level_val.get("recommended", None) condition_msg = requirement_level_val.get( @@ -174,7 +173,7 @@ def parse( msg = ( f"Value '{requirement_level_val}' for required field is not allowed" ) - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, fqn) if ( requirement_level == RequirementLevel.CONDITIONALLY_REQUIRED @@ -182,11 +181,11 @@ def parse( ): position = position_data["requirement_level"] msg = "Missing message for conditionally required field!" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, fqn) tag = attribute.get("tag", "").strip() stability = SemanticAttribute.parse_stability( - attribute.get("stability"), position_data, strict_validation + attribute.get("stability"), position_data, fqn, validation_ctx ) if stability == StabilityLevel.EXPERIMENTAL and isinstance( attr_type, EnumAttributeType @@ -197,14 +196,14 @@ def parse( f"Member '{member.member_id}' is marked as stable " + "but it is not allowed on experimental attribute!" ) - raise ValidationError.from_yaml_pos(position_data["type"], msg) + validation_ctx.raise_or_warn(position_data["type"], msg, fqn) deprecated = SemanticAttribute.parse_deprecated( - attribute.get("deprecated"), position_data + attribute.get("deprecated"), position_data, fqn, validation_ctx ) sampling_relevant = ( - AttributeType.to_bool("sampling_relevant", attribute) + AttributeType.to_bool("sampling_relevant", attribute, validation_ctx) if attribute.get("sampling_relevant") else False ) @@ -241,21 +240,19 @@ def parse( + " is already present at line " + str(attributes[fqn].position[0] + 1) ) - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, fqn) attributes[fqn] = attr return attributes @staticmethod - def parse_attribute(attribute): - check_no_missing_keys(attribute, ["type", "brief", "stability"]) + def parse_attribute(attribute, validation_ctx): + check_no_missing_keys(attribute, ["type", "brief", "stability"], validation_ctx) attr_val = attribute["type"] - try: - attr_type = EnumAttributeType.parse(attr_val) - except ValidationError as e: - if e.line != 0: # Does the error already have a position? - raise - position = attribute.lc.data["type"] - raise ValidationError.from_yaml_pos(position, e.message) from e + attr_id = attribute.get("id") + attr_type = EnumAttributeType.parse( + attr_val, attribute.lc.data["type"], validation_ctx + ) + brief = attribute["brief"] examples = attribute.get("examples") is_simple_type = AttributeType.is_simple_type(attr_type) @@ -268,7 +265,7 @@ def parse_attribute(attribute): ): position = attribute.lc.data[list(attribute)[0]] msg = f"Non array examples for {attr_type} are not allowed" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, attr_id) if not isinstance(examples, CommentedSeq) and examples is not None: # TODO: If validation fails later, this will crash when trying to access position data # since a list, contrary to a CommentedSeq, does not have position data @@ -288,7 +285,7 @@ def parse_attribute(attribute): if not examples: position = attribute.lc.data[list(attribute)[0]] msg = f"Empty examples for {attr_type} are not allowed" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, attr_id) if is_template_type: return attr_type, str(brief), examples @@ -301,11 +298,13 @@ def parse_attribute(attribute): # TODO: Implement type check for enum examples or forbid them if examples is not None and is_simple_type: - AttributeType.check_examples_type(attr_type, examples, zlass) + AttributeType.check_examples_type( + attr_type, examples, zlass, attr_id, validation_ctx + ) return attr_type, str(brief), examples @staticmethod - def parse_stability(stability, position_data, strict_validation=True): + def parse_stability(stability, position_data, attr_id, validation_ctx): if stability is None: return None @@ -317,26 +316,22 @@ def parse_stability(stability, position_data, strict_validation=True): if val is not None: return val - # TODO: remove this branch - it's necessary for now to allow back-compat checks against old spec versions - # where we used 'deprecated' as stability level - if not strict_validation and stability == "deprecated": - print( - 'WARNING: Using "deprecated" as stability level is no longer supported. Use "experimental" instead.' - ) - return StabilityLevel.EXPERIMENTAL - msg = f"Value '{stability}' is not allowed as a stability marker" - raise ValidationError.from_yaml_pos(position_data["stability"], msg) + validation_ctx.raise_or_warn(position_data["stability"], msg, attr_id) + # TODO: replace with None - it's necessary for now to give codegen + # a default value for semconv 1.24.0 and lower where we used + # 'deprecated' as stability level + return StabilityLevel.EXPERIMENTAL @staticmethod - def parse_deprecated(deprecated, position_data): + def parse_deprecated(deprecated, position_data, attr_id, validation_ctx): if deprecated is not None: if AttributeType.get_type(deprecated) != "string" or deprecated == "": msg = ( "Deprecated field expects a string that specifies why the attribute is deprecated and/or what" " to use instead! " ) - raise ValidationError.from_yaml_pos(position_data["deprecated"], msg) + validation_ctx.raise_or_warn(position_data["deprecated"], msg, attr_id) return deprecated.strip() return None @@ -415,7 +410,7 @@ def type_mapper(attr_type: str): return type_mapper.get(attr_type) @staticmethod - def check_examples_type(attr_type, examples, zlass): + def check_examples_type(attr_type, examples, zlass, fqn, validation_ctx): """This method checks example are correctly typed""" index = -1 for example in examples: @@ -426,15 +421,15 @@ def check_examples_type(attr_type, examples, zlass): if not isinstance(element, zlass): position = examples.lc.data[index] msg = f"Example with wrong type. Expected {attr_type} examples but is was {type(element)}." - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, fqn) else: # Single value example or array example with a single example array if not isinstance(example, zlass): position = examples.lc.data[index] msg = f"Example with wrong type. Expected {attr_type} examples but is was {type(example)}." - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, fqn) @staticmethod - def to_bool(key, parent_object): + def to_bool(key, parent_object, validation_ctx): """This method translate yaml boolean values to python boolean values""" yaml_value = parent_object.get(key) if isinstance(yaml_value, bool): @@ -446,7 +441,12 @@ def to_bool(key, parent_object): return False position = parent_object.lc.data[key] msg = f"Value '{yaml_value}' for {key} field is not allowed" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn( + position, + msg, + parent_object.get("id"), + ) + return None @dataclass @@ -468,7 +468,7 @@ def is_valid_enum_value(val): return isinstance(val, (int, str)) @staticmethod - def parse(attribute_type): + def parse(attribute_type, position, validation_ctx): """This method parses the yaml representation for semantic attribute types. If the type is an enumeration, it generated the EnumAttributeType object, otherwise it returns the basic type as string. @@ -478,13 +478,12 @@ def parse(attribute_type): attribute_type ) or AttributeType.is_template_type(attribute_type): return attribute_type - # Wrong type used - raise the exception and fill the missing data in the parent - raise ValidationError( - 0, 0, f"Invalid type: {attribute_type} is not allowed" + validation_ctx.raise_or_warn( + position, f"Invalid type: {attribute_type} is not allowed", None ) allowed_keys = ["allow_custom_values", "members"] mandatory_keys = ["members"] - validate_values(attribute_type, allowed_keys, mandatory_keys) + validate_values(attribute_type, allowed_keys, validation_ctx, mandatory_keys) custom_values = ( bool(attribute_type.get("allow_custom_values")) if "allow_custom_values" in attribute_type @@ -495,37 +494,37 @@ def parse(attribute_type): not isinstance(attribute_type["members"], CommentedSeq) or len(attribute_type["members"]) < 1 ): - raise ValidationError.from_yaml_pos( - attribute_type.lc.data["members"], "Enumeration without members!" + validation_ctx.raise_or_warn( + attribute_type.lc.data["members"], + "Enumeration without members!", + attribute_type.get("id"), ) allowed_keys = ["id", "value", "brief", "note", "stability", "deprecated"] - mandatory_keys = ["id", "value"] + mandatory_keys = ["id", "value", "stability"] for member in attribute_type["members"]: - validate_values(member, allowed_keys, mandatory_keys) + validate_values(member, allowed_keys, validation_ctx, mandatory_keys) if not EnumAttributeType.is_valid_enum_value(member["value"]): - raise ValidationError.from_yaml_pos( + validation_ctx.raise_or_warn( member.lc.data["value"][:2], f"Invalid value used in enum: <{member['value']}>", + attribute_type.get("id"), ) - validate_id(member["id"], member.lc.data["id"]) - stability_str = member.get("stability") - if not stability_str: - raise ValidationError.from_yaml_pos( - member.lc.data["id"], - f"Enumeration member '{member['value']}' must have a stability level", - ) + member_id = member["id"] + validate_id(member_id, member.lc.data["id"], validation_ctx) - stability = SemanticAttribute.parse_stability(stability_str, member.lc.data) + stability = SemanticAttribute.parse_stability( + member.get("stability"), member.lc.data, member_id, validation_ctx + ) deprecated = SemanticAttribute.parse_deprecated( - member.get("deprecated"), member.lc.data + member.get("deprecated"), member.lc.data, member_id, validation_ctx ) members.append( EnumMember( - member_id=member["id"], + member_id=member_id, value=member["value"], - brief=member.get("brief", member["id"]).strip(), + brief=member.get("brief", member_id).strip(), note=member.get("note", "").strip(), stability=stability, deprecated=deprecated, @@ -534,9 +533,10 @@ def parse(attribute_type): enum_type = AttributeType.get_type(members[0].value) for myaml, m in zip(attribute_type["members"], members): if enum_type != AttributeType.get_type(m.value): - raise ValidationError.from_yaml_pos( + validation_ctx.raise_or_warn( myaml.lc.data["value"], f"Enumeration member does not have type {enum_type}!", + m.member_id, ) return EnumAttributeType(custom_values, members, enum_type) diff --git a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py index b9893945..537e335a 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py @@ -28,7 +28,12 @@ SemanticAttribute, ) from opentelemetry.semconv.model.unit_member import UnitMember -from opentelemetry.semconv.model.utils import ValidatableYamlNode, validate_id +from opentelemetry.semconv.model.utils import ( + ValidatableYamlNode, + ValidationContext, + check_no_missing_keys, + validate_id, +) class SpanKind(Enum): @@ -60,16 +65,17 @@ def parse_semantic_convention_type(type_value): return CONVENTION_CLS_BY_GROUP_TYPE.get(type_value) -def parse_semantic_convention_groups(yaml_file, strict_validation=True): +def parse_semantic_convention_groups(yaml_file, validation_ctx): yaml = YAML().load(yaml_file) models = [] for group in yaml["groups"]: - models.append(SemanticConvention(group, strict_validation)) + models.append(SemanticConvention(group, validation_ctx)) return models -def SemanticConvention(group, strict_validation=True): +def SemanticConvention(group, validation_ctx): type_value = group.get("type") + semconv_id = group.get("id") if type_value is None: line = group.lc.data["id"][0] + 1 doc_url = "https://github.com/open-telemetry/build-tools/blob/main/semantic-conventions/syntax.md#groups" @@ -82,11 +88,11 @@ def SemanticConvention(group, strict_validation=True): if convention_type is None: position = group.lc.data["type"] if "type" in group else group.lc.data["id"] msg = f"Invalid value for semantic convention type: {group.get('type')}" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, semconv_id) # First, validate that the correct fields are available in the yaml - convention_type.validate_keys(group) - model = convention_type(group, strict_validation) + convention_type.validate_keys(group, validation_ctx) + model = convention_type(group, validation_ctx) # Also, validate that the value of the fields is acceptable model.validate_values() return model @@ -141,24 +147,27 @@ def comparison_key(attr): key=comparison_key, ) - def __init__(self, group, strict_validation=True): - super().__init__(group) + def __init__(self, group, validation_ctx): + super().__init__(group, validation_ctx) self.semconv_id = self.id self.note = group.get("note", "").strip() self.prefix = group.get("prefix", "").strip() + self.validation_ctx = validation_ctx position_data = group.lc.data self.stability = SemanticAttribute.parse_stability( - group.get("stability"), position_data, strict_validation + group.get("stability"), position_data, self.semconv_id, validation_ctx ) self.deprecated = SemanticAttribute.parse_deprecated( - group.get("deprecated"), position_data + group.get("deprecated"), position_data, self.semconv_id, validation_ctx ) self.extends = group.get("extends", "").strip() self.events = group.get("events", ()) - self.constraints = parse_constraints(group.get("constraints", ())) + self.constraints = parse_constraints( + group.get("constraints", ()), validation_ctx + ) self.attrs_by_name = SemanticAttribute.parse( - self.prefix, group.get("attributes"), strict_validation + self.prefix, group.get("attributes"), validation_ctx ) def contains_attribute(self, attr: "SemanticAttribute"): @@ -182,7 +191,7 @@ def has_attribute_constraint(self, attr): def validate_values(self): super().validate_values() if self.prefix: - validate_id(self.prefix, self._position) + validate_id(self.prefix, self._position, self.validation_ctx) class ResourceSemanticConvention(BaseSemanticConvention): @@ -205,13 +214,13 @@ class SpanSemanticConvention(BaseSemanticConvention): "span_kind", ) - def __init__(self, group, strict_validation=True): - super().__init__(group) + def __init__(self, group, validation_ctx): + super().__init__(group, validation_ctx) self.span_kind = SpanKind.parse(group.get("span_kind")) if self.span_kind is None: position = group.lc.data["span_kind"] msg = f"Invalid value for span_kind: {group.get('span_kind')}" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, group.get("id")) class EventSemanticConvention(BaseSemanticConvention): @@ -219,12 +228,14 @@ class EventSemanticConvention(BaseSemanticConvention): allowed_keys = BaseSemanticConvention.allowed_keys + ("name",) - def __init__(self, group, strict_validation=True): - super().__init__(group) + def __init__(self, group, validation_ctx): + super().__init__(group, validation_ctx) self.name = group.get("name", self.prefix) if not self.name: - raise ValidationError.from_yaml_pos( - self._position, "Event must define at least one of name or prefix" + validation_ctx.raise_or_warn( + self._position, + "Event must define at least one of name or prefix", + group.get("id"), ) @@ -238,9 +249,9 @@ class UnitSemanticConvention(BaseSemanticConvention): "members", ) - def __init__(self, group, strict_validation=True): - super().__init__(group) - self.members = UnitMember.parse(group.get("members")) + def __init__(self, group, validation_ctx): + super().__init__(group, validation_ctx) + self.members = UnitMember.parse(group.get("members"), validation_ctx) class MetricGroupSemanticConvention(BaseSemanticConvention): @@ -267,28 +278,29 @@ class MetricSemanticConvention(MetricGroupSemanticConvention): canonical_instrument_name_by_yaml_name.keys() ) - def __init__(self, group, strict_validation=True): - super().__init__(group) + def __init__(self, group, validation_ctx): + super().__init__(group, validation_ctx) self.metric_name = group.get("metric_name") self.unit = group.get("unit") self.instrument = group.get("instrument") + self.validation_ctx = validation_ctx namespaces = self.metric_name.split(".") self.root_namespace = namespaces[0] if len(namespaces) > 1 else "" - self.validate() + self.validate(group) - def validate(self): - val_tuple = (self.metric_name, self.unit, self.instrument, self.stability) - if not all(val_tuple): - raise ValidationError.from_yaml_pos( - self._position, - "All of metric_name, units, instrument, and stability must be defined", - ) + def validate(self, yaml): + check_no_missing_keys( + yaml, + ["metric_name", "unit", "instrument", "stability"], + self.validation_ctx, + ) if self.instrument not in self.allowed_instruments: - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( self._position, f"Instrument '{self.instrument}' is not a valid instrument name", + self.metric_name, ) @@ -301,17 +313,19 @@ class SemanticConventionSet: debug: bool models: typing.Dict[str, BaseSemanticConvention] = field(default_factory=dict) errors: bool = False + validation_ctx: Optional[ValidationContext] = None - def parse(self, file, strict_validation=True): + def parse(self, file, validation_ctx=None): + self.validation_ctx = validation_ctx or ValidationContext(file, True) with open(file, "r", encoding="utf-8") as yaml_file: try: semconv_models = parse_semantic_convention_groups( - yaml_file, strict_validation + yaml_file, self.validation_ctx ) for model in semconv_models: if model.semconv_id in self.models: self.errors = True - print(f"Error parsing {file}\n", file=sys.stderr) + print(f"\nError parsing {file}:", file=sys.stderr) print( f"Semantic convention '{model.semconv_id}' is already defined.", file=sys.stderr, @@ -319,8 +333,9 @@ def parse(self, file, strict_validation=True): self.models[model.semconv_id] = model except ValidationError as e: self.errors = True - print(f"Error parsing {file}\n", file=sys.stderr) + print(f"\nError parsing {file}:", file=sys.stderr) print(e, file=sys.stderr) + print() def has_error(self): return self.errors @@ -384,17 +399,18 @@ def _populate_extends_single(self, semconv, unprocessed): Resolves the parent/child relationship for a single Semantic Convention. If the parent **p** of the input semantic convention **i** has in turn a parent **pp**, it recursively resolves **pp** before processing **p**. :param semconv: The semantic convention for which resolve the parent/child relationship. - :param semconvs: The list of remaining semantic conventions to process. + :param unprocessed: The list of remaining semantic conventions to process. :return: A list of remaining semantic convention to process. """ # Resolve parent of current Semantic Convention if semconv.extends: extended = self.models.get(semconv.extends) if extended is None: - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( semconv._position, f"Semantic Convention {semconv.semconv_id} extends " f"{semconv.extends} but the latter cannot be found!", + semconv.semconv_id, ) # Process hierarchy chain @@ -435,10 +451,11 @@ def _populate_anyof_attributes(self): for attr_id in attr_ids: ref_attr = self._lookup_attribute(attr_id) if ref_attr is None: - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( any_of._yaml_src_position[index], - f"Any_of attribute '{attr_id}' of semantic convention " - "{semconv.semconv_id} does not exists!", + f"Any_of attribute '{attr_id}' of semantic " + "convention {semconv.semconv_id} does not exist!", + attr_id, ) constraint_attrs.append(ref_attr) if constraint_attrs: @@ -450,16 +467,18 @@ def _populate_events(self): for event_id in semconv.events: event = self.models.get(event_id) if event is None: - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( semconv._position, f"Semantic Convention {semconv.semconv_id} has " "{event_id} as event but the latter cannot be found!", + event_id, ) if not isinstance(event, EventSemanticConvention): - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( semconv._position, f"Semantic Convention {semconv.semconv_id} has {event_id} as event but" " the latter is not a semantic convention for events!", + event_id, ) events.append(event) semconv.events = events @@ -474,9 +493,10 @@ def resolve_ref(self, semconv): fixpoint_ref = False ref_attr = self._lookup_attribute(attr.ref) if not ref_attr: - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( semconv._position, f"Semantic Convention {semconv.semconv_id} reference `{attr.ref}` but it cannot be found!", + semconv.semconv_id, ) attr = self._merge_attribute(attr, ref_attr) return fixpoint_ref @@ -515,10 +535,11 @@ def resolve_include(self, semconv): include_semconv = self.models.get(constraint.semconv_id) # include required attributes and constraints if include_semconv is None: - raise ValidationError.from_yaml_pos( + self.validation_ctx.raise_or_warn( semconv._position, f"Semantic Convention {semconv.semconv_id} includes " "{constraint.semconv_id} but the latter cannot be found!", + semconv.semconv_id, ) # We resolve the parent/child relationship of the included semantic convention, if any self._populate_extends_single( diff --git a/semantic-conventions/src/opentelemetry/semconv/model/unit_member.py b/semantic-conventions/src/opentelemetry/semconv/model/unit_member.py index 92490a34..3068449b 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/unit_member.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/unit_member.py @@ -6,16 +6,16 @@ class UnitMember(ValidatableYamlNode): allowed_keys = ("id", "brief", "value") mandatory_keys = allowed_keys - def __init__(self, node): - super().__init__(node) + def __init__(self, node, validation_ctx): + super().__init__(node, validation_ctx) self.value = node.get("value") @staticmethod - def parse(members): + def parse(members, validation_ctx): parsed_members = {} for member in members: - UnitMember.validate_keys(member) - unit_member = UnitMember(member) + UnitMember.validate_keys(member, validation_ctx) + unit_member = UnitMember(member, validation_ctx) unit_member.validate_values() parsed_members[unit_member.id] = unit_member diff --git a/semantic-conventions/src/opentelemetry/semconv/model/utils.py b/semantic-conventions/src/opentelemetry/semconv/model/utils.py index 291d28f5..391acc2b 100644 --- a/semantic-conventions/src/opentelemetry/semconv/model/utils.py +++ b/semantic-conventions/src/opentelemetry/semconv/model/utils.py @@ -23,31 +23,33 @@ Each dot must be followed by at least one allowed non-dot character.""" -def validate_id(semconv_id, position): +def validate_id(semconv_id, position, validation_ctx): if not ID_RE.fullmatch(semconv_id): - raise ValidationError.from_yaml_pos( + validation_ctx.raise_or_warn( position, f"Invalid id {semconv_id}. Semantic Convention ids MUST match {ID_RE.pattern}", + semconv_id, ) -def validate_values(yaml, keys, mandatory=()): +def validate_values(yaml, keys, validation_ctx, mandatory=()): """This method checks only valid keywords and value types are used""" + node_id = yaml.get("id") unwanted = [k for k in yaml.keys() if k not in keys] if unwanted: position = yaml.lc.data[unwanted[0]] msg = f"Invalid keys: {unwanted}" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, node_id) if mandatory: - check_no_missing_keys(yaml, mandatory) + check_no_missing_keys(yaml, mandatory, validation_ctx) -def check_no_missing_keys(yaml, mandatory): +def check_no_missing_keys(yaml, mandatory, validation_ctx): missing = list(set(mandatory) - set(yaml)) if missing: position = (yaml.lc.line, yaml.lc.col) msg = f"Missing keys: {missing}" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, yaml.get("id")) class ValidatableYamlNode: @@ -55,22 +57,23 @@ class ValidatableYamlNode: allowed_keys = () # type: Tuple[str, ...] mandatory_keys = ("id", "brief") # type: Tuple[str, ...] - def __init__(self, yaml_node): + def __init__(self, yaml_node, validation_ctx): self.id = yaml_node.get("id").strip() self.brief = str(yaml_node.get("brief")).strip() + self.validation_ctx = validation_ctx self._position = (yaml_node.lc.line, yaml_node.lc.col) @classmethod - def validate_keys(cls, node): + def validate_keys(cls, node, validation_ctx): unwanted = [key for key in node.keys() if key not in cls.allowed_keys] if unwanted: position = node.lc.data[unwanted[0]] msg = f"Invalid keys: {unwanted}" - raise ValidationError.from_yaml_pos(position, msg) + validation_ctx.raise_or_warn(position, msg, node.get("id")) if cls.mandatory_keys: - check_no_missing_keys(node, cls.mandatory_keys) + check_no_missing_keys(node, cls.mandatory_keys, validation_ctx) def validate_values(self): """ @@ -78,4 +81,18 @@ def validate_values(self): This method should raise an exception with a descriptive message if the semantic convention is not valid. """ - validate_id(self.id, self._position) + validate_id(self.id, self._position, self.validation_ctx) + + +class ValidationContext: + def __init__(self, file_name: str, strict_validation: bool): + self.strict_validation = strict_validation + self.file_name = file_name + + def raise_or_warn(self, pos, msg, fqn): + # the yaml parser starts counting from 0 + # while in document is usually reported starting from 1 + error = ValidationError(pos[0] + 1, pos[1] + 1, msg, fqn) + if self.strict_validation: + raise error + print(f"[Warning] {self.file_name}: {error}\n") diff --git a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml index 02b97e43..f3fd1b9d 100644 --- a/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml +++ b/semantic-conventions/src/tests/data/yaml/errors/enum/enum_with_double_values.yaml @@ -9,8 +9,10 @@ groups: members: - id: OK value: 0.0 + stability: experimental - id: CANCELLED value: 1.0 + stability: experimental requirement_level: required brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." examples: [0.0, 1.0] diff --git a/semantic-conventions/src/tests/semconv/model/test_error_detection.py b/semantic-conventions/src/tests/semconv/model/test_error_detection.py index 62dfe360..a6225b73 100644 --- a/semantic-conventions/src/tests/semconv/model/test_error_detection.py +++ b/semantic-conventions/src/tests/semconv/model/test_error_detection.py @@ -22,6 +22,7 @@ SemanticConventionSet, parse_semantic_convention_groups, ) +from opentelemetry.semconv.model.utils import ValidationContext class TestCorrectErrorDetection(unittest.TestCase): @@ -118,8 +119,9 @@ def test_no_override_type(self): self.fail() e = ex.exception msg = e.message.lower() - self.assertIn("must not declare a type", msg) - self.assertIn("'test'", msg) + self.assertEqual("ref attribute must not declare a type", msg) + self.assertEqual("test", e.fqn) + self.assertIn("'test'", str(e)) self.assertEqual(e.line, 8) def test_invalid_key_in_constraint(self): @@ -160,7 +162,8 @@ def test_ref_override_stability(self): self.fail() e = ex.exception msg = e.message.lower() - self.assertIn("ref attribute 'test_attr' must not override stability", msg) + self.assertEqual("ref attribute must not override stability", msg) + self.assertEqual("test_attr", e.fqn) self.assertEqual(e.line, 14) def test_invalid_semconv_stability_with_deprecated(self): @@ -191,9 +194,16 @@ def test_missing_stability_value_on_enum_member(self): self.fail() e = ex.exception msg = e.message.lower() - self.assertIn("enumeration member 'one' must have a stability level", msg) + self.assertIn("missing keys: ['stability']", msg) self.assertEqual(e.line, 10) + def test_missing_stability_value_on_enum_member_not_strict(self): + path = "yaml/errors/stability/missing_stability_on_enum_member.yaml" + with open(self.load_file(path), encoding="utf-8") as file: + return parse_semantic_convention_groups( + file, ValidationContext(path, False) + ) + def test_multiple_stability_values_on_enum_member(self): with self.assertRaises(DuplicateKeyError): self.open_yaml( @@ -234,10 +244,11 @@ def test_extends_overrides_deprecation(self): self.fail() e = ex.exception msg = e.message.lower() - self.assertIn( - "ref attribute 'test.convention_version' must not override deprecation status", + self.assertEqual( + "ref attribute must not override deprecation status", msg, ) + self.assertEqual("test.convention_version", e.fqn) self.assertEqual(e.line, 19) def test_ref_overrides_deprecation(self): @@ -246,10 +257,11 @@ def test_ref_overrides_deprecation(self): self.fail() e = ex.exception msg = e.message.lower() - self.assertIn( - "ref attribute 'test.convention_version' must not override deprecation status", + self.assertEqual( + "ref attribute must not override deprecation status", msg, ) + self.assertEqual("test.convention_version", e.fqn) self.assertEqual(e.line, 17) def test_invalid_deprecated_boolean(self): @@ -498,7 +510,7 @@ def test_validate_anyof_attributes(self): e = ex.exception msg = e.message.lower() self.assertIn("any_of attribute", msg) - self.assertIn("does not exists", msg) + self.assertIn("does not exist", msg) self.assertEqual(e.line, 16) def test_missing_event(self): @@ -553,7 +565,7 @@ def test_multiple_requirement_level_values(self): def open_yaml(self, path): with open(self.load_file(path), encoding="utf-8") as file: - return parse_semantic_convention_groups(file) + return parse_semantic_convention_groups(file, ValidationContext(path, True)) _TEST_DIR = os.path.dirname(__file__) diff --git a/semantic-conventions/src/tests/semconv/model/test_semantic_attribute.py b/semantic-conventions/src/tests/semconv/model/test_semantic_attribute.py index 9a8ef067..28e4fe6c 100644 --- a/semantic-conventions/src/tests/semconv/model/test_semantic_attribute.py +++ b/semantic-conventions/src/tests/semconv/model/test_semantic_attribute.py @@ -15,11 +15,14 @@ import re from opentelemetry.semconv.model.semantic_attribute import SemanticAttribute +from opentelemetry.semconv.model.utils import ValidationContext def test_parse(load_yaml): yaml = load_yaml("semantic_attributes.yml") - attributes = SemanticAttribute.parse("prefix", yaml.get("attributes")) + attributes = SemanticAttribute.parse( + "prefix", yaml.get("attributes"), ValidationContext(None, True) + ) assert len(attributes) == 3 @@ -45,7 +48,9 @@ def test_parse(load_yaml): def test_parse_deprecated(load_yaml): yaml = load_yaml("semantic_attributes_deprecated.yml") - attributes = SemanticAttribute.parse("", yaml.get("attributes")) + attributes = SemanticAttribute.parse( + "", yaml.get("attributes"), ValidationContext(None, True) + ) assert len(attributes) == 1 assert list(attributes.keys()) == ["deprecated_attribute"] @@ -62,7 +67,9 @@ def test_parse_regex(): def test_parse_attribute_templates(load_yaml): yaml = load_yaml("attribute_templates.yml") - attribute_templates = SemanticAttribute.parse("prefix", yaml.get("attributes")) + attribute_templates = SemanticAttribute.parse( + "prefix", yaml.get("attributes"), ValidationContext(None, True) + ) assert len(attribute_templates) == 3 diff --git a/semantic-conventions/src/tests/semconv/model/test_semantic_convention.py b/semantic-conventions/src/tests/semconv/model/test_semantic_convention.py index df7a133f..98d9a208 100644 --- a/semantic-conventions/src/tests/semconv/model/test_semantic_convention.py +++ b/semantic-conventions/src/tests/semconv/model/test_semantic_convention.py @@ -18,11 +18,14 @@ SpanKind, parse_semantic_convention_groups, ) +from opentelemetry.semconv.model.utils import ValidationContext def test_parse_basic(open_test_file): with open_test_file(os.path.join("yaml", "basic_example.yml")) as yaml_file: - conventions = parse_semantic_convention_groups(yaml_file) + conventions = parse_semantic_convention_groups( + yaml_file, ValidationContext(open_test_file, True) + ) assert conventions is not None assert len(conventions) == 2 diff --git a/semantic-conventions/src/tests/semconv/model/test_semantic_convention_units.py b/semantic-conventions/src/tests/semconv/model/test_semantic_convention_units.py index 5728a749..c2cdc880 100644 --- a/semantic-conventions/src/tests/semconv/model/test_semantic_convention_units.py +++ b/semantic-conventions/src/tests/semconv/model/test_semantic_convention_units.py @@ -7,11 +7,14 @@ UnitSemanticConvention, parse_semantic_convention_groups, ) +from opentelemetry.semconv.model.utils import ValidationContext def test_build_units(open_test_file): with open_test_file(os.path.join("yaml", "metrics", "units.yaml")) as yaml_file: - conventions = parse_semantic_convention_groups(yaml_file) + conventions = parse_semantic_convention_groups( + yaml_file, ValidationContext(open_test_file, True) + ) assert len(conventions) == 1 convention = conventions[0] @@ -42,5 +45,7 @@ def test_build_units_bad(open_test_file): with pytest.raises(ValidationError) as excinfo, open_test_file( os.path.join("yaml", "metrics", "units_bad_with_attributes.yaml") ) as yaml_file: - parse_semantic_convention_groups(yaml_file) + parse_semantic_convention_groups( + yaml_file, ValidationContext(open_test_file, True) + ) assert "attributes" in str(excinfo.value) diff --git a/semantic-conventions/src/tests/semconv/model/test_utils.py b/semantic-conventions/src/tests/semconv/model/test_utils.py index 1bffee42..61875f60 100644 --- a/semantic-conventions/src/tests/semconv/model/test_utils.py +++ b/semantic-conventions/src/tests/semconv/model/test_utils.py @@ -14,7 +14,11 @@ import pytest from opentelemetry.semconv.model.exceptions import ValidationError -from opentelemetry.semconv.model.utils import validate_id, validate_values +from opentelemetry.semconv.model.utils import ( + ValidationContext, + validate_id, + validate_values, +) _POSITION = [10, 2] @@ -35,7 +39,7 @@ def test_validate_id__valid(semconv_id): # a lowercase letter. The rest of the id may contain only lowercase letters, # numbers, underscores, and dashes - validate_id(semconv_id, _POSITION) + validate_id(semconv_id, _POSITION, True) @pytest.mark.parametrize( @@ -43,11 +47,15 @@ def test_validate_id__valid(semconv_id): ) def test_validate_id__invalid(semconv_id): with pytest.raises(ValidationError) as err: - validate_id(semconv_id, _POSITION) + validate_id(semconv_id, _POSITION, ValidationContext(None, True)) assert err.value.message.startswith("Invalid id") +def test_validate_id__invalid_not_strict(): + validate_id("123", _POSITION, ValidationContext(None, False)) + + @pytest.mark.parametrize( "allowed, mandatory", [ @@ -63,7 +71,7 @@ def test_validate_values(load_yaml, allowed, mandatory): conventions = load_yaml("basic_example.yml") yaml = conventions["groups"][0] - validate_values(yaml, allowed, mandatory) + validate_values(yaml, allowed, ValidationContext(None, True), mandatory) @pytest.mark.parametrize( @@ -96,6 +104,6 @@ def test_validate_values__invalid(load_yaml, allowed, mandatory, expected_messag yaml = conventions["groups"][0] with pytest.raises(ValidationError) as err: - validate_values(yaml, allowed, mandatory) + validate_values(yaml, allowed, ValidationContext(None, True), mandatory) assert err.value.message == expected_message From 21407ccd8e46c5d64c1e0ac8994a06218b3c21bc Mon Sep 17 00:00:00 2001 From: "James Hughes (Splunk)" Date: Wed, 20 Mar 2024 05:58:25 -0700 Subject: [PATCH 29/31] add owner @open-telemetry/specs-semconv-maintainers to semantic-conventions owners (#287) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 90dcfb15..f8df15e5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,4 +16,4 @@ * @open-telemetry/specs-approvers # Owners for the semantic conventions generator tool -/semantic-conventions/ @open-telemetry/specs-approvers @open-telemetry/specs-semconv-approvers +/semantic-conventions/ @open-telemetry/specs-approvers @open-telemetry/specs-semconv-approvers @open-telemetry/specs-semconv-maintainers From 8f7108329dce028a78e0de8e04f089dd2bd42cea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 17:50:35 -0700 Subject: [PATCH 30/31] Bump black from 24.2.0 to 24.3.0 in /semantic-conventions (#301) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index bb5fe10c..97721526 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,4 +1,4 @@ -black==24.2.0 +black==24.3.0 mypy==1.8.0 pytest==8.1.1 flake8==7.0.0 From 917543bcfc68268c8fe559d802c284e64735651f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 17:55:47 -0700 Subject: [PATCH 31/31] Bump mypy from 1.8.0 to 1.9.0 in /semantic-conventions (#302) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- semantic-conventions/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-conventions/dev-requirements.txt b/semantic-conventions/dev-requirements.txt index 97721526..4f8efdd1 100644 --- a/semantic-conventions/dev-requirements.txt +++ b/semantic-conventions/dev-requirements.txt @@ -1,5 +1,5 @@ black==24.3.0 -mypy==1.8.0 +mypy==1.9.0 pytest==8.1.1 flake8==7.0.0 pylint==3.1.0