From 8e0e5f3a78a416da5a1dd447241a39462f0d9bb2 Mon Sep 17 00:00:00 2001 From: Georg Pirklbauer Date: Mon, 8 Aug 2022 23:44:23 +0200 Subject: [PATCH 001/127] fix a tiny typo and reflow (#421) --- opentelemetry/proto/trace/v1/trace.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index b41b48b97..590355074 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -268,8 +268,8 @@ message Status { enum StatusCode { // The default status. STATUS_CODE_UNSET = 0; - // The Span has been validated by an Application developers or Operator to have - // completed successfully. + // The Span has been validated by an Application developer or Operator to + // have completed successfully. STATUS_CODE_OK = 1; // The Span contains an error. STATUS_CODE_ERROR = 2; From 03a08fb0213d46b393c62312c7dd1e8891d5f6b6 Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Fri, 19 Aug 2022 07:46:12 -0700 Subject: [PATCH 002/127] Change the exponential histogram boundary condition (#409) --- opentelemetry/proto/metrics/v1/metrics.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index c0e30e541..0fff2cd1c 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -535,8 +535,8 @@ message ExponentialHistogramDataPoint { // base = (2^(2^-scale)) // // The histogram bucket identified by `index`, a signed integer, - // contains values that are greater than or equal to (base^index) and - // less than (base^(index+1)). + // contains values that are greater than (base^index) and + // less than or equal to (base^(index+1)). // // The positive and negative ranges of the histogram are expressed // separately. Negative values are mapped by their absolute value @@ -572,7 +572,7 @@ message ExponentialHistogramDataPoint { // Count is an array of counts, where count[i] carries the count // of the bucket at index (offset+i). count[i] is the count of - // values greater than or equal to base^(offset+i) and less than + // values greater than base^(offset+i) and less or equal to than // base^(offset+i+1). // // Note: By contrast, the explicit HistogramDataPoint uses From 9a9a5c8659ff08a2361e1847db576ead76fcb44d Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 8 Nov 2022 16:11:53 -0500 Subject: [PATCH 003/127] Prepare for declaring OTLP/JSON Stable (#435) This adds guarantees that are necessary for OTLP/JSON wire representation stability. This does not yet declare OTLP/JSON. It will be a separate PR once we are certain nothing else is needed. --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 27987728c..a4ab9906c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ The compiled files are published to central repositories (Maven, ...) from OpenT See [contribution guidelines](CONTRIBUTING.md) if you would like to make any changes. +## OTLP/JSON + +See additional requirements for [OTLP/JSON wire representation here](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#json-protobuf-encoding). + ## Generate gRPC Client Libraries To generate the raw gRPC client libraries, use `make gen-${LANGUAGE}`. Currently supported languages are: @@ -32,17 +36,17 @@ To generate the raw gRPC client libraries, use `make gen-${LANGUAGE}`. Currently ## Maturity Level -Component | Maturity | --------------------------------------|----------| -**Binary Protobuf Encoding** | | -common/* | Stable | -metrics/\*
collector/metrics/* | Stable | -resource/* | Stable | -trace/trace.proto
collector/trace/* | Stable | -trace/trace_config.proto | Alpha | -logs/\*
collector/logs/* | Stable | -**JSON encoding** | | -All messages | Alpha | +Component | Maturity | +-------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------| +**Binary Protobuf Encoding** | | +common/* | Stable | +metrics/\*
collector/metrics/* | Stable | +resource/* | Stable | +trace/trace.proto
collector/trace/* | Stable | +trace/trace_config.proto | Alpha | +logs/\*
collector/logs/* | Stable | +**JSON encoding** | | +All messages | [Alpha](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#json-protobuf-encoding) | (See [maturity-matrix.yaml](https://github.com/open-telemetry/community/blob/47813530864b9fe5a5146f466a58bd2bb94edc72/maturity-matrix.yaml#L57) for definition of maturity levels). @@ -51,8 +55,7 @@ for definition of maturity levels). Components marked `Stable` provide the following guarantees: -- Field types will not change. -- Field numbers will not change. +- Field types, numbers and names will not change. - Numbers assigned to enum choices will not change. - Service names and service package names will not change. - Service operation names, parameter and return types will not change. @@ -60,23 +63,20 @@ Components marked `Stable` provide the following guarantees: The following changes are allowed: - Message names may change. -- Field names may change. - Enum names may change. -- Enum choice names may change. +- Enum choice names may change. This is allowed because enum choice names are not sent on + the wire. - The location of messages and enums, i.e. whether they are declared at the top lexical scope or nested inside another message may change. - Package names may change. - Directory structure, location and the name of the files may change. -Note that none of the above allowed changes affects the binary wire representation. +Note that none of the above allowed changes affects the binary wire representation or the +JSON wire representation. No guarantees are provided whatsoever about the stability of the code that is generated from the .proto files by any particular code generator. -In the future when OTLP/JSON is declared stable, several of the changes that -are currently allowed will become disallowed since they are visible on the wire -for JSON encoding. - ## Experiments In some cases we are trying to experiment with different features. In this case, From 327e7b5957f73838435fb5d7802d30deec299f32 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 20 Jan 2023 14:36:16 -0500 Subject: [PATCH 004/127] Delete requirement to generate new trace/span id if an invalid id is received (#444) This is considered an bug in the spec that was uncovered in the discussion here: https://github.com/open-telemetry/opentelemetry-proto/pull/442#discussion_r1061995668 I did some spelunking and the "generate" recommendation comes from the very first commit: https://github.com/open-telemetry/opentelemetry-proto/commit/b5bcfffce09c956b1419b2b56a9aaff384797517#diff-ef5f80fbf835dd57e14cb9264944f03d80cf6b04cc7671b0e7fb33167c67efcc where they were copied from Java repo, to which they were copied from OpenCensus https://github.com/open-telemetry/opentelemetry-java/pull/134 and in OpenCensus the wording first time appeared here https://github.com/census-instrumentation/opencensus-proto/pull/160 (authored by @SergeyKanzhelev, merged by @bogdandrutu). We are deleting the requirement to generate a new trace id or span id if an invalid id is received. The receivers can decide how they want to treat the invalid id (just like upon receiving any other invalid id), e.g. they may drop it, log an error, accept the invalid data, etc. We are not going to prescribe a particular receiver behavior when invalid trace/span id is received. --- opentelemetry/proto/trace/v1/trace.proto | 6 ------ 1 file changed, 6 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 590355074..3103fe76f 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -82,9 +82,6 @@ message Span { // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes // is considered invalid. // - // This field is semantically required. Receiver should generate new - // random trace_id if empty or invalid trace_id was received. - // // This field is required. bytes trace_id = 1; @@ -92,9 +89,6 @@ message Span { // is created. The ID is an 8-byte array. An ID with all zeroes is considered // invalid. // - // This field is semantically required. Receiver should generate new - // random span_id if empty or invalid span_id was received. - // // This field is required. bytes span_id = 2; From a5ab8d9a21b261a1f6ae62dc65731420a0dc5cbc Mon Sep 17 00:00:00 2001 From: Ruslan Kovalov Date: Tue, 24 Jan 2023 00:27:05 +0100 Subject: [PATCH 005/127] Introduce an optional `zero_threshold` field to `ExponentialHistogramDataPoint` (#441) --- CHANGELOG.md | 3 ++- opentelemetry/proto/metrics/v1/metrics.proto | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b10db9efd..4643f6aba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,8 @@ Full list of differences found in [this compare](https://github.com/open-telemet ### Added -* Remove if no changes for this section before release. +* Introduce an optional `zero_threshold` field to `ExponentialHistogramDataPoint`. + [(#440)](https://github.com/open-telemetry/opentelemetry-proto/issues/440) ### Removed diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index 0fff2cd1c..aab8cfca5 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -595,6 +595,14 @@ message ExponentialHistogramDataPoint { // max is the maximum value over (start_time, end_time]. optional double max = 13; + + // ZeroThreshold may be optionally set to convey the width of the zero + // region. Where the zero region is defined as the closed interval + // [-ZeroThreshold, ZeroThreshold]. + // When ZeroThreshold is unset or 0, zero count bucket stores + // values that cannot be expressed using the standard exponential formula as + // well as values that have been rounded to zero. + optional double zero_threshold = 14; } // SummaryDataPoint is a single data point in a timeseries that describes the From f184864a21e7f4dd3151c0b490c52b6fc317d20d Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 26 Jan 2023 19:50:35 -0500 Subject: [PATCH 006/127] Clarify behavior for empty/not present/invalid trace_id and span_id fields (#442) Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/3040 This is not a breaking change: - For Span it now defines more precisely the receiver behavior that was previously defined vaguely (e.g. it was unclear what "empty" means for bytes field). - For LogRecord it now defines the receiver behavior that was previously unspecified. This ensures that the wording are consistent with what we have for the Span. --- opentelemetry/proto/logs/v1/logs.proto | 27 ++++++++++++++++++------ opentelemetry/proto/trace/v1/trace.proto | 10 +++++---- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/opentelemetry/proto/logs/v1/logs.proto b/opentelemetry/proto/logs/v1/logs.proto index 9d0e376ca..69928deb2 100644 --- a/opentelemetry/proto/logs/v1/logs.proto +++ b/opentelemetry/proto/logs/v1/logs.proto @@ -164,14 +164,29 @@ message LogRecord { fixed32 flags = 8; // A unique identifier for a trace. All logs from the same trace share - // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes - // is considered invalid. Can be set for logs that are part of request processing - // and have an assigned trace id. [Optional]. + // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR + // of length other than 16 bytes is considered invalid (empty string in OTLP/JSON + // is zero-length and thus is also invalid). + // + // This field is optional. + // + // The receivers SHOULD assume that the log record is not associated with a + // trace if any of the following is true: + // - the field is not present, + // - the field contains an invalid value. bytes trace_id = 9; // A unique identifier for a span within a trace, assigned when the span - // is created. The ID is an 8-byte array. An ID with all zeroes is considered - // invalid. Can be set for logs that are part of a particular processing span. - // If span_id is present trace_id SHOULD be also present. [Optional]. + // is created. The ID is an 8-byte array. An ID with all zeroes OR of length + // other than 8 bytes is considered invalid (empty string in OTLP/JSON + // is zero-length and thus is also invalid). + // + // This field is optional. If the sender specifies a valid span_id then it SHOULD also + // specify a valid trace_id. + // + // The receivers SHOULD assume that the log record is not associated with a + // span if any of the following is true: + // - the field is not present, + // - the field contains an invalid value. bytes span_id = 10; } diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 3103fe76f..beefc343e 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -79,15 +79,17 @@ message ScopeSpans { // The next available field id is 17. message Span { // A unique identifier for a trace. All spans from the same trace share - // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes - // is considered invalid. + // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR + // of length other than 16 bytes is considered invalid (empty string in OTLP/JSON + // is zero-length and thus is also invalid). // // This field is required. bytes trace_id = 1; // A unique identifier for a span within a trace, assigned when the span - // is created. The ID is an 8-byte array. An ID with all zeroes is considered - // invalid. + // is created. The ID is an 8-byte array. An ID with all zeroes OR of length + // other than 8 bytes is considered invalid (empty string in OTLP/JSON + // is zero-length and thus is also invalid). // // This field is required. bytes span_id = 2; From fb655c21cdd33e42bfc483f318c7b704c864006e Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 9 Feb 2023 15:01:09 -0500 Subject: [PATCH 007/127] Declare OTLP/JSON Stable (#436) --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a4ab9906c..3f0f9179d 100644 --- a/README.md +++ b/README.md @@ -36,17 +36,17 @@ To generate the raw gRPC client libraries, use `make gen-${LANGUAGE}`. Currently ## Maturity Level -Component | Maturity | --------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------| -**Binary Protobuf Encoding** | | -common/* | Stable | -metrics/\*
collector/metrics/* | Stable | -resource/* | Stable | -trace/trace.proto
collector/trace/* | Stable | -trace/trace_config.proto | Alpha | -logs/\*
collector/logs/* | Stable | -**JSON encoding** | | -All messages | [Alpha](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#json-protobuf-encoding) | +Component | Maturity | +-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| +**Binary Protobuf Encoding** | | +common/* | Stable | +metrics/\*
collector/metrics/* | Stable | +resource/* | Stable | +trace/trace.proto
collector/trace/* | Stable | +trace/trace_config.proto | Alpha | +logs/\*
collector/logs/* | Stable | +**JSON encoding** | | +All messages | [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#json-protobuf-encoding) | (See [maturity-matrix.yaml](https://github.com/open-telemetry/community/blob/47813530864b9fe5a5146f466a58bd2bb94edc72/maturity-matrix.yaml#L57) for definition of maturity levels). From 5dd897ca39082210835f71960be50208e443242d Mon Sep 17 00:00:00 2001 From: Armin Ruech Date: Wed, 1 Mar 2023 16:58:54 +0100 Subject: [PATCH 008/127] Update auto assignment to reflect current TC (#450) --- .github/auto_assign.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml index 176915f8f..4c9716df2 100644 --- a/.github/auto_assign.yml +++ b/.github/auto_assign.yml @@ -13,9 +13,10 @@ assigneeGroups: - arminru - bogdandrutu - carlosalberto + - jack-berg - jmacd - jsuereth - - SergeyKanzhelev + - reyang - tigrannajaryan - yurishkuro From 3aed265c30d9873982dac3d475cb88e44e315fd4 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:01:23 -0500 Subject: [PATCH 009/127] Update breaking-change to check against last published version (#454) * Update breaking-change to check against last published version * Fetch tags --- .github/workflows/build-check.yaml | 4 ++++ Makefile | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-check.yaml b/.github/workflows/build-check.yaml index 7f26bf39f..f8591b827 100644 --- a/.github/workflows/build-check.yaml +++ b/.github/workflows/build-check.yaml @@ -88,6 +88,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + # breaking-change checks against last published release which is determined + # using the last published tag + - name: Get tags + run: git fetch --tags origin - name: Run make breaking-change with json output to annotate PR # Formats JSON output into Github workflow commands # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message diff --git a/Makefile b/Makefile index 1d8c9965b..ac3020780 100755 --- a/Makefile +++ b/Makefile @@ -22,9 +22,10 @@ BUF_DOCKER ?= bufbuild/buf:1.7.0 PROTOC := docker run --rm -u ${shell id -u} -v${PWD}:${PWD} -w${PWD} ${OTEL_DOCKER_PROTOBUF} --proto_path=${PWD} BUF := docker run --rm -v "${PWD}:/workspace" -w /workspace ${BUF_DOCKER} -# When checking for protobuf breaking changes, check against the upstream repo's main branch. +# When checking for protobuf breaking changes, check against the latest release tag +LAST_RELEASE_TAG := $(shell git tag --sort=committerdate | tail -1) # Options are described in https://docs.buf.build/breaking/usage#git -BUF_AGAINST ?= "https://github.com/open-telemetry/opentelemetry-proto.git" +BUF_AGAINST ?= "https://github.com/open-telemetry/opentelemetry-proto.git\#tag=$(LAST_RELEASE_TAG)" PROTO_GEN_CPP_DIR ?= $(GENDIR)/cpp PROTO_GEN_CSHARP_DIR ?= $(GENDIR)/csharp From 1b4728c9214dcd016b60d3d79f106cf137a00f85 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 15 Mar 2023 13:44:16 -0700 Subject: [PATCH 010/127] Remove optional part from zero_threshold (#453) --- opentelemetry/proto/metrics/v1/metrics.proto | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index aab8cfca5..dc4630e69 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -599,10 +599,10 @@ message ExponentialHistogramDataPoint { // ZeroThreshold may be optionally set to convey the width of the zero // region. Where the zero region is defined as the closed interval // [-ZeroThreshold, ZeroThreshold]. - // When ZeroThreshold is unset or 0, zero count bucket stores - // values that cannot be expressed using the standard exponential formula as - // well as values that have been rounded to zero. - optional double zero_threshold = 14; + // When ZeroThreshold is 0, zero count bucket stores values that cannot be + // expressed using the standard exponential formula as well as values that + // have been rounded to zero. + double zero_threshold = 14; } // SummaryDataPoint is a single data point in a timeseries that describes the From 13d77977a1bd51800e3081d04cb1b08c4f44623b Mon Sep 17 00:00:00 2001 From: Craig Andrews <44933829+craigandrews@users.noreply.github.com> Date: Tue, 21 Mar 2023 16:31:02 +0000 Subject: [PATCH 011/127] change the collector trace endpoint to /v1/traces (#449) Co-authored-by: Reiley Yang Co-authored-by: Armin Ruech --- .../proto/collector/trace/v1/trace_service_http.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml b/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml index 287473597..d091b3a8d 100644 --- a/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml +++ b/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml @@ -5,5 +5,5 @@ config_version: 3 http: rules: - selector: opentelemetry.proto.collector.trace.v1.TraceService.Export - post: /v1/trace - body: "*" \ No newline at end of file + post: /v1/traces + body: "*" From e4eefea04ccda1653de25c9b11da90ff386d6b18 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 19 Apr 2023 20:31:44 -0400 Subject: [PATCH 012/127] Clarify how additive changes are handled (#455) This PR explicitly lists the additive changes allowed and adds a requirement that such additive changes must be accompanied by interoperability explanation when necessary. This is a subset of https://github.com/open-telemetry/opentelemetry-proto/pull/432 that contains other guarantees that we did not yet agree to. I believe this particular subset is necessary regardless of what we decide about #432. --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 3f0f9179d..8e46ff6c7 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,19 @@ The following changes are allowed: Note that none of the above allowed changes affects the binary wire representation or the JSON wire representation. +The following additive changes are allowed: + +- Adding new fields to existing messages. +- Adding new messages or enums. +- Adding new choices to existing enums. +- Adding new choices to existing oneof fields. +- Adding new services. +- Adding new methods to existing services. + +All the additive changes above must be accompanied by an explanation about how +new and old senders and receivers that implement the version of the protocol +before and after the change interoperate. + No guarantees are provided whatsoever about the stability of the code that is generated from the .proto files by any particular code generator. From 0b5552a26275742c822ea16e5dd0342b1eec96b3 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 27 Apr 2023 11:32:08 -0400 Subject: [PATCH 013/127] Define OTLP 1.0 Stability guarantees (#432) Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/400 --- README.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8e46ff6c7..75aab2414 100644 --- a/README.md +++ b/README.md @@ -56,23 +56,18 @@ for definition of maturity levels). Components marked `Stable` provide the following guarantees: - Field types, numbers and names will not change. -- Numbers assigned to enum choices will not change. - Service names and service package names will not change. -- Service operation names, parameter and return types will not change. - -The following changes are allowed: - -- Message names may change. -- Enum names may change. -- Enum choice names may change. This is allowed because enum choice names are not sent on - the wire. -- The location of messages and enums, i.e. whether they are declared at the top - lexical scope or nested inside another message may change. -- Package names may change. -- Directory structure, location and the name of the files may change. - -Note that none of the above allowed changes affects the binary wire representation or the -JSON wire representation. +- Service method names will not change. +- Service method parameter names will not change. +- Service method parameter types and return types will not change. +- Service method kind (unary vs streaming) will not change. +- Names of messages and enums will not change. +- Names of enum choices and numbers assigned to enum choices will not change. +- The location of messages and enums, i.e. whether they are declared at the top lexical + scope or nested inside another message will not change. +- Package names and directory structure will not change. +- `optional` and `repeated` declarators of existing fields will not change. +- No existing symbol will be deleted. The following additive changes are allowed: From c465f0ead2048bce805c70cb3fc3072ac16b68e9 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 6 Apr 2020 14:25:53 -0700 Subject: [PATCH 014/127] Move specifications into sub-directories per signal (#546) Signed-off-by: Bogdan Drutu --- specification/protocol/README.md | 7 ++ specification/protocol/design-goals.md | 19 +++++ specification/protocol/requirements.md | 99 ++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 specification/protocol/README.md create mode 100644 specification/protocol/design-goals.md create mode 100644 specification/protocol/requirements.md diff --git a/specification/protocol/README.md b/specification/protocol/README.md new file mode 100644 index 000000000..bf2560c63 --- /dev/null +++ b/specification/protocol/README.md @@ -0,0 +1,7 @@ +# OpenTelemetry Protocol + +This is the specification of new OpenTelemetry protocol. This is work in progress. + +- [Design Goals](design-goals.md). +- [Requirements](requirements.md). +- Specification (TBD). diff --git a/specification/protocol/design-goals.md b/specification/protocol/design-goals.md new file mode 100644 index 000000000..e51a4d70e --- /dev/null +++ b/specification/protocol/design-goals.md @@ -0,0 +1,19 @@ +# Design Goals for OpenTelemetry Wire Protocol + +We want to design a telemetry data exchange protocol that has the following characteristics: + +- Be suitable for use between all of the following node types: instrumented applications, telemetry backends, local agents, stand-alone collectors/forwarders. + +- Have high reliability of data delivery and clear visibility when the data cannot be delivered. + +- Have low CPU usage for serialization and deserialization. + +- Impose minimal pressure on memory manager, including pass-through scenarios, where deserialized data is short-lived and must be serialized as-is shortly after and where such short-lived data is created and discarded at high frequency (think telemetry data forwarders). + +- Support ability to efficiently modify deserialized data and serialize again to pass further. This is related but slightly different from the previous requirement. + +- Ensure high throughput (within the available bandwidth) in high latency networks (e.g. scenarios where telemetry source and the backend are separated by high latency network). + +- Allow backpressure signalling. + +- Be load-balancer friendly (do not hinder re-balancing). diff --git a/specification/protocol/requirements.md b/specification/protocol/requirements.md new file mode 100644 index 000000000..5d1f1cb66 --- /dev/null +++ b/specification/protocol/requirements.md @@ -0,0 +1,99 @@ +# OpenTelemetry Protocol Requirements + +This document will drive OpenTelemetry Protocol design and RFC. + +## Goals + +See the goals of OpenTelemetry Protocol design [here](design-goals.md). + +## Vocabulary + +There are 2 parties involved in telemetry data exchange. In this document the party that is the source of telemetry data is called the Client, the party that is the destination of telemetry data is called the Server. + +Examples of a Client are instrumented applications or sending side of telemetry collectors, examples of Servers are telemetry backends or receiving side of telemetry collectors (so a Collector is typically both a Client and a Server depending on which side you look from). + +## Known Issues with Existing Protocols + +Our experience with OpenCensus and other protocols has been that many of them have one or more of the following drawbacks: + +- High CPU consumption for serialization and especially deserialization of received telemetry data. +- High and frequent CPU consumption by Garbage Collector. +- Lack of delivery guarantees for certain protocols (e.g. stream-based gRPC OpenCensus protocol) which makes troubleshooting of telemetry pipelines difficult. +- Not aware / not cooperating with load balancers resulting in potentially large imbalances in horizontally scaled backends. +- Support either traces or metrics but not both. + +Our goal is to avoid or mitigate these known issues in the new protocol. + +## Requirements + +The following are OpenTelemetry protocol requirements. + +### Supported Node Types + +The protocol must be suitable for use between all of the following node types: instrumented applications, telemetry backends, telemetry agents running as local daemons, stand-alone collector/forwarder services. + +### Supported Data Types + +The protocol must support traces and metrics as data types. + +### Reliability of Delivery + +The protocol must ensure reliable data delivery and clear visibility when the data cannot be delivered. This should be achieved by sending data acknowledgements from the Server to the Client. + +Note that acknowledgements alone are not sufficient to guarantee that: a) no data will be lost and b) no data will be duplicated. Acknowledgements can help to guarantee a) but not b). Guaranteeing both at the same is difficult. Because it is usually preferable for telemetry data to be duplicated than to lose it, we choose to guarantee that there are no data losses while potentially allowing duplicate data. + +Duplicates can typically happen in edge cases (e.g. on reconnections, network interruptions, etc) when the client has no way of knowing if last sent data was delivered. In these cases the client will usually choose to re-send the data to guarantee the delivery which in turn may result in duplicate data on the server side. + +_To avoid having duplicates the client and the server could track sent and delivered items using uniquely identifying ids. The exact mechanism for tracking the ids and performing data de-duplication may be defined at the layer above the protocol layer and is outside the scope of this document._ + +For this reason we have slightly relaxed requirements and consider duplicate data acceptable in rare cases. + +Note: this protocol is concerned with reliability of delivery between one pair of client/server nodes and aims to ensure that no data is lost in-transit between the client and the server. Many telemetry collection systems have multiple nodes that the data must travel across until reaching the final destination (e.g. application -> agent -> collector -> backend). End-to-end delivery guarantees in such systems is outside of the scope for this document. The acknowledgements described in this protocol happen between a single client/server pair and do not span multiple nodes in multi-hop delivery paths. + +### Throughput + +The protocol must ensure high throughput in high latency networks when the client and the server are not in the same data center. + +This requirement may rule out half-duplex protocols. The throughput of half-duplex protocols is highly dependent on network roundtrip time and request size. To achieve good throughput request sizes may be too large to be practical. + +### Compression + +The protocol must achieve high compression ratios for telemetry data. The protocol design must consider batching of telemetry data and grouping of similar data (both can help to achieve better compression using common compression algorithms). + +### Encryption + +Industry standard encryption (e.g. TLS/HTTPS) must be supported. + +### Backpressure Signalling and Throttling + +The protocol must allow backpressure signalling. + +If the server is unable to keep up with the pace of data it receives from the client then it must be able to signal that fact to the client. The client may then throttle itself to avoid overwhelming the server. + +If the underlying transport is a stream that has its own flow control mechanism then the backpressure could be applied by delaying the reading of data from the server’s endpoint which could then be signalled to the client via underlying flow-control. However this approach makes it difficult for the client to distinguish server overloading from network delays (due to e.g. network losses). Such distinction is important for [observability reasons](https://github.com/open-telemetry/opentelemetry-service/pull/188). Because of this it is required for the protocol to allow to explicitly and clearly signal backpressure from the server to the client without relying on implicit signalling using underlying flow-control mechanisms. + +The backpressure signal should include a hint to the client about desirable reduced rate of data. + +### Serialization Performance + +The protocol must have fast data serialization and deserialization characteristics. + +Ideally it must also support very fast pass-through mode (when no modifications to the data are needed), fast “augmenting” or “tagging” of data and partial inspection of data (e.g. check for presence of specific tag). These requirements help to create fast Agents and Collectors. + +### Memory Usage Profile + +The protocol must impose minimal pressure on memory manager, including pass-through scenarios, when deserialized data is short-lived and must be serialized as-is shortly after and when such short-lived data is created and discarded at high frequency (think telemetry data forwarders). + +The implementation of telemetry protocol must aim to minimize the number of memory allocations and dealocations performed during serialization and deserialization and aim to minimize the pressure on Garbage Collection (for GC languages). + +### Level 7 Load Balancer Friendly + +The protocol must allow Level 7 load balancers such as Envoy to re-balance the traffic for each batch of telemetry data. The traffic should not get pinned by a load balancer to one server for the entire duration of telemetry data sending, thus potentially leading to imbalanced load of servers located behind the load balancer. + +### Backwards Compatibility + +The protocol should be possible to evolve over time. It should be possible for nodes that implement different versions of OpenTelemetry protocol to interoperate (while possibly regressing to the lowest common denominator from functional perspective). + +### General Requirements + +The protocol must use well-known, mature encoding and transport mechanisms with ubiquitous availability of implementations in wide selection of languages that are supported by OpenTelemetry. From 3a922ef1ae766047f81881a8376db20bef63cce5 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 17 Aug 2020 15:11:27 -0400 Subject: [PATCH 015/127] Add OTLP to the specification (#794) * Add OTLP to the specification We previously had OTLP definition scattered in multiple OTEPs. This amalgamates the OTEPs and brings OTLP to the specification repo. * Address PR comments * Address PR comments --- .../protocol/img/otlp-client-server.png | Bin 0 -> 10256 bytes .../protocol/img/otlp-concurrent.png | Bin 0 -> 9983 bytes .../protocol/img/otlp-multi-destination.png | Bin 0 -> 24900 bytes .../protocol/img/otlp-request-response.png | Bin 0 -> 22919 bytes .../protocol/img/otlp-sequential.png | Bin 0 -> 11665 bytes specification/protocol/otlp.md | 549 ++++++++++++++++++ 6 files changed, 549 insertions(+) create mode 100644 specification/protocol/img/otlp-client-server.png create mode 100644 specification/protocol/img/otlp-concurrent.png create mode 100644 specification/protocol/img/otlp-multi-destination.png create mode 100644 specification/protocol/img/otlp-request-response.png create mode 100644 specification/protocol/img/otlp-sequential.png create mode 100644 specification/protocol/otlp.md diff --git a/specification/protocol/img/otlp-client-server.png b/specification/protocol/img/otlp-client-server.png new file mode 100644 index 0000000000000000000000000000000000000000..664fdd1eadbc9fd3c87096eb8035cd9affb56249 GIT binary patch literal 10256 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 Kx`{aJy#EVnO~%mx literal 0 HcmV?d00001 diff --git a/specification/protocol/img/otlp-concurrent.png b/specification/protocol/img/otlp-concurrent.png new file mode 100644 index 0000000000000000000000000000000000000000..17d1ae18ec6e1a9c76bd07daffa5b37da8e15f9c GIT binary patch literal 9983 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 literal 0 HcmV?d00001 diff --git a/specification/protocol/img/otlp-multi-destination.png b/specification/protocol/img/otlp-multi-destination.png new file mode 100644 index 0000000000000000000000000000000000000000..743a9020bd9c38ab9baa80b72a6b7f2878dd3bb5 GIT binary patch literal 24900 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 b`e%p5nl8T<}yoZz}t+JG* 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�)=7u?R)o1%XULCn3ZXZM{42m zPb02fx^x!Gby<0N^?2_0YSZyjcP$<{*+D6XWtfiW-clNLg|z#&ZQI~tfjo>e#5)3| zW(dEbfOGOktNnvlvY}sEGL!fZo4zVBF*SYRfD#oIT?a0jjdJI`4f2RpF(>3#rWQ7I z0Od>_z_Ok0v zaI&OoIRWetN*$1>JfWv|+2+=@Ca3w`KV}UN^21#b4bo9rD5j?L#pK_)b2+?es2ob6 z18_YBahjFPEEji*7nPJ`pP8BY%~*nT7mb}KpJZZkWy#aS&GSR)8A!RnJ(SImK5z1* zLsB$ty}yu5rU4W% zi8VNubLQ`aWZPuz9xoPZts?)Qw==UnUXvy-o o?#j?(P$a5dC5RZ#{*`r2ZBcq@?#GV7RcizRXP|W#V|(`h0LhqB(EtDd literal 0 HcmV?d00001 diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md new file mode 100644 index 000000000..dd4739be0 --- /dev/null +++ b/specification/protocol/otlp.md @@ -0,0 +1,549 @@ +# OpenTelemetry Protocol Specification + +OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, +and delivery mechanism of telemetry data between telemetry sources, intermediate +nodes such as collectors and telemetry backends. + +## Table of Contents + +* [Table of Contents](#table-of-contents) +* [Protocol Details](#protocol-details) + * [OTLP/gRPC](#otlpgrpc) + * [Concurrent Requests](#concurrent-requests) + * [Response](#response) + * [Throttling](#throttling) + * [gRPC Service and Protobuf Definitions](#grpc-service-and-protobuf-definitions) + * [Default Port](#default-port) + * [OTLP/HTTP](#otlphttp) + * [Request](#request) + * [Response](#response-1) + * [Success](#success) + * [Failures](#failures) + * [Bad Data](#bad-data) + * [Throttling](#throttling-1) + * [All Other Responses](#all-other-responses) + * [Connection](#connection) + * [Concurrent Requests](#concurrent-requests-1) + * [Default Port](#default-port-1) +* [Implementation Recommendations](#implementation-recommendations) + * [Multi-Destination Exporting](#multi-destination-exporting) +* [Known Limitations](#known-limitations) + * [Request Acknowledgements](#request-acknowledgements) + * [Duplicate Data](#duplicate-data) + * [Partial Success](#partial-success) +* [Future Versions and Interoperability](#future-versions-and-interoperability) +* [Glossary](#glossary) +* [References](#references) + +OTLP is a general-purpose telemetry data delivery protocol designed in the scope +of OpenTelemetry project. + +## Protocol Details + +OTLP defines the encoding of telemetry data and the protocol used to exchange +data between the client and the server. + +This specification defines how OTLP is implemented over +[gRPC](https://grpc.io/) and HTTP 1.1 transports and specifies +[Protocol Buffers schema](https://developers.google.com/protocol-buffers/docs/overview) +that is used for the payloads. + +OTLP is a request/response style protocols: the clients send requests, the +server replies with corresponding responses. This document defines one requests +and response type: `Export`. + +### OTLP/gRPC + +After establishing the underlying gRPC transport the client starts sending +telemetry data using unary requests using +[Export*ServiceRequest](https://github.com/open-telemetry/opentelemetry-proto) +messages (`ExportTraceServiceRequest` for traces, `ExportMetricsServiceRequest` +for metrics, `ExportLogsServiceRequest` for logs). The client continuously sends +a sequence of requests to the server and expects to receive a response to each +request: + +![Request-Response](img/otlp-request-response.png) + +_Note: this protocol is concerned with reliability of delivery between one pair +of client/server nodes and aims to ensure that no data is lost in-transit +between the client and the server. Many telemetry collection systems have +intermediary nodes that the data must travel across until reaching the final +destination (e.g. application -> agent -> collector -> backend). End-to-end +delivery guarantees in such systems is outside of the scope of OTLP. The +acknowledgements described in this protocol happen between a single +client/server pair and do not span intermediary nodes in multi-hop delivery +paths._ + +#### Concurrent Requests + +After sending the request the client MAY wait until the response is received +from the server. In that case there will be at most only one request in flight +that is not yet acknowledged by the server. + +![Unary](img/otlp-sequential.png) + +Sequential operation is recommended when simplicity of implementation is +desirable and when the client and the server are connected via very low-latency +network, such as for example when the client is an instrumented application and +the server is a OpenTelemetry Collector running as a local daemon (agent). + +The implementations that need to achieve high throughput SHOULD support +concurrent Unary calls to achieve higher throughput. The client SHOULD send new +requests without waiting for the response to the earlier sent requests, +essentially creating a pipeline of requests that are currently in flight that +are not acknowledged. + +![Concurrent](img/otlp-concurrent.png) + +The number of concurrent requests SHOULD be configurable. + +The maximum achievable throughput is +`max_concurrent_requests * max_request_size / (network_latency + server_response_time)`. +For example if the request can contain at most 100 spans, network roundtrip +latency is 200ms and server response time is 300 ms, then the maximum achievable +throughput with one concurrent request is `100 spans / (200ms+300ms)` or 200 +spans per second. It is easy to see that in high latency networks or when the +server response time is high to achieve good throughput the requests need to be +very big or a lot concurrent requests must be done. + +If the client is shutting down (e.g. when the containing process wants to exit) +the client will optionally wait until all pending acknowledgements are received +or until an implementation specific timeout expires. This ensures reliable +delivery of telemetry data. The client implementation SHOULD expose an option to +turn on and off the waiting during shutdown. + +If the client is unable to deliver a certain request (e.g. a timer expired while +waiting for acknowledgements) the client SHOULD record the fact that the data +was not delivered. + +#### Response + +The server may respond with either a success or an error to the requests. + +The success response indicates telemetry data is successfully processed by the +server. If the server receives an empty request (a request that does not carry +any telemetry data) the server SHOULD respond with success. + +Success response is returned via +[Export*ServiceResponse](https://github.com/open-telemetry/opentelemetry-proto) +message (`ExportTraceServiceResponse` for traces, `ExportMetricsServiceResponse` +for metrics, `ExportLogsServiceResponse` for logs). + +When an error is returned by the server it falls into 2 broad categories: +retryable and not-retryable: + +- Retryable errors indicate that processing of telemetry data failed and the + client SHOULD record the error and may retry exporting the same data. This can + happen when the server is temporarily unable to process the data. + +- Not-retryable errors indicate that processing of telemetry data failed and the + client MUST NOT retry sending the same telemetry data. The telemetry data MUST + be dropped. This can happen, for example, when the request contains bad data + and cannot be deserialized or otherwise processed by the server. The client + SHOULD maintain a counter of such dropped data. + +The server MUST indicate retryable errors using code +[Unavailable](https://godoc.org/google.golang.org/grpc/codes) and MAY supply +additional +[details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) +using +[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40) +containing 0 value of RetryDelay. Here is a sample Go code to illustrate: + +```go + // Do this on server side. + st, err := status.New(codes.Unavailable, "Server is unavailable"). + WithDetails(&errdetails.RetryInfo{RetryDelay: &duration.Duration{Seconds: 0}}) + if err != nil { + log.Fatal(err) + } + + return st.Err() +``` + +To indicate not-retryable errors the server is recommended to use code +[InvalidArgument](https://godoc.org/google.golang.org/grpc/codes) and MAY supply +additional +[details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) +using +[BadRequest](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L119). +Other gRPC status code may be used if it is more appropriate. Here is a sample +Go code to illustrate: + +```go + // Do this on server side. + st, err := status.New(codes.InvalidArgument, "Invalid Argument"). + WithDetails(&errdetails.BadRequest{}) + if err != nil { + log.Fatal(err) + } + + return st.Err() +``` + +The server MAY use other gRPC codes to indicate retryable and not-retryable +errors if those other gRPC codes are more appropriate for a particular erroneous +situation. The client SHOULD interpret gRPC status codes as retryable or +not-retryable according to the following table: + +|gRPC Code|Retryable?| +|---------|----------| +|CANCELLED|Yes| +|UNKNOWN|No| +|INVALID_ARGUMENT|No| +|DEADLINE_EXCEEDED|Yes| +|NOT_FOUND|No| +|ALREADY_EXISTS|No| +|PERMISSION_DENIED|No| +|UNAUTHENTICATED|No| +|RESOURCE_EXHAUSTED|Yes| +|FAILED_PRECONDITION|No| +|ABORTED|Yes| +|OUT_OF_RANGE|Yes| +|UNIMPLEMENTED|No| +|INTERNAL|No| +|UNAVAILABLE|Yes| +|DATA_LOSS|Yes| + +When retrying, the client SHOULD implement an exponential backoff strategy. An +exception to this is the Throttling case explained below, which provides +explicit instructions about retrying interval. + +#### Throttling + +OTLP allows backpressure signalling. + +If the server is unable to keep up with the pace of data it receives from the +client then it SHOULD signal that fact to the client. The client MUST then +throttle itself to avoid overwhelming the server. + +To signal backpressure when using gRPC transport, the server MUST return an +error with code [Unavailable](https://godoc.org/google.golang.org/grpc/codes) +and MAY supply additional +[details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) +using +[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40). +Here is a sample Go code to illustrate: + +```go + // Do this on server side. + st, err := status.New(codes.Unavailable, "Server is unavailable"). + WithDetails(&errdetails.RetryInfo{RetryDelay: &duration.Duration{Seconds: 30}}) + if err != nil { + log.Fatal(err) + } + + return st.Err() + + ... + + // Do this on client side. + st := status.Convert(err) + for _, detail := range st.Details() { + switch t := detail.(type) { + case *errdetails.RetryInfo: + if t.RetryDelay.Seconds > 0 || t.RetryDelay.Nanos > 0 { + // Wait before retrying. + } + } + } +``` + +When the client receives this signal it SHOULD follow the recommendations +outlined in documentation for +[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40): + +``` +// Describes when the clients can retry a failed request. Clients could ignore +// the recommendation here or retry when this information is missing from error +// responses. +// +// It's always recommended that clients should use exponential backoff when +// retrying. +// +// Clients should wait until `retry_delay` amount of time has passed since +// receiving the error response before retrying. If retrying requests also +// fail, clients should use an exponential backoff scheme to gradually increase +// the delay between retries based on `retry_delay`, until either a maximum +// number of retires have been reached or a maximum retry delay cap has been +// reached. +``` + +The value of `retry_delay` is determined by the server and is implementation +dependant. The server SHOULD choose a `retry_delay` value that is big enough to +give the server time to recover, yet is not too big to cause the client to drop +data while it is throttled. + +#### gRPC Service and Protobuf Definitions + +gRPC service definitions +[are here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto/collector). + +Protobuf definitions for requests and responses +[are here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto). + +Please make sure to check the proto version and +[maturity level](https://github.com/open-telemetry/opentelemetry-proto/#maturity-level). +Schemas for different signals may be at different maturity level - some stable, +some in beta. + +#### Default Port + +The default network port for OTLP/gRPC is 55680. + +### OTLP/HTTP + +OTLP/HTTP uses Protobuf payloads encoded either in binary format or in JSON +format. The Protobuf schema of the messages is the same for OTLP/HTTP and +OTLP/gRPC. + +OTLP/HTTP uses HTTP POST requests to send telemetry data from clients to +servers. Implementations MAY use HTTP/1.1 or HTTP/2 transports. Implementations +that use HTTP/2 transport SHOULD fallback to HTTP/1.1 transport if HTTP/2 +connection cannot be established. + +#### Request + +Telemetry data is sent via HTTP POST request. The body of the POST request is a +payload either in binary-encoded Protobuf format or in JSON-encoded Protobuf +format. + +The default URL path for requests that carry trace data is `/v1/traces` (for +example the full URL when connecting to "example.com" server will be +`https://example.com/v1/traces`). The request body is a Protobuf-encoded +`ExportTraceServiceRequest` message. + +The default URL path for requests that carry metric data is `/v1/metrics` and +the request body is a Protobuf-encoded `ExportMetricsServiceRequest` message. + +The default URL path for requests that carry log data is `/v1/logs` and the +request body is a Protobuf-encoded `ExportLogsServiceRequest` message. + +The client MUST set "Content-Type: application/x-protobuf" request header when +sending binary-encoded Protobuf or "Content-Type: application/json" request +header when sending JSON encoded Protobuf payload. + +The client MAY gzip the content and in that case SHOULD include +"Content-Encoding: gzip" request header. The client MAY include +"Accept-Encoding: gzip" request header if it can receive gzip-encoded responses. + +Non-default URL paths for requests MAY be configured on the client and server +sides. + +JSON-encoded Protobuf payloads use proto3 standard defined +[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) +for mapping between Protobuf and JSON. `trace_id` and `span_id` is base64 +encoded, not hex. + +#### Response + +Response body MUST be the appropriate serialized Protobuf message (see below for +the specific message to use in the Success and Failure cases). + +The server MUST set "Content-Type: application/x-protobuf" header if the +response body is binary-encoded Protobuf payload. The server MUST set +"Content-Type: application/json" if the response is JSON-encoded Protobuf +payload. The server MUST use the same "Content-Type" in the response as it +received in the request. + +If the request header "Accept-Encoding: gzip" is present in the request the +server MAY gzip-encode the response and set "Content-Encoding: gzip" response +header. + +##### Success + +On success the server MUST respond with `HTTP 200 OK`. Response body MUST be +Protobuf-encoded `ExportTraceServiceResponse` message for traces, +`ExportMetricsServiceResponse` message for metrics and +`ExportLogsServiceResponse` message for logs. + +The server SHOULD respond with success no sooner than after successfully +decoding and validating the request. + +##### Failures + +If the processing of the request fails the server MUST respond with appropriate +`HTTP 4xx` or `HTTP 5xx` status code. See sections below for more details about +specific failure cases and HTTP status codes that should be used. + +Response body for all `HTTP 4xx` and `HTTP 5xx` responses MUST be a +Protobuf-encoded +[Status](https://godoc.org/google.golang.org/genproto/googleapis/rpc/status#Status) +message that describes the problem. + +This specification does not use `Status.code` field and the server MAY omit +`Status.code` field. The clients are not expected to alter their behavior based +on `Status.code` field but MAY record it for troubleshooting purposes. + +The `Status.message` field SHOULD contain a developer-facing error message as +defined in `Status` message schema. + +The server MAY include `Status.details` field with additional details. Read +below about what this field can contain in each specific failure case. + +##### Bad Data + +If the processing of the request fails because the request contains data that +cannot be decoded or is otherwise invalid and such failure is permanent then the +server MUST respond with `HTTP 400 Bad Request`. The `Status.details` field in +the response SHOULD contain a +[BadRequest](https://github.com/googleapis/googleapis/blob/d14bf59a446c14ef16e9931ebfc8e63ab549bf07/google/rpc/error_details.proto#L166) +that describes the bad data. + +The client MUST NOT retry the request when it receives `HTTP 400 Bad Request` +response. + +##### Throttling + +If the server receives more requests than the client is allowed or the server is +overloaded the server SHOULD respond with `HTTP 429 Too Many Requests` or +`HTTP 503 Service Unavailable` and MAY include +["Retry-After"](https://tools.ietf.org/html/rfc7231#section-7.1.3) header with a +recommended time interval in seconds to wait before retrying. + +The client SHOULD honour the waiting interval specified in "Retry-After" header +if it is present. If the client receives `HTTP 429` or `HTTP 503` response and +"Retry-After" header is not present in the response then the client SHOULD +implement an exponential backoff strategy between retries. + +##### All Other Responses + +All other HTTP responses that are not explicitly listed in this document should +be treated according to HTTP specification. + +If the server disconnects without returning a response the client SHOULD retry +and send the same request. The client SHOULD implement an exponential backoff +strategy between retries to avoid overwhelming the server. + +#### Connection + +If the client is unable to connect to the server the client SHOULD retry the +connection using exponential backoff strategy between retries. The interval +between retries must have a random jitter. + +The client SHOULD keep the connection alive between requests. + +Server implementations SHOULD accept OTLP/HTTP with binary-encoded Protobuf +payload and OTLP/HTTP with JSON-encoded Protobuf payload requests on the same +port and multiplex the requests to the corresponding payload decoder based on +the "Content-Type" request header. + +Server implementations MAY accept OTLP/gRPC and OTLP/HTTP requests on the same +port and multiplex the connections to the corresponding transport handler based +on the "Content-Type" request header. + +#### Concurrent Requests + +To achieve higher total throughput the client MAY send requests using several +parallel HTTP connections. In that case the maximum number of parallel +connections SHOULD be configurable. + +#### Default Port + +The default network port for OTLP/HTTP is 55681. There is currently an [open +issue](https://github.com/open-telemetry/opentelemetry-collector/issues/1256) to +use the same port for OTLP/gRPC and OTLP/HTTP. In that case this spec will be +updated to use the same default port for OTLP/gRPC and OTLP/HTTP. + +## Implementation Recommendations + +### Multi-Destination Exporting + +When the telemetry data from one client must be sent to more than one +destination server there is an additional complication that must be accounted +for. When one of the servers acknowledges the data and the other server does not +(yet) acknowledges the client needs to make a decision about how to move +forward. + +In such situation the the client SHOULD implement queuing, acknowledgement +handling and retrying logic per destination. This ensures that servers do not +block each other. The queues SHOULD reference shared, immutable data to be sent, +thus minimizing the memory overhead caused by having multiple queues. + +![Multi-Destination Exporting](img/otlp-multi-destination.png) + +This ensures that all destination servers receive the data regardless of their +speed of reception (within the available limits imposed by the size of the +client-side queue). + +## Known Limitations + +### Request Acknowledgements + +#### Duplicate Data + +In edge cases (e.g. on reconnections, network interruptions, etc) the client has +no way of knowing if recently sent data was delivered if no acknowledgement was +received yet. The client will typically choose to re-send such data to guarantee +delivery, which may result in duplicate data on the server side. This is a +deliberate choice and is considered to be the right tradeoff for telemetry data. + +### Partial Success + +The protocol does not attempt to communicate partial reception success from the +server to the client (i.e. when part of the data can be received by the server +and part of it cannot). Attempting to do so would complicate the protocol and +implementations significantly and is left out as a possible future area of work. + +## Future Versions and Interoperability + +OTLP will evolve and change over time. Future versions of OTLP must be designed +and implemented in a way that ensures that clients and servers that implement +different versions of OTLP can interoperate and exchange telemetry data. Old +clients must be able to talk to new servers and vice versa. If new versions of +OTLP introduce new functionality that cannot be understood and supported by +nodes implementing the old versions of OTLP the protocol must regress to the +lowest common denominator from functional perspective. + +When possible the interoperability MUST be ensured between all versions of +OTLP that are not declared obsolete. + +OTLP does not use explicit protocol version numbering. OTLP's interoperability +of clients and servers of different versions is based on the following concepts: + +1. OTLP (current and future versions) defines a set of capabilities, some of + which are mandatory, others are optional. Clients and servers must implement + mandatory capabilities and can choose implement only a subset of optional + capabilities. + +2. For minor changes to the protocol future versions and extension of OTLP are + encouraged to use the ability of Protobufs to evolve message schema in + backwards compatible manner. Newer versions of OTLP may add new fields to + messages that will be ignored by clients and servers that do not understand + these fields. In many cases careful design of such schema changes and correct + choice of default values for new fields is enough to ensure interoperability + of different versions without nodes explicitly detecting that their peer node + has different capabilities. + +3. More significant changes must be explicitly defined as new optional + capabilities in future OTEPs. Such capabilities SHOULD be discovered by + client and server implementations after establishing the underlying + transport. The exact discovery mechanism SHOULD be described in future OTEPs + which define the new capabilities and typically can be implemented by making + a discovery request/response message exchange from the client to server. The + mandatory capabilities defined by this specification are implied and do not + require a discovery. The implementation which supports a new, optional + capability MUST adjust its behavior to match the expectation of a peer that + does not support a particular capability. + +## Glossary + +There are 2 parties involved in telemetry data exchange. In this document the +party that is the source of telemetry data is called the `Client`, the party +that is the destination of telemetry data is called the `Server`. + +![Client-Server](img/otlp-client-server.png) + +Examples of a Client are instrumented applications or sending side of telemetry +collectors, examples of Servers are telemetry backends or receiving side of +telemetry collectors (so a Collector is typically both a Client and a Server +depending on which side you look from). + +Both the Client and the Server are also a `Node`. This term is used in the +document when referring to either one. + +## References + +- [OTEP 0035](https://github.com/open-telemetry/oteps/blob/master/text/0035-opentelemetry-protocol.md) OpenTelemetry Protocol Specification +- [OTEP 0099](https://github.com/open-telemetry/oteps/blob/master/text/0099-otlp-http.md) OTLP/HTTP: HTTP Transport Extension for OTLP +- [OTEP 0122](https://github.com/open-telemetry/oteps/blob/master/text/0122-otlp-http-json.md) OTLP: JSON Encoding for OTLP/HTTP From 3a56263190b5d956535dd03faeb9d44bc66f8124 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 17 Aug 2020 19:36:01 -0400 Subject: [PATCH 016/127] Add link to OTLP specification from README (#816) --- specification/protocol/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/protocol/README.md b/specification/protocol/README.md index bf2560c63..d0357ccdb 100644 --- a/specification/protocol/README.md +++ b/specification/protocol/README.md @@ -1,7 +1,7 @@ # OpenTelemetry Protocol -This is the specification of new OpenTelemetry protocol. This is work in progress. +This is the specification of new OpenTelemetry protocol (OTLP). - [Design Goals](design-goals.md). - [Requirements](requirements.md). -- Specification (TBD). +- [Specification](otlp.md). From 68c5856b64e025ebbd1200efcc0f642dfeead0f7 Mon Sep 17 00:00:00 2001 From: alrex Date: Wed, 19 Aug 2020 12:51:06 -0500 Subject: [PATCH 017/127] Allow specifying a single configuration (#820) * Allow specifying a single configuration The following change describes that the OTLP exporter must support configuration for all signals via a single set of configuration options. There is also an example for configuring different signals with different endpoints via environment variables. * adding a third example * moving otlp exporter into protocol directory * add link to exporter from readme * apply review feedback --- specification/protocol/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/protocol/README.md b/specification/protocol/README.md index d0357ccdb..2d7ecec94 100644 --- a/specification/protocol/README.md +++ b/specification/protocol/README.md @@ -5,3 +5,4 @@ This is the specification of new OpenTelemetry protocol (OTLP). - [Design Goals](design-goals.md). - [Requirements](requirements.md). - [Specification](otlp.md). +- [SDK Exporter](exporter.md). From 25eb61c76634d97739c908da5a9cd1f61ac9fa37 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 8 Sep 2020 19:36:21 -0400 Subject: [PATCH 018/127] Use hex encoding for trace id and span id fields in OTLP JSON encoding (#911) Resolves: https://github.com/open-telemetry/opentelemetry-specification/issues/786 See discussion and motivation for the change in the issue linked above. Co-authored-by: Sergey Kanzhelev --- specification/protocol/otlp.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index dd4739be0..5be5a40e8 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -332,8 +332,13 @@ sides. JSON-encoded Protobuf payloads use proto3 standard defined [JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) -for mapping between Protobuf and JSON. `trace_id` and `span_id` is base64 -encoded, not hex. +for mapping between Protobuf and JSON, with one deviation from that mapping: the +`trace_id` and `span_id` byte arrays are represented as +[case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8), +they are not base64-encoded like it is defined in the standard +[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). +The hex encoding is used for `trace_id` and `span_id` fields in all OTLP +Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. #### Response From 90245b8f4e4f72646c2b01aaa203f05e3bdc78e7 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 30 Sep 2020 14:48:22 -0400 Subject: [PATCH 019/127] Fix the unclear SHOULD requirement for "gzip" OTLP content type (#1038) MUST is the correct requirement here. There is no situation when a different content type is a better choice. --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 5be5a40e8..c2342343d 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -323,7 +323,7 @@ The client MUST set "Content-Type: application/x-protobuf" request header when sending binary-encoded Protobuf or "Content-Type: application/json" request header when sending JSON encoded Protobuf payload. -The client MAY gzip the content and in that case SHOULD include +The client MAY gzip the content and in that case MUST include "Content-Encoding: gzip" request header. The client MAY include "Accept-Encoding: gzip" request header if it can receive gzip-encoded responses. From 0472f8cfa268b0d735468409cba2221435a2af6b Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 16 Nov 2020 14:33:01 -0500 Subject: [PATCH 020/127] Change default OTLP port number (#1221) * Change default OTLP port number Contributes to https://github.com/open-telemetry/opentelemetry-specification/issues/1148 Note that a separate port is used for OTLP/HTTP for now. There is currently work in progress to confirm that we can use the same port. Once we have the confirmation I will update the spec again to use one port. * Address PR comments --- specification/protocol/otlp.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index c2342343d..00e7db36d 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -289,7 +289,7 @@ some in beta. #### Default Port -The default network port for OTLP/gRPC is 55680. +The default network port for OTLP/gRPC is 4317. ### OTLP/HTTP @@ -445,10 +445,7 @@ connections SHOULD be configurable. #### Default Port -The default network port for OTLP/HTTP is 55681. There is currently an [open -issue](https://github.com/open-telemetry/opentelemetry-collector/issues/1256) to -use the same port for OTLP/gRPC and OTLP/HTTP. In that case this spec will be -updated to use the same default port for OTLP/gRPC and OTLP/HTTP. +The default network port for OTLP/HTTP is 4317. ## Implementation Recommendations From 9be4aed961f99a02e29349723f67e677bbe8abfd Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 30 Nov 2020 09:33:56 -0500 Subject: [PATCH 021/127] Remove support to allow_different_nesting, from markdownlint (#1248) * Remove support to allow_different_nesting, from markdownlint Signed-off-by: Bogdan Drutu * Update specification/metrics/semantic_conventions/README.md Co-authored-by: Armin Ruech * Run markdown-toc Signed-off-by: Bogdan Drutu Co-authored-by: Armin Ruech --- specification/protocol/otlp.md | 72 +++++++++++++++++----------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 00e7db36d..258cd2aff 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -4,36 +4,38 @@ OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, and delivery mechanism of telemetry data between telemetry sources, intermediate nodes such as collectors and telemetry backends. -## Table of Contents +
+ +Table of Contents + -* [Table of Contents](#table-of-contents) -* [Protocol Details](#protocol-details) +- [Protocol Details](#protocol-details) * [OTLP/gRPC](#otlpgrpc) - * [Concurrent Requests](#concurrent-requests) - * [Response](#response) - * [Throttling](#throttling) - * [gRPC Service and Protobuf Definitions](#grpc-service-and-protobuf-definitions) - * [Default Port](#default-port) + + [OTLP/gRPC Concurrent Requests](#otlpgrpc-concurrent-requests) + + [OTLP/gRPC Response](#otlpgrpc-response) + + [OTLP/gRPC Throttling](#otlpgrpc-throttling) + + [OTLP/gRPC Service and Protobuf Definitions](#otlpgrpc-service-and-protobuf-definitions) + + [OTLP/gRPC Default Port](#otlpgrpc-default-port) * [OTLP/HTTP](#otlphttp) - * [Request](#request) - * [Response](#response-1) - * [Success](#success) - * [Failures](#failures) - * [Bad Data](#bad-data) - * [Throttling](#throttling-1) - * [All Other Responses](#all-other-responses) - * [Connection](#connection) - * [Concurrent Requests](#concurrent-requests-1) - * [Default Port](#default-port-1) -* [Implementation Recommendations](#implementation-recommendations) + + [OTLP/HTTP Request](#otlphttp-request) + + [OTLP/HTTP Response](#otlphttp-response) + - [Success](#success) + - [Failures](#failures) + - [Bad Data](#bad-data) + - [OTLP/HTTP Throttling](#otlphttp-throttling) + - [All Other Responses](#all-other-responses) + + [OTLP/HTTP Connection](#otlphttp-connection) + + [OTLP/HTTP Concurrent Requests](#otlphttp-concurrent-requests) + + [OTLP/HTTP Default Port](#otlphttp-default-port) +- [Implementation Recommendations](#implementation-recommendations) * [Multi-Destination Exporting](#multi-destination-exporting) -* [Known Limitations](#known-limitations) +- [Known Limitations](#known-limitations) * [Request Acknowledgements](#request-acknowledgements) - * [Duplicate Data](#duplicate-data) + + [Duplicate Data](#duplicate-data) * [Partial Success](#partial-success) -* [Future Versions and Interoperability](#future-versions-and-interoperability) -* [Glossary](#glossary) -* [References](#references) +- [Future Versions and Interoperability](#future-versions-and-interoperability) +- [Glossary](#glossary) +- [References](#references) OTLP is a general-purpose telemetry data delivery protocol designed in the scope of OpenTelemetry project. @@ -74,7 +76,7 @@ acknowledgements described in this protocol happen between a single client/server pair and do not span intermediary nodes in multi-hop delivery paths._ -#### Concurrent Requests +#### OTLP/gRPC Concurrent Requests After sending the request the client MAY wait until the response is received from the server. In that case there will be at most only one request in flight @@ -116,7 +118,7 @@ If the client is unable to deliver a certain request (e.g. a timer expired while waiting for acknowledgements) the client SHOULD record the fact that the data was not delivered. -#### Response +#### OTLP/gRPC Response The server may respond with either a success or an error to the requests. @@ -209,7 +211,7 @@ When retrying, the client SHOULD implement an exponential backoff strategy. An exception to this is the Throttling case explained below, which provides explicit instructions about retrying interval. -#### Throttling +#### OTLP/gRPC Throttling OTLP allows backpressure signalling. @@ -274,7 +276,7 @@ dependant. The server SHOULD choose a `retry_delay` value that is big enough to give the server time to recover, yet is not too big to cause the client to drop data while it is throttled. -#### gRPC Service and Protobuf Definitions +#### OTLP/gRPC Service and Protobuf Definitions gRPC service definitions [are here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto/collector). @@ -287,7 +289,7 @@ Please make sure to check the proto version and Schemas for different signals may be at different maturity level - some stable, some in beta. -#### Default Port +#### OTLP/gRPC Default Port The default network port for OTLP/gRPC is 4317. @@ -302,7 +304,7 @@ servers. Implementations MAY use HTTP/1.1 or HTTP/2 transports. Implementations that use HTTP/2 transport SHOULD fallback to HTTP/1.1 transport if HTTP/2 connection cannot be established. -#### Request +#### OTLP/HTTP Request Telemetry data is sent via HTTP POST request. The body of the POST request is a payload either in binary-encoded Protobuf format or in JSON-encoded Protobuf @@ -340,7 +342,7 @@ they are not base64-encoded like it is defined in the standard The hex encoding is used for `trace_id` and `span_id` fields in all OTLP Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. -#### Response +#### OTLP/HTTP Response Response body MUST be the appropriate serialized Protobuf message (see below for the specific message to use in the Success and Failure cases). @@ -398,7 +400,7 @@ that describes the bad data. The client MUST NOT retry the request when it receives `HTTP 400 Bad Request` response. -##### Throttling +##### OTLP/HTTP Throttling If the server receives more requests than the client is allowed or the server is overloaded the server SHOULD respond with `HTTP 429 Too Many Requests` or @@ -420,7 +422,7 @@ If the server disconnects without returning a response the client SHOULD retry and send the same request. The client SHOULD implement an exponential backoff strategy between retries to avoid overwhelming the server. -#### Connection +#### OTLP/HTTP Connection If the client is unable to connect to the server the client SHOULD retry the connection using exponential backoff strategy between retries. The interval @@ -437,13 +439,13 @@ Server implementations MAY accept OTLP/gRPC and OTLP/HTTP requests on the same port and multiplex the connections to the corresponding transport handler based on the "Content-Type" request header. -#### Concurrent Requests +#### OTLP/HTTP Concurrent Requests To achieve higher total throughput the client MAY send requests using several parallel HTTP connections. In that case the maximum number of parallel connections SHOULD be configurable. -#### Default Port +#### OTLP/HTTP Default Port The default network port for OTLP/HTTP is 4317. From 6e1fed8e2048c30e1c859e08f018aadaede8dbc6 Mon Sep 17 00:00:00 2001 From: Zhongyang Wu Date: Mon, 7 Dec 2020 09:26:13 -0500 Subject: [PATCH 022/127] fix: otlp.md missing closing details label. (#1278) ## Changes It seems wired that the closing tag of `
` is missing. As a result, most of the content has been folded. Added a closing `
` tags to only fold the table of contents. Before the change: ![image](https://user-images.githubusercontent.com/12531298/101312037-ccbd5080-3820-11eb-89d0-e153de96dacd.png) After the change: ![image](https://user-images.githubusercontent.com/12531298/101312107-ef4f6980-3820-11eb-86c9-f8a35627dc9b.png) --- specification/protocol/otlp.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 258cd2aff..8255abf43 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -37,6 +37,8 @@ Table of Contents - [Glossary](#glossary) - [References](#references) +
+ OTLP is a general-purpose telemetry data delivery protocol designed in the scope of OpenTelemetry project. From 6b3e559a5fae67a8b6aad7a2fa0980b22339f836 Mon Sep 17 00:00:00 2001 From: Ted Young Date: Wed, 20 Jan 2021 11:13:47 -0800 Subject: [PATCH 023/127] Versioning and Stability for OpenTelemetry (#1291) * Versioning and support based on OTEP 143 --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 8255abf43..6a93c7063 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -89,7 +89,7 @@ that is not yet acknowledged by the server. Sequential operation is recommended when simplicity of implementation is desirable and when the client and the server are connected via very low-latency network, such as for example when the client is an instrumented application and -the server is a OpenTelemetry Collector running as a local daemon (agent). +the server is an OpenTelemetry Collector running as a local daemon (agent). The implementations that need to achieve high throughput SHOULD support concurrent Unary calls to achieve higher throughput. The client SHOULD send new From f0b09bb9337d60d31a8268e9321a00171d6daf4a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 27 Jan 2021 15:04:40 -0800 Subject: [PATCH 024/127] Update links/github actions after the master -> main rename (#1384) Signed-off-by: Bogdan Drutu --- specification/protocol/otlp.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 6a93c7063..10b8d54c8 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -550,6 +550,6 @@ document when referring to either one. ## References -- [OTEP 0035](https://github.com/open-telemetry/oteps/blob/master/text/0035-opentelemetry-protocol.md) OpenTelemetry Protocol Specification -- [OTEP 0099](https://github.com/open-telemetry/oteps/blob/master/text/0099-otlp-http.md) OTLP/HTTP: HTTP Transport Extension for OTLP -- [OTEP 0122](https://github.com/open-telemetry/oteps/blob/master/text/0122-otlp-http-json.md) OTLP: JSON Encoding for OTLP/HTTP +- [OTEP 0035](https://github.com/open-telemetry/oteps/blob/main/text/0035-opentelemetry-protocol.md) OpenTelemetry Protocol Specification +- [OTEP 0099](https://github.com/open-telemetry/oteps/blob/main/text/0099-otlp-http.md) OTLP/HTTP: HTTP Transport Extension for OTLP +- [OTEP 0122](https://github.com/open-telemetry/oteps/blob/main/text/0122-otlp-http-json.md) OTLP: JSON Encoding for OTLP/HTTP From 95cba31e61ee3a4c5a6162163bee2e3d8d69c624 Mon Sep 17 00:00:00 2001 From: Ted Young Date: Thu, 4 Feb 2021 06:06:46 -0800 Subject: [PATCH 025/127] Add lifecycle statuses to all documents (#1385) --- specification/protocol/otlp.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 10b8d54c8..8ed0497bc 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -1,5 +1,7 @@ # OpenTelemetry Protocol Specification +**Status**: [Mixed](../document-status.md) + OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, and delivery mechanism of telemetry data between telemetry sources, intermediate nodes such as collectors and telemetry backends. @@ -58,6 +60,8 @@ and response type: `Export`. ### OTLP/gRPC +**Status**: [Stable](../document-status.md) + After establishing the underlying gRPC transport the client starts sending telemetry data using unary requests using [Export*ServiceRequest](https://github.com/open-telemetry/opentelemetry-proto) @@ -297,6 +301,8 @@ The default network port for OTLP/gRPC is 4317. ### OTLP/HTTP +**Status**: [Experimental](../document-status.md) + OTLP/HTTP uses Protobuf payloads encoded either in binary format or in JSON format. The Protobuf schema of the messages is the same for OTLP/HTTP and OTLP/gRPC. From 4b1f210c0cf5bcdd6c1580cafc2e3f4444c67e8e Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Fri, 5 Feb 2021 20:01:17 +0100 Subject: [PATCH 026/127] OTLP stability clarifications (#1400) --- specification/protocol/otlp.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 8ed0497bc..0bbac03c6 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -11,6 +11,7 @@ nodes such as collectors and telemetry backends. Table of Contents +- [Signals Maturity Level](#signals-maturity-level) - [Protocol Details](#protocol-details) * [OTLP/gRPC](#otlpgrpc) + [OTLP/gRPC Concurrent Requests](#otlpgrpc-concurrent-requests) @@ -44,6 +45,17 @@ Table of Contents OTLP is a general-purpose telemetry data delivery protocol designed in the scope of OpenTelemetry project. +## Signals Maturity Level + +Each signal has different support and stability in OTLP, described through its +own maturity level, which in turn applies to **all** the OTLP Transports listed below. + +* Tracing: **Stable** +* Metrics: **Beta** +* Logs: **Alpha** + +See [OTLP Maturity Level](https://github.com/open-telemetry/opentelemetry-proto#maturity-level). + ## Protocol Details OTLP defines the encoding of telemetry data and the protocol used to exchange @@ -301,7 +313,8 @@ The default network port for OTLP/gRPC is 4317. ### OTLP/HTTP -**Status**: [Experimental](../document-status.md) +**Binary Format Status**: [Stable](../document-status.md) +**JSON Format Status**: [Experimental](../document-status.md) OTLP/HTTP uses Protobuf payloads encoded either in binary format or in JSON format. The Protobuf schema of the messages is the same for OTLP/HTTP and From bb9fddff37bb8198066bd7155fd7cdff4846e57b Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 27 Apr 2021 12:46:18 -0400 Subject: [PATCH 027/127] Clarify that 64 bit integer numbers are decimal strings in OTLP/JSON (#1637) Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/268 This behavior is already the documented behavior for JSON Protobuf, see https://developers.google.com/protocol-buffers/docs/proto3#json: >JSON value will be a decimal string. Either numbers or strings are accepted. --- specification/protocol/otlp.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 0bbac03c6..241558d95 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -363,6 +363,11 @@ they are not base64-encoded like it is defined in the standard The hex encoding is used for `trace_id` and `span_id` fields in all OTLP Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. +Note that according to [Protobuf specs]( +https://developers.google.com/protocol-buffers/docs/proto3#json) 64-bit integer +numbers in JSON-encoded payloads are encoded as decimal strings, and either +numbers or strings are accepted when decoding. + #### OTLP/HTTP Response Response body MUST be the appropriate serialized Protobuf message (see below for From cff7fa16d0e87b994f0b7bdb0f9845ea934c46fe Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 7 Jun 2021 17:07:44 -0400 Subject: [PATCH 028/127] Mark relevant portions of Metrics DataModel stable (#1728) * Mark sections of datamodel stable. * Generated ToC * Clean up MUST and SHOULD in the document. * adjust for bug in markdown-toc * Mark protocol as stable. Co-authored-by: Carlos Alberto Cortez --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 241558d95..14e29a35b 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -51,7 +51,7 @@ Each signal has different support and stability in OTLP, described through its own maturity level, which in turn applies to **all** the OTLP Transports listed below. * Tracing: **Stable** -* Metrics: **Beta** +* Metrics: **Stable** * Logs: **Alpha** See [OTLP Maturity Level](https://github.com/open-telemetry/opentelemetry-proto#maturity-level). From a5a5e5b18a573ea09ce84ee00f533a32cec3119a Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 8 Jun 2021 10:55:44 -0400 Subject: [PATCH 029/127] Declare OTLP Logs Beta (#1741) The Log SIG discussed and made a decision to declare Log data model and Log part of OTLP Beta. (See SIG meeting notes here https://docs.google.com/document/d/1cX5fWXyWqVVzYHSFUymYUfWxUK5hT97gc23w595LmdM/edit#heading=h.28y76as82bvu) --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 14e29a35b..6c83e2dc5 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -52,7 +52,7 @@ own maturity level, which in turn applies to **all** the OTLP Transports listed * Tracing: **Stable** * Metrics: **Stable** -* Logs: **Alpha** +* Logs: **Beta** See [OTLP Maturity Level](https://github.com/open-telemetry/opentelemetry-proto#maturity-level). From dddbb4290578d2a1ae73f99db69e53e9a618874b Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 3 Aug 2021 12:05:31 +0400 Subject: [PATCH 030/127] Change OTLP/HTTP port from 4317 to 4318 (#1839) Related to https://github.com/open-telemetry/opentelemetry-specification/issues/1816 Fixes https://github.com/open-telemetry/opentelemetry-specification/issues/1835 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: https://github.com/open-telemetry/opentelemetry-collector/issues/1256 The conclusion is that there are technical hurdles that make it unfeasible: https://github.com/open-telemetry/opentelemetry-collector/issues/1256#issuecomment-880048833 Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: https://github.com/open-telemetry/opentelemetry-specification/issues/1148#issuecomment-725067404 --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 6c83e2dc5..16ffe30fd 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -473,7 +473,7 @@ connections SHOULD be configurable. #### OTLP/HTTP Default Port -The default network port for OTLP/HTTP is 4317. +The default network port for OTLP/HTTP is 4318. ## Implementation Recommendations From 79216bb39b05d519e613af4a136e20b75d3f696c Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 6 Aug 2021 12:32:28 +0400 Subject: [PATCH 031/127] Revert "Change OTLP/HTTP port from 4317 to 4318 (#1839)" (#1847) Apparently there is new evidence that one port may work after all: https://github.com/open-telemetry/opentelemetry-collector/pull/3765/files This reverts commit cce1d5996873de38a68e05eafa4d5e224df9b8f1 until we have the final decision about the ability to have a single port, see: https://github.com/open-telemetry/opentelemetry-specification/issues/1846#issuecomment-892523208 --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 16ffe30fd..6c83e2dc5 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -473,7 +473,7 @@ connections SHOULD be configurable. #### OTLP/HTTP Default Port -The default network port for OTLP/HTTP is 4318. +The default network port for OTLP/HTTP is 4317. ## Implementation Recommendations From 0aea3fed0a926267b0fc893d4cb7d4cf521dcdd8 Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Wed, 29 Sep 2021 12:40:23 +0200 Subject: [PATCH 032/127] Clarify OTLP server components MUST support none/gzip compression. (#1955) --- specification/protocol/otlp.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 6c83e2dc5..0e5e6da0b 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -70,6 +70,11 @@ OTLP is a request/response style protocols: the clients send requests, the server replies with corresponding responses. This document defines one requests and response type: `Export`. +All server components MUST support the following transport compression options: + +* No compression, denotated by `none`. +* Gzip compression, denoted by `gzip`. + ### OTLP/gRPC **Status**: [Stable](../document-status.md) From b52a1d72221ddd8386bc88df690f6bd4f6e879ff Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 29 Sep 2021 16:50:55 -0400 Subject: [PATCH 033/127] Change OTLP/HTTP port from 4317 to 4318 (#1839) (#1970) Related to https://github.com/open-telemetry/opentelemetry-specification/issues/1816 Fixes https://github.com/open-telemetry/opentelemetry-specification/issues/1835 Fixes https://github.com/open-telemetry/opentelemetry-specification/issues/1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: https://github.com/open-telemetry/opentelemetry-collector/issues/1256 The conclusion is that there are technical hurdles that make it unfeasible: https://github.com/open-telemetry/opentelemetry-collector/issues/1256#issuecomment-880048833 Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: https://github.com/open-telemetry/opentelemetry-specification/issues/1148#issuecomment-725067404 There was also a draft PR to merge the ports in the Collector but it was not completed: https://github.com/open-telemetry/opentelemetry-collector/pull/3765 Note that this change was initially submitted in PR https://github.com/open-telemetry/opentelemetry-specification/pull/1839 and then reverted in PR https://github.com/open-telemetry/opentelemetry-specification/pull/1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change. --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 0e5e6da0b..ff5f5679a 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -478,7 +478,7 @@ connections SHOULD be configurable. #### OTLP/HTTP Default Port -The default network port for OTLP/HTTP is 4317. +The default network port for OTLP/HTTP is 4318. ## Implementation Recommendations From 494e79c516311035e3eb665eed626c14161afa49 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 24 Nov 2021 09:57:38 -0500 Subject: [PATCH 034/127] Ensure all ToCs are generated using markdown-toc (#2146) --- specification/protocol/otlp.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index ff5f5679a..d4f605ab3 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -7,9 +7,9 @@ and delivery mechanism of telemetry data between telemetry sources, intermediate nodes such as collectors and telemetry backends.
- -Table of Contents - +Table of Contents + + - [Signals Maturity Level](#signals-maturity-level) - [Protocol Details](#protocol-details) @@ -40,6 +40,8 @@ Table of Contents - [Glossary](#glossary) - [References](#references) + +
OTLP is a general-purpose telemetry data delivery protocol designed in the scope @@ -259,7 +261,7 @@ Here is a sample Go code to illustrate: } return st.Err() - + ... // Do this on client side. From 9347edb92a1b02b7b896f13881f13227d206ff8c Mon Sep 17 00:00:00 2001 From: Nicholas Volker <45795784+nvolker@users.noreply.github.com> Date: Fri, 18 Mar 2022 17:58:13 +0200 Subject: [PATCH 035/127] Duplicate word removal (#2423) --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index d4f605ab3..462b8fd72 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -492,7 +492,7 @@ for. When one of the servers acknowledges the data and the other server does not (yet) acknowledges the client needs to make a decision about how to move forward. -In such situation the the client SHOULD implement queuing, acknowledgement +In such situation the client SHOULD implement queuing, acknowledgement handling and retrying logic per destination. This ensures that servers do not block each other. The queues SHOULD reference shared, immutable data to be sent, thus minimizing the memory overhead caused by having multiple queues. From 0dd37aab469450be4b8176aee6cacd9578815ef7 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 25 Mar 2022 20:28:08 -0400 Subject: [PATCH 036/127] Fix formatting of OTLP/HTTP's two status lines (#2442) --- specification/protocol/otlp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 462b8fd72..4634937fa 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -320,8 +320,8 @@ The default network port for OTLP/gRPC is 4317. ### OTLP/HTTP -**Binary Format Status**: [Stable](../document-status.md) -**JSON Format Status**: [Experimental](../document-status.md) +**Status**: Binary format is [Stable](../document-status.md), + JSON format is [Experimental](../document-status.md) OTLP/HTTP uses Protobuf payloads encoded either in binary format or in JSON format. The Protobuf schema of the messages is the same for OTLP/HTTP and From 50b937618bf4b53ba3f738c13578c9eccecae72d Mon Sep 17 00:00:00 2001 From: Stepan Rakitin Date: Wed, 13 Apr 2022 05:41:20 +0200 Subject: [PATCH 037/127] Retry RESOURCE_EXHAUSTED only if the server can recover (#2480) --- specification/protocol/otlp.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 4634937fa..2868340ae 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -223,7 +223,7 @@ not-retryable according to the following table: |ALREADY_EXISTS|No| |PERMISSION_DENIED|No| |UNAUTHENTICATED|No| -|RESOURCE_EXHAUSTED|Yes| +|RESOURCE_EXHAUSTED|Only if the server can recover (see below)| |FAILED_PRECONDITION|No| |ABORTED|Yes| |OUT_OF_RANGE|Yes| @@ -236,6 +236,11 @@ When retrying, the client SHOULD implement an exponential backoff strategy. An exception to this is the Throttling case explained below, which provides explicit instructions about retrying interval. +The client SHOULD interpret `RESOURCE_EXHAUSTED` code as retryable only if the server signals that the recovery from resource exhaustion is possible. This is signalled by the server by returning [a status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) +containing +[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40). In this case the behavior of the server and the client is exactly as described in [OTLP/gRPC Throttling](#otlpgrpc-throttling) section. +If no such status is returned then the `RESOURCE_EXHAUSTED` code SHOULD be treated as non-retryable. + #### OTLP/gRPC Throttling OTLP allows backpressure signalling. From b1c16bd5c582a6843f6932d1aa4776ebd78fc0fb Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Sat, 21 May 2022 00:57:11 -0400 Subject: [PATCH 038/127] Mark OTLP Logs Stable (#2565) --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 2868340ae..42766e721 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -54,7 +54,7 @@ own maturity level, which in turn applies to **all** the OTLP Transports listed * Tracing: **Stable** * Metrics: **Stable** -* Logs: **Beta** +* Logs: **Stable** See [OTLP Maturity Level](https://github.com/open-telemetry/opentelemetry-proto#maturity-level). From 5413422263ef863a22d9e4f88a35f19dd72f40a1 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Tue, 2 Aug 2022 18:08:08 +0200 Subject: [PATCH 039/127] Add support for partial success in an OTLP export response [2] (#2696) --- specification/protocol/otlp.md | 127 ++++++++++++++++++++++++++------- 1 file changed, 101 insertions(+), 26 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 42766e721..e8d548a49 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -16,14 +16,18 @@ nodes such as collectors and telemetry backends. * [OTLP/gRPC](#otlpgrpc) + [OTLP/gRPC Concurrent Requests](#otlpgrpc-concurrent-requests) + [OTLP/gRPC Response](#otlpgrpc-response) + - [Full Success](#full-success) + - [Partial Success](#partial-success) + - [Failures](#failures) + [OTLP/gRPC Throttling](#otlpgrpc-throttling) + [OTLP/gRPC Service and Protobuf Definitions](#otlpgrpc-service-and-protobuf-definitions) + [OTLP/gRPC Default Port](#otlpgrpc-default-port) * [OTLP/HTTP](#otlphttp) + [OTLP/HTTP Request](#otlphttp-request) + [OTLP/HTTP Response](#otlphttp-response) - - [Success](#success) - - [Failures](#failures) + - [Full Success](#full-success-1) + - [Partial Success](#partial-success-1) + - [Failures](#failures-1) - [Bad Data](#bad-data) - [OTLP/HTTP Throttling](#otlphttp-throttling) - [All Other Responses](#all-other-responses) @@ -35,7 +39,6 @@ nodes such as collectors and telemetry backends. - [Known Limitations](#known-limitations) * [Request Acknowledgements](#request-acknowledgements) + [Duplicate Data](#duplicate-data) - * [Partial Success](#partial-success) - [Future Versions and Interoperability](#future-versions-and-interoperability) - [Glossary](#glossary) - [References](#references) @@ -145,16 +148,57 @@ was not delivered. #### OTLP/gRPC Response -The server may respond with either a success or an error to the requests. +The response MUST be the appropriate message (see below for +the specific message to use in the [Full Success](#full-success), +[Partial Success](#partial-success) and [Failure](#failures) cases). + +##### Full Success -The success response indicates telemetry data is successfully processed by the -server. If the server receives an empty request (a request that does not carry +The success response indicates telemetry data is successfully accepted by the +server. + +If the server receives an empty request (a request that does not carry any telemetry data) the server SHOULD respond with success. -Success response is returned via -[Export*ServiceResponse](https://github.com/open-telemetry/opentelemetry-proto) -message (`ExportTraceServiceResponse` for traces, `ExportMetricsServiceResponse` -for metrics, `ExportLogsServiceResponse` for logs). +On success, the server response MUST be a +[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +message (`ExportTraceServiceResponse` for traces, +`ExportMetricsServiceResponse` for metrics and +`ExportLogsServiceResponse` for logs). + +The server MUST leave the `partial_success` field unset +in case of a successful response. + +##### Partial Success + +If the request is only partially accepted +(i.e. when the server accepts only parts of the data and rejects the rest), the +server response MUST be the same +[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +message as in the [Full Success](#full-success) case. + +Additionally, the server MUST initialize the `partial_success` field +(`ExportTracePartialSuccess` message for traces, +`ExportMetricsPartialSuccess` message for metrics and +`ExportLogsPartialSuccess` message for logs), and it MUST set the respective +`rejected_spans`, `rejected_data_points` or `rejected_log_records` field with +the number of spans/data points/log records it rejected. + +The server SHOULD populate the `error_message` field with a human-readable +error message in English. The message should explain why the +server rejected parts of the data, and might offer guidance on how users +can address the issues. +The protocol does not attempt to define the structure of the error message. + +Servers MAY also make use of the `partial_success` field to convey +warnings/suggestions to clients even when the request was fully accepted. +In such cases, the `rejected_` field MUST have a value of `0` and +the `error_message` field MUST be non-empty. + +The client MUST NOT retry the request when it receives a partial success +response where the `partial_success` is populated. + +##### Failures When an error is returned by the server it falls into 2 broad categories: retryable and not-retryable: @@ -382,8 +426,9 @@ numbers or strings are accepted when decoding. #### OTLP/HTTP Response -Response body MUST be the appropriate serialized Protobuf message (see below for -the specific message to use in the Success and Failure cases). +The response body MUST be the appropriate serialized Protobuf message (see below for +the specific message to use in the [Full Success](#full-success-1), +[Partial Success](#partial-success-1) and [Failure](#failures-1) cases). The server MUST set "Content-Type: application/x-protobuf" header if the response body is binary-encoded Protobuf payload. The server MUST set @@ -395,15 +440,52 @@ If the request header "Accept-Encoding: gzip" is present in the request the server MAY gzip-encode the response and set "Content-Encoding: gzip" response header. -##### Success +##### Full Success -On success the server MUST respond with `HTTP 200 OK`. Response body MUST be -Protobuf-encoded `ExportTraceServiceResponse` message for traces, -`ExportMetricsServiceResponse` message for metrics and -`ExportLogsServiceResponse` message for logs. +The success response indicates telemetry data is successfully accepted by the +server. -The server SHOULD respond with success no sooner than after successfully -decoding and validating the request. +If the server receives an empty request (a request that does not carry +any telemetry data) the server SHOULD respond with success. + +On success, the server MUST respond with `HTTP 200 OK`. The response body MUST be +a Protobuf-encoded +[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +message (`ExportTraceServiceResponse` for traces, +`ExportMetricsServiceResponse` for metrics and +`ExportLogsServiceResponse` for logs). + +The server MUST leave the `partial_success` field unset +in case of a successful response. + +##### Partial Success + +If the request is only partially accepted +(i.e. when the server accepts only parts of the data and rejects the rest), the +server MUST respond with `HTTP 200 OK`. The response body MUST be the same +[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +message as in the [Full Success](#full-success-1) case. + +Additionally, the server MUST initialize the `partial_success` field +(`ExportTracePartialSuccess` message for traces, +`ExportMetricsPartialSuccess` message for metrics and +`ExportLogsPartialSuccess` message for logs), and it MUST set the respective +`rejected_spans`, `rejected_data_points` or `rejected_log_records` field with +the number of spans/data points/log records it rejected. + +The server SHOULD populate the `error_message` field with a human-readable +error message in English. The message should explain why the +server rejected parts of the data, and might offer guidance on how users +can address the issues. +The protocol does not attempt to define the structure of the error message. + +Servers MAY also make use of the `partial_success` field to convey +warnings/suggestions to clients even when the request was fully accepted. +In such cases, the `rejected_` field MUST have a value of `0` and +the `error_message` field MUST be non-empty. + +The client MUST NOT retry the request when it receives a partial success +response where the `partial_success` is populated. ##### Failures @@ -520,13 +602,6 @@ received yet. The client will typically choose to re-send such data to guarantee delivery, which may result in duplicate data on the server side. This is a deliberate choice and is considered to be the right tradeoff for telemetry data. -### Partial Success - -The protocol does not attempt to communicate partial reception success from the -server to the client (i.e. when part of the data can be received by the server -and part of it cannot). Attempting to do so would complicate the protocol and -implementations significantly and is left out as a possible future area of work. - ## Future Versions and Interoperability OTLP will evolve and change over time. Future versions of OTLP must be designed From bdbef239edf12d69b2f882484d18e4439e02faf9 Mon Sep 17 00:00:00 2001 From: Gustavo Pantuza Date: Fri, 12 Aug 2022 00:07:14 -0300 Subject: [PATCH 040/127] Inserts links to each Protocol Buffer definition by Telemetry signal (#2723) --- specification/protocol/otlp.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index e8d548a49..64afb223d 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -87,10 +87,11 @@ All server components MUST support the following transport compression options: After establishing the underlying gRPC transport the client starts sending telemetry data using unary requests using [Export*ServiceRequest](https://github.com/open-telemetry/opentelemetry-proto) -messages (`ExportTraceServiceRequest` for traces, `ExportMetricsServiceRequest` -for metrics, `ExportLogsServiceRequest` for logs). The client continuously sends -a sequence of requests to the server and expects to receive a response to each -request: +messages ([ExportLogsServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/logs/v1/logs_service.proto) for logs, +[ExportMetricsServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/metrics/v1/metrics_service.proto) for metrics, +[ExportTraceServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/trace/v1/trace_service.proto) for traces). +The client continuously sends a sequence of requests to the server and expects +to receive a response to each request: ![Request-Response](img/otlp-request-response.png) From c3f1c0231bd22597d1af3e42a87a83894d4e8601 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 30 Aug 2022 10:54:35 -0400 Subject: [PATCH 041/127] Refactor OTLP/HTTP section (#2756) Make Binary and JSON encodings their own sections. This makes the spec easier to understand and also makes adding further clarifications to JSON easier. There are no functional changes. OTLP protocol behavior remains exactly the same. This is purely editorial change. --- specification/protocol/otlp.md | 64 +++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 64afb223d..c91d820be 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -23,6 +23,8 @@ nodes such as collectors and telemetry backends. + [OTLP/gRPC Service and Protobuf Definitions](#otlpgrpc-service-and-protobuf-definitions) + [OTLP/gRPC Default Port](#otlpgrpc-default-port) * [OTLP/HTTP](#otlphttp) + + [Binary Protobuf Encoding](#binary-protobuf-encoding) + + [JSON Protobuf Encoding](#json-protobuf-encoding) + [OTLP/HTTP Request](#otlphttp-request) + [OTLP/HTTP Response](#otlphttp-response) - [Full Success](#full-success-1) @@ -370,18 +372,49 @@ The default network port for OTLP/gRPC is 4317. ### OTLP/HTTP -**Status**: Binary format is [Stable](../document-status.md), - JSON format is [Experimental](../document-status.md) - -OTLP/HTTP uses Protobuf payloads encoded either in binary format or in JSON -format. The Protobuf schema of the messages is the same for OTLP/HTTP and -OTLP/gRPC. +OTLP/HTTP uses Protobuf payloads encoded either in +[binary format](#binary-protobuf-encoding) or in [JSON format](#json-protobuf-encoding). +Regardless of the encoding the Protobuf schema of the messages is the same for +OTLP/HTTP and OTLP/gRPC as +[defined here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto). OTLP/HTTP uses HTTP POST requests to send telemetry data from clients to servers. Implementations MAY use HTTP/1.1 or HTTP/2 transports. Implementations that use HTTP/2 transport SHOULD fallback to HTTP/1.1 transport if HTTP/2 connection cannot be established. +#### Binary Protobuf Encoding + +**Status**: [Stable](../document-status.md) + +Binary Protobuf encoded payloads use proto3 +[encoding standard](https://developers.google.com/protocol-buffers/docs/encoding). + +The client and the server MUST set "Content-Type: application/x-protobuf" request and +response headers when sending binary Protobuf encoded payload. + +#### JSON Protobuf Encoding + +**Status**: [Experimental](../document-status.md) + +JSON Protobuf encoded payloads use proto3 standard defined +[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) +for mapping between Protobuf and JSON, with one deviation from that mapping: the +`trace_id` and `span_id` byte arrays are represented as +[case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8), +they are not base64-encoded like it is defined in the standard +[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). +The hex encoding is used for `trace_id` and `span_id` fields in all OTLP +Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. + +Note that according to [Protobuf specs]( +https://developers.google.com/protocol-buffers/docs/proto3#json) 64-bit integer +numbers in JSON-encoded payloads are encoded as decimal strings, and either +numbers or strings are accepted when decoding. + +The client and the server MUST set "Content-Type: application/json" request and +response headers when sending JSON Protobuf encoded payload. + #### OTLP/HTTP Request Telemetry data is sent via HTTP POST request. The body of the POST request is a @@ -399,10 +432,6 @@ the request body is a Protobuf-encoded `ExportMetricsServiceRequest` message. The default URL path for requests that carry log data is `/v1/logs` and the request body is a Protobuf-encoded `ExportLogsServiceRequest` message. -The client MUST set "Content-Type: application/x-protobuf" request header when -sending binary-encoded Protobuf or "Content-Type: application/json" request -header when sending JSON encoded Protobuf payload. - The client MAY gzip the content and in that case MUST include "Content-Encoding: gzip" request header. The client MAY include "Accept-Encoding: gzip" request header if it can receive gzip-encoded responses. @@ -410,21 +439,6 @@ The client MAY gzip the content and in that case MUST include Non-default URL paths for requests MAY be configured on the client and server sides. -JSON-encoded Protobuf payloads use proto3 standard defined -[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) -for mapping between Protobuf and JSON, with one deviation from that mapping: the -`trace_id` and `span_id` byte arrays are represented as -[case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8), -they are not base64-encoded like it is defined in the standard -[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). -The hex encoding is used for `trace_id` and `span_id` fields in all OTLP -Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. - -Note that according to [Protobuf specs]( -https://developers.google.com/protocol-buffers/docs/proto3#json) 64-bit integer -numbers in JSON-encoded payloads are encoded as decimal strings, and either -numbers or strings are accepted when decoding. - #### OTLP/HTTP Response The response body MUST be the appropriate serialized Protobuf message (see below for From 89363fe601c769671ace78d9dd9ff61ffce163cd Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 19 Sep 2022 14:36:17 -0400 Subject: [PATCH 042/127] Prohibit usage of enum value name strings in OTLP/JSON (#2758) * Prohibit usage of enum value name strings in OTLP/JSON Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/424 This change disallows using enum value names as strings in OTLP/JSON and requires to use enum integer values only. * Fix grammar Co-authored-by: Bogdan Drutu --- specification/protocol/otlp.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index c91d820be..824aadc55 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -399,13 +399,25 @@ response headers when sending binary Protobuf encoded payload. JSON Protobuf encoded payloads use proto3 standard defined [JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) -for mapping between Protobuf and JSON, with one deviation from that mapping: the -`trace_id` and `span_id` byte arrays are represented as -[case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8), -they are not base64-encoded like it is defined in the standard -[JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). -The hex encoding is used for `trace_id` and `span_id` fields in all OTLP -Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. +for mapping between Protobuf and JSON, with the following deviations from that mapping: + +- The `trace_id` and `span_id` byte arrays are represented as + [case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8); + they are not base64-encoded like as it is defined in the standard + [Protobuf JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). + The hex encoding is used for `trace_id` and `span_id` fields in all OTLP + Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. + For example, the `trace_id` field in a Span can be represented like this: + { "trace_id": "5B8EFFF798038103D269B633813FC60C", ... } + +- Values of enum fields MUST be encoded as integer values. Unlike the standard + [Protobuf JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json), + which allows values of enum fields to be encoded as either integer values or as enum + name strings, only integer enum values are allowed in OTLP JSON Protobuf Encoding; + the enum name strings MUST NOT be used. + For example, the `kind` field with a value of SPAN_KIND_SERVER in a Span can be + represented like this: + { "kind": 2, ... } Note that according to [Protobuf specs]( https://developers.google.com/protocol-buffers/docs/proto3#json) 64-bit integer From d9687276259769cca9f5332cc7314191702d8d8b Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 27 Sep 2022 13:14:10 -0400 Subject: [PATCH 043/127] Clarify that unknown fields must be ignored when receiving OTLP/JSON (#2816) * Clarify that unknown fields must be ignored when receiving OTLP/JSON Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/425 The proposed behavior is necessary for interoperability of senders and receivers when OTLP protocol evolves in an allowed way: by adding new fields to existing messages. * Remove unnecessary sentence * Fix typo Co-authored-by: Yuri Shkuro --- specification/protocol/otlp.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 824aadc55..75f6fd6f7 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -419,6 +419,11 @@ for mapping between Protobuf and JSON, with the following deviations from that m represented like this: { "kind": 2, ... } +- OTLP/JSON receivers MUST ignore message fields with unknown names and MUST unmarshal the + message as if the unknown field was not present in the payload. + This aligns with the behavior of the Binary Protobuf unmarshaler and ensures that adding + new fields to OTLP messages does not break existing receivers. + Note that according to [Protobuf specs]( https://developers.google.com/protocol-buffers/docs/proto3#json) 64-bit integer numbers in JSON-encoded payloads are encoded as decimal strings, and either From 5967e37d86e7e779348679cbf8ae3cc2ec9d92d8 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 12 Oct 2022 12:45:49 -0400 Subject: [PATCH 044/127] Clarify that lowerCamelCase field names MUST be used for OTLP/JSON (#2829) Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/2795 This is a breaking change for OTLP/JSON and is allowed because OTLP/JSON is not yet Stable. --- specification/protocol/otlp.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 75f6fd6f7..158e54c26 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -424,6 +424,13 @@ for mapping between Protobuf and JSON, with the following deviations from that m This aligns with the behavior of the Binary Protobuf unmarshaler and ensures that adding new fields to OTLP messages does not break existing receivers. +- The keys of JSON objects are field names converted to lowerCamelCase. Original + field names are not valid to use a keys of JSON objects. + For example this is a valid JSON representation of a Resource: + `{ "attributes": {...}, "droppedAttributesCount": 123 }`, and this is NOT a valid + representation: + `{ "attributes": {...}, "dropped_attributes_count": 123 }`. + Note that according to [Protobuf specs]( https://developers.google.com/protocol-buffers/docs/proto3#json) 64-bit integer numbers in JSON-encoded payloads are encoded as decimal strings, and either From f25d197d1df4f345d35213501d311868d79df091 Mon Sep 17 00:00:00 2001 From: Peter Deng Date: Wed, 21 Dec 2022 04:38:39 +0800 Subject: [PATCH 045/127] Add table for OTLP/HTTP response code and client retry recommendation (#3028) --- specification/protocol/otlp.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 158e54c26..4d222c4c1 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -547,6 +547,19 @@ defined in `Status` message schema. The server MAY include `Status.details` field with additional details. Read below about what this field can contain in each specific failure case. +The server SHOULD use HTTP response status codes to indicate +retryable and not-retryable errors for a particular erroneous situation. The +client SHOULD honour HTTP response status codes as retryable or not-retryable. +The requests that receive a response status code listed in following table SHOULD be retried. +All other `4xx` or `5xx` response status codes MUST NOT be retried. + +|HTTP response status code| +|---------| +|429 Too Many Requests| +|502 Bad Gateway| +|503 Service Unavailable| +|504 Gateway Timeout| + ##### Bad Data If the processing of the request fails because the request contains data that From e8ea719e0ae20b1be70199eae00ade031a4ab957 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 9 Feb 2023 15:00:03 -0500 Subject: [PATCH 046/127] Declare OTLP/JSON Stable (#2930) See also https://github.com/open-telemetry/opentelemetry-proto/pull/436 Co-authored-by: Carlos Alberto Cortez --- specification/protocol/otlp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 4d222c4c1..5eb25f9f8 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -395,7 +395,7 @@ response headers when sending binary Protobuf encoded payload. #### JSON Protobuf Encoding -**Status**: [Experimental](../document-status.md) +**Status**: [Stable](../document-status.md) JSON Protobuf encoded payloads use proto3 standard defined [JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) From 38372ff842d8beefb80cc0c589304372347eea53 Mon Sep 17 00:00:00 2001 From: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Date: Wed, 22 Feb 2023 12:27:11 -0500 Subject: [PATCH 047/127] Fix typos and grammar in the OTLP spec (#3121) --- specification/protocol/otlp.md | 217 +++++++++++++++++---------------- 1 file changed, 111 insertions(+), 106 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 5eb25f9f8..2c5828cca 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -2,7 +2,7 @@ **Status**: [Mixed](../document-status.md) -OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, +The OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, and delivery mechanism of telemetry data between telemetry sources, intermediate nodes such as collectors and telemetry backends. @@ -50,7 +50,7 @@ nodes such as collectors and telemetry backends. OTLP is a general-purpose telemetry data delivery protocol designed in the scope -of OpenTelemetry project. +of the OpenTelemetry project. ## Signals Maturity Level @@ -73,20 +73,20 @@ This specification defines how OTLP is implemented over [Protocol Buffers schema](https://developers.google.com/protocol-buffers/docs/overview) that is used for the payloads. -OTLP is a request/response style protocols: the clients send requests, the -server replies with corresponding responses. This document defines one requests +OTLP is a request/response style protocol: the clients send requests, and the +server replies with corresponding responses. This document defines one request and response type: `Export`. All server components MUST support the following transport compression options: -* No compression, denotated by `none`. +* No compression, denoted by `none`. * Gzip compression, denoted by `gzip`. ### OTLP/gRPC **Status**: [Stable](../document-status.md) -After establishing the underlying gRPC transport the client starts sending +After establishing the underlying gRPC transport, the client starts sending telemetry data using unary requests using [Export*ServiceRequest](https://github.com/open-telemetry/opentelemetry-proto) messages ([ExportLogsServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/logs/v1/logs_service.proto) for logs, @@ -97,8 +97,8 @@ to receive a response to each request: ![Request-Response](img/otlp-request-response.png) -_Note: this protocol is concerned with reliability of delivery between one pair -of client/server nodes and aims to ensure that no data is lost in-transit +_Note: this protocol is concerned with the reliability of delivery between one +pair of client/server nodes and aims to ensure that no data is lost in transit between the client and the server. Many telemetry collection systems have intermediary nodes that the data must travel across until reaching the final destination (e.g. application -> agent -> collector -> backend). End-to-end @@ -116,8 +116,8 @@ that is not yet acknowledged by the server. ![Unary](img/otlp-sequential.png) Sequential operation is recommended when simplicity of implementation is -desirable and when the client and the server are connected via very low-latency -network, such as for example when the client is an instrumented application and +desirable, and when the client and the server are connected via very low-latency +network, such as when the client is an instrumented application and the server is an OpenTelemetry Collector running as a local daemon (agent). The implementations that need to achieve high throughput SHOULD support @@ -132,18 +132,18 @@ The number of concurrent requests SHOULD be configurable. The maximum achievable throughput is `max_concurrent_requests * max_request_size / (network_latency + server_response_time)`. -For example if the request can contain at most 100 spans, network roundtrip -latency is 200ms and server response time is 300 ms, then the maximum achievable +For example, if the request can contain at most 100 spans, network roundtrip +latency is 200ms, and server response time is 300 ms, then the maximum achievable throughput with one concurrent request is `100 spans / (200ms+300ms)` or 200 spans per second. It is easy to see that in high latency networks or when the -server response time is high to achieve good throughput the requests need to be +server response time is high to achieve good throughput, the requests need to be very big or a lot concurrent requests must be done. If the client is shutting down (e.g. when the containing process wants to exit) the client will optionally wait until all pending acknowledgements are received -or until an implementation specific timeout expires. This ensures reliable +or until an implementation-specific timeout expires. This ensures the reliable delivery of telemetry data. The client implementation SHOULD expose an option to -turn on and off the waiting during shutdown. +turn on and off the waiting during a shutdown. If the client is unable to deliver a certain request (e.g. a timer expired while waiting for acknowledgements) the client SHOULD record the fact that the data @@ -189,13 +189,13 @@ the number of spans/data points/log records it rejected. The server SHOULD populate the `error_message` field with a human-readable error message in English. The message should explain why the -server rejected parts of the data, and might offer guidance on how users +server rejected parts of the data and might offer guidance on how users can address the issues. The protocol does not attempt to define the structure of the error message. -Servers MAY also make use of the `partial_success` field to convey -warnings/suggestions to clients even when the request was fully accepted. -In such cases, the `rejected_` field MUST have a value of `0` and +Servers MAY also use the `partial_success` field to convey +warnings/suggestions to clients even when the server fully accepts the request. +In such cases, the `rejected_` field MUST have a value of `0`, and the `error_message` field MUST be non-empty. The client MUST NOT retry the request when it receives a partial success @@ -203,17 +203,19 @@ response where the `partial_success` is populated. ##### Failures -When an error is returned by the server it falls into 2 broad categories: +When the server returns an error, it falls into 2 broad categories: retryable and not-retryable: -- Retryable errors indicate that processing of telemetry data failed and the - client SHOULD record the error and may retry exporting the same data. This can - happen when the server is temporarily unable to process the data. +- Retryable errors indicate that telemetry data processing failed, and the + client SHOULD record the error and may retry exporting the same data. + For example, this can happen when the server is temporarily unable to + process the data. -- Not-retryable errors indicate that processing of telemetry data failed and the - client MUST NOT retry sending the same telemetry data. The telemetry data MUST - be dropped. This can happen, for example, when the request contains bad data - and cannot be deserialized or otherwise processed by the server. The client +- Not-retryable errors indicate that telemetry data processing failed, and the + client MUST NOT retry sending the same telemetry data. The client MUST drop + the telemetry data. + For example, this can happen, when the request contains bad data + and cannot be deserialized or processed by the server. The client SHOULD maintain a counter of such dropped data. The server MUST indicate retryable errors using code @@ -235,17 +237,17 @@ containing 0 value of RetryDelay. Here is a sample Go code to illustrate: return st.Err() ``` -To indicate not-retryable errors the server is recommended to use code +To indicate not-retryable errors, the server is recommended to use code [InvalidArgument](https://godoc.org/google.golang.org/grpc/codes) and MAY supply additional [details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) using [BadRequest](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L119). -Other gRPC status code may be used if it is more appropriate. Here is a sample -Go code to illustrate: +If more appropriate, another gRPC status code may be used. Here is a +snippet of sample Go code to illustrate: ```go - // Do this on server side. + // Do this on the server side. st, err := status.New(codes.InvalidArgument, "Invalid Argument"). WithDetails(&errdetails.BadRequest{}) if err != nil { @@ -283,14 +285,18 @@ When retrying, the client SHOULD implement an exponential backoff strategy. An exception to this is the Throttling case explained below, which provides explicit instructions about retrying interval. -The client SHOULD interpret `RESOURCE_EXHAUSTED` code as retryable only if the server signals that the recovery from resource exhaustion is possible. This is signalled by the server by returning [a status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) -containing -[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40). In this case the behavior of the server and the client is exactly as described in [OTLP/gRPC Throttling](#otlpgrpc-throttling) section. -If no such status is returned then the `RESOURCE_EXHAUSTED` code SHOULD be treated as non-retryable. +The client SHOULD interpret `RESOURCE_EXHAUSTED` code as retryable only if the +server signals that the recovery from resource exhaustion is possible. +This is signaled by the server by returning +[a status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) containing +[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40). +In this case the behavior of the server and the client is exactly as described in +[OTLP/gRPC Throttling](#otlpgrpc-throttling) section. If no such status is returned, +then the `RESOURCE_EXHAUSTED` code SHOULD be treated as non-retryable. #### OTLP/gRPC Throttling -OTLP allows backpressure signalling. +OTLP allows backpressure signaling. If the server is unable to keep up with the pace of data it receives from the client then it SHOULD signal that fact to the client. The client MUST then @@ -302,10 +308,10 @@ and MAY supply additional [details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails) using [RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40). -Here is a sample Go code to illustrate: +Here is a snippet of sample Go code to illustrate: ```go - // Do this on server side. + // Do this on the server side. st, err := status.New(codes.Unavailable, "Server is unavailable"). WithDetails(&errdetails.RetryInfo{RetryDelay: &duration.Duration{Seconds: 30}}) if err != nil { @@ -316,7 +322,7 @@ Here is a sample Go code to illustrate: ... - // Do this on client side. + // Do this on the client side. st := status.Convert(err) for _, detail := range st.Details() { switch t := detail.(type) { @@ -328,13 +334,13 @@ Here is a sample Go code to illustrate: } ``` -When the client receives this signal it SHOULD follow the recommendations +When the client receives this signal, it SHOULD follow the recommendations outlined in documentation for [RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40): ``` // Describes when the clients can retry a failed request. Clients could ignore -// the recommendation here or retry when this information is missing from error +// the recommendation here or retry when this information is missing from the error // responses. // // It's always recommended that clients should use exponential backoff when @@ -342,16 +348,16 @@ outlined in documentation for // // Clients should wait until `retry_delay` amount of time has passed since // receiving the error response before retrying. If retrying requests also -// fail, clients should use an exponential backoff scheme to gradually increase -// the delay between retries based on `retry_delay`, until either a maximum -// number of retires have been reached or a maximum retry delay cap has been +// fail, clients should use an exponential backoff scheme to increase gradually +// the delay between retries based on `retry_delay` until either a maximum +// number of retries has been reached, or a maximum retry delay cap has been // reached. ``` The value of `retry_delay` is determined by the server and is implementation dependant. The server SHOULD choose a `retry_delay` value that is big enough to -give the server time to recover, yet is not too big to cause the client to drop -data while it is throttled. +give the server time to recover yet is not too big to cause the client to drop +data while being throttled. #### OTLP/gRPC Service and Protobuf Definitions @@ -390,8 +396,8 @@ connection cannot be established. Binary Protobuf encoded payloads use proto3 [encoding standard](https://developers.google.com/protocol-buffers/docs/encoding). -The client and the server MUST set "Content-Type: application/x-protobuf" request and -response headers when sending binary Protobuf encoded payload. +The client and the server MUST set "Content-Type: application/x-protobuf" +request and response headers when sending binary Protobuf encoded payload. #### JSON Protobuf Encoding @@ -403,30 +409,29 @@ for mapping between Protobuf and JSON, with the following deviations from that m - The `trace_id` and `span_id` byte arrays are represented as [case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8); - they are not base64-encoded like as it is defined in the standard + they are not base64-encoded as is defined in the standard [Protobuf JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). - The hex encoding is used for `trace_id` and `span_id` fields in all OTLP - Protobuf messages, e.g. the `Span`, `Link`, `LogRecord`, etc. messages. + Hex encoding is used for `trace_id` and `span_id` fields in all OTLP + Protobuf messages, e.g., the `Span`, `Link`, `LogRecord`, etc. messages. For example, the `trace_id` field in a Span can be represented like this: { "trace_id": "5B8EFFF798038103D269B633813FC60C", ... } - Values of enum fields MUST be encoded as integer values. Unlike the standard [Protobuf JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json), - which allows values of enum fields to be encoded as either integer values or as enum - name strings, only integer enum values are allowed in OTLP JSON Protobuf Encoding; - the enum name strings MUST NOT be used. - For example, the `kind` field with a value of SPAN_KIND_SERVER in a Span can be - represented like this: - { "kind": 2, ... } - -- OTLP/JSON receivers MUST ignore message fields with unknown names and MUST unmarshal the - message as if the unknown field was not present in the payload. - This aligns with the behavior of the Binary Protobuf unmarshaler and ensures that adding - new fields to OTLP messages does not break existing receivers. + which allows values of enum fields to be encoded as either integer values or + as enum name strings, only integer enum values are allowed in OTLP JSON + Protobuf Encoding; the enum name strings MUST NOT be used. For example, the + `kind` field with a value of SPAN_KIND_SERVER in a Span can be represented + like this: { "kind": 2, ... } + +- OTLP/JSON receivers MUST ignore message fields with unknown names and MUST + unmarshal the message as if the unknown field was not present in the payload. + This aligns with the behavior of the Binary Protobuf unmarshaler and ensures + that adding new fields to OTLP messages does not break existing receivers. - The keys of JSON objects are field names converted to lowerCamelCase. Original - field names are not valid to use a keys of JSON objects. - For example this is a valid JSON representation of a Resource: + field names are not valid to use as keys for JSON objects. + For example, this is a valid JSON representation of a Resource: `{ "attributes": {...}, "droppedAttributesCount": 123 }`, and this is NOT a valid representation: `{ "attributes": {...}, "dropped_attributes_count": 123 }`. @@ -465,8 +470,8 @@ sides. #### OTLP/HTTP Response -The response body MUST be the appropriate serialized Protobuf message (see below for -the specific message to use in the [Full Success](#full-success-1), +The response body MUST be the appropriate serialized Protobuf message (see +below for the specific message to use in the [Full Success](#full-success-1), [Partial Success](#partial-success-1) and [Failure](#failures-1) cases). The server MUST set "Content-Type: application/x-protobuf" header if the @@ -514,13 +519,13 @@ the number of spans/data points/log records it rejected. The server SHOULD populate the `error_message` field with a human-readable error message in English. The message should explain why the -server rejected parts of the data, and might offer guidance on how users +server rejected parts of the data and might offer guidance on how users can address the issues. The protocol does not attempt to define the structure of the error message. -Servers MAY also make use of the `partial_success` field to convey -warnings/suggestions to clients even when the request was fully accepted. -In such cases, the `rejected_` field MUST have a value of `0` and +Servers MAY also use the `partial_success` field to convey +warnings/suggestions to clients even when it fully accepts the request. +In such cases, the `rejected_` field MUST have a value of `0`, and the `error_message` field MUST be non-empty. The client MUST NOT retry the request when it receives a partial success @@ -528,11 +533,11 @@ response where the `partial_success` is populated. ##### Failures -If the processing of the request fails the server MUST respond with appropriate -`HTTP 4xx` or `HTTP 5xx` status code. See sections below for more details about +If the processing of the request fails, the server MUST respond with appropriate +`HTTP 4xx` or `HTTP 5xx` status code. See the sections below for more details about specific failure cases and HTTP status codes that should be used. -Response body for all `HTTP 4xx` and `HTTP 5xx` responses MUST be a +The response body for all `HTTP 4xx` and `HTTP 5xx` responses MUST be a Protobuf-encoded [Status](https://godoc.org/google.golang.org/genproto/googleapis/rpc/status#Status) message that describes the problem. @@ -550,7 +555,8 @@ below about what this field can contain in each specific failure case. The server SHOULD use HTTP response status codes to indicate retryable and not-retryable errors for a particular erroneous situation. The client SHOULD honour HTTP response status codes as retryable or not-retryable. -The requests that receive a response status code listed in following table SHOULD be retried. +The requests that receive a response status code listed in following table SHOULD +be retried. All other `4xx` or `5xx` response status codes MUST NOT be retried. |HTTP response status code| @@ -563,7 +569,7 @@ All other `4xx` or `5xx` response status codes MUST NOT be retried. ##### Bad Data If the processing of the request fails because the request contains data that -cannot be decoded or is otherwise invalid and such failure is permanent then the +cannot be decoded or is otherwise invalid and such failure is permanent, then the server MUST respond with `HTTP 400 Bad Request`. The `Status.details` field in the response SHOULD contain a [BadRequest](https://github.com/googleapis/googleapis/blob/d14bf59a446c14ef16e9931ebfc8e63ab549bf07/google/rpc/error_details.proto#L166) @@ -575,29 +581,29 @@ response. ##### OTLP/HTTP Throttling If the server receives more requests than the client is allowed or the server is -overloaded the server SHOULD respond with `HTTP 429 Too Many Requests` or +overloaded, the server SHOULD respond with `HTTP 429 Too Many Requests` or `HTTP 503 Service Unavailable` and MAY include ["Retry-After"](https://tools.ietf.org/html/rfc7231#section-7.1.3) header with a recommended time interval in seconds to wait before retrying. -The client SHOULD honour the waiting interval specified in "Retry-After" header -if it is present. If the client receives `HTTP 429` or `HTTP 503` response and -"Retry-After" header is not present in the response then the client SHOULD -implement an exponential backoff strategy between retries. +The client SHOULD honour the waiting interval specified in the "Retry-After" +header if it is present. If the client receives an `HTTP 429` or an `HTTP 503` +response and the "Retry-After" header is not present in the response, then the +client SHOULD implement an exponential backoff strategy between retries. ##### All Other Responses All other HTTP responses that are not explicitly listed in this document should -be treated according to HTTP specification. +be treated according to HTTP specifications. -If the server disconnects without returning a response the client SHOULD retry +If the server disconnects without returning a response, the client SHOULD retry and send the same request. The client SHOULD implement an exponential backoff strategy between retries to avoid overwhelming the server. #### OTLP/HTTP Connection -If the client is unable to connect to the server the client SHOULD retry the -connection using exponential backoff strategy between retries. The interval +If the client cannot connect to the server, the client SHOULD retry the +connection using an exponential backoff strategy between retries. The interval between retries must have a random jitter. The client SHOULD keep the connection alive between requests. @@ -613,8 +619,8 @@ on the "Content-Type" request header. #### OTLP/HTTP Concurrent Requests -To achieve higher total throughput the client MAY send requests using several -parallel HTTP connections. In that case the maximum number of parallel +To achieve higher total throughput, the client MAY send requests using several +parallel HTTP connections. In that case, the maximum number of parallel connections SHOULD be configurable. #### OTLP/HTTP Default Port @@ -625,14 +631,13 @@ The default network port for OTLP/HTTP is 4318. ### Multi-Destination Exporting -When the telemetry data from one client must be sent to more than one -destination server there is an additional complication that must be accounted -for. When one of the servers acknowledges the data and the other server does not -(yet) acknowledges the client needs to make a decision about how to move -forward. +An additional complication must be accounted for when one client must send +telemetry data to more than one destination server. When one of the servers +acknowledges the data and the other server does not (yet), the client needs +to decide how to move forward. -In such situation the client SHOULD implement queuing, acknowledgement -handling and retrying logic per destination. This ensures that servers do not +In such a situation, the client SHOULD implement queuing, acknowledgment +handling, and retrying logic per destination. This ensures that servers do not block each other. The queues SHOULD reference shared, immutable data to be sent, thus minimizing the memory overhead caused by having multiple queues. @@ -659,27 +664,27 @@ deliberate choice and is considered to be the right tradeoff for telemetry data. OTLP will evolve and change over time. Future versions of OTLP must be designed and implemented in a way that ensures that clients and servers that implement different versions of OTLP can interoperate and exchange telemetry data. Old -clients must be able to talk to new servers and vice versa. If new versions of -OTLP introduce new functionality that cannot be understood and supported by -nodes implementing the old versions of OTLP the protocol must regress to the -lowest common denominator from functional perspective. +clients must be able to talk to new servers and vice versa. Suppose new versions +of OTLP introduce new functionality that cannot be understood and supported by +nodes implementing the old versions of OTLP. In that case, the protocol must +regress to the lowest common denominator from a functional perspective. -When possible the interoperability MUST be ensured between all versions of +When possible, the interoperability MUST be ensured between all versions of OTLP that are not declared obsolete. OTLP does not use explicit protocol version numbering. OTLP's interoperability of clients and servers of different versions is based on the following concepts: 1. OTLP (current and future versions) defines a set of capabilities, some of - which are mandatory, others are optional. Clients and servers must implement - mandatory capabilities and can choose implement only a subset of optional + which are mandatory, while others are optional. Clients and servers must implement + mandatory capabilities and can choose to implement only a subset of optional capabilities. -2. For minor changes to the protocol future versions and extension of OTLP are - encouraged to use the ability of Protobufs to evolve message schema in - backwards compatible manner. Newer versions of OTLP may add new fields to +2. For minor changes to the protocol, future versions and extensions of OTLP are + encouraged to use the Protobuf's ability to evolve the message schema in + a backward-compatible manner. Newer versions of OTLP may add new fields to messages that will be ignored by clients and servers that do not understand - these fields. In many cases careful design of such schema changes and correct + these fields. In many cases, careful design of such schema changes and correct choice of default values for new fields is enough to ensure interoperability of different versions without nodes explicitly detecting that their peer node has different capabilities. @@ -687,11 +692,11 @@ of clients and servers of different versions is based on the following concepts: 3. More significant changes must be explicitly defined as new optional capabilities in future OTEPs. Such capabilities SHOULD be discovered by client and server implementations after establishing the underlying - transport. The exact discovery mechanism SHOULD be described in future OTEPs + transport. The exact discovery mechanism SHOULD be described in future OTEPs, which define the new capabilities and typically can be implemented by making a discovery request/response message exchange from the client to server. The mandatory capabilities defined by this specification are implied and do not - require a discovery. The implementation which supports a new, optional + require discovery. The implementation which supports a new, optional capability MUST adjust its behavior to match the expectation of a peer that does not support a particular capability. From 36cdc8df31a69b08d88fca98e10950bdfccea0b1 Mon Sep 17 00:00:00 2001 From: Jonatan Ivanov Date: Wed, 8 Mar 2023 10:04:47 -0800 Subject: [PATCH 048/127] Declare OTLP stable (#3274) --- specification/protocol/otlp.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 2c5828cca..83836ad47 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -1,6 +1,6 @@ # OpenTelemetry Protocol Specification -**Status**: [Mixed](../document-status.md) +**Status**: [Stable](../document-status.md) The OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, and delivery mechanism of telemetry data between telemetry sources, intermediate @@ -11,7 +11,6 @@ nodes such as collectors and telemetry backends. -- [Signals Maturity Level](#signals-maturity-level) - [Protocol Details](#protocol-details) * [OTLP/gRPC](#otlpgrpc) + [OTLP/gRPC Concurrent Requests](#otlpgrpc-concurrent-requests) @@ -52,17 +51,6 @@ nodes such as collectors and telemetry backends. OTLP is a general-purpose telemetry data delivery protocol designed in the scope of the OpenTelemetry project. -## Signals Maturity Level - -Each signal has different support and stability in OTLP, described through its -own maturity level, which in turn applies to **all** the OTLP Transports listed below. - -* Tracing: **Stable** -* Metrics: **Stable** -* Logs: **Stable** - -See [OTLP Maturity Level](https://github.com/open-telemetry/opentelemetry-proto#maturity-level). - ## Protocol Details OTLP defines the encoding of telemetry data and the protocol used to exchange @@ -84,8 +72,6 @@ All server components MUST support the following transport compression options: ### OTLP/gRPC -**Status**: [Stable](../document-status.md) - After establishing the underlying gRPC transport, the client starts sending telemetry data using unary requests using [Export*ServiceRequest](https://github.com/open-telemetry/opentelemetry-proto) @@ -391,8 +377,6 @@ connection cannot be established. #### Binary Protobuf Encoding -**Status**: [Stable](../document-status.md) - Binary Protobuf encoded payloads use proto3 [encoding standard](https://developers.google.com/protocol-buffers/docs/encoding). @@ -401,8 +385,6 @@ request and response headers when sending binary Protobuf encoded payload. #### JSON Protobuf Encoding -**Status**: [Stable](../document-status.md) - JSON Protobuf encoded payloads use proto3 standard defined [JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) for mapping between Protobuf and JSON, with the following deviations from that mapping: From 883eb82a2d8e2eedfdf5d629fc8a0af7909ceb85 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Thu, 27 Apr 2023 14:09:30 -0400 Subject: [PATCH 049/127] Eliminate nested "protocol" directory and fix all links The "protocol" sub-directory is superfluous, I just moved all the files to the "specification" directory. Fixed all links, used relative links to files in this repo. TODO: add link checker in another PR. --- README.md | 7 ++++- RELEASING.md | 11 ++----- specification/{protocol => }/README.md | 2 +- specification/{protocol => }/design-goals.md | 0 .../{protocol => }/img/otlp-client-server.png | Bin .../{protocol => }/img/otlp-concurrent.png | Bin .../img/otlp-multi-destination.png | Bin .../img/otlp-request-response.png | Bin .../{protocol => }/img/otlp-sequential.png | Bin specification/{protocol => }/otlp.md | 29 ++++++++---------- specification/{protocol => }/requirements.md | 0 11 files changed, 22 insertions(+), 27 deletions(-) rename specification/{protocol => }/README.md (60%) rename specification/{protocol => }/design-goals.md (100%) rename specification/{protocol => }/img/otlp-client-server.png (100%) rename specification/{protocol => }/img/otlp-concurrent.png (100%) rename specification/{protocol => }/img/otlp-multi-destination.png (100%) rename specification/{protocol => }/img/otlp-request-response.png (100%) rename specification/{protocol => }/img/otlp-sequential.png (100%) rename specification/{protocol => }/otlp.md (94%) rename specification/{protocol => }/requirements.md (100%) diff --git a/README.md b/README.md index 75aab2414..efdf9599c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Language Independent Interface Types For OpenTelemetry +# OpenTelemetry Protocol (OTLP) Specification **NOTE** @@ -10,6 +10,11 @@ This repo is currently pinned to [v0.19.0](https://github.com/open-telemetry/ope [![Build Check](https://github.com/open-telemetry/opentelemetry-proto/workflows/Build%20Check/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-proto/actions?query=workflow%3A%22Build+Check%22+branch%3Amain) +This repository contains the [OTLP protocol specification](specification/otlp.md) +and the corresponding Language Independent Interface Types ([.proto files](opentelemetry/proto)). + +## Language Independent Interface Types + The proto files can be consumed as GIT submodules or copied and built directly in the consumer project. The compiled files are published to central repositories (Maven, ...) from OpenTelemetry client libraries. diff --git a/RELEASING.md b/RELEASING.md index a3d267bb7..207d234a9 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -79,16 +79,11 @@ You can use `git log upstream/v$MAJOR.$((MINOR-1)).x..upstream/v$MAJOR.$MINOR.x or the Github [compare tool](https://github.com/open-telemetry/opentelemetry-proto/compare/) to view a summary of all commits since last release as a reference. -In addition, you can refer to -[CHANGELOG.md](https://github.com/open-telemetry/opentelemetry-proto/blob/main/CHANGELOG.md) +In addition, you can refer to [CHANGELOG.md](CHANGELOG.md) for a list of major changes since last release. ## Update release versions in documentations and CHANGELOG files -After releasing is done, you need to update -[README.md](https://github.com/open-telemetry/opentelemetry-proto/blob/main/README.md) and -[CHANGELOG.md](https://github.com/open-telemetry/opentelemetry-proto/blob/main/CHANGELOG.md). +After releasing is done, you need to update [README.md](README.md) and [CHANGELOG.md](CHANGELOG.md). -Create a PR to mark the new release in -[CHANGELOG.md](https://github.com/open-telemetry/opentelemetry-proto/blob/main/CHANGELOG.md) -on main branch. +Create a PR to mark the new release in [CHANGELOG.md](CHANGELOG.md) on main branch. diff --git a/specification/protocol/README.md b/specification/README.md similarity index 60% rename from specification/protocol/README.md rename to specification/README.md index 2d7ecec94..4797f16fc 100644 --- a/specification/protocol/README.md +++ b/specification/README.md @@ -5,4 +5,4 @@ This is the specification of new OpenTelemetry protocol (OTLP). - [Design Goals](design-goals.md). - [Requirements](requirements.md). - [Specification](otlp.md). -- [SDK Exporter](exporter.md). +- [SDK Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md). diff --git a/specification/protocol/design-goals.md b/specification/design-goals.md similarity index 100% rename from specification/protocol/design-goals.md rename to specification/design-goals.md diff --git a/specification/protocol/img/otlp-client-server.png b/specification/img/otlp-client-server.png similarity index 100% rename from specification/protocol/img/otlp-client-server.png rename to specification/img/otlp-client-server.png diff --git a/specification/protocol/img/otlp-concurrent.png b/specification/img/otlp-concurrent.png similarity index 100% rename from specification/protocol/img/otlp-concurrent.png rename to specification/img/otlp-concurrent.png diff --git a/specification/protocol/img/otlp-multi-destination.png b/specification/img/otlp-multi-destination.png similarity index 100% rename from specification/protocol/img/otlp-multi-destination.png rename to specification/img/otlp-multi-destination.png diff --git a/specification/protocol/img/otlp-request-response.png b/specification/img/otlp-request-response.png similarity index 100% rename from specification/protocol/img/otlp-request-response.png rename to specification/img/otlp-request-response.png diff --git a/specification/protocol/img/otlp-sequential.png b/specification/img/otlp-sequential.png similarity index 100% rename from specification/protocol/img/otlp-sequential.png rename to specification/img/otlp-sequential.png diff --git a/specification/protocol/otlp.md b/specification/otlp.md similarity index 94% rename from specification/protocol/otlp.md rename to specification/otlp.md index 83836ad47..d6c463228 100644 --- a/specification/protocol/otlp.md +++ b/specification/otlp.md @@ -1,6 +1,6 @@ # OpenTelemetry Protocol Specification -**Status**: [Stable](../document-status.md) +**Status**: [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md) The OpenTelemetry Protocol (OTLP) specification describes the encoding, transport, and delivery mechanism of telemetry data between telemetry sources, intermediate @@ -75,9 +75,9 @@ All server components MUST support the following transport compression options: After establishing the underlying gRPC transport, the client starts sending telemetry data using unary requests using [Export*ServiceRequest](https://github.com/open-telemetry/opentelemetry-proto) -messages ([ExportLogsServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/logs/v1/logs_service.proto) for logs, -[ExportMetricsServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/metrics/v1/metrics_service.proto) for metrics, -[ExportTraceServiceRequest](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/trace/v1/trace_service.proto) for traces). +messages ([ExportLogsServiceRequest](../opentelemetry/proto/collector/logs/v1/logs_service.proto) for logs, +[ExportMetricsServiceRequest](../opentelemetry/proto/collector/metrics/v1/metrics_service.proto) for metrics, +[ExportTraceServiceRequest](../opentelemetry/proto/collector/trace/v1/trace_service.proto) for traces). The client continuously sends a sequence of requests to the server and expects to receive a response to each request: @@ -150,7 +150,7 @@ If the server receives an empty request (a request that does not carry any telemetry data) the server SHOULD respond with success. On success, the server response MUST be a -[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +[ExportServiceResponse](../opentelemetry/proto/collector) message (`ExportTraceServiceResponse` for traces, `ExportMetricsServiceResponse` for metrics and `ExportLogsServiceResponse` for logs). @@ -163,7 +163,7 @@ in case of a successful response. If the request is only partially accepted (i.e. when the server accepts only parts of the data and rejects the rest), the server response MUST be the same -[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +[ExportServiceResponse](../opentelemetry/proto/collector) message as in the [Full Success](#full-success) case. Additionally, the server MUST initialize the `partial_success` field @@ -347,14 +347,11 @@ data while being throttled. #### OTLP/gRPC Service and Protobuf Definitions -gRPC service definitions -[are here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto/collector). +gRPC service definitions [are here](../opentelemetry/proto/collector). -Protobuf definitions for requests and responses -[are here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto). +Protobuf definitions for requests and responses [are here](../opentelemetry/proto). -Please make sure to check the proto version and -[maturity level](https://github.com/open-telemetry/opentelemetry-proto/#maturity-level). +Please make sure to check the proto version and [maturity level](../README.md#maturity-level). Schemas for different signals may be at different maturity level - some stable, some in beta. @@ -367,8 +364,7 @@ The default network port for OTLP/gRPC is 4317. OTLP/HTTP uses Protobuf payloads encoded either in [binary format](#binary-protobuf-encoding) or in [JSON format](#json-protobuf-encoding). Regardless of the encoding the Protobuf schema of the messages is the same for -OTLP/HTTP and OTLP/gRPC as -[defined here](https://github.com/open-telemetry/opentelemetry-proto/tree/master/opentelemetry/proto). +OTLP/HTTP and OTLP/gRPC as [defined here](../opentelemetry/proto). OTLP/HTTP uses HTTP POST requests to send telemetry data from clients to servers. Implementations MAY use HTTP/1.1 or HTTP/2 transports. Implementations @@ -475,8 +471,7 @@ If the server receives an empty request (a request that does not carry any telemetry data) the server SHOULD respond with success. On success, the server MUST respond with `HTTP 200 OK`. The response body MUST be -a Protobuf-encoded -[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +a Protobuf-encoded [ExportServiceResponse](../opentelemetry/proto/collector) message (`ExportTraceServiceResponse` for traces, `ExportMetricsServiceResponse` for metrics and `ExportLogsServiceResponse` for logs). @@ -489,7 +484,7 @@ in case of a successful response. If the request is only partially accepted (i.e. when the server accepts only parts of the data and rejects the rest), the server MUST respond with `HTTP 200 OK`. The response body MUST be the same -[ExportServiceResponse](https://github.com/open-telemetry/opentelemetry-proto/tree/main/opentelemetry/proto/collector) +[ExportServiceResponse](../opentelemetry/proto/collector) message as in the [Full Success](#full-success-1) case. Additionally, the server MUST initialize the `partial_success` field diff --git a/specification/protocol/requirements.md b/specification/requirements.md similarity index 100% rename from specification/protocol/requirements.md rename to specification/requirements.md From 9cde6ed86c470ccee47d53a4047fda58a7fb20fe Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Thu, 4 May 2023 19:01:56 -0400 Subject: [PATCH 050/127] Use "example.com" where an example domain is needed (#465) --- opentelemetry/proto/trace/v1/trace.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index beefc343e..b2869edc4 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -172,8 +172,8 @@ message Span { // // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" // "/http/server_latency": 300 - // "abc.com/myattribute": true - // "abc.com/score": 10.239 + // "example.com/myattribute": true + // "example.com/score": 10.239 // // The OpenTelemetry API specification further restricts the allowed value types: // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute From d36a8f6ebc7949002031125619a3ed385673f412 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 9 May 2023 15:34:43 -0400 Subject: [PATCH 051/127] Clarify that symbolic guarantees go into effect from 1.0.0 (#467) We merged the https://github.com/open-telemetry/opentelemetry-proto/pull/432 without clarifying when exactly the guarantees start applying. The intent was that the guarantees are needed for 1.0 release but we didn't make this explicit. We are now making this explicit and until 1.0 released we should be free to fix the remaining known issues listed here: https://github.com/open-telemetry/opentelemetry-proto/issues/456 Once 1.0 release is made we can remove the [from 1.0.0] labels from the README.md. --- README.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index efdf9599c..25d25c222 100644 --- a/README.md +++ b/README.md @@ -62,17 +62,21 @@ Components marked `Stable` provide the following guarantees: - Field types, numbers and names will not change. - Service names and service package names will not change. -- Service method names will not change. -- Service method parameter names will not change. -- Service method parameter types and return types will not change. +- Service method names will not change. [from 1.0.0] +- Service method parameter names will not change. [from 1.0.0] +- Service method parameter types and return types will not change. [from 1.0.0] - Service method kind (unary vs streaming) will not change. -- Names of messages and enums will not change. -- Names of enum choices and numbers assigned to enum choices will not change. +- Names of messages and enums will not change. [from 1.0.0] +- Numbers assigned to enum choices will not change. +- Names of enum choices will not change. [from 1.0.0] - The location of messages and enums, i.e. whether they are declared at the top lexical - scope or nested inside another message will not change. -- Package names and directory structure will not change. -- `optional` and `repeated` declarators of existing fields will not change. -- No existing symbol will be deleted. + scope or nested inside another message will not change. [from 1.0.0] +- Package names and directory structure will not change. [from 1.0.0] +- `optional` and `repeated` declarators of existing fields will not change. [from 1.0.0] +- No existing symbol will be deleted. [from 1.0.0] + +Note: guarantees marked [from 1.0.0] will go into effect when this repository is tagged +with version number 1.0.0. The following additive changes are allowed: From e2a23a93008f39fb9e7d332f2a724bfd63e8eef9 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Thu, 4 May 2023 11:20:48 +0200 Subject: [PATCH 052/127] Add OTLP JSON payload examples --- specification/otlp-json-examples/README.md | 43 +++++++ specification/otlp-json-examples/logs.json | 100 ++++++++++++++++ specification/otlp-json-examples/metrics.json | 107 ++++++++++++++++++ specification/otlp-json-examples/trace.json | 51 +++++++++ specification/otlp.md | 2 + 5 files changed, 303 insertions(+) create mode 100644 specification/otlp-json-examples/README.md create mode 100644 specification/otlp-json-examples/logs.json create mode 100644 specification/otlp-json-examples/metrics.json create mode 100644 specification/otlp-json-examples/trace.json diff --git a/specification/otlp-json-examples/README.md b/specification/otlp-json-examples/README.md new file mode 100644 index 000000000..28ebb086d --- /dev/null +++ b/specification/otlp-json-examples/README.md @@ -0,0 +1,43 @@ +# OTLP JSON request examples + +This folder contains a collection of OTLP JSON files for all signals +that can be used as request payloads. + +- Trace [trace.json](trace.json) +- Metrics [metrics.json](metrics.json) +- Logs [logs.json](logs.json) + +## Trying it out + +First run a OpenTelemetry collector with the following configuration: + +```yaml +receivers: + otlp: + protocols: + http: + +exporters: + logging: + verbosity: detailed + +service: + pipelines: + traces: + receivers: [otlp] + exporters: [logging] + metrics: + receivers: [otlp] + exporters: [logging] + logs: + receivers: [otlp] + exporters: [logging] +``` + +Then send a curl request to the collector (e.g. for Logs): + +```shell +curl -X POST -H "Content-Type: application/json" -d @logs.json -i localhost:4318/v1/logs +``` + +> Remember to change the URL path when sending other signals (traces/metrics). diff --git a/specification/otlp-json-examples/logs.json b/specification/otlp-json-examples/logs.json new file mode 100644 index 000000000..8c7a84131 --- /dev/null +++ b/specification/otlp-json-examples/logs.json @@ -0,0 +1,100 @@ +{ + "resourceLogs": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "my.service" + } + } + ] + }, + "scopeLogs": [ + { + "scope": { + "name": "my.library", + "version": "1.0.0", + "attributes": [ + { + "key": "my.scope.attribute", + "value": { + "stringValue": "some scope attribute" + } + } + ] + }, + "logRecords": [ + { + "timeUnixNano": 1544712660300000000, + "observedTimeUnixNano": 1544712660300000000, + "severityText": "Information", + "traceId": "5B8EFFF798038103D269B633813FC60C", + "spanId": "EEE19B7EC3C1B174", + "body": { + "stringValue": "Example log record" + }, + "attributes": [ + { + "key": "string.attribute", + "value": { + "stringValue": "some string" + } + }, + { + "key": "boolean.attribute", + "value": { + "boolValue": true + } + }, + { + "key": "int.attribute", + "value": { + "intValue": 10 + } + }, + { + "key": "double.attribute", + "value": { + "doubleValue": 637.704 + } + }, + { + "key": "array.attribute", + "value": { + "arrayValue": { + "values": [ + { + "stringValue": "many" + }, + { + "stringValue": "values" + } + ] + } + } + }, + { + "key": "map.attribute", + "value": { + "kvlistValue": { + "values": [ + { + "key": "some.map.key", + "value": { + "stringValue": "some value" + } + } + ] + } + } + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/specification/otlp-json-examples/metrics.json b/specification/otlp-json-examples/metrics.json new file mode 100644 index 000000000..b3143a5c8 --- /dev/null +++ b/specification/otlp-json-examples/metrics.json @@ -0,0 +1,107 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "my.service" + } + } + ] + }, + "scopeMetrics": [ + { + "scope": { + "name": "my.library", + "version": "1.0.0", + "attributes": [ + { + "key": "my.scope.attribute", + "value": { + "stringValue": "some scope attribute" + } + } + ] + }, + "metrics": [ + { + "name": "my.counter", + "unit": "1", + "description": "I'm a Counter", + "sum": { + "aggregationTemporality": 1, + "isMonotonic": true, + "dataPoints": [ + { + "asDouble": 5, + "startTimeUnixNano": 1544712660300000000, + "timeUnixNano": 1544712660300000000, + "attributes": [ + { + "key": "my.counter.attr", + "value": { + "stringValue": "some value" + } + } + ] + } + ] + } + }, + { + "name": "my.gauge", + "unit": "1", + "description": "I'm a Gauge", + "gauge": { + "dataPoints": [ + { + "asDouble": 10, + "timeUnixNano": 1544712660300000000, + "attributes": [ + { + "key": "my.gauge.attr", + "value": { + "stringValue": "some value" + } + } + ] + } + ] + } + }, + { + "name": "my.histogram", + "unit": "1", + "description": "I'm a Histogram", + "histogram": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "startTimeUnixNano": 1544712660300000000, + "timeUnixNano": 1544712660300000000, + "count": 3, + "sum": 3, + "bucketCounts": [1,1,1], + "explicitBounds": [1], + "min": 1, + "max": 1, + "attributes": [ + { + "key": "my.histogram.attr", + "value": { + "stringValue": "some value" + } + } + ] + } + ] + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/specification/otlp-json-examples/trace.json b/specification/otlp-json-examples/trace.json new file mode 100644 index 000000000..f4999d596 --- /dev/null +++ b/specification/otlp-json-examples/trace.json @@ -0,0 +1,51 @@ +{ + "resource_spans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "my.service" + } + } + ] + }, + "scope_spans": [ + { + "scope": { + "name": "my.library", + "version": "1.0.0", + "attributes": [ + { + "key": "my.scope.attribute", + "value": { + "stringValue": "some scope attribute" + } + } + ] + }, + "spans": [ + { + "traceId": "5B8EFFF798038103D269B633813FC60C", + "spanId": "EEE19B7EC3C1B174", + "parentSpanId": "EEE19B7EC3C1B173", + "name": "I'm a server span", + "startTimeUnixNano": 1544712660000000000, + "endTimeUnixNano": 1544712661000000000, + "kind": 2, + "attributes": [ + { + "key": "my.span.attr", + "value": { + "stringValue": "some value" + } + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/specification/otlp.md b/specification/otlp.md index d6c463228..47910dc35 100644 --- a/specification/otlp.md +++ b/specification/otlp.md @@ -422,6 +422,8 @@ numbers or strings are accepted when decoding. The client and the server MUST set "Content-Type: application/json" request and response headers when sending JSON Protobuf encoded payload. +For JSON payload examples see: [OTLP JSON request examples](otlp-json-examples/README.md) + #### OTLP/HTTP Request Telemetry data is sent via HTTP POST request. The body of the POST request is a From d154235affa16b17dfa70623e1c854e05ca0517d Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Wed, 10 May 2023 17:55:08 +0200 Subject: [PATCH 053/127] Update specification/otlp-json-examples/README.md Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- specification/otlp-json-examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/otlp-json-examples/README.md b/specification/otlp-json-examples/README.md index 28ebb086d..2c689431b 100644 --- a/specification/otlp-json-examples/README.md +++ b/specification/otlp-json-examples/README.md @@ -1,6 +1,6 @@ # OTLP JSON request examples -This folder contains a collection of OTLP JSON files for all signals +This folder contains a collection of example OTLP JSON files for all signals that can be used as request payloads. - Trace [trace.json](trace.json) From 481cdacffaa6b2eb20dbb0b3deccb371dead2c06 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Thu, 27 Apr 2023 15:04:57 -0400 Subject: [PATCH 054/127] Add link checking Borrowed from https://github.com/open-telemetry/opentelemetry-specification --- .github/workflows/build-check.yaml | 12 + .gitignore | 2 + .markdown_link_check_config.json | 18 + Makefile | 14 + package-lock.json | 815 +++++++++++++++++++++++++++++ package.json | 5 + 6 files changed, 866 insertions(+) create mode 100644 .markdown_link_check_config.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.github/workflows/build-check.yaml b/.github/workflows/build-check.yaml index f8591b827..4512d9308 100644 --- a/.github/workflows/build-check.yaml +++ b/.github/workflows/build-check.yaml @@ -99,3 +99,15 @@ jobs: BUF_FLAGS="--error-format json" make -s breaking-change | jq -rs '.[] | "::error file=\(.path),line=\(.start_line),endLine=\(.end_line),title=Buf detected breaking change \(.type)::\(.message)"' ; (exit ${PIPESTATUS[0]}) + + markdown-link-check: + runs-on: ubuntu-latest + steps: + - name: check out code + uses: actions/checkout@v2 + + - name: install dependencies + run: npm install + + - name: run markdown-link-check + run: make markdown-link-check diff --git a/.gitignore b/.gitignore index a8c2ffc5c..e2436ac8c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ # Generated code /gen/ + +node_modules diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json new file mode 100644 index 000000000..dac3ae97b --- /dev/null +++ b/.markdown_link_check_config.json @@ -0,0 +1,18 @@ +{ + "ignorePatterns": [ + { + "pattern": "^https://github\\.com/open-telemetry/opentelemetry-specification/(issues|pull)" + } + ], + "replacementPatterns": [ + { + "pattern": "^/", + "replacement": "{{BASEURL}}/" + } + ], + "retryOn429": true, + "aliveStatusCodes": [ + 200, + 403 + ] +} diff --git a/Makefile b/Makefile index ac3020780..6e7136465 100755 --- a/Makefile +++ b/Makefile @@ -13,6 +13,9 @@ $(1) endef +.PHONY: all +all: gen-all markdown-link-check + # Generate all implementations .PHONY: gen-all gen-all: gen-cpp gen-csharp gen-go gen-java gen-kotlin gen-objc gen-openapi gen-php gen-python gen-ruby @@ -151,3 +154,14 @@ gen-ruby: .PHONY: breaking-change breaking-change: $(BUF) breaking --against $(BUF_AGAINST) $(BUF_FLAGS) + + +ALL_DOCS := $(shell find . -type f -name '*.md' -not -path './.github/*' -not -path './node_modules/*' | sort) + +.PHONY: markdown-link-check +markdown-link-check: + @if ! npm ls markdown-link-check; then npm install; fi + @for f in $(ALL_DOCS); do \ + npx --no -- markdown-link-check --quiet --config .markdown_link_check_config.json $$f \ + || exit 1; \ + done diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..da3ef4546 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,815 @@ +{ + "name": "otlp", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "markdown-link-check": "3.10.3" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dev": true, + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-link-extractor": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/html-link-extractor/-/html-link-extractor-1.0.5.tgz", + "integrity": "sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==", + "dev": true, + "dependencies": { + "cheerio": "^1.0.0-rc.10" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-relative-url": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-4.0.0.tgz", + "integrity": "sha512-PkzoL1qKAYXNFct5IKdKRH/iBQou/oCC85QhXj6WKtUQBliZ4Yfd3Zk27RHu9KQG8r6zgvAA2AQKC9p+rqTszg==", + "dev": true, + "dependencies": { + "is-absolute-url": "^4.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "dependencies": { + "punycode": "2.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/link-check": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/link-check/-/link-check-5.2.0.tgz", + "integrity": "sha512-xRbhYLaGDw7eRDTibTAcl6fXtmUQ13vkezQiTqshHHdGueQeumgxxmQMIOmJYsh2p8BF08t8thhDQ++EAOOq3w==", + "dev": true, + "dependencies": { + "is-relative-url": "^4.0.0", + "isemail": "^3.2.0", + "ms": "^2.1.3", + "needle": "^3.1.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/markdown-link-check": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/markdown-link-check/-/markdown-link-check-3.10.3.tgz", + "integrity": "sha512-uGdJiZOy1CVWlRe7CyBSJ0Gz80Xm4vt++xjX9sNFjB7qcAxLinaMmzFQ5xOwERaXC9mK770BhnqnsyJT1gTr9w==", + "dev": true, + "dependencies": { + "async": "^3.2.4", + "chalk": "^4.1.2", + "commander": "^6.2.0", + "link-check": "^5.2.0", + "lodash": "^4.17.21", + "markdown-link-extractor": "^3.1.0", + "needle": "^3.1.0", + "progress": "^2.0.3" + }, + "bin": { + "markdown-link-check": "markdown-link-check" + } + }, + "node_modules/markdown-link-extractor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/markdown-link-extractor/-/markdown-link-extractor-3.1.0.tgz", + "integrity": "sha512-r0NEbP1dsM+IqB62Ru9TXLP/HDaTdBNIeylYXumuBi6Xv4ufjE1/g3TnslYL8VNqNcGAGbMptQFHrrdfoZ/Sug==", + "dev": true, + "dependencies": { + "html-link-extractor": "^1.0.5", + "marked": "^4.1.0" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/needle": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dev": true, + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + } + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dev": true, + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + } + }, + "cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dev": true, + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "html-link-extractor": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/html-link-extractor/-/html-link-extractor-1.0.5.tgz", + "integrity": "sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==", + "dev": true, + "requires": { + "cheerio": "^1.0.0-rc.10" + } + }, + "htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "dev": true + }, + "is-relative-url": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-4.0.0.tgz", + "integrity": "sha512-PkzoL1qKAYXNFct5IKdKRH/iBQou/oCC85QhXj6WKtUQBliZ4Yfd3Zk27RHu9KQG8r6zgvAA2AQKC9p+rqTszg==", + "dev": true, + "requires": { + "is-absolute-url": "^4.0.1" + } + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + } + }, + "link-check": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/link-check/-/link-check-5.2.0.tgz", + "integrity": "sha512-xRbhYLaGDw7eRDTibTAcl6fXtmUQ13vkezQiTqshHHdGueQeumgxxmQMIOmJYsh2p8BF08t8thhDQ++EAOOq3w==", + "dev": true, + "requires": { + "is-relative-url": "^4.0.0", + "isemail": "^3.2.0", + "ms": "^2.1.3", + "needle": "^3.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "markdown-link-check": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/markdown-link-check/-/markdown-link-check-3.10.3.tgz", + "integrity": "sha512-uGdJiZOy1CVWlRe7CyBSJ0Gz80Xm4vt++xjX9sNFjB7qcAxLinaMmzFQ5xOwERaXC9mK770BhnqnsyJT1gTr9w==", + "dev": true, + "requires": { + "async": "^3.2.4", + "chalk": "^4.1.2", + "commander": "^6.2.0", + "link-check": "^5.2.0", + "lodash": "^4.17.21", + "markdown-link-extractor": "^3.1.0", + "needle": "^3.1.0", + "progress": "^2.0.3" + } + }, + "markdown-link-extractor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/markdown-link-extractor/-/markdown-link-extractor-3.1.0.tgz", + "integrity": "sha512-r0NEbP1dsM+IqB62Ru9TXLP/HDaTdBNIeylYXumuBi6Xv4ufjE1/g3TnslYL8VNqNcGAGbMptQFHrrdfoZ/Sug==", + "dev": true, + "requires": { + "html-link-extractor": "^1.0.5", + "marked": "^4.1.0" + } + }, + "marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "needle": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", + "dev": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "requires": { + "entities": "^4.4.0" + } + }, + "parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dev": true, + "requires": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..ed875da02 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "markdown-link-check": "3.10.3" + } +} From 80f161aaf99e11876b278056d1fa4a7aaad83961 Mon Sep 17 00:00:00 2001 From: Ruslan Kovalov Date: Tue, 3 Jan 2023 15:58:59 +0100 Subject: [PATCH 055/127] [chore] Change comment on `bucket_counts` to reflect spec. See https://opentelemetry.io/docs/reference/specification/metrics/data-model/#exponential-buckets --- opentelemetry/proto/metrics/v1/metrics.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index dc4630e69..cc47a8b4c 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -570,9 +570,9 @@ message ExponentialHistogramDataPoint { // Note: This uses a varint encoding as a simple form of compression. sint32 offset = 1; - // Count is an array of counts, where count[i] carries the count - // of the bucket at index (offset+i). count[i] is the count of - // values greater than base^(offset+i) and less or equal to than + // BucketCounts is an array of count values, where BucketCounts[i] carries + // the count of the bucket at index (offset+i). BucketCounts[i] is the count + // of values greater than base^(offset+i) and less than or equal to // base^(offset+i+1). // // Note: By contrast, the explicit HistogramDataPoint uses From c08d035d8bae77c0fe3ff8bff307ff1d0c27d34e Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 9 May 2023 18:00:30 -0400 Subject: [PATCH 056/127] Update opentelemetry/proto/metrics/v1/metrics.proto Fix field name Co-authored-by: Bogdan Drutu --- opentelemetry/proto/metrics/v1/metrics.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index cc47a8b4c..b6c7a24ff 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -570,8 +570,8 @@ message ExponentialHistogramDataPoint { // Note: This uses a varint encoding as a simple form of compression. sint32 offset = 1; - // BucketCounts is an array of count values, where BucketCounts[i] carries - // the count of the bucket at index (offset+i). BucketCounts[i] is the count + // bucket_counts is an array of count values, where bucket_counts[i] carries + // the count of the bucket at index (offset+i). bucket_counts[i] is the count // of values greater than base^(offset+i) and less than or equal to // base^(offset+i+1). // From b0cc60610cd04b0e416d9eb023ea6266d4b594c0 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 11 May 2023 12:35:55 -0400 Subject: [PATCH 057/127] Move examples into an example folder (#472) Co-authored-by: Armin Ruech --- {specification/otlp-json-examples => examples}/README.md | 0 {specification/otlp-json-examples => examples}/logs.json | 0 {specification/otlp-json-examples => examples}/metrics.json | 0 {specification/otlp-json-examples => examples}/trace.json | 0 specification/otlp.md | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) rename {specification/otlp-json-examples => examples}/README.md (100%) rename {specification/otlp-json-examples => examples}/logs.json (100%) rename {specification/otlp-json-examples => examples}/metrics.json (100%) rename {specification/otlp-json-examples => examples}/trace.json (100%) diff --git a/specification/otlp-json-examples/README.md b/examples/README.md similarity index 100% rename from specification/otlp-json-examples/README.md rename to examples/README.md diff --git a/specification/otlp-json-examples/logs.json b/examples/logs.json similarity index 100% rename from specification/otlp-json-examples/logs.json rename to examples/logs.json diff --git a/specification/otlp-json-examples/metrics.json b/examples/metrics.json similarity index 100% rename from specification/otlp-json-examples/metrics.json rename to examples/metrics.json diff --git a/specification/otlp-json-examples/trace.json b/examples/trace.json similarity index 100% rename from specification/otlp-json-examples/trace.json rename to examples/trace.json diff --git a/specification/otlp.md b/specification/otlp.md index 47910dc35..27f433a39 100644 --- a/specification/otlp.md +++ b/specification/otlp.md @@ -422,7 +422,7 @@ numbers or strings are accepted when decoding. The client and the server MUST set "Content-Type: application/json" request and response headers when sending JSON Protobuf encoded payload. -For JSON payload examples see: [OTLP JSON request examples](otlp-json-examples/README.md) +For JSON payload examples see: [OTLP JSON request examples](../examples/README.md) #### OTLP/HTTP Request From 764275eecb4336b508cdcbbcf1df2b5cceaec13e Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Tue, 9 May 2023 12:19:24 -0400 Subject: [PATCH 058/127] Use correct lowerCameCase for JSON field references The rule is: >The keys of JSON objects are field names converted to lowerCamelCase. The rule was introduced here: https://github.com/open-telemetry/opentelemetry-proto/commit/5a5e750bf984ad6088e8238397003c0d3693ec25 --- specification/otlp.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/otlp.md b/specification/otlp.md index 27f433a39..dabf4c53c 100644 --- a/specification/otlp.md +++ b/specification/otlp.md @@ -385,14 +385,14 @@ JSON Protobuf encoded payloads use proto3 standard defined [JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) for mapping between Protobuf and JSON, with the following deviations from that mapping: -- The `trace_id` and `span_id` byte arrays are represented as +- The `traceId` and `spanId` byte arrays are represented as [case-insensitive hex-encoded strings](https://tools.ietf.org/html/rfc4648#section-8); they are not base64-encoded as is defined in the standard [Protobuf JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json). - Hex encoding is used for `trace_id` and `span_id` fields in all OTLP + Hex encoding is used for `traceId` and `spanId` fields in all OTLP Protobuf messages, e.g., the `Span`, `Link`, `LogRecord`, etc. messages. - For example, the `trace_id` field in a Span can be represented like this: - { "trace_id": "5B8EFFF798038103D269B633813FC60C", ... } + For example, the `traceId` field in a Span can be represented like this: + { "traceId": "5B8EFFF798038103D269B633813FC60C", ... } - Values of enum fields MUST be encoded as integer values. Unlike the standard [Protobuf JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json), From 102cc107c6318d85f4c0e0d32086b62a0a0f1f2d Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Thu, 27 Apr 2023 14:09:30 -0400 Subject: [PATCH 059/127] Clarify bitfield helper enums Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/433 ## Problem The zero values defined in helper enums encourage incorrect usage of the bitfields. The typical incorrect code looks like this: ```proto enum DataPointFlags { FLAG_NONE = 0; FLAG_NO_RECORDED_VALUE = 1; // Bits 2-31 are reserved for future use. } ``` ```go if datapoint.Flags == FLAG_NONE { // do something when there is no recorded value } ``` This is incorrect because it does not take into account that the Flags field can be extended in the future to use the reserved bits. The `if` statement above will be incorrect if any other bit is set. The correct code looks like this: ```go if (datapoint.Flags & FLAG_NO_RECORDED_VALUE) == 0 { // do something when there is no recorded value } ``` ## Solution To prevent this mistake the following changes are done: - All bitfield mask enums are suffixed with a _MASK to signify their purpose. - Zero value of the enum is prefixed with an underscore to discourage its use. - Some additional comments are added to explain how bitfields and their enums should be used. ## Alternates Tried I also tried to remove the zero values from enums altogether, but it turned out to be impossible. I tried a few possible approaches and none worked. Protobufs [require that enums start with a 0 value](https://protobuf.dev/programming-guides/proto3/#enum). If you try to omit it you get a compilation error: ``` opentelemetry/proto/metrics/v1/metrics.proto:325:28: The first enum value must be zero in proto3. ``` Alternatively, trying to use a dummy name, e.g.: ``` enum DataPointFlags { _ = 0; FLAG_NO_RECORDED_VALUE = 1; } ``` Fails Objective-C generator: ``` error: got empty string for making TextFormat data, input: "", desired: "_". ``` Also tried declaring it reserved as the doc says should be possible: ``` enum DataPointFlags { reserved 0; FLAG_NO_RECORDED_VALUE = 1; } ``` but get an error again: ``` opentelemetry/proto/metrics/v1/metrics.proto:327:28: The first enum value must be zero in proto3. ``` --- opentelemetry/proto/logs/v1/logs.proto | 15 +++++++++++++-- opentelemetry/proto/metrics/v1/metrics.proto | 8 +++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/opentelemetry/proto/logs/v1/logs.proto b/opentelemetry/proto/logs/v1/logs.proto index 69928deb2..97e9272a8 100644 --- a/opentelemetry/proto/logs/v1/logs.proto +++ b/opentelemetry/proto/logs/v1/logs.proto @@ -104,10 +104,21 @@ enum SeverityNumber { SEVERITY_NUMBER_FATAL4 = 24; } -// Masks for LogRecord.flags field. +// LogRecordFlags is defined as a protobuf 'uint32' type and is to be used as +// bit-fields. Each non-zero value defined in this enum is a bit-mask. +// To extract the bit-field, for example, use an expression like: +// +// (logRecord.flags & LOG_RECORD_FLAG_TRACE_FLAGS_MASK) +// enum LogRecordFlags { - LOG_RECORD_FLAG_UNSPECIFIED = 0; + // The zero value for the enum. Should not be used for comparisons. + // Instead use bitwise "and" with the appropriate mask as shown above. + LOG_RECORD_FLAG_DO_NOT_USE = 0; + + // Bits 0-7 are used for trace flags. LOG_RECORD_FLAG_TRACE_FLAGS_MASK = 0x000000FF; + + // Bits 8-31 are reserved for future use. } // A log record according to OpenTelemetry Log Data Model: diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index b6c7a24ff..9380af9bf 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -334,15 +334,17 @@ enum AggregationTemporality { // enum is a bit-mask. To test the presence of a single flag in the flags of // a data point, for example, use an expression like: // -// (point.flags & FLAG_NO_RECORDED_VALUE) == FLAG_NO_RECORDED_VALUE +// (point.flags & FLAG_NO_RECORDED_VALUE_MASK) == FLAG_NO_RECORDED_VALUE_MASK // enum DataPointFlags { - FLAG_NONE = 0; + // The zero value for the enum. Should not be used for comparisons. + // Instead use bitwise "and" with the appropriate mask as shown above. + FLAG_DO_NOT_USE = 0; // This DataPoint is valid but has no recorded value. This value // SHOULD be used to reflect explicitly missing data in a series, as // for an equivalent to the Prometheus "staleness marker". - FLAG_NO_RECORDED_VALUE = 1; + FLAG_NO_RECORDED_VALUE_MASK = 1; // Bits 2-31 are reserved for future use. } From 8feb80a6d2c2519a2d04a679789be3b0a2f7c411 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 19 May 2023 12:43:00 -0400 Subject: [PATCH 060/127] Rename ./specification to ./docs (#469) * Rename ./specification to ./docs * Add Hugo front matter, and some README copyedits --- README.md | 4 ++-- docs/README.md | 16 ++++++++++++++++ {specification => docs}/design-goals.md | 8 ++++++++ .../img/otlp-client-server.png | Bin {specification => docs}/img/otlp-concurrent.png | Bin .../img/otlp-multi-destination.png | Bin .../img/otlp-request-response.png | Bin {specification => docs}/img/otlp-sequential.png | Bin {specification => docs}/requirements.md | 8 ++++++++ specification/otlp.md => docs/specification.md | 10 ++++++++++ specification/README.md | 8 -------- 11 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 docs/README.md rename {specification => docs}/design-goals.md (82%) rename {specification => docs}/img/otlp-client-server.png (100%) rename {specification => docs}/img/otlp-concurrent.png (100%) rename {specification => docs}/img/otlp-multi-destination.png (100%) rename {specification => docs}/img/otlp-request-response.png (100%) rename {specification => docs}/img/otlp-sequential.png (100%) rename {specification => docs}/requirements.md (96%) rename specification/otlp.md => docs/specification.md (98%) delete mode 100644 specification/README.md diff --git a/README.md b/README.md index 25d25c222..324008ff6 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This repo is currently pinned to [v0.19.0](https://github.com/open-telemetry/ope [![Build Check](https://github.com/open-telemetry/opentelemetry-proto/workflows/Build%20Check/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-proto/actions?query=workflow%3A%22Build+Check%22+branch%3Amain) -This repository contains the [OTLP protocol specification](specification/otlp.md) +This repository contains the [OTLP protocol specification](docs/specification.md) and the corresponding Language Independent Interface Types ([.proto files](opentelemetry/proto)). ## Language Independent Interface Types @@ -64,7 +64,7 @@ Components marked `Stable` provide the following guarantees: - Service names and service package names will not change. - Service method names will not change. [from 1.0.0] - Service method parameter names will not change. [from 1.0.0] -- Service method parameter types and return types will not change. [from 1.0.0] +- Service method parameter types and return types will not change. [from 1.0.0] - Service method kind (unary vs streaming) will not change. - Names of messages and enums will not change. [from 1.0.0] - Numbers assigned to enum choices will not change. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..21c52b646 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,16 @@ + + +# OpenTelemetry Protocol (OTLP) + +This is the specification of the OpenTelemetry Protocol (OTLP). + +- [Design Goals](design-goals.md) +- [Requirements](requirements.md) +- [Specification](specification.md) +- [SDK Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md) diff --git a/specification/design-goals.md b/docs/design-goals.md similarity index 82% rename from specification/design-goals.md rename to docs/design-goals.md index e51a4d70e..06255b2f2 100644 --- a/specification/design-goals.md +++ b/docs/design-goals.md @@ -1,3 +1,11 @@ + + # Design Goals for OpenTelemetry Wire Protocol We want to design a telemetry data exchange protocol that has the following characteristics: diff --git a/specification/img/otlp-client-server.png b/docs/img/otlp-client-server.png similarity index 100% rename from specification/img/otlp-client-server.png rename to docs/img/otlp-client-server.png diff --git a/specification/img/otlp-concurrent.png b/docs/img/otlp-concurrent.png similarity index 100% rename from specification/img/otlp-concurrent.png rename to docs/img/otlp-concurrent.png diff --git a/specification/img/otlp-multi-destination.png b/docs/img/otlp-multi-destination.png similarity index 100% rename from specification/img/otlp-multi-destination.png rename to docs/img/otlp-multi-destination.png diff --git a/specification/img/otlp-request-response.png b/docs/img/otlp-request-response.png similarity index 100% rename from specification/img/otlp-request-response.png rename to docs/img/otlp-request-response.png diff --git a/specification/img/otlp-sequential.png b/docs/img/otlp-sequential.png similarity index 100% rename from specification/img/otlp-sequential.png rename to docs/img/otlp-sequential.png diff --git a/specification/requirements.md b/docs/requirements.md similarity index 96% rename from specification/requirements.md rename to docs/requirements.md index 5d1f1cb66..7a319dd1f 100644 --- a/specification/requirements.md +++ b/docs/requirements.md @@ -1,3 +1,11 @@ + + # OpenTelemetry Protocol Requirements This document will drive OpenTelemetry Protocol design and RFC. diff --git a/specification/otlp.md b/docs/specification.md similarity index 98% rename from specification/otlp.md rename to docs/specification.md index dabf4c53c..976a81eb9 100644 --- a/specification/otlp.md +++ b/docs/specification.md @@ -1,3 +1,13 @@ + + # OpenTelemetry Protocol Specification **Status**: [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md) diff --git a/specification/README.md b/specification/README.md deleted file mode 100644 index 4797f16fc..000000000 --- a/specification/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# OpenTelemetry Protocol - -This is the specification of new OpenTelemetry protocol (OTLP). - -- [Design Goals](design-goals.md). -- [Requirements](requirements.md). -- [Specification](otlp.md). -- [SDK Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md). From f72e8c3a173f119a5d58e38f2fb755a23f5b02a3 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Sat, 20 May 2023 18:58:32 -0400 Subject: [PATCH 061/127] Fix LogRecordFlags and DataPointFlags enum element name inconsistency (#474) Other enum element names in this repo are prefixed by enum name in CAPITAL_CASE. This change makes naming of LogRecordFlags and DataPointFlags elements consistent with the rest of the enums. Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/473 Co-authored-by: Bogdan Drutu --- opentelemetry/proto/logs/v1/logs.proto | 8 ++++---- opentelemetry/proto/metrics/v1/metrics.proto | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/opentelemetry/proto/logs/v1/logs.proto b/opentelemetry/proto/logs/v1/logs.proto index 97e9272a8..0b4b64972 100644 --- a/opentelemetry/proto/logs/v1/logs.proto +++ b/opentelemetry/proto/logs/v1/logs.proto @@ -108,15 +108,15 @@ enum SeverityNumber { // bit-fields. Each non-zero value defined in this enum is a bit-mask. // To extract the bit-field, for example, use an expression like: // -// (logRecord.flags & LOG_RECORD_FLAG_TRACE_FLAGS_MASK) +// (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK) // enum LogRecordFlags { // The zero value for the enum. Should not be used for comparisons. // Instead use bitwise "and" with the appropriate mask as shown above. - LOG_RECORD_FLAG_DO_NOT_USE = 0; + LOG_RECORD_FLAGS_DO_NOT_USE = 0; // Bits 0-7 are used for trace flags. - LOG_RECORD_FLAG_TRACE_FLAGS_MASK = 0x000000FF; + LOG_RECORD_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; // Bits 8-31 are reserved for future use. } @@ -171,7 +171,7 @@ message LogRecord { // defined in W3C Trace Context specification. 24 most significant bits are reserved // and must be set to 0. Readers must not assume that 24 most significant bits // will be zero and must correctly mask the bits when reading 8-bit trace flag (use - // flags & TRACE_FLAGS_MASK). [Optional]. + // flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK). [Optional]. fixed32 flags = 8; // A unique identifier for a trace. All logs from the same trace share diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index 9380af9bf..2362f51c6 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -334,17 +334,17 @@ enum AggregationTemporality { // enum is a bit-mask. To test the presence of a single flag in the flags of // a data point, for example, use an expression like: // -// (point.flags & FLAG_NO_RECORDED_VALUE_MASK) == FLAG_NO_RECORDED_VALUE_MASK +// (point.flags & DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK) == DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK // enum DataPointFlags { // The zero value for the enum. Should not be used for comparisons. // Instead use bitwise "and" with the appropriate mask as shown above. - FLAG_DO_NOT_USE = 0; + DATA_POINT_FLAGS_DO_NOT_USE = 0; // This DataPoint is valid but has no recorded value. This value // SHOULD be used to reflect explicitly missing data in a series, as // for an equivalent to the Prometheus "staleness marker". - FLAG_NO_RECORDED_VALUE_MASK = 1; + DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK = 1; // Bits 2-31 are reserved for future use. } From 0ab15443d12e00911e8a8751f08b60b00d723296 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 24 May 2023 10:52:50 -0400 Subject: [PATCH 062/127] Fix JSON field capitalization in trace.json example (#477) --- examples/trace.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/trace.json b/examples/trace.json index f4999d596..6d01eeefc 100644 --- a/examples/trace.json +++ b/examples/trace.json @@ -1,5 +1,5 @@ { - "resource_spans": [ + "resourceSpans": [ { "resource": { "attributes": [ @@ -11,7 +11,7 @@ } ] }, - "scope_spans": [ + "scopeSpans": [ { "scope": { "name": "my.library", From 76f350c64e60304400a2fadb39295309c10f3f85 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 24 May 2023 07:53:56 -0700 Subject: [PATCH 063/127] Remove trace_config from maturity matrix, already removed from repo (#475) --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 324008ff6..642090e30 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,7 @@ Component | Maturity common/* | Stable | metrics/\*
collector/metrics/* | Stable | resource/* | Stable | -trace/trace.proto
collector/trace/* | Stable | -trace/trace_config.proto | Alpha | +trace/\*
collector/trace/* | Stable | logs/\*
collector/logs/* | Stable | **JSON encoding** | | All messages | [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#json-protobuf-encoding) | From af545c55cce5b28d8c8133a0d2817f656f70aac6 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 30 May 2023 07:34:15 -0400 Subject: [PATCH 064/127] Update CHANGELOG.md (#478) --- CHANGELOG.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4643f6aba..15e6d5db1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,20 +6,33 @@ Full list of differences found in [this compare](https://github.com/open-telemet ### Maturity -* Remove if no changes for this section before release. +* Declare OTLP/JSON Stable. + [#436](https://github.com/open-telemetry/opentelemetry-proto/pull/436) + [#435](https://github.com/open-telemetry/opentelemetry-proto/pull/435) +* Provide stronger symbolic stability guarantees. + [#432](https://github.com/open-telemetry/opentelemetry-proto/pull/432) +* Clarify how additive changes are handled. + [#455](https://github.com/open-telemetry/opentelemetry-proto/pull/455) ### Changed -* Remove if no changes for this section before release. +* Change the exponential histogram boundary condition. + [#409](https://github.com/open-telemetry/opentelemetry-proto/pull/409) +* Clarify behavior for empty/not present/invalid trace_id and span_id fields. + [#442](https://github.com/open-telemetry/opentelemetry-proto/pull/442) +* Change the collector trace endpoint to /v1/traces. + [#449](https://github.com/open-telemetry/opentelemetry-proto/pull/449) ### Added * Introduce an optional `zero_threshold` field to `ExponentialHistogramDataPoint`. - [(#440)](https://github.com/open-telemetry/opentelemetry-proto/issues/440) + [#441](https://github.com/open-telemetry/opentelemetry-proto/pull/441) + [#453](https://github.com/open-telemetry/opentelemetry-proto/pull/453) ### Removed -* Remove if no changes for this section before release. +* Delete requirement to generate new trace/span id if an invalid id is received. + [#444](https://github.com/open-telemetry/opentelemetry-proto/pull/444) ## 0.19.0 - 2022-08-03 From 53c0fe2e01b8594b4081358b25979a68e41a147e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 30 May 2023 10:20:17 -0500 Subject: [PATCH 065/127] Fix zero_threshold changelog entry (#481) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15e6d5db1..94750d26b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ Full list of differences found in [this compare](https://github.com/open-telemet ### Added -* Introduce an optional `zero_threshold` field to `ExponentialHistogramDataPoint`. +* Introduce `zero_threshold` field to `ExponentialHistogramDataPoint`. [#441](https://github.com/open-telemetry/opentelemetry-proto/pull/441) [#453](https://github.com/open-telemetry/opentelemetry-proto/pull/453) From 3e68d9114c3201ce255af261726068bae0cb0f19 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 1 Jun 2023 10:56:18 -0400 Subject: [PATCH 066/127] [editorial] Drop or adjust Hugo front matter in doc pages (#479) --- docs/README.md | 8 -------- docs/design-goals.md | 8 -------- docs/requirements.md | 8 -------- docs/specification.md | 13 +++++++++++-- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/docs/README.md b/docs/README.md index 21c52b646..dd95f61a0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,3 @@ - - # OpenTelemetry Protocol (OTLP) This is the specification of the OpenTelemetry Protocol (OTLP). diff --git a/docs/design-goals.md b/docs/design-goals.md index 06255b2f2..e51a4d70e 100644 --- a/docs/design-goals.md +++ b/docs/design-goals.md @@ -1,11 +1,3 @@ - - # Design Goals for OpenTelemetry Wire Protocol We want to design a telemetry data exchange protocol that has the following characteristics: diff --git a/docs/requirements.md b/docs/requirements.md index 7a319dd1f..5d1f1cb66 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -1,11 +1,3 @@ - - # OpenTelemetry Protocol Requirements This document will drive OpenTelemetry Protocol design and RFC. diff --git a/docs/specification.md b/docs/specification.md index 976a81eb9..c36023f88 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -1,11 +1,20 @@ # OpenTelemetry Protocol Specification From 411e95060be0a0fe8f1f6c5acb5db43c925ca520 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Mon, 29 May 2023 10:54:45 -0400 Subject: [PATCH 067/127] Clarify uniqueness of Scope attribute keys We use exact same wording as we already have for LogRecord, Span, etc. --- opentelemetry/proto/common/v1/common.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opentelemetry/proto/common/v1/common.proto b/opentelemetry/proto/common/v1/common.proto index 0219561cd..b47cfe16e 100644 --- a/opentelemetry/proto/common/v1/common.proto +++ b/opentelemetry/proto/common/v1/common.proto @@ -81,6 +81,10 @@ message InstrumentationScope { // An empty instrumentation scope name means the name is unknown. string name = 1; string version = 2; + + // Additional attributes that describe the scope. [Optional]. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). repeated KeyValue attributes = 3; uint32 dropped_attributes_count = 4; } From de589d8ed91c5990c46a403ee5eeab99eb868442 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Tue, 6 Jun 2023 18:49:58 -0400 Subject: [PATCH 068/127] Update CHANGELOG.md after 0.20.0 release --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94750d26b..bca0bb7ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,11 @@ ## Unreleased -Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.19.0...main). +Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...main). + +## 0.20.0 - 2023-06-06 + +Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.19.0...v0.20.0). ### Maturity From d135794c98b4fdcad6f3fb1aa1b4644fd982b9f6 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 27 Jun 2023 12:04:12 -0400 Subject: [PATCH 069/127] [editorial] spec: escape HTML chars in markdown link syntax --- docs/specification.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/specification.md b/docs/specification.md index c36023f88..a4bcb13cc 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -169,7 +169,7 @@ If the server receives an empty request (a request that does not carry any telemetry data) the server SHOULD respond with success. On success, the server response MUST be a -[ExportServiceResponse](../opentelemetry/proto/collector) +[Export\ServiceResponse](../opentelemetry/proto/collector) message (`ExportTraceServiceResponse` for traces, `ExportMetricsServiceResponse` for metrics and `ExportLogsServiceResponse` for logs). @@ -182,7 +182,7 @@ in case of a successful response. If the request is only partially accepted (i.e. when the server accepts only parts of the data and rejects the rest), the server response MUST be the same -[ExportServiceResponse](../opentelemetry/proto/collector) +[Export\ServiceResponse](../opentelemetry/proto/collector) message as in the [Full Success](#full-success) case. Additionally, the server MUST initialize the `partial_success` field @@ -492,7 +492,7 @@ If the server receives an empty request (a request that does not carry any telemetry data) the server SHOULD respond with success. On success, the server MUST respond with `HTTP 200 OK`. The response body MUST be -a Protobuf-encoded [ExportServiceResponse](../opentelemetry/proto/collector) +a Protobuf-encoded [Export\ServiceResponse](../opentelemetry/proto/collector) message (`ExportTraceServiceResponse` for traces, `ExportMetricsServiceResponse` for metrics and `ExportLogsServiceResponse` for logs). @@ -505,7 +505,7 @@ in case of a successful response. If the request is only partially accepted (i.e. when the server accepts only parts of the data and rejects the rest), the server MUST respond with `HTTP 200 OK`. The response body MUST be the same -[ExportServiceResponse](../opentelemetry/proto/collector) +[Export\ServiceResponse](../opentelemetry/proto/collector) message as in the [Full Success](#full-success-1) case. Additionally, the server MUST initialize the `partial_success` field From 24aa27527a9405d597277138e23468167a7255fb Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 29 Jun 2023 11:43:58 -0400 Subject: [PATCH 070/127] Add note about the possibility to have unstable components after 1.0.0 (#489) --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 642090e30..35eef4aff 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ To generate the raw gRPC client libraries, use `make gen-${LANGUAGE}`. Currently ## Maturity Level +1.0.0 and newer releases from this repository may contain unstable (alpha or beta) +components as indicated by the Maturity table below. + Component | Maturity | -------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| **Binary Protobuf Encoding** | | From da40c2d9e22a56615e09694e8357a3dde92ac52e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 29 Jun 2023 10:26:11 -0700 Subject: [PATCH 071/127] Add maturity JSON entry per package This is because otherwise, when merged a new package will be automatically stable as JSON. --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 35eef4aff..b5afdef7b 100644 --- a/README.md +++ b/README.md @@ -44,16 +44,13 @@ To generate the raw gRPC client libraries, use `make gen-${LANGUAGE}`. Currently 1.0.0 and newer releases from this repository may contain unstable (alpha or beta) components as indicated by the Maturity table below. -Component | Maturity | --------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| -**Binary Protobuf Encoding** | | -common/* | Stable | -metrics/\*
collector/metrics/* | Stable | -resource/* | Stable | -trace/\*
collector/trace/* | Stable | -logs/\*
collector/logs/* | Stable | -**JSON encoding** | | -All messages | [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#json-protobuf-encoding) | +| Component | Binary Protobuf Maturity | JSON Maturity | +| --------- |--------------- | ------------- | +| common/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | +| resource/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | +| metrics/\*
collector/metrics/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | +| trace/\*
collector/trace/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | +| logs/\*
collector/logs/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | (See [maturity-matrix.yaml](https://github.com/open-telemetry/community/blob/47813530864b9fe5a5146f466a58bd2bb94edc72/maturity-matrix.yaml#L57) for definition of maturity levels). From fa9cbfe7e90981eaf08da2b7275b61ebe41bb780 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:10:55 -0400 Subject: [PATCH 072/127] Update CHANGELOG.md for 1.0.0 release (#493) --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bca0bb7ae..8ac7a6eca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,18 @@ ## Unreleased -Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...main). +Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.0.0...main). + +## 1.0.0 - 2023-07-03 + +Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...v1.0.0). + +### Maturity + +* Add note about the possibility to have unstable components after 1.0.0 + [#489](https://github.com/open-telemetry/opentelemetry-proto/pull/489) +* Add maturity JSON entry per package + [#490](https://github.com/open-telemetry/opentelemetry-proto/pull/490) ## 0.20.0 - 2023-06-06 From 41db0adf468c6e004f9c6433544b0cf87d249bdf Mon Sep 17 00:00:00 2001 From: Tobias Andersen Date: Wed, 12 Jul 2023 15:17:40 +0200 Subject: [PATCH 073/127] Fix EOF issue in metrics payload --- examples/metrics.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/metrics.json b/examples/metrics.json index b3143a5c8..ee6f92374 100644 --- a/examples/metrics.json +++ b/examples/metrics.json @@ -29,7 +29,7 @@ { "name": "my.counter", "unit": "1", - "description": "I'm a Counter", + "description": "I`m a Counter", "sum": { "aggregationTemporality": 1, "isMonotonic": true, @@ -53,7 +53,7 @@ { "name": "my.gauge", "unit": "1", - "description": "I'm a Gauge", + "description": "I`m a Gauge", "gauge": { "dataPoints": [ { @@ -74,7 +74,7 @@ { "name": "my.histogram", "unit": "1", - "description": "I'm a Histogram", + "description": "I`m a Histogram", "histogram": { "aggregationTemporality": 1, "dataPoints": [ From 86215ee0895e19d716a1f558e52551241c0a7cef Mon Sep 17 00:00:00 2001 From: Tobias Andersen Date: Wed, 12 Jul 2023 19:46:09 +0200 Subject: [PATCH 074/127] Update metrics.json Changing to "I am a...." based on maintainer request --- examples/metrics.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/metrics.json b/examples/metrics.json index ee6f92374..2b4592205 100644 --- a/examples/metrics.json +++ b/examples/metrics.json @@ -29,7 +29,7 @@ { "name": "my.counter", "unit": "1", - "description": "I`m a Counter", + "description": "I am a Counter", "sum": { "aggregationTemporality": 1, "isMonotonic": true, @@ -53,7 +53,7 @@ { "name": "my.gauge", "unit": "1", - "description": "I`m a Gauge", + "description": "I am a Gauge", "gauge": { "dataPoints": [ { @@ -74,7 +74,7 @@ { "name": "my.histogram", "unit": "1", - "description": "I`m a Histogram", + "description": "I am a Histogram", "histogram": { "aggregationTemporality": 1, "dataPoints": [ @@ -104,4 +104,4 @@ ] } ] -} \ No newline at end of file +} From d5ec6cb1d706267034005e143f4b366e4a3ed1ad Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Jul 2023 10:46:07 -0400 Subject: [PATCH 075/127] [CI] Report link-check error when external URL used for local doc page (#498) Co-authored-by: Carlos Alberto Cortez --- .markdown_link_check_config.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index dac3ae97b..f8cf2cdd0 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -6,8 +6,12 @@ ], "replacementPatterns": [ { - "pattern": "^/", - "replacement": "{{BASEURL}}/" + "pattern": "^/", + "replacement": "{{BASEURL}}/" + }, + { + "pattern": "^https://github.com/open-telemetry/opentelemetry-proto/(blob|tree)/[^/]+/docs/", + "replacement": "LINK-CHECK-ERROR-USE-LOCAL-PATH-TO-DOC-PAGE-NOT-EXTERNAL-URL/" } ], "retryOn429": true, From a499d05938a994ca15c20a1b0718609c278bde7b Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Tue, 4 Jul 2023 12:36:51 -0400 Subject: [PATCH 076/127] add markdown linting to makefile and github actions (reference: #464) --- .github/workflows/build-check.yaml | 12 + .markdownlint.yaml | 14 + CHANGELOG.md | 10 +- Makefile | 11 +- package-lock.json | 564 ++++++++++++++++++++++++++++- package.json | 3 +- 6 files changed, 605 insertions(+), 9 deletions(-) create mode 100644 .markdownlint.yaml diff --git a/.github/workflows/build-check.yaml b/.github/workflows/build-check.yaml index 4512d9308..d84a42ae3 100644 --- a/.github/workflows/build-check.yaml +++ b/.github/workflows/build-check.yaml @@ -111,3 +111,15 @@ jobs: - name: run markdown-link-check run: make markdown-link-check + + markdownlint: + runs-on: ubuntu-latest + steps: + - name: check out code + uses: actions/checkout@v2 + + - name: install dependencies + run: npm install + + - name: run markdownlint + run: make markdownlint \ No newline at end of file diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 000000000..eb42d5b55 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,14 @@ +# See https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md +# and https://github.com/DavidAnson/markdownlint/blob/main/README.md + +# Default state for all rules +default: true + +ul-style: false +line-length: false +no-duplicate-header: + siblings_only: true +ol-prefix: + style: ordered +no-inline-html: false +fenced-code-language: false \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ac7a6eca..d2d22123e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,7 @@ Full list of differences found in [this compare](https://github.com/open-telemet * Add `csharp_namespace` option to protos. ([#399](https://github.com/open-telemetry/opentelemetry-proto/pull/399)) * Fix some out-of-date urls which link to [specification](https://github.com/open-telemetry/opentelemetry-specification). ([#402](https://github.com/open-telemetry/opentelemetry-proto/pull/402)) -* :stop_sign: [BREAKING] Delete deprecated InstrumentationLibrary, +* :stop_sign: [BREAKING] Delete deprecated InstrumentationLibrary, InstrumentationLibraryLogs, InstrumentationLibrarySpans and InstrumentationLibraryMetrics messages. Delete deprecated instrumentation_library_logs, instrumentation_library_spans and @@ -137,7 +137,7 @@ Full list of differences found in [this compare](https://github.com/open-telemet * Remove unused deprecated message StringKeyValue (#358) * Remove experimental metrics config service (#359) - + ## 0.12.0 - 2022-01-19 Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.11.0...v0.12.0). @@ -288,9 +288,9 @@ Full list of differences found in [this compare.](https://github.com/open-teleme ### Changed * :stop_sign: [BREAKING] Metrics - protocol was refactored, and lots of breaking changes. -** Removed MetricDescriptor and embedded into Metric and the new data types. -** Add new data types Gauge/Sum/Histogram. -** Make use of the "AggregationTemporality" into the data types that allow that support. + * Removed MetricDescriptor and embedded into Metric and the new data types. + * Add new data types Gauge/Sum/Histogram. + * Make use of the "AggregationTemporality" into the data types that allow that support. * Rename enum values to follow the proto3 style guide. ### Added diff --git a/Makefile b/Makefile index 6e7136465..f1d608c87 100755 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ $(1) endef .PHONY: all -all: gen-all markdown-link-check +all: gen-all markdown-link-check markdownlint # Generate all implementations .PHONY: gen-all @@ -165,3 +165,12 @@ markdown-link-check: npx --no -- markdown-link-check --quiet --config .markdown_link_check_config.json $$f \ || exit 1; \ done + +.PHONY: markdownlint +markdownlint: + @if ! npm ls markdownlint; then npm install; fi + @for f in $(ALL_DOCS); do \ + echo $$f; \ + npx --no -p markdownlint-cli markdownlint -c .markdownlint.yaml $$f \ + || exit 1; \ + done diff --git a/package-lock.json b/package-lock.json index da3ef4546..331c5bc33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,12 @@ { - "name": "otlp", + "name": "opentelemetry-proto", "lockfileVersion": 2, "requires": true, "packages": { "": { "devDependencies": { - "markdown-link-check": "3.10.3" + "markdown-link-check": "3.10.3", + "markdownlint-cli": "0.31.0" } }, "node_modules/ansi-styles": { @@ -23,18 +24,40 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -116,6 +139,12 @@ "node": ">= 6" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -153,6 +182,15 @@ "ms": "^2.1.1" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -220,6 +258,56 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -269,6 +357,40 @@ "node": ">=0.10.0" } }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/is-absolute-url": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", @@ -308,6 +430,24 @@ "node": ">=4.0.0" } }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, "node_modules/link-check": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/link-check/-/link-check-5.2.0.tgz", @@ -320,12 +460,46 @@ "needle": "^3.1.0" } }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-link-check": { "version": "3.10.3", "resolved": "https://registry.npmjs.org/markdown-link-check/-/markdown-link-check-3.10.3.tgz", @@ -355,6 +529,57 @@ "marked": "^4.1.0" } }, + "node_modules/markdownlint": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz", + "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==", + "dev": true, + "dependencies": { + "markdown-it": "12.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.0.tgz", + "integrity": "sha512-UCNA10I2evrEqGWUGM4I6ae6LubLeySkKegP1GQaZSES516BYBgOn8Ai8MXU+5rSIeCvMyKi91alqHyRDuUnYA==", + "dev": true, + "dependencies": { + "commander": "~9.0.0", + "get-stdin": "~9.0.0", + "glob": "~7.2.0", + "ignore": "~5.2.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.0.0", + "markdownlint": "~0.25.1", + "markdownlint-rule-helpers": "~0.16.0", + "minimatch": "~3.0.4", + "run-con": "~1.2.10" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/markdownlint-cli/node_modules/commander": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz", + "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/markdownlint-rule-helpers": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz", + "integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==", + "dev": true + }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -367,6 +592,33 @@ "node": ">= 12" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -402,6 +654,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -427,6 +688,15 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -445,6 +715,21 @@ "node": ">=6" } }, + "node_modules/run-con": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.12.tgz", + "integrity": "sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~3.0.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -457,6 +742,18 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -468,6 +765,18 @@ "engines": { "node": ">=8" } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true } }, "dependencies": { @@ -480,18 +789,40 @@ "color-convert": "^2.0.1" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -552,6 +883,12 @@ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -580,6 +917,12 @@ "ms": "^2.1.1" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -623,6 +966,43 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -659,6 +1039,34 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", + "dev": true + }, "is-absolute-url": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", @@ -683,6 +1091,21 @@ "punycode": "2.x.x" } }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, "link-check": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/link-check/-/link-check-5.2.0.tgz", @@ -695,12 +1118,42 @@ "needle": "^3.1.0" } }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } + } + }, "markdown-link-check": { "version": "3.10.3", "resolved": "https://registry.npmjs.org/markdown-link-check/-/markdown-link-check-3.10.3.tgz", @@ -727,12 +1180,74 @@ "marked": "^4.1.0" } }, + "markdownlint": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz", + "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==", + "dev": true, + "requires": { + "markdown-it": "12.3.2" + } + }, + "markdownlint-cli": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.0.tgz", + "integrity": "sha512-UCNA10I2evrEqGWUGM4I6ae6LubLeySkKegP1GQaZSES516BYBgOn8Ai8MXU+5rSIeCvMyKi91alqHyRDuUnYA==", + "dev": true, + "requires": { + "commander": "~9.0.0", + "get-stdin": "~9.0.0", + "glob": "~7.2.0", + "ignore": "~5.2.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.0.0", + "markdownlint": "~0.25.1", + "markdownlint-rule-helpers": "~0.16.0", + "minimatch": "~3.0.4", + "run-con": "~1.2.10" + }, + "dependencies": { + "commander": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz", + "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==", + "dev": true + } + } + }, + "markdownlint-rule-helpers": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz", + "integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==", + "dev": true + }, "marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -759,6 +1274,15 @@ "boolbase": "^1.0.0" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, "parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -778,6 +1302,12 @@ "parse5": "^7.0.0" } }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -790,6 +1320,18 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, + "run-con": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.12.tgz", + "integrity": "sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~3.0.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -802,6 +1344,12 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -810,6 +1358,18 @@ "requires": { "has-flag": "^4.0.0" } + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true } } } diff --git a/package.json b/package.json index ed875da02..a590a3fbe 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "devDependencies": { - "markdown-link-check": "3.10.3" + "markdown-link-check": "3.10.3", + "markdownlint-cli": "0.31.0" } } From 07568e90243296ceb11fc1b07a8dcdbddbe1851c Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Thu, 13 Jul 2023 18:43:33 -0400 Subject: [PATCH 077/127] fix linting errors from recent merge from main --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d22123e..b93bd0618 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ Full list of differences found in [this compare](https://github.com/open-telemet Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...v1.0.0). ### Maturity - -* Add note about the possibility to have unstable components after 1.0.0 + +* Add note about the possibility to have unstable components after 1.0.0 [#489](https://github.com/open-telemetry/opentelemetry-proto/pull/489) * Add maturity JSON entry per package [#490](https://github.com/open-telemetry/opentelemetry-proto/pull/490) From 98e6c63aa8f6e9d8103d5efdd3c0f779284af623 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Thu, 17 Aug 2023 12:07:32 -0400 Subject: [PATCH 078/127] Add comment to explain schema_url fields Resolves https://github.com/open-telemetry/opentelemetry-proto/issues/502 --- opentelemetry/proto/logs/v1/logs.proto | 6 ++++++ opentelemetry/proto/metrics/v1/metrics.proto | 6 ++++++ opentelemetry/proto/trace/v1/trace.proto | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/opentelemetry/proto/logs/v1/logs.proto b/opentelemetry/proto/logs/v1/logs.proto index 0b4b64972..b6679b7ac 100644 --- a/opentelemetry/proto/logs/v1/logs.proto +++ b/opentelemetry/proto/logs/v1/logs.proto @@ -55,6 +55,9 @@ message ResourceLogs { // A list of ScopeLogs that originate from a resource. repeated ScopeLogs scope_logs = 2; + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to the data in the "resource" field. It does not apply // to the data in the "scope_logs" field which have their own schema_url field. string schema_url = 3; @@ -70,6 +73,9 @@ message ScopeLogs { // A list of log records. repeated LogRecord log_records = 2; + // The Schema URL, if known. This is the identifier of the Schema that the log data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to all logs in the "logs" field. string schema_url = 3; } diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index 2362f51c6..0b1cf4f98 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -55,6 +55,9 @@ message ResourceMetrics { // A list of metrics that originate from a resource. repeated ScopeMetrics scope_metrics = 2; + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to the data in the "resource" field. It does not apply // to the data in the "scope_metrics" field which have their own schema_url field. string schema_url = 3; @@ -70,6 +73,9 @@ message ScopeMetrics { // A list of metrics that originate from an instrumentation library. repeated Metric metrics = 2; + // The Schema URL, if known. This is the identifier of the Schema that the metric data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to all metrics in the "metrics" field. string schema_url = 3; } diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index b2869edc4..8af5743d7 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -55,6 +55,9 @@ message ResourceSpans { // A list of ScopeSpans that originate from a resource. repeated ScopeSpans scope_spans = 2; + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to the data in the "resource" field. It does not apply // to the data in the "scope_spans" field which have their own schema_url field. string schema_url = 3; @@ -70,6 +73,9 @@ message ScopeSpans { // A list of Spans that originate from an instrumentation scope. repeated Span spans = 2; + // The Schema URL, if known. This is the identifier of the Schema that the span data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to all spans and span events in the "spans" field. string schema_url = 3; } From 8b022d8c9fa79bb9d9e7b1c53d4e662c252169e5 Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Thu, 14 Sep 2023 08:48:13 -0700 Subject: [PATCH 079/127] Add W3C-specified trace flags to v1 Span proto (#503) --- CHANGELOG.md | 5 +++ opentelemetry/proto/logs/v1/logs.proto | 8 ++-- opentelemetry/proto/trace/v1/trace.proto | 51 ++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b93bd0618..470f1f43e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.0.0...main). +### Added + +* Add a field for W3C-specified Trace Context flags to the `Span` and `Link`. + [#503](https://github.com/open-telemetry/opentelemetry-proto/pull/503) + ## 1.0.0 - 2023-07-03 Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...v1.0.0). diff --git a/opentelemetry/proto/logs/v1/logs.proto b/opentelemetry/proto/logs/v1/logs.proto index b6679b7ac..f9b97dd74 100644 --- a/opentelemetry/proto/logs/v1/logs.proto +++ b/opentelemetry/proto/logs/v1/logs.proto @@ -110,9 +110,11 @@ enum SeverityNumber { SEVERITY_NUMBER_FATAL4 = 24; } -// LogRecordFlags is defined as a protobuf 'uint32' type and is to be used as -// bit-fields. Each non-zero value defined in this enum is a bit-mask. -// To extract the bit-field, for example, use an expression like: +// LogRecordFlags represents constants used to interpret the +// LogRecord.flags field, which is protobuf 'fixed32' type and is to +// be used as bit-fields. Each non-zero value defined in this enum is +// a bit-mask. To extract the bit-field, for example, use an +// expression like: // // (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK) // diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 8af5743d7..a1fdfa3ac 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -109,6 +109,22 @@ message Span { // field must be empty. The ID is an 8-byte array. bytes parent_span_id = 4; + // Flags, a bit field. 8 least significant bits are the trace + // flags as defined in W3C Trace Context specification. Readers + // MUST not assume that 24 most significant bits will be zero. + // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. + // + // When creating span messages, if the message is logically forwarded from another source + // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD + // be copied as-is. If creating from a source that does not have an equivalent flags field + // (such as a runtime representation of an OpenTelemetry span), the high 24 bits MUST + // be set to zero. + // + // [Optional]. + // + // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + fixed32 flags = 16; + // A description of the span's operation. // // For example, the name can be a qualified method name or a file name @@ -242,6 +258,16 @@ message Span { // dropped_attributes_count is the number of dropped attributes. If the value is 0, // then no attributes were dropped. uint32 dropped_attributes_count = 5; + + // Flags, a bit field. 8 least significant bits are the trace + // flags as defined in W3C Trace Context specification. Readers + // MUST not assume that 24 most significant bits will be zero. + // When creating new spans, the most-significant 24-bits MUST be + // zero. To read the 8-bit W3C trace flag (use flags & + // SPAN_FLAGS_TRACE_FLAGS_MASK). [Optional]. + // + // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + fixed32 flags = 6; } // links is a collection of Links, which are references from this span to a span @@ -280,3 +306,28 @@ message Status { // The status code. StatusCode code = 3; } + +// SpanFlags represents constants used to interpret the +// Span.flags field, which is protobuf 'fixed32' type and is to +// be used as bit-fields. Each non-zero value defined in this enum is +// a bit-mask. To extract the bit-field, for example, use an +// expression like: +// +// (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK) +// +// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. +// +// Note that Span flags were introduced in version 1.1 of the +// OpenTelemetry protocol. Older Span producers do not set this +// field, consequently consumers should not rely on the absence of a +// particular flag bit to indicate the presence of a particular feature. +enum SpanFlags { + // The zero value for the enum. Should not be used for comparisons. + // Instead use bitwise "and" with the appropriate mask as shown above. + SPAN_FLAGS_DO_NOT_USE = 0; + + // Bits 0-7 are used for trace flags. + SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; + + // Bits 8-31 are reserved for future use. +} From 458784b9b7a765edd1e43b6b02e2d8fdaa2668c5 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 7 Nov 2023 07:55:15 -0500 Subject: [PATCH 080/127] Remove irrelevant comments from metric name field (#512) --- opentelemetry/proto/metrics/v1/metrics.proto | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index 0b1cf4f98..41605c888 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -166,7 +166,9 @@ message ScopeMetrics { // when the start time is truly unknown, setting StartTimeUnixNano is // strongly encouraged. message Metric { - // name of the metric, including its DNS name prefix. It must be unique. + reserved 4, 6, 8; + + // name of the metric. string name = 1; // description of the metric, which can be used in documentation. @@ -536,7 +538,7 @@ message ExponentialHistogramDataPoint { // doing so. This is specifically to enforce compatibility w/ OpenMetrics, // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram optional double sum = 5; - + // scale describes the resolution of the histogram. Boundaries are // located at powers of the base, where: // @@ -574,7 +576,7 @@ message ExponentialHistogramDataPoint { // of counts. message Buckets { // Offset is the bucket index of the first entry in the bucket_counts array. - // + // // Note: This uses a varint encoding as a simple form of compression. sint32 offset = 1; @@ -588,7 +590,7 @@ message ExponentialHistogramDataPoint { // especially zeros, so uint64 has been selected to ensure // varint encoding. repeated uint64 bucket_counts = 2; - } + } // Flags that apply to this specific data point. See DataPointFlags // for the available flags and their meaning. From bf53163949905157f48092d1114d765870a351c7 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Fri, 27 Oct 2023 11:01:24 -0400 Subject: [PATCH 081/127] Fix the incorrect histogram example in metrics.json There are 2 buckets (-inf, 1), [1, +inf) but 3 bucket counts. --- examples/metrics.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/metrics.json b/examples/metrics.json index 2b4592205..feeacb50e 100644 --- a/examples/metrics.json +++ b/examples/metrics.json @@ -81,11 +81,11 @@ { "startTimeUnixNano": 1544712660300000000, "timeUnixNano": 1544712660300000000, - "count": 3, - "sum": 3, - "bucketCounts": [1,1,1], + "count": 2, + "sum": 2, + "bucketCounts": [1,1], "explicitBounds": [1], - "min": 1, + "min": 0, "max": 1, "attributes": [ { From 9212a22191f08e27391975076f36710d8cd1fd0c Mon Sep 17 00:00:00 2001 From: Yang Song Date: Fri, 27 Oct 2023 16:53:24 -0400 Subject: [PATCH 082/127] Update metrics.json --- examples/metrics.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/metrics.json b/examples/metrics.json index feeacb50e..6704c3b57 100644 --- a/examples/metrics.json +++ b/examples/metrics.json @@ -86,7 +86,7 @@ "bucketCounts": [1,1], "explicitBounds": [1], "min": 0, - "max": 1, + "max": 2, "attributes": [ { "key": "my.histogram.attr", From ec4b0e9d4f8f5018953543df504addf0e1de4284 Mon Sep 17 00:00:00 2001 From: Ben Blackmore Date: Tue, 9 Jan 2024 20:14:14 +0100 Subject: [PATCH 083/127] fix: OTLP JSON examples (#516) # Why The example files do not follow the specification. 64 bit integers must be [string encoded](https://protobuf.dev/programming-guides/proto3/#json). # What - Fix the encoding in the examples - Add an example for log `severityNumber` to point at the enum encoding rules. --- examples/logs.json | 7 ++++--- examples/metrics.json | 10 +++++----- examples/trace.json | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/logs.json b/examples/logs.json index 8c7a84131..3fd771629 100644 --- a/examples/logs.json +++ b/examples/logs.json @@ -27,8 +27,9 @@ }, "logRecords": [ { - "timeUnixNano": 1544712660300000000, - "observedTimeUnixNano": 1544712660300000000, + "timeUnixNano": "1544712660300000000", + "observedTimeUnixNano": "1544712660300000000", + "severityNumber": 10, "severityText": "Information", "traceId": "5B8EFFF798038103D269B633813FC60C", "spanId": "EEE19B7EC3C1B174", @@ -51,7 +52,7 @@ { "key": "int.attribute", "value": { - "intValue": 10 + "intValue": "10" } }, { diff --git a/examples/metrics.json b/examples/metrics.json index 6704c3b57..36e0767d9 100644 --- a/examples/metrics.json +++ b/examples/metrics.json @@ -36,8 +36,8 @@ "dataPoints": [ { "asDouble": 5, - "startTimeUnixNano": 1544712660300000000, - "timeUnixNano": 1544712660300000000, + "startTimeUnixNano": "1544712660300000000", + "timeUnixNano": "1544712660300000000", "attributes": [ { "key": "my.counter.attr", @@ -58,7 +58,7 @@ "dataPoints": [ { "asDouble": 10, - "timeUnixNano": 1544712660300000000, + "timeUnixNano": "1544712660300000000", "attributes": [ { "key": "my.gauge.attr", @@ -79,8 +79,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "startTimeUnixNano": 1544712660300000000, - "timeUnixNano": 1544712660300000000, + "startTimeUnixNano": "1544712660300000000", + "timeUnixNano": "1544712660300000000", "count": 2, "sum": 2, "bucketCounts": [1,1], diff --git a/examples/trace.json b/examples/trace.json index 6d01eeefc..41130ff1a 100644 --- a/examples/trace.json +++ b/examples/trace.json @@ -31,8 +31,8 @@ "spanId": "EEE19B7EC3C1B174", "parentSpanId": "EEE19B7EC3C1B173", "name": "I'm a server span", - "startTimeUnixNano": 1544712660000000000, - "endTimeUnixNano": 1544712661000000000, + "startTimeUnixNano": "1544712660000000000", + "endTimeUnixNano": "1544712661000000000", "kind": 2, "attributes": [ { From 18d0564ec51b0e697bb0da92c31626f53dfdec53 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 11 Jan 2024 08:54:12 -0800 Subject: [PATCH 084/127] Prepare release 1.1.0 (#523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prepare release 1.1.0 Signed-off-by: Bogdan Drutu * Update CHANGELOG.md Co-authored-by: Piotr Kiełkowicz * Update CHANGELOG.md * Update CHANGELOG.md Co-authored-by: Yuri Shkuro --------- Signed-off-by: Bogdan Drutu Co-authored-by: Piotr Kiełkowicz Co-authored-by: Yuri Shkuro --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 470f1f43e..ab793a015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,25 @@ ## Unreleased -Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.0.0...main). +Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.1.0...main). + +## 1.1.0 - 2024-01-10 + +Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.0.0...v1.1.0). ### Added -* Add a field for W3C-specified Trace Context flags to the `Span` and `Link`. +* Add `flags` field to `Span` and `Span/Link` for W3C-specified Trace Context flags . [#503](https://github.com/open-telemetry/opentelemetry-proto/pull/503) +### Changed + +* Update and fix OTLP JSON examples. [#516](https://github.com/open-telemetry/opentelemetry-proto/pull/516), + [#510](https://github.com/open-telemetry/opentelemetry-proto/pull/510), + [#499](https://github.com/open-telemetry/opentelemetry-proto/pull/499) +* Remove irrelevant comments from metric name field. [#512](https://github.com/open-telemetry/opentelemetry-proto/pull/512) +* Add comment to explain schema_url fields. [#504](https://github.com/open-telemetry/opentelemetry-proto/pull/504) + ## 1.0.0 - 2023-07-03 Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...v1.0.0). From 8d01002a39c31e335bc3c29e23b80347522112ce Mon Sep 17 00:00:00 2001 From: Armin Ruech <7052238+arminru@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:29:14 +0100 Subject: [PATCH 085/127] Fix typo in requirements.md --- docs/requirements.md | 2 +- docs/specification.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/requirements.md b/docs/requirements.md index 5d1f1cb66..842ca77fe 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -84,7 +84,7 @@ Ideally it must also support very fast pass-through mode (when no modifications The protocol must impose minimal pressure on memory manager, including pass-through scenarios, when deserialized data is short-lived and must be serialized as-is shortly after and when such short-lived data is created and discarded at high frequency (think telemetry data forwarders). -The implementation of telemetry protocol must aim to minimize the number of memory allocations and dealocations performed during serialization and deserialization and aim to minimize the pressure on Garbage Collection (for GC languages). +The implementation of telemetry protocol must aim to minimize the number of memory allocations and deallocations performed during serialization and deserialization and aim to minimize the pressure on Garbage Collection (for GC languages). ### Level 7 Load Balancer Friendly diff --git a/docs/specification.md b/docs/specification.md index a4bcb13cc..d017eada4 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -5,7 +5,7 @@ aliases: - /docs/reference/specification/protocol/otlp - /docs/specs/otel/protocol/otlp spelling: - cSpell:ignore backoff backpressure dealocations errdetails nanos proto reconnections retryable + cSpell:ignore backoff backpressure errdetails nanos proto reconnections retryable cascade: body_class: otel-docs-spec github_repo: &repo https://github.com/open-telemetry/opentelemetry-proto From 80bf0a341899915de5994758906dd783770a45ec Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 13 Jun 2023 13:21:07 +0200 Subject: [PATCH 086/127] Add parent_span_is_remote to Span message --- opentelemetry/proto/trace/v1/trace.proto | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index a1fdfa3ac..b000b3325 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -281,6 +281,12 @@ message Span { // An optional final status for this span. Semantically when Status isn't set, it means // span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0). Status status = 15; + + // parent_span_is_remote identifies whether a span's parent is remote or not. + // This helps determine whether a span can be considered an entry-point span. + // A span is an entry-point span if it has no parent (parent_span_id is empty), + // or if parent_span_is_remote is true. + bool parent_span_is_remote = 16; } // The Status type defines a logical error model that is suitable for different From 6ccc2e36b6a779c216d624a0812c121479d9f76b Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 15 Aug 2023 12:07:31 +0200 Subject: [PATCH 087/127] Use enum for ParentSpanIsRemote --- opentelemetry/proto/trace/v1/trace.proto | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index b000b3325..afe8934b3 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -282,11 +282,24 @@ message Span { // span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0). Status status = 15; + // ParentSpanIsRemote indicates whether the span's parent is remote (true / false) or + // if the field is unset. + enum ParentIsRemote { + // Unset. + PARENT_SPAN_IS_REMOTE_UNSET = 0; + + // The parent span is not remote. + PARENT_SPAN_IS_REMOTE_FALSE = 1; + + // The parent span is remote. + PARENT_SPAN_IS_REMOTE_TRUE = 2; + } + // parent_span_is_remote identifies whether a span's parent is remote or not. // This helps determine whether a span can be considered an entry-point span. // A span is an entry-point span if it has no parent (parent_span_id is empty), - // or if parent_span_is_remote is true. - bool parent_span_is_remote = 16; + // or if parent_is_remote is true. + ParentSpanIsRemote parent_span_is_remote = 16; } // The Status type defines a logical error model that is suitable for different From 30e091e65eb66c4a58c2f442afeb6c5e72d3e4fd Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 15 Aug 2023 12:10:07 +0200 Subject: [PATCH 088/127] Adjust enum name --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index afe8934b3..ba38229b0 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -284,7 +284,7 @@ message Span { // ParentSpanIsRemote indicates whether the span's parent is remote (true / false) or // if the field is unset. - enum ParentIsRemote { + enum ParentSpanIsRemote { // Unset. PARENT_SPAN_IS_REMOTE_UNSET = 0; From 8867ebecf9cd0c2fa9e2c70b0110c58502d78ac0 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 15 Aug 2023 14:20:36 +0200 Subject: [PATCH 089/127] Add extra comment about unset value from older clients --- opentelemetry/proto/trace/v1/trace.proto | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index ba38229b0..21e944398 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -285,7 +285,8 @@ message Span { // ParentSpanIsRemote indicates whether the span's parent is remote (true / false) or // if the field is unset. enum ParentSpanIsRemote { - // Unset. + // Unset. This value is expected from older clients. In which case, ParentSpanIsRemote + // can be derived by looking at the parent span and determining if it has a different Resource. PARENT_SPAN_IS_REMOTE_UNSET = 0; // The parent span is not remote. From d48c4dbaffeaa31d4aa54766bdc332b624b28f2f Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 22 Aug 2023 12:17:39 +0200 Subject: [PATCH 090/127] Remove misleading documentation --- opentelemetry/proto/trace/v1/trace.proto | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 21e944398..bdf765e21 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -285,8 +285,7 @@ message Span { // ParentSpanIsRemote indicates whether the span's parent is remote (true / false) or // if the field is unset. enum ParentSpanIsRemote { - // Unset. This value is expected from older clients. In which case, ParentSpanIsRemote - // can be derived by looking at the parent span and determining if it has a different Resource. + // Unset. This value is expected from older clients. PARENT_SPAN_IS_REMOTE_UNSET = 0; // The parent span is not remote. From 2df5ef9509669e1dcb7b8d23499946f13e50778d Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 22 Aug 2023 12:19:11 +0200 Subject: [PATCH 091/127] Update names --- opentelemetry/proto/trace/v1/trace.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index bdf765e21..1e29f08b2 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -286,13 +286,13 @@ message Span { // if the field is unset. enum ParentSpanIsRemote { // Unset. This value is expected from older clients. - PARENT_SPAN_IS_REMOTE_UNSET = 0; + PARENT_SPAN_UNKNOWN_REMOTE = 0; // The parent span is not remote. - PARENT_SPAN_IS_REMOTE_FALSE = 1; + PARENT_SPAN_NOT_REMOTE = 1; // The parent span is remote. - PARENT_SPAN_IS_REMOTE_TRUE = 2; + PARENT_SPAN_REMOTE = 2; } // parent_span_is_remote identifies whether a span's parent is remote or not. From 8b6ecfc00b7a3a11c5a73cdccbdb5a06791b03ab Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Mon, 18 Sep 2023 16:18:40 +0200 Subject: [PATCH 092/127] Remove ParentSpanIsRemote attribute --- opentelemetry/proto/trace/v1/trace.proto | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 1e29f08b2..a1fdfa3ac 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -281,25 +281,6 @@ message Span { // An optional final status for this span. Semantically when Status isn't set, it means // span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0). Status status = 15; - - // ParentSpanIsRemote indicates whether the span's parent is remote (true / false) or - // if the field is unset. - enum ParentSpanIsRemote { - // Unset. This value is expected from older clients. - PARENT_SPAN_UNKNOWN_REMOTE = 0; - - // The parent span is not remote. - PARENT_SPAN_NOT_REMOTE = 1; - - // The parent span is remote. - PARENT_SPAN_REMOTE = 2; - } - - // parent_span_is_remote identifies whether a span's parent is remote or not. - // This helps determine whether a span can be considered an entry-point span. - // A span is an entry-point span if it has no parent (parent_span_id is empty), - // or if parent_is_remote is true. - ParentSpanIsRemote parent_span_is_remote = 16; } // The Status type defines a logical error model that is suitable for different From c72b39d4783da05f55afcbac07062c3cdbb269a0 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Mon, 18 Sep 2023 16:20:45 +0200 Subject: [PATCH 093/127] Add defintion of 2 bit parent is remote flag --- opentelemetry/proto/trace/v1/trace.proto | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index a1fdfa3ac..6816d159c 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -123,6 +123,10 @@ message Span { // [Optional]. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + // + // Bits 8 and 9 are reserved for representing the 3 states of whether a span's parent + // is remote. The states are unknown, is not remote, is remote. + // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_IS_REMOTE_MASK`. fixed32 flags = 16; // A description of the span's operation. @@ -329,5 +333,8 @@ enum SpanFlags { // Bits 0-7 are used for trace flags. SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; - // Bits 8-31 are reserved for future use. + // Bits 8 and 9 are used for for the parent is remote flag. + SPAN_FLAGS_PARENT_IS_REMOTE_MASK = 0x00000300; + + // Bits 10-31 are reserved for future use. } From 377e9761496b84a0371561319f31b0589ac46ec3 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 19 Sep 2023 13:07:53 +0200 Subject: [PATCH 094/127] Include enum for interpreting ParentIsRemote flag and update documentation --- opentelemetry/proto/trace/v1/trace.proto | 38 ++++++++++++++++++------ 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 6816d159c..d80d770f9 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -109,24 +109,27 @@ message Span { // field must be empty. The ID is an 8-byte array. bytes parent_span_id = 4; - // Flags, a bit field. 8 least significant bits are the trace - // flags as defined in W3C Trace Context specification. Readers - // MUST not assume that 24 most significant bits will be zero. + // Flags, a bit field. Bits 0-7 (8 least significant bits) are the trace + // flags as defined in W3C Trace Context specification. // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. // // When creating span messages, if the message is logically forwarded from another source // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD // be copied as-is. If creating from a source that does not have an equivalent flags field - // (such as a runtime representation of an OpenTelemetry span), the high 24 bits MUST + // (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST // be set to zero. // // [Optional]. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // - // Bits 8 and 9 are reserved for representing the 3 states of whether a span's parent + // Bits 8 and 9 represent the 3 states of whether a span's parent // is remote. The states are unknown, is not remote, is remote. // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_IS_REMOTE_MASK`. + // + // [Optional]. + // + // Readers MUST not assume that bits 10-31 (22 most significant bits) will be zero. fixed32 flags = 16; // A description of the span's operation. @@ -263,11 +266,11 @@ message Span { // then no attributes were dropped. uint32 dropped_attributes_count = 5; - // Flags, a bit field. 8 least significant bits are the trace + // Flags, a bit field. Bit 0-7 (8 least significant bits) are the trace // flags as defined in W3C Trace Context specification. Readers - // MUST not assume that 24 most significant bits will be zero. - // When creating new spans, the most-significant 24-bits MUST be - // zero. To read the 8-bit W3C trace flag (use flags & + // MUST not assume that bits 10-31 (22 most significant bits) will be zero. + // When creating new spans, bits 10-31 (most-significant 22-bits) MUST be + // zero. To read the 8-bit W3C trace flag (use flags & // SPAN_FLAGS_TRACE_FLAGS_MASK). [Optional]. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. @@ -334,7 +337,24 @@ enum SpanFlags { SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; // Bits 8 and 9 are used for for the parent is remote flag. + // See SpanFlagsParentIsRemote for the valid values. SPAN_FLAGS_PARENT_IS_REMOTE_MASK = 0x00000300; // Bits 10-31 are reserved for future use. } + +// SpanFlagsParentIsRemote represents constants used to interpret +// bits 8 and 9 of the Span.flags field. These two bits represent whether +// the span's parent is remote. Bit 8 represents whether the field has been +// set and bit 9 represents whether the parent is remote. +// Once the bits have been read using SPAN_FLAGS_PARENT_IS_REMOTE_MASK, +// the following constants can be used to interpret them. +enum SpanFlagsParentIsRemote { + // Older clients may not set this field, so 00 represents that this value + // has not been set. + SPAN_FLAGS_PARENT_IS_REMOTE_UNKNOWN = 0; + // The parent is remote: 11 + SPAN_FLAGS_PARENT_IS_REMOTE = 0x00000300; + // The parent is not remote: 01 + SPAN_FLAGS_PARENT_IS_NOT_REMOTE = 0x00000100; +} From 741fd3e59640d02cd2f55a7b748bd92d7537c084 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Wed, 27 Sep 2023 16:22:07 +0200 Subject: [PATCH 095/127] Add constants and enum for interpreting bits 8 and 9 of a Link's flags --- opentelemetry/proto/trace/v1/trace.proto | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index d80d770f9..9500ae5af 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -274,6 +274,10 @@ message Span { // SPAN_FLAGS_TRACE_FLAGS_MASK). [Optional]. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + // + // Bits 8 and 9 represent the 3 states of whether the link + // is remote. The states are unknown, is not remote, is remote. + // To read the 2-bit flag, use `flags & SPAN_FLAGS_LINK_IS_REMOTE_MASK`. fixed32 flags = 6; } @@ -340,6 +344,10 @@ enum SpanFlags { // See SpanFlagsParentIsRemote for the valid values. SPAN_FLAGS_PARENT_IS_REMOTE_MASK = 0x00000300; + // Bits 8 and 9 are used for for the link is remote flag. + // See SpanFlagsLinkIsRemote for the valid values. + SPAN_FLAGS_LINK_IS_REMOTE_MASK = 0x00000300; + // Bits 10-31 are reserved for future use. } @@ -358,3 +366,19 @@ enum SpanFlagsParentIsRemote { // The parent is not remote: 01 SPAN_FLAGS_PARENT_IS_NOT_REMOTE = 0x00000100; } + +// SpanFlagsLinkIsRemote represents constants used to interpret +// bits 8 and 9 of the Link.flags field. These two bits represent whether +// the link is remote. Bit 8 represents whether the field has been +// set and bit 9 represents whether the link is remote. +// Once the bits have been read using SPAN_FLAGS_LINK_IS_REMOTE_MASK, +// the following constants can be used to interpret them. +enum SpanFlagsLinkIsRemote { + // Older clients may not set this field, so 00 represents that this value + // has not been set. + SPAN_FLAGS_LINK_IS_REMOTE_UNKNOWN = 0; + // The linked span is remote: 11 + SPAN_FLAGS_LINK_IS_REMOTE = 0x00000300; + // The linked span is not remote: 01 + SPAN_FLAGS_LINK_IS_NOT_REMOTE = 0x00000100; +} From 7abd842afbb069731ea84c834c33d00dc48f8214 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Wed, 27 Sep 2023 16:27:30 +0200 Subject: [PATCH 096/127] One constant for link and parent is remote mask --- opentelemetry/proto/trace/v1/trace.proto | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 9500ae5af..fedb7e9bd 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -125,7 +125,7 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether a span's parent // is remote. The states are unknown, is not remote, is remote. - // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_IS_REMOTE_MASK`. + // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. // // [Optional]. // @@ -277,7 +277,7 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether the link // is remote. The states are unknown, is not remote, is remote. - // To read the 2-bit flag, use `flags & SPAN_FLAGS_LINK_IS_REMOTE_MASK`. + // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. fixed32 flags = 6; } @@ -340,13 +340,10 @@ enum SpanFlags { // Bits 0-7 are used for trace flags. SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; - // Bits 8 and 9 are used for for the parent is remote flag. - // See SpanFlagsParentIsRemote for the valid values. - SPAN_FLAGS_PARENT_IS_REMOTE_MASK = 0x00000300; - - // Bits 8 and 9 are used for for the link is remote flag. - // See SpanFlagsLinkIsRemote for the valid values. - SPAN_FLAGS_LINK_IS_REMOTE_MASK = 0x00000300; + // Bits 8 and 9 are used for the parent or link is remote flag. + // See SpanFlagsParentIsRemote and SpanFlagsLinkIsRemote for the + // valid values. + SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK = 0x00000300; // Bits 10-31 are reserved for future use. } @@ -355,7 +352,7 @@ enum SpanFlags { // bits 8 and 9 of the Span.flags field. These two bits represent whether // the span's parent is remote. Bit 8 represents whether the field has been // set and bit 9 represents whether the parent is remote. -// Once the bits have been read using SPAN_FLAGS_PARENT_IS_REMOTE_MASK, +// Once the bits have been read using SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK, // the following constants can be used to interpret them. enum SpanFlagsParentIsRemote { // Older clients may not set this field, so 00 represents that this value @@ -371,7 +368,7 @@ enum SpanFlagsParentIsRemote { // bits 8 and 9 of the Link.flags field. These two bits represent whether // the link is remote. Bit 8 represents whether the field has been // set and bit 9 represents whether the link is remote. -// Once the bits have been read using SPAN_FLAGS_LINK_IS_REMOTE_MASK, +// Once the bits have been read using SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK, // the following constants can be used to interpret them. enum SpanFlagsLinkIsRemote { // Older clients may not set this field, so 00 represents that this value From 17e2038bfca2ee7100d6d387c382592fba5411bf Mon Sep 17 00:00:00 2001 From: Emily S Date: Wed, 27 Sep 2023 17:49:09 +0200 Subject: [PATCH 097/127] Update opentelemetry/proto/trace/v1/trace.proto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Neumüller --- opentelemetry/proto/trace/v1/trace.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index fedb7e9bd..2bb74523c 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -127,9 +127,9 @@ message Span { // is remote. The states are unknown, is not remote, is remote. // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. // - // [Optional]. + // Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. // - // Readers MUST not assume that bits 10-31 (22 most significant bits) will be zero. + // [Optional]. fixed32 flags = 16; // A description of the span's operation. From ad149e68d03229253f1d916dba21d8d8e48ca673 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Thu, 28 Sep 2023 16:03:40 +0200 Subject: [PATCH 098/127] Adjust flags documentation ordering --- opentelemetry/proto/trace/v1/trace.proto | 33 ++++++++++++------------ 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 2bb74523c..bd0e42404 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -113,20 +113,17 @@ message Span { // flags as defined in W3C Trace Context specification. // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. // - // When creating span messages, if the message is logically forwarded from another source - // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD - // be copied as-is. If creating from a source that does not have an equivalent flags field - // (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST - // be set to zero. - // - // [Optional]. - // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // // Bits 8 and 9 represent the 3 states of whether a span's parent // is remote. The states are unknown, is not remote, is remote. // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. // + // When creating span messages, if the message is logically forwarded from another source + // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD + // be copied as-is. If creating from a source that does not have an equivalent flags field + // (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST + // be set to zero. // Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. // // [Optional]. @@ -266,18 +263,20 @@ message Span { // then no attributes were dropped. uint32 dropped_attributes_count = 5; - // Flags, a bit field. Bit 0-7 (8 least significant bits) are the trace - // flags as defined in W3C Trace Context specification. Readers - // MUST not assume that bits 10-31 (22 most significant bits) will be zero. - // When creating new spans, bits 10-31 (most-significant 22-bits) MUST be - // zero. To read the 8-bit W3C trace flag (use flags & - // SPAN_FLAGS_TRACE_FLAGS_MASK). [Optional]. + // Flags, a bit field. Bits 0-7 (8 least significant bits) are the trace + // flags as defined in W3C Trace Context specification. To read the 8-bit W3C trace + // flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // - // Bits 8 and 9 represent the 3 states of whether the link - // is remote. The states are unknown, is not remote, is remote. + // Bits 8 and 9 represent the 3 states of whether the link is remote. The states + // are unknown, is not remote, is remote. // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. + // + // Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. + // When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. + // + // [Optional]. fixed32 flags = 6; } @@ -340,7 +339,7 @@ enum SpanFlags { // Bits 0-7 are used for trace flags. SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; - // Bits 8 and 9 are used for the parent or link is remote flag. + // Bits 8 and 9 are used to indicate that the parent span or link span is remote. // See SpanFlagsParentIsRemote and SpanFlagsLinkIsRemote for the // valid values. SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK = 0x00000300; From daf0fea8bcb1cc6c226c1bc48775f270e1fc28a9 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Thu, 28 Sep 2023 16:25:14 +0200 Subject: [PATCH 099/127] Merge parent and link is remote enums into one --- opentelemetry/proto/trace/v1/trace.proto | 40 +++++++----------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index bd0e42404..986a2c46d 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -340,41 +340,25 @@ enum SpanFlags { SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; // Bits 8 and 9 are used to indicate that the parent span or link span is remote. - // See SpanFlagsParentIsRemote and SpanFlagsLinkIsRemote for the - // valid values. + // See SpanFlagsParentOrLinkIsRemote for the valid values. SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK = 0x00000300; // Bits 10-31 are reserved for future use. } -// SpanFlagsParentIsRemote represents constants used to interpret -// bits 8 and 9 of the Span.flags field. These two bits represent whether -// the span's parent is remote. Bit 8 represents whether the field has been -// set and bit 9 represents whether the parent is remote. +// SpanFlagsParentOrLinkIsRemote represents constants used to interpret +// bits 8 and 9 of the Spans.flags or Link.flags field. These two bits +// represent whether the parent or link is remote. Bit 8 represents whether +// the field has been set and bit 9 represents whether the parent or link is +// remote. // Once the bits have been read using SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK, // the following constants can be used to interpret them. -enum SpanFlagsParentIsRemote { +enum SpanFlagsParentOrLinkIsRemote { // Older clients may not set this field, so 00 represents that this value // has not been set. - SPAN_FLAGS_PARENT_IS_REMOTE_UNKNOWN = 0; - // The parent is remote: 11 - SPAN_FLAGS_PARENT_IS_REMOTE = 0x00000300; - // The parent is not remote: 01 - SPAN_FLAGS_PARENT_IS_NOT_REMOTE = 0x00000100; -} - -// SpanFlagsLinkIsRemote represents constants used to interpret -// bits 8 and 9 of the Link.flags field. These two bits represent whether -// the link is remote. Bit 8 represents whether the field has been -// set and bit 9 represents whether the link is remote. -// Once the bits have been read using SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK, -// the following constants can be used to interpret them. -enum SpanFlagsLinkIsRemote { - // Older clients may not set this field, so 00 represents that this value - // has not been set. - SPAN_FLAGS_LINK_IS_REMOTE_UNKNOWN = 0; - // The linked span is remote: 11 - SPAN_FLAGS_LINK_IS_REMOTE = 0x00000300; - // The linked span is not remote: 01 - SPAN_FLAGS_LINK_IS_NOT_REMOTE = 0x00000100; + SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_UNKNOWN = 0; + // The parent or linked span is remote: 11 + SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE = 0x00000300; + // The parent or linked span is not remote: 01 + SPAN_FLAGS_PARENT_OR_LINK_IS_NOT_REMOTE = 0x00000100; } From b0149ff1a2b1bce5d2ac954132240ad817de1dfe Mon Sep 17 00:00:00 2001 From: Emily S Date: Thu, 12 Oct 2023 14:23:04 +0200 Subject: [PATCH 100/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 986a2c46d..07d192c89 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -353,7 +353,7 @@ enum SpanFlags { // remote. // Once the bits have been read using SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK, // the following constants can be used to interpret them. -enum SpanFlagsParentOrLinkIsRemote { +enum SpanFlagsContextIsRemote { // Older clients may not set this field, so 00 represents that this value // has not been set. SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_UNKNOWN = 0; From d58b07ee12cf02fcd16e42ec68e8fbcd390047fe Mon Sep 17 00:00:00 2001 From: Emily S Date: Thu, 12 Oct 2023 14:23:15 +0200 Subject: [PATCH 101/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Joshua MacDonald --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 07d192c89..917e662e8 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -351,7 +351,7 @@ enum SpanFlags { // represent whether the parent or link is remote. Bit 8 represents whether // the field has been set and bit 9 represents whether the parent or link is // remote. -// Once the bits have been read using SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK, +// Once the bits have been read using SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK, // the following constants can be used to interpret them. enum SpanFlagsContextIsRemote { // Older clients may not set this field, so 00 represents that this value From 4cee2e3d61e2806344cccd05cf7dbd763efb4656 Mon Sep 17 00:00:00 2001 From: Emily S Date: Thu, 12 Oct 2023 14:23:26 +0200 Subject: [PATCH 102/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Joshua MacDonald --- opentelemetry/proto/trace/v1/trace.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 917e662e8..c8f5b1db6 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -356,9 +356,9 @@ enum SpanFlags { enum SpanFlagsContextIsRemote { // Older clients may not set this field, so 00 represents that this value // has not been set. - SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_UNKNOWN = 0; + SPAN_FLAGS_CONTEXT_IS_REMOTE_UNKNOWN = 0; // The parent or linked span is remote: 11 - SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE = 0x00000300; + SPAN_FLAGS_CONTEXT_IS_REMOTE = 0x00000300; // The parent or linked span is not remote: 01 - SPAN_FLAGS_PARENT_OR_LINK_IS_NOT_REMOTE = 0x00000100; + SPAN_FLAGS_CONTEXT_IS_NOT_REMOTE = 0x00000100; } From cceb98b606029db455019d3981a8fe97feb6667d Mon Sep 17 00:00:00 2001 From: Emily S Date: Thu, 12 Oct 2023 14:23:37 +0200 Subject: [PATCH 103/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Joshua MacDonald --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index c8f5b1db6..cb07920c7 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -271,7 +271,7 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether the link is remote. The states // are unknown, is not remote, is remote. - // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. + // To read the 2-bit flag, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. // // Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. // When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. From 9c27cc93e3d1f63dbea5d70d5c6665b6b159da54 Mon Sep 17 00:00:00 2001 From: Emily S Date: Thu, 12 Oct 2023 14:23:47 +0200 Subject: [PATCH 104/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Joshua MacDonald --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index cb07920c7..eac4b99e1 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -341,7 +341,7 @@ enum SpanFlags { // Bits 8 and 9 are used to indicate that the parent span or link span is remote. // See SpanFlagsParentOrLinkIsRemote for the valid values. - SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK = 0x00000300; + SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 0x00000300; // Bits 10-31 are reserved for future use. } From 291d76f7c87a363d7a97c1c2158a4aa3c08af75c Mon Sep 17 00:00:00 2001 From: Emily S Date: Thu, 12 Oct 2023 14:25:30 +0200 Subject: [PATCH 105/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Joshua MacDonald --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index eac4b99e1..7f98ec1e7 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -117,7 +117,7 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether a span's parent // is remote. The states are unknown, is not remote, is remote. - // To read the 2-bit flag, use `flags & SPAN_FLAGS_PARENT_OR_LINK_IS_REMOTE_MASK`. + // To read the 2-bit flag, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. // // When creating span messages, if the message is logically forwarded from another source // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD From 04ab71f9b30feb2583c8023a1677569f5ab415c5 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Thu, 12 Oct 2023 14:29:28 +0200 Subject: [PATCH 106/127] Change doc references to updated enum name --- opentelemetry/proto/trace/v1/trace.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 7f98ec1e7..69e690f2c 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -340,13 +340,13 @@ enum SpanFlags { SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; // Bits 8 and 9 are used to indicate that the parent span or link span is remote. - // See SpanFlagsParentOrLinkIsRemote for the valid values. + // See SpanFlagsContextIsRemote for the valid values. SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 0x00000300; // Bits 10-31 are reserved for future use. } -// SpanFlagsParentOrLinkIsRemote represents constants used to interpret +// SpanFlagsContextIsRemote represents constants used to interpret // bits 8 and 9 of the Spans.flags or Link.flags field. These two bits // represent whether the parent or link is remote. Bit 8 represents whether // the field has been set and bit 9 represents whether the parent or link is From ce1baa5dbabf21c09f1b876f18db22ffa471376a Mon Sep 17 00:00:00 2001 From: Emily S Date: Mon, 16 Oct 2023 12:56:49 +0200 Subject: [PATCH 107/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- opentelemetry/proto/trace/v1/trace.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 69e690f2c..49db2dbe7 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -109,7 +109,9 @@ message Span { // field must be empty. The ID is an 8-byte array. bytes parent_span_id = 4; - // Flags, a bit field. Bits 0-7 (8 least significant bits) are the trace + // Flags, a bit field. + // + // Bits 0-7 (8 least significant bits) are the trace // flags as defined in W3C Trace Context specification. // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. // From 4e79ac628865b847182ed6ec202582976c066777 Mon Sep 17 00:00:00 2001 From: Emily S Date: Mon, 16 Oct 2023 12:56:58 +0200 Subject: [PATCH 108/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- opentelemetry/proto/trace/v1/trace.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 49db2dbe7..a68eba6ce 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -118,7 +118,7 @@ message Span { // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // // Bits 8 and 9 represent the 3 states of whether a span's parent - // is remote. The states are unknown, is not remote, is remote. + // is remote. The states are (unknown, is not remote, is remote). // To read the 2-bit flag, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. // // When creating span messages, if the message is logically forwarded from another source From 7b258fba42a61e67ecc0e01dad90192ffeb7b8ca Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Mon, 16 Oct 2023 13:00:23 +0200 Subject: [PATCH 109/127] Adjust formatting of comments --- opentelemetry/proto/trace/v1/trace.proto | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index a68eba6ce..cf0c0883f 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -109,11 +109,11 @@ message Span { // field must be empty. The ID is an 8-byte array. bytes parent_span_id = 4; - // Flags, a bit field. + // Flags, a bit field. // - // Bits 0-7 (8 least significant bits) are the trace - // flags as defined in W3C Trace Context specification. - // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. + // Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace + // Context specification. To read the 8-bit W3C trace flag, use + // `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // @@ -265,9 +265,11 @@ message Span { // then no attributes were dropped. uint32 dropped_attributes_count = 5; - // Flags, a bit field. Bits 0-7 (8 least significant bits) are the trace - // flags as defined in W3C Trace Context specification. To read the 8-bit W3C trace - // flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. + // Flags, a bit field. + // + // Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace + // Context specification. To read the 8-bit W3C trace flag, use + // `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // From de25dbc13c4c3ff4d16a4ea6f0953c8092c7d7c0 Mon Sep 17 00:00:00 2001 From: Emily S Date: Tue, 17 Oct 2023 22:15:53 +0200 Subject: [PATCH 110/127] Update opentelemetry/proto/trace/v1/trace.proto Co-authored-by: Johannes Tax --- opentelemetry/proto/trace/v1/trace.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index cf0c0883f..275c3b9e9 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -358,8 +358,8 @@ enum SpanFlags { // Once the bits have been read using SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK, // the following constants can be used to interpret them. enum SpanFlagsContextIsRemote { - // Older clients may not set this field, so 00 represents that this value - // has not been set. + // Older client not supporting this flag, or not known whether parent or + // linked span is remote: 00 SPAN_FLAGS_CONTEXT_IS_REMOTE_UNKNOWN = 0; // The parent or linked span is remote: 11 SPAN_FLAGS_CONTEXT_IS_REMOTE = 0x00000300; From dab891821951f737af1374e72d9222c9dc2d79b8 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 28 Nov 2023 14:21:49 -0500 Subject: [PATCH 111/127] Remove enum, describe values in comment --- opentelemetry/proto/trace/v1/trace.proto | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 275c3b9e9..b3750da2c 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -344,25 +344,9 @@ enum SpanFlags { SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; // Bits 8 and 9 are used to indicate that the parent span or link span is remote. - // See SpanFlagsContextIsRemote for the valid values. + // Bit 8 indicates whether the value is known. Bit 9 indicates whether the span + // or link is remote. SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 0x00000300; // Bits 10-31 are reserved for future use. } - -// SpanFlagsContextIsRemote represents constants used to interpret -// bits 8 and 9 of the Spans.flags or Link.flags field. These two bits -// represent whether the parent or link is remote. Bit 8 represents whether -// the field has been set and bit 9 represents whether the parent or link is -// remote. -// Once the bits have been read using SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK, -// the following constants can be used to interpret them. -enum SpanFlagsContextIsRemote { - // Older client not supporting this flag, or not known whether parent or - // linked span is remote: 00 - SPAN_FLAGS_CONTEXT_IS_REMOTE_UNKNOWN = 0; - // The parent or linked span is remote: 11 - SPAN_FLAGS_CONTEXT_IS_REMOTE = 0x00000300; - // The parent or linked span is not remote: 01 - SPAN_FLAGS_CONTEXT_IS_NOT_REMOTE = 0x00000100; -} From fbf680b2f8f209a9a2e4c2e9e5fd1747395b7aea Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Thu, 11 Jan 2024 14:42:23 +0100 Subject: [PATCH 112/127] Split isremote into two masks --- opentelemetry/proto/trace/v1/trace.proto | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index b3750da2c..c2c1a0217 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -344,9 +344,10 @@ enum SpanFlags { SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; // Bits 8 and 9 are used to indicate that the parent span or link span is remote. - // Bit 8 indicates whether the value is known. Bit 9 indicates whether the span - // or link is remote. - SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 0x00000300; + // Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. + // Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote. + SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK = 0x00000100; + SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 0x00000200; // Bits 10-31 are reserved for future use. } From 924eb3f60f74584631162d1420ae3dae762e627f Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Thu, 11 Jan 2024 14:47:00 +0100 Subject: [PATCH 113/127] Update references to isremote masks --- opentelemetry/proto/trace/v1/trace.proto | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index c2c1a0217..104e2f597 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -119,7 +119,8 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether a span's parent // is remote. The states are (unknown, is not remote, is remote). - // To read the 2-bit flag, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. + // To read whether the value is known, use `flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK`. + // To read whether the span is remote, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. // // When creating span messages, if the message is logically forwarded from another source // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD @@ -275,7 +276,8 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether the link is remote. The states // are unknown, is not remote, is remote. - // To read the 2-bit flag, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. + // To read whether the value is known, use `flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK`. + // To read whether the link is remote, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. // // Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. // When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. From de4ad66ebfa81221340bf2f490519a2e6d85dc73 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Thu, 11 Jan 2024 14:48:36 +0100 Subject: [PATCH 114/127] Update inconsistency in docs formatting --- opentelemetry/proto/trace/v1/trace.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 104e2f597..2fa5b9fbd 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -274,8 +274,8 @@ message Span { // // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. // - // Bits 8 and 9 represent the 3 states of whether the link is remote. The states - // are unknown, is not remote, is remote. + // Bits 8 and 9 represent the 3 states of whether the link is remote. + // The states are (unknown, is not remote, is remote). // To read whether the value is known, use `flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK`. // To read whether the link is remote, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. // From 715ffe2290c88f683700c6df9e2f4a7a9fa3e220 Mon Sep 17 00:00:00 2001 From: Emily Stolfo Date: Tue, 23 Jan 2024 15:51:21 +0100 Subject: [PATCH 115/127] Add Changelog entry --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab793a015..f5d257a8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,10 @@ Full list of differences found in [this compare](https://github.com/open-telemet ### Added -* Add `flags` field to `Span` and `Span/Link` for W3C-specified Trace Context flags . +* Add `flags` field to `Span` and `Span/Link` for W3C-specified Trace Context flags. [#503](https://github.com/open-telemetry/opentelemetry-proto/pull/503) +* Indicate if a `Span`'s parent or link is remote using 2 bit flag. + [#484](https://github.com/open-telemetry/opentelemetry-proto/pull/484) ### Changed From abaa16c73e6bc7b5fb20e80f58e3467db1211ea0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 30 Jan 2024 08:27:48 -0600 Subject: [PATCH 116/127] Clarify formulas for reading span flags (#528) * Add bitshift to comment for reading span flags * Change >> to != 0 --- opentelemetry/proto/trace/v1/trace.proto | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opentelemetry/proto/trace/v1/trace.proto b/opentelemetry/proto/trace/v1/trace.proto index 2fa5b9fbd..5cb2f3ce1 100644 --- a/opentelemetry/proto/trace/v1/trace.proto +++ b/opentelemetry/proto/trace/v1/trace.proto @@ -119,8 +119,8 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether a span's parent // is remote. The states are (unknown, is not remote, is remote). - // To read whether the value is known, use `flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK`. - // To read whether the span is remote, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. + // To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. + // To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. // // When creating span messages, if the message is logically forwarded from another source // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD @@ -276,8 +276,8 @@ message Span { // // Bits 8 and 9 represent the 3 states of whether the link is remote. // The states are (unknown, is not remote, is remote). - // To read whether the value is known, use `flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK`. - // To read whether the link is remote, use `flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK`. + // To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. + // To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. // // Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. // When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. From a45b1c4aecd5bf1e7afaa1b59b892cd6a2c86d3b Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 2 Feb 2024 11:03:39 -0500 Subject: [PATCH 117/127] Add metric.metadata for supporting additional metadata on metrics (#514) * add metric.attributes for supporting additional metadata on metrics --- CHANGELOG.md | 7 +++++++ opentelemetry/proto/metrics/v1/metrics.proto | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5d257a8d..11091d6aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.1.0...main). +### Added + +* Add metric.metadata for supporting additional metadata on metrics + [#514](https://github.com/open-telemetry/opentelemetry-proto/pull/514) + +### Changed + ## 1.1.0 - 2024-01-10 Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.0.0...v1.1.0). diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index 41605c888..8912632a5 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -208,6 +208,15 @@ message Metric { ExponentialHistogram exponential_histogram = 10; Summary summary = 11; } + + // Additional metadata attributes that describe the metric. [Optional]. + // Attributes are non-identifying. + // Consumers SHOULD NOT need to be aware of these attributes. + // These attributes MAY be used to encode information allowing + // for lossless roundtrip translation to / from another data model. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue metadata = 12; } // Gauge represents the type of a scalar metric that always exports the From e690cb67644388f7fd6dfdd664a8718b73d98cb6 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 9 Feb 2024 12:27:20 -0500 Subject: [PATCH 118/127] [editorial] Fix path base in Hugo front matter (#530) --- docs/specification.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/specification.md b/docs/specification.md index d017eada4..efa2c3654 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -9,12 +9,8 @@ spelling: cascade: body_class: otel-docs-spec github_repo: &repo https://github.com/open-telemetry/opentelemetry-proto - github_subdir: docs - path_base_for_github_subdir: content/en/docs/specs/otlp/ + path_base_for_github_subdir: tmp/otlp github_project_repo: *repo -path_base_for_github_subdir: - from: content/en/docs/specs/otlp/_index.md - to: specification.md ---> # OpenTelemetry Protocol Specification From 20fda659b10f4713101764541b8abe73485b9e3d Mon Sep 17 00:00:00 2001 From: Armin Ruech <7052238+arminru@users.noreply.github.com> Date: Wed, 3 Apr 2024 00:01:48 +0200 Subject: [PATCH 119/127] Unset executable flag on Makefile (#541) Fixes #540. --- Makefile | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Makefile diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 From 13669b98ff1c21b01dee61212c06791892625978 Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Fri, 5 Apr 2024 22:26:48 +0200 Subject: [PATCH 120/127] Prepare Release 1.2.0 (#537) --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11091d6aa..5e824b6d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ Full list of differences found in [this compare](https://github.com/open-telemet ### Added +### Changed + +## 1.2.0 - 2024-03-29 + +### Added + +* Indicate if a `Span`'s parent or link is remote using 2 bit flag. + [#484](https://github.com/open-telemetry/opentelemetry-proto/pull/484) * Add metric.metadata for supporting additional metadata on metrics [#514](https://github.com/open-telemetry/opentelemetry-proto/pull/514) @@ -19,8 +27,6 @@ Full list of differences found in [this compare](https://github.com/open-telemet * Add `flags` field to `Span` and `Span/Link` for W3C-specified Trace Context flags. [#503](https://github.com/open-telemetry/opentelemetry-proto/pull/503) -* Indicate if a `Span`'s parent or link is remote using 2 bit flag. - [#484](https://github.com/open-telemetry/opentelemetry-proto/pull/484) ### Changed From d9268a18aee09b6a7cab94c707680798f34b4737 Mon Sep 17 00:00:00 2001 From: Steve Rao Date: Tue, 9 Apr 2024 21:22:13 +0800 Subject: [PATCH 121/127] Polish document content in README.md (#542) * Fix wrong spelling in README.md Fix wrong spelling in README.md * Polish document content --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b5afdef7b..f77c03f71 100644 --- a/README.md +++ b/README.md @@ -60,16 +60,16 @@ for definition of maturity levels). Components marked `Stable` provide the following guarantees: - Field types, numbers and names will not change. -- Service names and service package names will not change. +- Service names and `service` package names will not change. - Service method names will not change. [from 1.0.0] - Service method parameter names will not change. [from 1.0.0] - Service method parameter types and return types will not change. [from 1.0.0] - Service method kind (unary vs streaming) will not change. -- Names of messages and enums will not change. [from 1.0.0] -- Numbers assigned to enum choices will not change. -- Names of enum choices will not change. [from 1.0.0] -- The location of messages and enums, i.e. whether they are declared at the top lexical - scope or nested inside another message will not change. [from 1.0.0] +- Names of `message`s and `enum`s will not change. [from 1.0.0] +- Numbers assigned to `enum` choices will not change. +- Names of `enum` choices will not change. [from 1.0.0] +- The location of `message`s and `enum`s, i.e. whether they are declared at the top lexical + scope or nested inside another `message` will not change. [from 1.0.0] - Package names and directory structure will not change. [from 1.0.0] - `optional` and `repeated` declarators of existing fields will not change. [from 1.0.0] - No existing symbol will be deleted. [from 1.0.0] @@ -79,12 +79,12 @@ with version number 1.0.0. The following additive changes are allowed: -- Adding new fields to existing messages. -- Adding new messages or enums. -- Adding new choices to existing enums. -- Adding new choices to existing oneof fields. -- Adding new services. -- Adding new methods to existing services. +- Adding new fields to existing `message`s. +- Adding new `message`s or `enum`s. +- Adding new choices to existing `enum`s. +- Adding new choices to existing `oneof` fields. +- Adding new `service`s. +- Adding new `method`s to existing `service`s. All the additive changes above must be accompanied by an explanation about how new and old senders and receivers that implement the version of the protocol From 8ff98d3eda8036e4d1c8553a09d37e6b771ab6b7 Mon Sep 17 00:00:00 2001 From: Dmitry Filimonov Date: Tue, 23 Apr 2024 08:39:24 -0700 Subject: [PATCH 122/127] Add new profile signal (#534) This is a follow up to [OTEP 239: Introduces Profiling Data Model v2](https://github.com/open-telemetry/oteps/pull/239) The main motivation behind this PR is that this will allow us to start experimenting with the profiles proto in opentelemetry-collector. I marked the profiles part as `Experimental` to indicate that this is not a final version of the data model. I copied the proto from the OTEP, and moved `pprofextended.proto` from `profiles/v1/alternatives/pprofextended.proto` to just `profiles/v1/pprofextended.proto`. I did this because I figured we no longer have alternative representations and this will reduce confusion for people outside of Profiling SIG. The rest of the proto stayed the same. I tested this file with a collector fork and I it compiles properly. --- README.md | 1 + .../v1experimental/profiles_service.proto | 78 ++++ .../v1experimental/profiles_service_http.yaml | 9 + .../v1experimental/pprofextended.proto | 386 ++++++++++++++++++ .../profiles/v1experimental/profiles.proto | 191 +++++++++ 5 files changed, 665 insertions(+) create mode 100644 opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto create mode 100644 opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml create mode 100644 opentelemetry/proto/profiles/v1experimental/pprofextended.proto create mode 100644 opentelemetry/proto/profiles/v1experimental/profiles.proto diff --git a/README.md b/README.md index f77c03f71..bc26f1db7 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ components as indicated by the Maturity table below. | metrics/\*
collector/metrics/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | | trace/\*
collector/trace/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | | logs/\*
collector/logs/* | Stable | [Stable](docs/specification.md#json-protobuf-encoding) | +| profiles/\*
collector/profiles/* | Experimental | [Experimental](docs/specification.md#json-protobuf-encoding) | (See [maturity-matrix.yaml](https://github.com/open-telemetry/community/blob/47813530864b9fe5a5146f466a58bd2bb94edc72/maturity-matrix.yaml#L57) for definition of maturity levels). diff --git a/opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto b/opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto new file mode 100644 index 000000000..d0e7894b2 --- /dev/null +++ b/opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto @@ -0,0 +1,78 @@ +// Copyright 2023, 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. + +syntax = "proto3"; + +package opentelemetry.proto.collector.profiles.v1experimental; + +import "opentelemetry/proto/profiles/v1experimental/profiles.proto"; + +option csharp_namespace = "OpenTelemetry.Proto.Collector.Profiles.V1Experimental"; +option java_multiple_files = true; +option java_package = "io.opentelemetry.proto.collector.profiles.v1experimental"; +option java_outer_classname = "ProfilesServiceProto"; +option go_package = "go.opentelemetry.io/proto/otlp/collector/profiles/v1experimental"; + +// Service that can be used to push profiles between one Application instrumented with +// OpenTelemetry and a collector, or between a collector and a central collector. +service ProfilesService { + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + rpc Export(ExportProfilesServiceRequest) returns (ExportProfilesServiceResponse) {} +} + +message ExportProfilesServiceRequest { + // An array of ResourceProfiles. + // For data coming from a single resource this array will typically contain one + // element. Intermediary nodes (such as OpenTelemetry Collector) that receive + // data from multiple origins typically batch the data before forwarding further and + // in that case this array will contain multiple elements. + repeated opentelemetry.proto.profiles.v1experimental.ResourceProfiles resource_profiles = 1; +} + +message ExportProfilesServiceResponse { + // The details of a partially successful export request. + // + // If the request is only partially accepted + // (i.e. when the server accepts only parts of the data and rejects the rest) + // the server MUST initialize the `partial_success` field and MUST + // set the `rejected_` with the number of items it rejected. + // + // Servers MAY also make use of the `partial_success` field to convey + // warnings/suggestions to senders even when the request was fully accepted. + // In such cases, the `rejected_` MUST have a value of `0` and + // the `error_message` MUST be non-empty. + // + // A `partial_success` message with an empty value (rejected_ = 0 and + // `error_message` = "") is equivalent to it not being set/present. Senders + // SHOULD interpret it the same way as in the full success case. + ExportProfilesPartialSuccess partial_success = 1; +} + +message ExportProfilesPartialSuccess { + // The number of rejected profiles. + // + // A `rejected_` field holding a `0` value indicates that the + // request was fully accepted. + int64 rejected_profiles = 1; + + // A developer-facing human-readable message in English. It should be used + // either to explain why the server rejected parts of the data during a partial + // success or to convey warnings/suggestions during a full success. The message + // should offer guidance on how users can address such issues. + // + // error_message is an optional field. An error_message with an empty value + // is equivalent to it not being set. + string error_message = 2; +} diff --git a/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml b/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml new file mode 100644 index 000000000..6bb7cf740 --- /dev/null +++ b/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml @@ -0,0 +1,9 @@ +# This is an API configuration to generate an HTTP/JSON -> gRPC gateway for the +# OpenTelemetry service using github.com/grpc-ecosystem/grpc-gateway. +type: google.api.Service +config_version: 3 +http: + rules: + - selector: opentelemetry.proto.collector.profiles.v1.ProfilesService.Export + post: /v1experimental/profiles + body: "*" diff --git a/opentelemetry/proto/profiles/v1experimental/pprofextended.proto b/opentelemetry/proto/profiles/v1experimental/pprofextended.proto new file mode 100644 index 000000000..bd3008355 --- /dev/null +++ b/opentelemetry/proto/profiles/v1experimental/pprofextended.proto @@ -0,0 +1,386 @@ +// Copyright 2023, 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. +// +// This file includes work covered by the following copyright and permission notices: +// +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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. + +// Profile is a common stacktrace profile format. +// +// Measurements represented with this format should follow the +// following conventions: +// +// - Consumers should treat unset optional fields as if they had been +// set with their default value. +// +// - When possible, measurements should be stored in "unsampled" form +// that is most useful to humans. There should be enough +// information present to determine the original sampled values. +// +// - On-disk, the serialized proto must be gzip-compressed. +// +// - The profile is represented as a set of samples, where each sample +// references a sequence of locations, and where each location belongs +// to a mapping. +// - There is a N->1 relationship from sample.location_id entries to +// locations. For every sample.location_id entry there must be a +// unique Location with that index. +// - There is an optional N->1 relationship from locations to +// mappings. For every nonzero Location.mapping_id there must be a +// unique Mapping with that index. + +syntax = "proto3"; + +package opentelemetry.proto.profiles.v1experimental; + +import "opentelemetry/proto/common/v1/common.proto"; + +option csharp_namespace = "OpenTelemetry.Proto.Profiles.V1Experimental"; +option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1experimental"; + +// Represents a complete profile, including sample types, samples, +// mappings to binaries, locations, functions, string table, and additional metadata. +message Profile { + // A description of the samples associated with each Sample.value. + // For a cpu profile this might be: + // [["cpu","nanoseconds"]] or [["wall","seconds"]] or [["syscall","count"]] + // For a heap profile, this might be: + // [["allocations","count"], ["space","bytes"]], + // If one of the values represents the number of events represented + // by the sample, by convention it should be at index 0 and use + // sample_type.unit == "count". + repeated ValueType sample_type = 1; + // The set of samples recorded in this profile. + repeated Sample sample = 2; + // Mapping from address ranges to the image/binary/library mapped + // into that address range. mapping[0] will be the main binary. + repeated Mapping mapping = 3; + // Locations referenced by samples via location_indices. + repeated Location location = 4; + // Array of locations referenced by samples. + repeated int64 location_indices = 15; + // Functions referenced by locations. + repeated Function function = 5; + // Lookup table for attributes. + repeated opentelemetry.proto.common.v1.KeyValue attribute_table = 16; + // Represents a mapping between Attribute Keys and Units. + repeated AttributeUnit attribute_units = 17; + // Lookup table for links. + repeated Link link_table = 18; + // A common table for strings referenced by various messages. + // string_table[0] must always be "". + repeated string string_table = 6; + // frames with Function.function_name fully matching the following + // regexp will be dropped from the samples, along with their successors. + int64 drop_frames = 7; // Index into string table. + // frames with Function.function_name fully matching the following + // regexp will be kept, even if it matches drop_frames. + int64 keep_frames = 8; // Index into string table. + + // The following fields are informational, do not affect + // interpretation of results. + + // Time of collection (UTC) represented as nanoseconds past the epoch. + int64 time_nanos = 9; + // Duration of the profile, if a duration makes sense. + int64 duration_nanos = 10; + // The kind of events between sampled occurrences. + // e.g [ "cpu","cycles" ] or [ "heap","bytes" ] + ValueType period_type = 11; + // The number of events between sampled occurrences. + int64 period = 12; + // Free-form text associated with the profile. The text is displayed as is + // to the user by the tools that read profiles (e.g. by pprof). This field + // should not be used to store any machine-readable information, it is only + // for human-friendly content. The profile must stay functional if this field + // is cleaned. + repeated int64 comment = 13; // Indices into string table. + // Index into the string table of the type of the preferred sample + // value. If unset, clients should default to the last sample value. + int64 default_sample_type = 14; +} + +// Represents a mapping between Attribute Keys and Units. +message AttributeUnit { + // Index into string table. + int64 attribute_key = 1; + // Index into string table. + int64 unit = 2; +} + +// A pointer from a profile Sample to a trace Span. +// Connects a profile sample to a trace span, identified by unique trace and span IDs. +message Link { + // A unique identifier of a trace that this linked span is part of. The ID is a + // 16-byte array. + bytes trace_id = 1; + + // A unique identifier for the linked span. The ID is an 8-byte array. + bytes span_id = 2; +} + +// Specifies the method of aggregating metric values, either DELTA (change since last report) +// or CUMULATIVE (total since a fixed start time). +enum AggregationTemporality { + /* UNSPECIFIED is the default AggregationTemporality, it MUST not be used. */ + AGGREGATION_TEMPORALITY_UNSPECIFIED = 0; + + /** DELTA is an AggregationTemporality for a profiler which reports + changes since last report time. Successive metrics contain aggregation of + values from continuous and non-overlapping intervals. + + The values for a DELTA metric are based only on the time interval + associated with one measurement cycle. There is no dependency on + previous measurements like is the case for CUMULATIVE metrics. + + For example, consider a system measuring the number of requests that + it receives and reports the sum of these requests every second as a + DELTA metric: + + 1. The system starts receiving at time=t_0. + 2. A request is received, the system measures 1 request. + 3. A request is received, the system measures 1 request. + 4. A request is received, the system measures 1 request. + 5. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+1 with a value of 3. + 6. A request is received, the system measures 1 request. + 7. A request is received, the system measures 1 request. + 8. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0+1 to + t_0+2 with a value of 2. */ + AGGREGATION_TEMPORALITY_DELTA = 1; + + /** CUMULATIVE is an AggregationTemporality for a profiler which + reports changes since a fixed start time. This means that current values + of a CUMULATIVE metric depend on all previous measurements since the + start time. Because of this, the sender is required to retain this state + in some form. If this state is lost or invalidated, the CUMULATIVE metric + values MUST be reset and a new fixed start time following the last + reported measurement time sent MUST be used. + + For example, consider a system measuring the number of requests that + it receives and reports the sum of these requests every second as a + CUMULATIVE metric: + + 1. The system starts receiving at time=t_0. + 2. A request is received, the system measures 1 request. + 3. A request is received, the system measures 1 request. + 4. A request is received, the system measures 1 request. + 5. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+1 with a value of 3. + 6. A request is received, the system measures 1 request. + 7. A request is received, the system measures 1 request. + 8. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+2 with a value of 5. + 9. The system experiences a fault and loses state. + 10. The system recovers and resumes receiving at time=t_1. + 11. A request is received, the system measures 1 request. + 12. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_1 to + t_0+1 with a value of 1. + + Note: Even though, when reporting changes since last report time, using + CUMULATIVE is valid, it is not recommended. */ + AGGREGATION_TEMPORALITY_CUMULATIVE = 2; +} + +// ValueType describes the type and units of a value, with an optional aggregation temporality. +message ValueType { + int64 type = 1; // Index into string table. + int64 unit = 2; // Index into string table. + + AggregationTemporality aggregation_temporality = 3; +} + +// Each Sample records values encountered in some program +// context. The program context is typically a stack trace, perhaps +// augmented with auxiliary information like the thread-id, some +// indicator of a higher level request being handled etc. +message Sample { + // The indices recorded here correspond to locations in Profile.location. + // The leaf is at location_index[0]. [deprecated, superseded by locations_start_index / locations_length] + repeated uint64 location_index = 1; + // locations_start_index along with locations_length refers to to a slice of locations in Profile.location. + // Supersedes location_index. + uint64 locations_start_index = 7; + // locations_length along with locations_start_index refers to a slice of locations in Profile.location. + // Supersedes location_index. + uint64 locations_length = 8; + // A 128bit id that uniquely identifies this stacktrace, globally. Index into string table. [optional] + uint32 stacktrace_id_index = 9; + // The type and unit of each value is defined by the corresponding + // entry in Profile.sample_type. All samples must have the same + // number of values, the same as the length of Profile.sample_type. + // When aggregating multiple samples into a single sample, the + // result has a list of values that is the element-wise sum of the + // lists of the originals. + repeated int64 value = 2; + // label includes additional context for this sample. It can include + // things like a thread id, allocation size, etc. + // + // NOTE: While possible, having multiple values for the same label key is + // strongly discouraged and should never be used. Most tools (e.g. pprof) do + // not have good (or any) support for multi-value labels. And an even more + // discouraged case is having a string label and a numeric label of the same + // name on a sample. Again, possible to express, but should not be used. + // [deprecated, superseded by attributes] + repeated Label label = 3; + // References to attributes in Profile.attribute_table. [optional] + repeated uint64 attributes = 10; + + // Reference to link in Profile.link_table. [optional] + uint64 link = 12; + + // Timestamps associated with Sample represented in nanoseconds. These timestamps are expected + // to fall within the Profile's time range. [optional] + repeated uint64 timestamps_unix_nano = 13; +} + +// Provides additional context for a sample, +// such as thread ID or allocation size, with optional units. [deprecated] +message Label { + int64 key = 1; // Index into string table + + // At most one of the following must be present + int64 str = 2; // Index into string table + int64 num = 3; + + // Should only be present when num is present. + // Specifies the units of num. + // Use arbitrary string (for example, "requests") as a custom count unit. + // If no unit is specified, consumer may apply heuristic to deduce the unit. + // Consumers may also interpret units like "bytes" and "kilobytes" as memory + // units and units like "seconds" and "nanoseconds" as time units, + // and apply appropriate unit conversions to these. + int64 num_unit = 4; // Index into string table +} + +// Indicates the semantics of the build_id field. +enum BuildIdKind { + // Linker-generated build ID, stored in the ELF binary notes. + BUILD_ID_LINKER = 0; + // Build ID based on the content hash of the binary. Currently no particular + // hashing approach is standardized, so a given producer needs to define it + // themselves and thus unlike BUILD_ID_LINKER this kind of hash is producer-specific. + // We may choose to provide a standardized stable hash recommendation later. + BUILD_ID_BINARY_HASH = 1; +} + +// Describes the mapping of a binary in memory, including its address range, +// file offset, and metadata like build ID +message Mapping { + // Unique nonzero id for the mapping. [deprecated] + uint64 id = 1; + // Address at which the binary (or DLL) is loaded into memory. + uint64 memory_start = 2; + // The limit of the address range occupied by this mapping. + uint64 memory_limit = 3; + // Offset in the binary that corresponds to the first mapped address. + uint64 file_offset = 4; + // The object this entry is loaded from. This can be a filename on + // disk for the main binary and shared libraries, or virtual + // abstractions like "[vdso]". + int64 filename = 5; // Index into string table + // A string that uniquely identifies a particular program version + // with high probability. E.g., for binaries generated by GNU tools, + // it could be the contents of the .note.gnu.build-id field. + int64 build_id = 6; // Index into string table + // Specifies the kind of build id. See BuildIdKind enum for more details [optional] + BuildIdKind build_id_kind = 11; + // References to attributes in Profile.attribute_table. [optional] + repeated uint64 attributes = 12; + // The following fields indicate the resolution of symbolic info. + bool has_functions = 7; + bool has_filenames = 8; + bool has_line_numbers = 9; + bool has_inline_frames = 10; +} + +// Describes function and line table debug information. +message Location { + // Unique nonzero id for the location. A profile could use + // instruction addresses or any integer sequence as ids. [deprecated] + uint64 id = 1; + // The index of the corresponding profile.Mapping for this location. + // It can be unset if the mapping is unknown or not applicable for + // this profile type. + uint64 mapping_index = 2; + // The instruction address for this location, if available. It + // should be within [Mapping.memory_start...Mapping.memory_limit] + // for the corresponding mapping. A non-leaf address may be in the + // middle of a call instruction. It is up to display tools to find + // the beginning of the instruction if necessary. + uint64 address = 3; + // Multiple line indicates this location has inlined functions, + // where the last entry represents the caller into which the + // preceding entries were inlined. + // + // E.g., if memcpy() is inlined into printf: + // line[0].function_name == "memcpy" + // line[1].function_name == "printf" + repeated Line line = 4; + // Provides an indication that multiple symbols map to this location's + // address, for example due to identical code folding by the linker. In that + // case the line information above represents one of the multiple + // symbols. This field must be recomputed when the symbolization state of the + // profile changes. + bool is_folded = 5; + + // Type of frame (e.g. kernel, native, python, hotspot, php). Index into string table. + uint32 type_index = 6; + + // References to attributes in Profile.attribute_table. [optional] + repeated uint64 attributes = 7; +} + +// Details a specific line in a source code, linked to a function. +message Line { + // The index of the corresponding profile.Function for this line. + uint64 function_index = 1; + // Line number in source code. + int64 line = 2; + // Column number in source code. + int64 column = 3; +} + +// Describes a function, including its human-readable name, system name, +// source file, and starting line number in the source. +message Function { + // Unique nonzero id for the function. [deprecated] + uint64 id = 1; + // Name of the function, in human-readable form if available. + int64 name = 2; // Index into string table + // Name of the function, as identified by the system. + // For instance, it can be a C++ mangled name. + int64 system_name = 3; // Index into string table + // Source file containing the function. + int64 filename = 4; // Index into string table + // Line number in source file. + int64 start_line = 5; +} diff --git a/opentelemetry/proto/profiles/v1experimental/profiles.proto b/opentelemetry/proto/profiles/v1experimental/profiles.proto new file mode 100644 index 000000000..bbc2b2931 --- /dev/null +++ b/opentelemetry/proto/profiles/v1experimental/profiles.proto @@ -0,0 +1,191 @@ +// Copyright 2023, 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. + +syntax = "proto3"; + +package opentelemetry.proto.profiles.v1experimental; + +import "opentelemetry/proto/common/v1/common.proto"; +import "opentelemetry/proto/resource/v1/resource.proto"; +import "opentelemetry/proto/profiles/v1experimental/pprofextended.proto"; + +option csharp_namespace = "OpenTelemetry.Proto.Profiles.V1Experimental"; +option java_multiple_files = true; +option java_package = "io.opentelemetry.proto.profiles.v1experimental"; +option java_outer_classname = "ProfilesProto"; +option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1experimental"; + +// Relationships Diagram +// +// ┌──────────────────┐ LEGEND +// │ ProfilesData │ +// └──────────────────┘ ─────▶ embedded +// │ +// │ 1-n ─────▷ referenced by index +// ▼ +// ┌──────────────────┐ +// │ ResourceProfiles │ +// └──────────────────┘ +// │ +// │ 1-n +// ▼ +// ┌──────────────────┐ +// │ ScopeProfiles │ +// └──────────────────┘ +// │ +// │ 1-n +// ▼ +// ┌──────────────────┐ +// │ ProfileContainer │ +// └──────────────────┘ +// │ +// │ 1-1 +// ▼ +// ┌──────────────────┐ +// │ Profile │ +// └──────────────────┘ +// │ 1-n +// │ 1-n ┌───────────────────────────────────────┐ +// ▼ │ ▽ +// ┌──────────────────┐ 1-n ┌──────────────┐ ┌──────────┐ +// │ Sample │ ──────▷ │ KeyValue │ │ Link │ +// └──────────────────┘ └──────────────┘ └──────────┘ +// │ 1-n △ △ +// │ 1-n ┌─────────────────┘ │ 1-n +// ▽ │ │ +// ┌──────────────────┐ n-1 ┌──────────────┐ +// │ Location │ ──────▷ │ Mapping │ +// └──────────────────┘ └──────────────┘ +// │ +// │ 1-n +// ▼ +// ┌──────────────────┐ +// │ Line │ +// └──────────────────┘ +// │ +// │ 1-1 +// ▽ +// ┌──────────────────┐ +// │ Function │ +// └──────────────────┘ +// + +// ProfilesData represents the profiles data that can be stored in persistent storage, +// OR can be embedded by other protocols that transfer OTLP profiles data but do not +// implement the OTLP protocol. +// +// The main difference between this message and collector protocol is that +// in this message there will not be any "control" or "metadata" specific to +// OTLP protocol. +// +// When new fields are added into this message, the OTLP request MUST be updated +// as well. +message ProfilesData { + // An array of ResourceProfiles. + // For data coming from a single resource this array will typically contain + // one element. Intermediary nodes that receive data from multiple origins + // typically batch the data before forwarding further and in that case this + // array will contain multiple elements. + repeated ResourceProfiles resource_profiles = 1; +} + + +// A collection of ScopeProfiles from a Resource. +message ResourceProfiles { + reserved 1000; + + // The resource for the profiles in this message. + // If this field is not set then no resource info is known. + opentelemetry.proto.resource.v1.Resource resource = 1; + + // A list of ScopeProfiles that originate from a resource. + repeated ScopeProfiles scope_profiles = 2; + + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + // This schema_url applies to the data in the "resource" field. It does not apply + // to the data in the "scope_profiles" field which have their own schema_url field. + string schema_url = 3; +} + +// A collection of ProfileContainers produced by an InstrumentationScope. +message ScopeProfiles { + // The instrumentation scope information for the profiles in this message. + // Semantically when InstrumentationScope isn't set, it is equivalent with + // an empty instrumentation scope name (unknown). + opentelemetry.proto.common.v1.InstrumentationScope scope = 1; + + // A list of ProfileContainers that originate from an instrumentation scope. + repeated ProfileContainer profiles = 2; + + // The Schema URL, if known. This is the identifier of the Schema that the metric data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + // This schema_url applies to all profiles in the "profiles" field. + string schema_url = 3; +} + +// A ProfileContainer represents a single profile. It wraps pprof profile with OpenTelemetry specific metadata. +message ProfileContainer { + // A globally unique identifier for a profile. The ID is a 16-byte array. An ID with + // all zeroes is considered invalid. + // + // This field is required. + bytes profile_id = 1; + + // start_time_unix_nano is the start time of the profile. + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + // + // This field is semantically required and it is expected that end_time >= start_time. + fixed64 start_time_unix_nano = 2; + + // end_time_unix_nano is the end time of the profile. + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + // + // This field is semantically required and it is expected that end_time >= start_time. + fixed64 end_time_unix_nano = 3; + + // attributes is a collection of key/value pairs. Note, global attributes + // like server name can be set using the resource API. Examples of attributes: + // + // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" + // "/http/server_latency": 300 + // "abc.com/myattribute": true + // "abc.com/score": 10.239 + // + // The OpenTelemetry API specification further restricts the allowed value types: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue attributes = 4; + + // dropped_attributes_count is the number of attributes that were discarded. Attributes + // can be discarded because their keys are too long or because there are too many + // attributes. If this value is 0, then no attributes were dropped. + uint32 dropped_attributes_count = 5; + + // Specifies format of the original payload. Common values are defined in semantic conventions. [required if original_payload is present] + string original_payload_format = 6; + + // Original payload can be stored in this field. This can be useful for users who want to get the original payload. + // Formats such as JFR are highly extensible and can contain more information than what is defined in this spec. + // Inclusion of original payload should be configurable by the user. Default behavior should be to not include the original payload. + // If the original payload is in pprof format, it SHOULD not be included in this field. + // The field is optional, however if it is present `profile` MUST be present and contain the same profiling information. + bytes original_payload = 7; + + // This is a reference to a pprof profile. Required, even when original_payload is present. + opentelemetry.proto.profiles.v1experimental.Profile profile = 8; +} From 95775bf43b1262d4048f6492607729eadb0043b5 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:38:28 -0400 Subject: [PATCH 123/127] Prepare v1.3.0 release (#549) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e824b6d4..7af14f176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ Full list of differences found in [this compare](https://github.com/open-telemet ### Changed +## 1.3.0 - 2024-04-24 + +### Added + +* Add new profile signal. + [#534](https://github.com/open-telemetry/opentelemetry-proto/pull/534) + ## 1.2.0 - 2024-03-29 ### Added From 63c94a1bbe1f894a74a92e974762a17c52a69a86 Mon Sep 17 00:00:00 2001 From: Florian Lehner Date: Thu, 25 Apr 2024 16:26:05 +0200 Subject: [PATCH 124/127] profiles: fix versioning in selector (#551) --- .../profiles/v1experimental/profiles_service_http.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml b/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml index 6bb7cf740..ea501afbb 100644 --- a/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml +++ b/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml @@ -4,6 +4,6 @@ type: google.api.Service config_version: 3 http: rules: - - selector: opentelemetry.proto.collector.profiles.v1.ProfilesService.Export + - selector: opentelemetry.proto.collector.profiles.v1experimental.ProfilesService.Export post: /v1experimental/profiles body: "*" From ce5f949cfa16e14ffd954c2390899a439a147698 Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Thu, 25 Apr 2024 17:55:35 +0200 Subject: [PATCH 125/127] generate profiles proto for CI (#552) --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index f1d608c87..504e02254 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ gen-cpp: $(PROTOC) --cpp_out=./$(PROTO_GEN_CPP_DIR) --grpc-cpp_out=./$(PROTO_GEN_CPP_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --cpp_out=./$(PROTO_GEN_CPP_DIR) --grpc-cpp_out=./$(PROTO_GEN_CPP_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --cpp_out=./$(PROTO_GEN_CPP_DIR) --grpc-cpp_out=./$(PROTO_GEN_CPP_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --cpp_out=./$(PROTO_GEN_CPP_DIR) --grpc-cpp_out=./$(PROTO_GEN_CPP_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for C#. .PHONY: gen-csharp @@ -67,6 +68,7 @@ gen-csharp: $(PROTOC) --csharp_out=./$(PROTO_GEN_CSHARP_DIR) --grpc-csharp_out=./$(PROTO_GEN_CSHARP_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --csharp_out=./$(PROTO_GEN_CSHARP_DIR) --grpc-csharp_out=./$(PROTO_GEN_CSHARP_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --csharp_out=./$(PROTO_GEN_CSHARP_DIR) --grpc-csharp_out=./$(PROTO_GEN_CSHARP_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --csharp_out=./$(PROTO_GEN_CSHARP_DIR) --grpc-csharp_out=./$(PROTO_GEN_CSHARP_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for Go. .PHONY: gen-go @@ -77,6 +79,7 @@ gen-go: $(PROTOC) --grpc-gateway_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/trace/v1/trace_service_http.yaml:./$(PROTO_GEN_GO_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --grpc-gateway_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/metrics/v1/metrics_service_http.yaml:./$(PROTO_GEN_GO_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --grpc-gateway_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/logs/v1/logs_service_http.yaml:./$(PROTO_GEN_GO_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --grpc-gateway_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml:./$(PROTO_GEN_GO_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for Java. .PHONY: gen-java @@ -102,6 +105,7 @@ gen-js: $(PROTOC) --js_out=import_style=commonjs:./$(PROTO_GEN_JS_DIR) --grpc-web_out=import_style=commonjs,mode=grpcweb:./$(PROTO_GEN_JS_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --js_out=import_style=commonjs:./$(PROTO_GEN_JS_DIR) --grpc-web_out=import_style=commonjs,mode=grpcweb:./$(PROTO_GEN_JS_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --js_out=import_style=commonjs:./$(PROTO_GEN_JS_DIR) --grpc-web_out=import_style=commonjs,mode=grpcweb:./$(PROTO_GEN_JS_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --js_out=import_style=commonjs:./$(PROTO_GEN_JS_DIR) --grpc-web_out=import_style=commonjs,mode=grpcweb:./$(PROTO_GEN_JS_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for Objective-C. .PHONY: gen-objc @@ -112,6 +116,7 @@ gen-objc: $(PROTOC) --objc_out=./$(PROTO_GEN_OBJC_DIR) --grpc-objc_out=./$(PROTO_GEN_OBJC_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --objc_out=./$(PROTO_GEN_OBJC_DIR) --grpc-objc_out=./$(PROTO_GEN_OBJC_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --objc_out=./$(PROTO_GEN_OBJC_DIR) --grpc-objc_out=./$(PROTO_GEN_OBJC_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --objc_out=./$(PROTO_GEN_OBJC_DIR) --grpc-objc_out=./$(PROTO_GEN_OBJC_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf for openapi v2 (swagger) .PHONY: gen-openapi @@ -120,6 +125,7 @@ gen-openapi: $(PROTOC) --openapiv2_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/trace/v1/trace_service_http.yaml:$(PROTO_GEN_OPENAPI_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --openapiv2_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/metrics/v1/metrics_service_http.yaml:$(PROTO_GEN_OPENAPI_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --openapiv2_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/logs/v1/logs_service_http.yaml:$(PROTO_GEN_OPENAPI_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --openapiv2_out=logtostderr=true,grpc_api_configuration=opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml:$(PROTO_GEN_OPENAPI_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for PhP. .PHONY: gen-php @@ -130,6 +136,7 @@ gen-php: $(PROTOC) --php_out=./$(PROTO_GEN_PHP_DIR) --grpc-php_out=./$(PROTO_GEN_PHP_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --php_out=./$(PROTO_GEN_PHP_DIR) --grpc-php_out=./$(PROTO_GEN_PHP_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --php_out=./$(PROTO_GEN_PHP_DIR) --grpc-php_out=./$(PROTO_GEN_PHP_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --php_out=./$(PROTO_GEN_PHP_DIR) --grpc-php_out=./$(PROTO_GEN_PHP_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for Python. .PHONY: gen-python @@ -140,6 +147,7 @@ gen-python: $(PROTOC) --python_out=./$(PROTO_GEN_PYTHON_DIR) --grpc-python_out=./$(PROTO_GEN_PYTHON_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --python_out=./$(PROTO_GEN_PYTHON_DIR) --grpc-python_out=./$(PROTO_GEN_PYTHON_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --python_out=./$(PROTO_GEN_PYTHON_DIR) --grpc-python_out=./$(PROTO_GEN_PYTHON_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --python_out=./$(PROTO_GEN_PYTHON_DIR) --grpc-python_out=./$(PROTO_GEN_PYTHON_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto # Generate gRPC/Protobuf implementation for Ruby. .PHONY: gen-ruby @@ -150,6 +158,7 @@ gen-ruby: $(PROTOC) --ruby_out=./$(PROTO_GEN_RUBY_DIR) --grpc-ruby_out=./$(PROTO_GEN_RUBY_DIR) opentelemetry/proto/collector/trace/v1/trace_service.proto $(PROTOC) --ruby_out=./$(PROTO_GEN_RUBY_DIR) --grpc-ruby_out=./$(PROTO_GEN_RUBY_DIR) opentelemetry/proto/collector/metrics/v1/metrics_service.proto $(PROTOC) --ruby_out=./$(PROTO_GEN_RUBY_DIR) --grpc-ruby_out=./$(PROTO_GEN_RUBY_DIR) opentelemetry/proto/collector/logs/v1/logs_service.proto + $(PROTOC) --ruby_out=./$(PROTO_GEN_RUBY_DIR) --grpc-ruby_out=./$(PROTO_GEN_RUBY_DIR) opentelemetry/proto/collector/profiles/v1experimental/profiles_service.proto .PHONY: breaking-change breaking-change: From 2b0227c99d774b836a67f9fa1a9530d1b55fc19d Mon Sep 17 00:00:00 2001 From: Mike Goldsmth Date: Wed, 24 May 2023 14:15:53 +0100 Subject: [PATCH 126/127] Revert "Remove deprecated messages and fields from metrics (#342)" This reverts commit 8ba33cceb4a6704af68a4022d17868a7ac1d94f4. --- opentelemetry/proto/metrics/v1/metrics.proto | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/opentelemetry/proto/metrics/v1/metrics.proto b/opentelemetry/proto/metrics/v1/metrics.proto index 8912632a5..1e068998e 100644 --- a/opentelemetry/proto/metrics/v1/metrics.proto +++ b/opentelemetry/proto/metrics/v1/metrics.proto @@ -166,9 +166,7 @@ message ScopeMetrics { // when the start time is truly unknown, setting StartTimeUnixNano is // strongly encouraged. message Metric { - reserved 4, 6, 8; - - // name of the metric. + // name of the metric, including its DNS name prefix. It must be unique. string name = 1; // description of the metric, which can be used in documentation. From d161664415fafe61d618ca883444893a27333c40 Mon Sep 17 00:00:00 2001 From: Mike Goldsmth Date: Tue, 30 May 2023 11:09:13 +0100 Subject: [PATCH 127/127] Update README with details on forked repo