Skip to content

Commit

Permalink
Merge branch 'master' into lang-agnostic-1
Browse files Browse the repository at this point in the history
  • Loading branch information
tsloughter authored Jan 31, 2020
2 parents 909e175 + 3bbed37 commit 0ef4cbc
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 73 deletions.
51 changes: 29 additions & 22 deletions specification/api-metrics-user.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ TODO: Add a table of contents.

## Overview

Metric instruments are the entry point for application and framework
developers to instrument their code using counters, gauges, and
measures.
Metric instruments are the entry point for application and framework developers to instrument their code using counters, gauges, and measures.
Metrics are created by calling methods on a `Meter` which is in turn created by a global `MeterFactory`.

### Obtaining a Meter

New `Meter` instances can be created via a `MeterFactory` and its `getMeter` method.
`MeterFactory`s are generally expected to be used as singletons.
Implementations SHOULD provide a single global default `MeterFactory`. The `getMeter` method expects two string arguments:

- `name` (required): This name must identify the instrumentation library (also referred to as integration, e.g. `io.opentelemetry.contrib.mongodb`)
and *not* the instrumented library.
In case an invalid name (null or empty string) is specified, a working default `Meter` implementation as a fallback is returned
rather than returning null or throwing an exception.
A `MeterFactory` could also return a no-op `Meter` here if application owners configure the SDK to suppress telemetry produced by this library.
- `version` (optional): Specifies the version of the instrumentation library (e.g. `semver:1.0.0`).

### Metric names

Expand All @@ -23,23 +35,18 @@ external systems. Metric names conform to the following syntax:
3. The first character must be non-numeric, non-space, non-punctuation
4. Subsequent characters must be belong to the alphanumeric characters, '_', '.', and '-'.

Metrics names belong to a namespace by virtue of a "Named" `Meter`
instance. A "Named" `Meter` refers to the requirement that every
`Meter` instance must have an associated `component` label, determined
statically in the code. The `component` label value of the associated
`Meter` serves as its namespace, allowing the same metric name to be
used in multiple libraries of code, unambiguously, within the same
application.

