Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add http request duration to SDK metrics #2007

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .chloggen/requests-duration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Use this changelog template to create an entry for release notes.
#
# If your change doesn't affect end users you should instead start
# your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: 'enhancement'

# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db)
component: 'otel'

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Adds SDK self-monitoring metrics for exporter request duration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
note: Adds SDK self-monitoring metrics for exporter request duration
note: Adds SDK self-monitoring metrics for exporter call duration


# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
# The values here must be integers.
issues: [1906]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
101 changes: 101 additions & 0 deletions docs/otel/sdk-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ This document describes metrics emitted by the OpenTelemetry SDK components them
- [Metric: `otel.sdk.processor.span.processed.count`](#metric-otelsdkprocessorspanprocessedcount)
- [Metric: `otel.sdk.exporter.span.inflight.count`](#metric-otelsdkexporterspaninflightcount)
- [Metric: `otel.sdk.exporter.span.exported.count`](#metric-otelsdkexporterspanexportedcount)
- [Request Metrics](#request-metrics)
- [Metric: `otel.sdk.exporter.http.request.duration`](#metric-otelsdkexporterhttprequestduration)

<!-- tocstop -->

Expand Down Expand Up @@ -452,5 +454,104 @@ E.g. for Java the fully qualified classname SHOULD be used in this case.
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

## Request Metrics

### Metric: `otel.sdk.exporter.http.request.duration`

This metric is [recommended][MetricRecommended].

This metric SHOULD be specified with
[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.42.0/specification/metrics/api.md#instrument-advisory-parameters)
of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`.

<!-- semconv metric.otel.sdk.exporter.http.request.duration -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->
<!-- markdownlint-capture -->
<!-- markdownlint-disable -->

| Name | Instrument Type | Unit (UCUM) | Description | Stability |
| -------- | --------------- | ----------- | -------------- | --------- |
| `otel.sdk.exporter.http.request.duration` | Histogram | `s` | The duration of any http request(s) made from the exporter during export. [1] | ![Development](https://img.shields.io/badge/-development-blue) |

**[1]:** This metric defines successful requests using the full success definitions for [http](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1).
Anything else is defined as an unsuccessful request. For successful requests, `error.type` MUST NOT be set. For unsuccessful requests, `error.type` must contain a relevant failure cause.

| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `rejected`; `timeout`; `500`; `java.net.UnknownHostException` | `Conditionally Required` If request has ended with an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`otel.component.name`](/docs/attributes-registry/otel.md) | string | A name uniquely identifying the instance of the OpenTelemetry component within its containing SDK instance. [2] | `otlp_grpc_span_exporter/0`; `custom-name` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| [`otel.component.type`](/docs/attributes-registry/otel.md) | string | A name identifying the type of the OpenTelemetry component. [3] | `batching_span_processor`; `com.example.MySpanExporter` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` when applicable | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Recommended` when applicable | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |

**[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality.

When `error.type` is set to a type (e.g., an exception type), its
canonical class name identifying the type within the artifact SHOULD be used.

Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low.
Telemetry consumers that aggregate data from multiple instrumentation libraries and applications
should be prepared for `error.type` to have high cardinality at query time when no
additional filters are applied.

If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.

If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes),
it's RECOMMENDED to:

- Use a domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not.

**[2] `otel.component.name`:** Implementations SHOULD ensure a low cardinality for this attribute, even across application or SDK restarts.
E.g. implementations MUST NOT use UUIDs as values for this attribute.

Implementations MAY achieve these goals by following a `<otel.component.type>/<instance-counter>` pattern, e.g. `batching_span_processor/0`.
Hereby `otel.component.type` refers to the corresponding attribute value of the component.

The value of `instance-counter` MAY be automatically assigned by the component and uniqueness within the enclosing SDK instance MUST be guaranteed.
For example, `<instance-counter>` MAY be implemented by using a monotonically increasing counter (starting with `0`), which is incremented every time an
instance of the given component type is started.

With this implementation, for example the first Batching Span Processor would have `batching_span_processor/0`
as `otel.component.name`, the second one `batching_span_processor/1` and so on.
These values will therefore be reused in the case of an application restart.

**[3] `otel.component.type`:** If none of the standardized values apply, implementations SHOULD use the language-defined name of the type.
E.g. for Java the fully qualified classname SHOULD be used in this case.

**[4] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.

**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.

---

`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
|---|---|---|
| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |

---

`otel.component.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
|---|---|---|
| `batching_span_processor` | The builtin SDK Batching Span Processor | ![Development](https://img.shields.io/badge/-development-blue) |
| `otlp_grpc_span_exporter` | OTLP span exporter over gRPC with protobuf serialization | ![Development](https://img.shields.io/badge/-development-blue) |
| `otlp_http_json_span_exporter` | OTLP span exporter over HTTP with JSON serialization | ![Development](https://img.shields.io/badge/-development-blue) |
| `otlp_http_span_exporter` | OTLP span exporter over HTTP with protobuf serialization | ![Development](https://img.shields.io/badge/-development-blue) |
| `simple_span_processor` | The builtin SDK Simple Span Processor | ![Development](https://img.shields.io/badge/-development-blue) |

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended
27 changes: 27 additions & 0 deletions model/otel/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,30 @@ groups:
recommended: when applicable
- ref: error.type
examples: ["rejected", "timeout", "500", "java.net.UnknownHostException"]

- id: metric.otel.sdk.exporter.http.request.duration
type: metric
metric_name: otel.sdk.exporter.http.request.duration
stability: development
brief: "The duration of any http request(s) made from the exporter during export."
note: |
This metric defines successful requests using the full success definitions for [http](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1).
Anything else is defined as an unsuccessful request. For successful requests, `error.type` MUST NOT be set. For unsuccessful requests, `error.type` must contain a relevant failure cause.
instrument: histogram
unit: "s"
attributes:
- ref: otel.component.type
- ref: otel.component.name
- ref: server.address
requirement_level:
recommended: when applicable
- ref: server.port
requirement_level:
recommended: when applicable
- ref: error.type
requirement_level:
conditionally_required: If request has ended with an error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
conditionally_required: If request has ended with an error
conditionally_required: If the operation has ended with an error

examples: ["rejected", "timeout", "500", "java.net.UnknownHostException"]
- ref: http.response.status_code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- ref: http.response.status_code
- ref: http.response.status_code
brief: The HTTP status code of the last HTTP request performed in scope of this export call.

requirement_level:
conditionally_required: If and only if one was received/sent.
Loading