Metric instruments are defined using a `Meter` instance, using a
variety of `New` methods specific to the kind of metric and type of
input (integer or floating point). The Meter will return an error
when a metric name is already registered with a different kind for the
same component name. Metric systems are expected to automatically
prefix exported metrics by the `component` namespace in a manner
consistent with the target system. For example, a Prometheus exporter
SHOULD use the component followed by `_` as the [application
prefix](https://prometheus.io/docs/practices/naming/#metric-names).
Metric names belong to a namespace. The `name` of the associated `Meter`
serves as its namespace, allowing the same metric name to be used in
multiple libraries of code, unambiguously, within the same application.

Metric instruments are defined using a `Meter` instance, using a variety
of `New` methods specific to the kind of metric and type of input(integer
or floating point). The Meter will return an error when a metric name is
already registered with a different kind for the same name. Metric systems
are expected to automatically prefix exported metrics by the namespace in a
manner consistent with the target system. For example, a Prometheus exporter
SHOULD use the namespace followed by `_` as the
[application prefix](https://prometheus.io/docs/practices/naming/#metric-names).

### Format of a metric event

Expand Down Expand Up @@ -71,7 +78,7 @@ either floating point or integer inputs, see the detailed design below.
Binding instruments to a single `Meter` instance has two benefits:

1. Instruments can be exported from the zero state, prior to first use, with no explicit `Register` call
2. The component name provided by the named `Meter` satisfies a namespace requirement
2. The name provided by the `Meter` satisfies a namespace requirement

The recommended practice is to define structures to contain the
instruments in use and keep references only to the instruments that
Expand All @@ -82,7 +89,7 @@ metric instruments statically and providing the `Meter` interface at
the time of use. In this example, typical of statsd clients, existing
code may not be structured with a convenient place to store new metric
instruments. Where this becomes a burden, it is recommended to use
the global meter factory to construct a static named `Meter`, to
the global meter factory to construct a static `Meter`, to
construct metric instruments.

The situation is similar for users of Prometheus clients, where
Expand Down
48 changes: 42 additions & 6 deletions specification/api-tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Table of Contents
* [SpanContext](#spancontext)
* [Span](#span)
* [Span creation](#span-creation)
* [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context)
* [Add Links](#add-links)
* [Span operations](#span-operations)
* [Get Context](#get-context)
Expand Down Expand Up @@ -177,7 +178,7 @@ sub-operations.

`Span`s encapsulate:

- The operation name
- The span name
- An immutable [`SpanContext`](#spancontext) that uniquely identifies the
`Span`
- A parent span in the form of a [`Span`](#span), [`SpanContext`](#spancontext),
Expand All @@ -189,6 +190,24 @@ sub-operations.
- A list of timestamped [`Event`s](#add-events)
- A [`Status`](#set-status).

The _span name_ is a human-readable string which concisely identifies the work
represented by the Span, for example, an RPC method name, a function name,
or the name of a subtask or stage within a larger computation. The span name
should be the most general string that identifies a (statistically) interesting
_class of Spans_, rather than individual Span instances. That is, "get_user" is
a reasonable name, while "get_user/314159", where "314159" is a user ID, is not
a good name due to its high cardinality.

For example, here are potential span names for an endpoint that gets a
hypothetical account information:

| Span Name | Guidance |
| ----------------- | ------------ |
| `get` | Too general |
| `get_account/42` | Too specific |
| `get_account` | Good, and account_id=42 would make a nice Span attribute |
| `get_account/{accountId}` | Also good (using the "HTTP route") |

The `Span`'s start and end timestamps reflect the elapsed real time of the
operation. A `Span`'s start time SHOULD be set to the current time on [span
creation](#span-creation). After the `Span` is created, it SHOULD be possible to
Expand All @@ -215,10 +234,12 @@ as a separate operation.

The API MUST accept the following parameters:

- The operation name. This is a required parameter.
- The parent Span or parent Span context, and whether the new `Span` should be a
root `Span`. API MAY also have an option for implicit parent context
extraction from the current context as a default behavior.
- The span name. This is a required parameter.
- The parent `Span` or a `Context` containing a parent `Span` or `SpanContext`,
and whether the new `Span` should be a root `Span`. API MAY also have an
option for implicit parenting from the current context as a default behavior.
See [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context)
for guidance on `Span` parenting from explicit and implicit `Context`s.
- [`SpanKind`](#spankind), default to `SpanKind.Internal` if not specified.
- `Attribute`s - A collection of key-value pairs, with the same semantics as
the ones settable with [Span::SetAttributes](#set-attributes). Additionally,
Expand Down Expand Up @@ -249,6 +270,21 @@ created in another process. Each propagators' deserialization must set
`IsRemote` to true on a parent `SpanContext` so `Span` creation knows if the
parent is remote.

#### Determining the Parent Span from a Context

When a new `Span` is created from a `Context`, the `Context` may contain:

- A current `Span`
- An extracted `SpanContext`
- A current `Span` and an extracted `SpanContext`
- Neither a current `Span` nor an extracted `Span` context

The parent should be selected in the following order of precedence:

- Use the current `Span`, if available.
- Use the extracted `SpanContext`, if available.
- There is no parent. Create a root `Span`.

#### Add Links

During the `Span` creation user MUST have the ability to record links to other `Span`s. Linked
Expand Down Expand Up @@ -405,7 +441,7 @@ started with the explicit timestamp from the past at the moment where the final

Required parameters:

- The new **operation name**, which supersedes whatever was passed in when the
- The new **span name**, which supersedes whatever was passed in when the
`Span` was started

#### End
Expand Down
24 changes: 17 additions & 7 deletions specification/data-http.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,19 @@ and various HTTP versions like 1.1, 2 and SPDY.

## Name

Given an [RFC 3986](https://tools.ietf.org/html/rfc3986) compliant URI of the form `scheme:[//host[:port]]path[?query][#fragment]`,
the span name of the span SHOULD be set to the URI path value,
unless another value that represents the identity of the request and has a lower cardinality can be identified
(e.g. the route for server spans; see below).
HTTP spans MUST follow the overall [guidelines for span names](./api-tracing.md#span).
Many REST APIs encode parameters into URI path, e.g. `/api/users/123` where `123`
is a user id, which creates high cardinality value space not suitable for span
names. In case of HTTP servers, these endpoints are often mapped by the server
frameworks to more concise _HTTP routes_, e.g. `/api/users/{user_id}`, which are
recommended as the low cardinality span names. However, the same approach usually
does not work for HTTP client spans, especially when instrumentation is provided
by a lower-level middleware that is not aware of the specifics of how the URIs
are formed. Therefore, HTTP client spans SHOULD be using conservative, low
cardinality names formed from the available parameters of an HTTP request,
such as `"HTTP {METHOD_NAME}"`. Instrumentation MUST NOT default to using URI
path as span name, but MAY provide hooks to allow custom logic to override the
default span name.

## Status

Expand Down Expand Up @@ -70,12 +79,14 @@ Note that the items marked with [1] are different from the mapping defined in th
| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | If and only if one was received/sent. |
| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | No |
| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No |
| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | No |

It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed.

[network attributes]: data-span-general.md#general-network-connection-attributes
[HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
[HTTP reason phrase]: https://tools.ietf.org/html/rfc7230#section-3.1.2
[User-Agent]: https://tools.ietf.org/html/rfc7231#section-5.5.3

## HTTP client

Expand Down Expand Up @@ -176,12 +187,10 @@ If the route cannot be determined, the `name` attribute MUST be set as defined i
| `http.server_name` | The primary server name of the matched virtual host. This should be obtained via configuration. If no such configuration can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). | [1] |
| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | No |
| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | No |
| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | No |

[HTTP request line]: https://tools.ietf.org/html/rfc7230#section-3.1.1
[HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4
[X-Forwarded-For]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
[User-Agent]: https://tools.ietf.org/html/rfc7231#section-5.5.3

**[1]**: `http.url` is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. <https://github.com/open-telemetry/opentelemetry-python/pull/148>).
It is thus preferred to supply the raw data that *is* available.
Expand Down Expand Up @@ -211,7 +220,7 @@ Span name: `/webshop/articles/4` (NOTE: This is subject to change, see [open-tel
| `http.method` | `"GET"` |
| `http.flavor` | `"1.1"` |
| `http.url` | `"https://example.com:8080/webshop/articles/4?s=1"` |
| `peer.ip4` | `"192.0.2.5"` |
| `net.peer.ip` | `"192.0.2.5"` |
| `http.status_code` | `200` |
| `http.status_text` | `"OK"` |

Expand All @@ -234,6 +243,7 @@ Span name: `/webshop/articles/:article_id`.
| `http.status_text` | `"OK"` |
| `http.client_ip` | `"192.0.2.4"` |
| `net.peer.ip` | `"192.0.2.5"` (the client goes through a proxy) |
| `http.user_agent` | `"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"` |

Note that following the recommendations above, `http.url` is not set in the above example.
If set, it would be
Expand Down
3 changes: 3 additions & 0 deletions specification/data-resource-semantic-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ Attributes defining a computing instance (e.g. host).
| host.id | Unique host id.<br/> For Cloud this must be the instance_id assigned by the cloud provider | `opentelemetry-test` |
| host.name | Name of the host.<br/> It may contain what `hostname` returns on Unix systems, the fully qualified, or a name specified by the user. | `opentelemetry-test` |
| host.type | Type of host.<br/> For Cloud this must be the machine type.| `n1-standard-1` |
| host.image.name | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`, `CentOS-8-x86_64-1905` |
| host.image.id | VM image id. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` |
| host.image.version | The version string of the VM image as defined in [Version Attributes](#version-attributes). | `0.1` |

## Environment

Expand Down
9 changes: 7 additions & 2 deletions specification/data-rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ Examples of span name: `grpc.test.EchoService/Echo`.

| Attribute name | Notes and examples | Required? |
| -------------- | ------------------------------------------------------------ | --------- |
| `component` | Declares that this is a grpc component. Value MUST be `"grpc"` | Yes |
| `component` | Declares that this is a grpc component. Value MUST be `"grpc"`. | Yes |
| `rpc.service` | The service name, must be equal to the $service part in the span name. | Yes |
| `net.peer.ip` | See [network attributes][]. | See below |
| `net.peer.name` | See [network attributes][]. | See below |
| `net.peer.port` | See [network attributes][]. | See below |

Additionally, the `net.peer.name` and `net.peer.port` [network attributes][] are required.
At least one of [network attributes][] `net.peer.name` or `net.peer.ip` is required.
For client-side spans `net.peer.port` is required (it describes the server port they are connecting to).
For server-side spans `net.peer.port` is optional (it describes the port the client is connecting from).

[network attributes]: data-span-general.md#general-network-connection-attributes

Expand Down
47 changes: 47 additions & 0 deletions specification/data-span-general.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Particular operations may refer to or require some of these attributes.
<!-- toc -->

- [General network connection attributes](#general-network-connection-attributes)
- [General identity attributes](#general-identity-attributes)

<!-- tocstop -->

Expand Down Expand Up @@ -65,3 +66,49 @@ It will usually not make sense to use reverse-lookup to obtain `net.host.name`,
If `net.transport` is `"unix"` or `"pipe"`, the absolute path to the file representing it should be used as `net.peer.name` (`net.host.name` doesn't make sense in that context).
If there is no such file (e.g., anonymous pipe),
the name should explicitly be set to the empty string to distinguish it from the case where the name is just unknown or not covered by the instrumentation.

## General identity attributes

These attributes may be used for any operation with an authenticated and/or authorized enduser.

| Attribute name | Notes and examples |
| :-------------- | :-------------------------------------------------------------------------------- |
| `enduser.id` | Username or client_id extracted from the access token or [Authorization] header in the inbound request from outside the system. |
| `enduser.role` | Actual/assumed role the client is making the request under extracted from token or application security context. |
| `enduser.scope` | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token] or an attribute value in a [SAML 2.0 Assertion]. |

These attributes describe the authenticated user driving the user agent making requests to the instrumented
system. It is expected this information would be propagated unchanged from node-to-node within the system
using the Correlation Context mechanism. These attributes should not be used to record system-to-system
authentication attributes.

Examples of where the `enduser.id` value is extracted from:

| Authentication protocol | Field or description |
| :---------------------- | :------------------------------ |
| [HTTP Basic/Digest Authentication] | `username` |
| [OAuth 2.0 Bearer Token] | [OAuth 2.0 Client Identifier] value from `client_id` for the [OAuth 2.0 Client Credentials Grant] flow and `subject` or `username` from get token info response for other flows using opaque tokens. |
| [OpenID Connect 1.0 IDToken] | `sub` |
| [SAML 2.0 Assertion] | `urn:oasis:names:tc:SAML:2.0:assertion:Subject` |
| [Kerberos] | `PrincipalName` |

| Framework | Field or description |
| :---------------------- | :------------------------------ |
| [JavaEE/JakartaEE Servlet] | `javax.servlet.http.HttpServletRequest.getUserPrincipal()` |
| [Windows Communication Foundation] | `ServiceSecurityContext.Current.PrimaryIdentity` |

[Authorization]: https://tools.ietf.org/html/rfc7235#section-4.2
[OAuth 2.0 Access Token]: https://tools.ietf.org/html/rfc6749#section-3.3
[SAML 2.0 Assertion]: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html
[HTTP Basic/Digest Authentication]: https://tools.ietf.org/html/rfc2617
[OAuth 2.0 Bearer Token]: https://tools.ietf.org/html/rfc6750
[OAuth 2.0 Client Identifier]: https://tools.ietf.org/html/rfc6749#section-2.2
[OAuth 2.0 Client Credentials Grant]: https://tools.ietf.org/html/rfc6749#section-4.4
[OpenID Connect 1.0 IDToken]: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
[Kerberos]: https://tools.ietf.org/html/rfc4120
[JavaEE/JakartaEE Servlet]: https://jakarta.ee/specifications/platform/8/apidocs/javax/servlet/http/HttpServletRequest.html
[Windows Communication Foundation]: https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.servicesecuritycontext?view=netframework-4.8

Given the sensitive nature of this information, SDKs and exporters SHOULD drop these attributes by
default and then provide a configuration parameter to turn on retention for use cases where the
information is required and would not violate any policies or regulations.
Loading

0 comments on commit 0ef4cbc

Please sign in to comment.