From a107e697c81b5787e434f8bc2a0ada7309330bf7 Mon Sep 17 00:00:00 2001 From: Giovanni Liva Date: Thu, 27 Aug 2020 22:18:51 +0200 Subject: [PATCH] YAML Model for Semantic Conventions (#571) * First model draft * Fix checkstyle * Generate network table from YAML * HTTP semantic convention tables * Fix requirements order * Add code and basic documentation * Missing \n * Remove tool * Add General and HTTP semantic convention * Update table style * yaml->semantic_conventions * Fix small errors * Fix docfx errors * Update Makefile to use otel Docker repo Co-authored-by: Armin Ruech --- .../workflows/semantic-conventions-check.yaml | 18 ++ Makefile | 6 + semantic_conventions/syntax.md | 228 ++++++++++++++++++ semantic_conventions/trace/general.yaml | 97 ++++++++ semantic_conventions/trace/http.yaml | 147 +++++++++++ semantic_conventions/version.properties | 1 + .../trace/semantic_conventions/http.md | 83 ++++--- .../semantic_conventions/span-general.md | 73 +++--- 8 files changed, 584 insertions(+), 69 deletions(-) create mode 100644 .github/workflows/semantic-conventions-check.yaml create mode 100644 semantic_conventions/syntax.md create mode 100644 semantic_conventions/trace/general.yaml create mode 100644 semantic_conventions/trace/http.yaml create mode 100644 semantic_conventions/version.properties diff --git a/.github/workflows/semantic-conventions-check.yaml b/.github/workflows/semantic-conventions-check.yaml new file mode 100644 index 00000000000..769b3884f35 --- /dev/null +++ b/.github/workflows/semantic-conventions-check.yaml @@ -0,0 +1,18 @@ +name: Semantic Conventions Check +on: + push: + tags: [ '**' ] + branches: [ master ] + pull_request: + branches: [ master ] + paths: + - .github/workflows/semantic-convention-check.yml + - '**/semantic_conventions/**' + +jobs: + test-markdown: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Verify that semantic convention tables are up-to-date + run: docker run --rm -v $(pwd)/semantic_conventions:/source -v $(pwd)/specification:/spec otel/semconvgen -f /source markdown -md /spec --md-check \ No newline at end of file diff --git a/Makefile b/Makefile index ccfcfac1096..fca4bac1d3a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,13 @@ # All documents to be used in spell check. ALL_DOCS := $(shell find . -name '*.md' -not -path './.github/*' -type f | grep -v ^./node_modules | sort) +PWD := $(shell pwd) TOOLS_DIR := ./.tools MISSPELL_BINARY=$(TOOLS_DIR)/misspell MARKDOWN_LINK_CHECK=markdown-link-check MARKDOWN_LINT=markdownlint + .PHONY: install-misspell install-misspell: go build -o $(MISSPELL_BINARY) github.com/client9/misspell/cmd/misspell @@ -34,3 +36,7 @@ install-markdown-lint: markdown-lint: @echo $(ALL_DOCS) @for f in $(ALL_DOCS); do echo $$f; $(MARKDOWN_LINT) -c .markdownlint.yaml $$f || exit 1; done + +.PHONY: table-generation +table-generation: + docker run --rm -v $(PWD)/semantic_conventions:/source -v $(PWD)/specification:/spec otel/semconvgen -f /source markdown -md /spec diff --git a/semantic_conventions/syntax.md b/semantic_conventions/syntax.md new file mode 100644 index 00000000000..33926286d64 --- /dev/null +++ b/semantic_conventions/syntax.md @@ -0,0 +1,228 @@ +# Semantic Convention YAML Language + +First, the syntax with a pseudo [EBNF](https://en.wikipedia.org/wiki/Extended_Backus-Naur_form) grammar is presented. +Then, the semantic of each field is described. + +## Syntax + +All attributes are lower case. + +```bnf +groups ::= semconv + | semconv groups + +semconv ::= id brief [note] [prefix] [extends] [span_kind] attributes [constraints] + +id ::= string +brief ::= string +note ::= string + +prefix ::= string + +# extends MUST point to an existing semconv id +extends ::= string + +span_kind ::= "client" + | "server" + | "producer" + | "consumer" + | "internal" + +attributes ::= (id type brief examples | ref [brief] [examples]) [required] [note] + +# ref MUST point to an existing attribute id +ref ::= id + +type ::= "string" + | "number" + | "boolean" + | "string[]" + | "number[]" + | "boolean[]" + | enum + +enum ::= [allow_custom_values] members + +allow_custom_values := boolean + +members ::= member {member} + +member ::= id value [brief] [note] + +required ::= "always" + | "conditional" + +examples ::= {} + +constraints ::= constraint {constraint} + +constraint ::= any_of + | include + +any_of ::= id {id} + +include ::= id + +``` + +## Semantics + +### Groups + +Groups contain the list of semantic conventions and it is the root node of each yaml file. + +### Semantic Convention + +The field `semconv` represents a semantic convention and it is made by: + +- `id`, string that uniquely identifies the semantic convention. +- `brief`, string, a brief description of the semantic convention. +- `note`, optional string, a more elaborate description of the semantic convention. + It defaults to an empty string. +- `prefix`, optional string, prefix for the attributes for this semantic convention. + It defaults to an empty string. +- `extends`, optional string, reference another semantic convention `id`. + It inherits the prefix, constraints, and all attributes defined in the specified semantic convention. +- `span_kind`, optional enum, specifies the kind of the span. +- `attributes`, list of attributes that belong to the semantic convention. +- `constraints`, optional list, additional constraints (See later). It defaults to an empty list. + +### Attributes + +An attribute is defined by: + +- `id`, string that uniquely identifies the attribute. +- `type`, either a string literal denoting the type or an enum definition (See later). + The accepted strings literals are: + * "string": String attributes. + * "number": Numeric attributes. + * "boolean": Boolean attributes. + * "string[]": Array of strings attributes. + * "number[]": Array of numbers attributes. + * "boolean[]": Array of booleans attributes. +- `ref`, optional string, reference an existing attribute, see later. +- `required`, optional, specifies if the attribute is mandatory. + Can be "always", or "conditional". When omitted, the attribute is not required. + When set to "conditional",the string provided as `` MUST specify + the conditions under which the attribute is required. +- `brief`, string, brief description of the attribute. +- `note`, optional string, additional notes to the attribute. It defaults to an empty string. +- `examples`, sequence/dictionary of example values for the attribute. + They are optional for boolean and enum attributes. + Example values must be of the same type of the attribute. + If only a single example is provided, it can directly be reported without encapsulating it into a sequence/dictionary. + +Examples for setting the `examples` field: + +A single example value for a string attribute. All the following three representations are equivalent: + +```yaml +examples: 'this is a single string' +``` + +or + +```yaml +examples: ['this is a single string'] +``` + +or + +```yaml +examples: + - 'this is a single string' +``` + +Attention, the following will throw a type mismatch error because a string type as example value is expected and not an array of string: + +```yaml +examples: + - ['this is an error'] + +examples: [['this is an error']] +``` + +Multiple example values for a string attribute: + +```yaml +examples: ['this is a single string', 'this is another one'] +``` + +or + +```yaml +examples: + - 'this is a single string' + - 'this is another one' +``` + +A single example value for an array of strings attribute: + +```yaml +examples: ['first element of first array', 'second element of first array'] +``` + +or + +```yaml +examples: + - ['first element of first array', 'second element of first array'] +``` + +Attention, the following will throw a type mismatch error because an array of strings as type for the example values is expected and not a string: + +```yaml +examples: 'this is an error' +``` + +Multiple example values for an array of string attribute: + +```yaml +examples: [ ['first element of first array', 'second element of first array'], ['first element of second array', 'second element of second array'] ] +``` + +or + +```yaml +examples: + - ['first element of first array', 'second element of first array'] + - ['first element of second array', 'second element of second array'] +``` + +### Ref + +`ref` MUST have an id of an existing attribute. When it is set, `id` and `type` MUST not be present. +`ref` is useful for specifying that an existing attribute of another semantic convention is part of +the current semantic convention and inherit its `brief`, `note`, and `example` values. However, if these +fields are present in the current attribute definition, they override the inherited values. + +### Type + +An attribute type can either be a string, number, boolean, array of strings, array of numbers, +array of booleans, or an enumeration. If it is an enumeration, additional fields are required: + +- `allow_custom_values`, optional boolean, set to false to not accept values + other than the specified members. It defaults to `true`. +- `members`, list of enum entries. + +An enum entry has the following fields: + +- `id`, string that uniquely identifies the enum entry. +- `value`, string, number, or boolean, value of the enum entry. +- `brief`, optional string, brief description of the enum entry value. It defaults to the value of `id`. +- `note`, optional string, longer description. It defaults to an empty string. + +### Constraints + +Allow to define additional requirements on the semantic convention. +Currently, it supports `any_of` and `include`. + +#### Any Of + +`any_of` accepts a list of sequences. Each sequence contains a list of attribute ids that are required. +`any_of` enforces that all attributes of at least one of the sequences are set. + +#### Include + +`include` accepts a semantic conventions `id`. It includes as part of this semantic convention all constraints +and required attributes that are not already defined in the current semantic convention. diff --git a/semantic_conventions/trace/general.yaml b/semantic_conventions/trace/general.yaml new file mode 100644 index 00000000000..27c0c38c7f8 --- /dev/null +++ b/semantic_conventions/trace/general.yaml @@ -0,0 +1,97 @@ +groups: + - id: network + prefix: net + brief: > + These attributes may be used for any network related operation. + attributes: + - id: transport + type: + allow_custom_values: false + members: + - id: IP.TCP + value: "IP.TCP" + - id: IP.UDP + value: "IP.UDP" + - id: IP + value: "IP" + brief: 'Another IP-based protocol' + - id: Unix + value: "Unix" + brief: 'Unix Domain socket. See below.' + - id: pipe + value: "pipe" + brief: 'Named or anonymous pipe. See note below.' + - id: inproc + value: "inproc" + brief: 'In-process communication.' + note: > + Signals that there is only in-process communication not using a "real" network protocol + in cases where network attributes would normally be expected. Usually all other network + attributes can be left out in that case. + - id: other + value: "other" + brief: 'Something else (non IP-based).' + brief: > + Transport protocol used. See note below. + examples: 'IP.TCP' + - id: peer.ip + type: string + brief: > + Remote address of the peer (dotted decimal for IPv4 or + [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) + examples: '127.0.0.1' + - id: peer.port + type: number + brief: 'Remote port number.' + examples: [80, 8080, 443] + - id: peer.name + type: string + brief: 'Remote hostname or similar, see note below.' + examples: 'example.com' + - id: host.ip + type: string + brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.' + examples: '192.168.0.1' + - id: host.port + type: number + brief: 'Like `net.peer.port` but for the host port.' + examples: 35555 + - id: host.name + type: string + brief: 'Local hostname or similar, see note below.' + examples: 'localhost' + - id: peer + prefix: peer + brief: "Operations that access some remote service." + attributes: + - id: service + type: string + brief: > + The [`service.name`](../../resource/semantic_conventions/README.md#service) + of the remote service. SHOULD be equal to the actual `service.name` + resource attribute of the remote service if any. + examples: "AuthTokenCache" + - id: identity + prefix: enduser + brief: > + These attributes may be used for any operation with an authenticated and/or authorized enduser. + attributes: + - id: id + type: string + brief: > + Username or client_id extracted from the access token or + [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) + header in the inbound request from outside the system. + examples: 'username' + - id: role + type: string + brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' + examples: 'admin' + - id: scope + type: string + brief: > + Scopes or granted authorities the client currently possesses extracted from token + or application security context. The value would come from the scope associated + with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) + or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). + examples: 'read:message, write:files' \ No newline at end of file diff --git a/semantic_conventions/trace/http.yaml b/semantic_conventions/trace/http.yaml new file mode 100644 index 00000000000..bb68d9f5024 --- /dev/null +++ b/semantic_conventions/trace/http.yaml @@ -0,0 +1,147 @@ +groups: + - id: http + prefix: http + brief: 'This document defines semantic conventions for HTTP client and server Spans.' + note: > + These conventions can be used for http and https schemes + and various HTTP versions like 1.1, 2 and SPDY. + attributes: + - id: method + type: string + required: always + brief: 'HTTP request method.' + examples: ["GET", "POST", "HEAD"] + - id: url + type: string + brief: > + Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. + Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. + examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] + - id: target + type: string + brief: 'The full request target as passed in a HTTP request line or equivalent.' + examples: ['/path/12314/?q=ddds#123'] + - id: host + type: string + brief: > + The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). + When the header is empty or not present, this attribute should be the same. + examples: ['www.example.org'] + - id: scheme + type: string + brief: 'The URI scheme identifying the used protocol.' + examples: ["http", "https"] + - id: status_code + type: number + required: + conditional: If and only if one was received/sent. + brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' + examples: [200] + - id: status_text + type: string + brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).' + examples: ['OK'] + - id: flavor + type: + # Default value: `true`. If false, it helps the code gen tool to + # encode checks that only accept the listed values. + allow_custom_values: true + members: + - id: HTTP_1_0 + value: '1.0' + brief: 'HTTP 1.0' + - id: HTTP_1_1 + value: '1.1' + brief: 'HTTP 1.1' + - id: HTTP_2_0 + value: '2.0' + brief: 'HTTP 2' + - id: SPDY + value: 'SPDY' + brief: 'SPDY protocol.' + - id: QUIC + value: 'QUIC' + brief: 'QUIC protocol.' + brief: 'Kind of HTTP protocol used' + note: > + If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` + is `QUIC`, in which case `IP.UDP` is assumed. + examples: ['1.0'] + - id: user_agent + type: string + brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.' + examples: ['CERN-LineMode/2.15 libwww/2.17b3'] + - id: request_content_length + type: number + brief: > + The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and + is often, but not always, present as the [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) + header. For requests using transport encoding, this should be the compressed size. + examples: 3495 + - id: request_content_length_uncompressed + type: number + brief: > + The size of the uncompressed request payload body after transport decoding. Not set if transport encoding not used. + examples: 5493 + - id: response_content_length + type: number + brief: > + The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and + is often, but not always, present as the [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) + header. For requests using transport encoding, this should be the compressed size. + examples: 3495 + - id: response_content_length_uncompressed + type: number + brief: > + The size of the uncompressed response payload body after transport decoding. Not set if transport encoding not used. + examples: 5493 + constraints: + - include: network + + - id: http.client + prefix: http + extends: http + span_kind: client + brief: 'Semantic Convention for HTTP Client' + constraints: + - any_of: + - [http.url] + - [http.scheme, http.host, http.target] + - [http.scheme, net.peer.name, net.peer.port, http.target] + - [http.scheme, net.peer.ip, net.peer.port, http.target] + + - id: http.server + prefix: http + extends: http + span_kind: server + brief: 'Semantic Convention for HTTP Server' + attributes: + - id: server_name + type: string + brief: > + 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). + note: > + `http.url` is usually not readily available on the server side but would have to be assembled in a cumbersome and + sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). + It is thus preferred to supply the raw data that is available. + examples: ['example.com'] + - id: route + type: string + brief: > + The matched route (path template). + examples: '/users/:userID?' + - id: client_ip + type: string + brief: > + The IP address of the original client behind all proxies, if + known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). + note: > + This is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. + examples: '83.164.160.102' + constraints: + - any_of: + - [http.scheme, http.host, http.target] + - [http.scheme, http.server_name, net.host.port, http.target] + - [http.scheme, net.host.name, net.host.port, http.target] + - [http.url] \ No newline at end of file diff --git a/semantic_conventions/version.properties b/semantic_conventions/version.properties new file mode 100644 index 00000000000..03770cf2807 --- /dev/null +++ b/semantic_conventions/version.properties @@ -0,0 +1 @@ +version=1 diff --git a/specification/trace/semantic_conventions/http.md b/specification/trace/semantic_conventions/http.md index d7e806804c2..9c0cd04a55f 100644 --- a/specification/trace/semantic_conventions/http.md +++ b/specification/trace/semantic_conventions/http.md @@ -70,29 +70,39 @@ Note that the items marked with [1] are different from the mapping defined in th ## Common Attributes -| Attribute name | Notes and examples | Required? | -| :------------- | :----------------------------------------------------------- | --------- | -| `http.method` | HTTP request method. E.g. `"GET"`. | Yes | -| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. | -| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. | -| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. | -| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. | -| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | 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 | -| `http.request_content_length` | The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length][] header. For requests using transport encoding, this should be the compressed size. | No | -| `http.request_content_length_uncompressed` | The size of the uncompressed request payload body after transport decoding. Not set if transport encoding not used. | No | -| `http.response_content_length` | The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length][] header. For requests using transport encoding, this should be the compressed size. | No | -| `http.response_content_length_uncompressed` | The size of the uncompressed response payload body after transport decoding. Not set if transport encoding not used. | No | + +| Attribute | Type | Description | Example | Required | +|---|---|---|---|---| +| `http.method` | string | HTTP request method. | `GET`
`POST`
`HEAD` | Yes | +| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | No | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | No | +| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | No | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`
`https` | No | +| `http.status_code` | number | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditional
If and only if one was received/sent. | +| `http.status_text` | string | [HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | No | +| `http.flavor` | string | Kind of HTTP protocol used [1] | `1.0` | No | +| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | No | +| `http.request_content_length` | number | The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) header. For requests using transport encoding, this should be the compressed size. | `3495` | No | +| `http.request_content_length_uncompressed` | number | The size of the uncompressed request payload body after transport decoding. Not set if transport encoding not used. | `5493` | No | +| `http.response_content_length` | number | The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) header. For requests using transport encoding, this should be the compressed size. | `3495` | No | +| `http.response_content_length_uncompressed` | number | The size of the uncompressed response payload body after transport decoding. Not set if transport encoding not used. | `5493` | No | + +**[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. + +`http.flavor` MUST be one of the following or, if none of the listed values apply, a custom value: + +| Value | Description | +|---|---| +| `1.0` | HTTP 1.0 | +| `1.1` | HTTP 1.1 | +| `2.0` | HTTP 2 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. [network attributes]: span-general.md#general-network-connection-attributes -[HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 -[HTTP reason phrase]: https://tools.ietf.org/html/rfc7230#section-3.1.2 -[User-Agent]: https://tools.ietf.org/html/rfc7231#section-5.5.3 -[Content-Length]: https://tools.ietf.org/html/rfc7230#section-3.3.2 ## HTTP client @@ -103,12 +113,15 @@ For an HTTP client span, `SpanKind` MUST be `Client`. If set, `http.url` must be the originally requested URL, before any HTTP-redirects that may happen when executing the request. -One of the following sets of attributes is required (in order of usual preference unless for a particular web client/framework it is known that some other set is preferable for some reason; all strings must be non-empty): + + +**Additional attribute requirements:** At least one of the following sets of attributes is required: * `http.url` * `http.scheme`, `http.host`, `http.target` -* `http.scheme`, `net.peer.name`, `net.peer.port`, `http.target` -* `http.scheme`, `net.peer.ip`, `net.peer.port`, `http.target` +* `http.scheme`, [`net.peer.name`](span-general.md), [`net.peer.port`](span-general.md), `http.target` +* `http.scheme`, [`net.peer.ip`](span-general.md), [`net.peer.port`](span-general.md), `http.target` + Note that in some cases `http.host` might be different from the `net.peer.name` @@ -188,24 +201,24 @@ If the route does not include the application root, it SHOULD be prepended to th If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. -| Attribute name | Notes and examples | Required? | -| :------------- | :----------------------------------------------------------- | --------- | -| `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 | + +| Attribute | Type | Description | Example | Required | +|---|---|---|---|---| +| `http.server_name` | string | 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] | `example.com` | See below | +| `http.route` | string | The matched route (path template). | `/users/:userID?` | No | +| `http.client_ip` | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [2] | `83.164.160.102` | No | + +**[1]:** `http.url` is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus preferred to supply the raw data that is available. -[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 +**[2]:** This is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. -**[1]**: `http.url` is usually not readily available on the server side but would have to be assembled in a cumbersome and sometimes lossy process from other information (see e.g. ). -It is thus preferred to supply the raw data that *is* available. -Namely, one of the following sets is required (in order of usual preference unless for a particular web server/framework it is known that some other set is preferable for some reason; all strings must be non-empty): +**Additional attribute requirements:** At least one of the following sets of attributes is required: * `http.scheme`, `http.host`, `http.target` -* `http.scheme`, `http.server_name`, `net.host.port`, `http.target` -* `http.scheme`, `net.host.name`, `net.host.port`, `http.target` +* `http.scheme`, `http.server_name`, [`net.host.port`](span-general.md), `http.target` +* `http.scheme`, [`net.host.name`](span-general.md), [`net.host.port`](span-general.md), `http.target` * `http.url` + Of course, more than the required attributes can be supplied, but this is recommended only if they cannot be inferred from the sent ones. For example, `http.server_name` has shown great value in practice, as bogus HTTP Host headers occur often in the wild. diff --git a/specification/trace/semantic_conventions/span-general.md b/specification/trace/semantic_conventions/span-general.md index dcb76bc06e5..877e52e3342 100644 --- a/specification/trace/semantic_conventions/span-general.md +++ b/specification/trace/semantic_conventions/span-general.md @@ -26,32 +26,33 @@ while the `net.host.*` properties describe the local end. In an ideal situation, not accounting for proxies, multiple IP addresses or host names, the `net.peer.*` properties of a client are equal to the `net.host.*` properties of the server and vice versa. -| Attribute name | Notes and examples | -| :--------------- | :-------------------------------------------------------------------------------- | -| `net.transport` | Transport protocol used. See [note below](#net.transport). | -| `net.peer.ip` | Remote address of the peer (dotted decimal for IPv4 or [RFC5952][] for IPv6) | -| `net.peer.port` | Remote port number as an integer. E.g., `80`. | -| `net.peer.name` | Remote hostname or similar, see [note below](#net.name). | -| `net.host.ip` | Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. | -| `net.host.port` | Like `net.peer.port` but for the host port. | -| `net.host.name` | Local hostname or similar, see [note below](#net.name). | - -[RFC5952]: https://tools.ietf.org/html/rfc5952 - - - -### `net.transport` attribute - -This attribute should be set to the name of the transport layer protocol (or the relevant protocol below the "application protocol"). One of these strings should be used: - -* `IP.TCP` -* `IP.UDP` -* `IP`: Another IP-based protocol. -* `Unix`: Unix Domain socket. See note below. -* `pipe`: Named or anonymous pipe. See note below. -* `inproc`: Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. -* `other`: Something else (not IP-based). - + + +| Attribute | Type | Description | Example | Required | +|---|---|---|---|---| +| `net.transport` | string enum | Transport protocol used. See note below. | `IP.TCP` | No | +| `net.peer.ip` | string | Remote address of the peer (dotted decimal for IPv4 or [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6) | `127.0.0.1` | No | +| `net.peer.port` | number | Remote port number. | `80`
`8080`
`443` | No | +| `net.peer.name` | string | Remote hostname or similar, see note below. | `example.com` | No | +| `net.host.ip` | string | Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. | `192.168.0.1` | No | +| `net.host.port` | number | Like `net.peer.port` but for the host port. | `35555` | No | +| `net.host.name` | string | Local hostname or similar, see note below. | `localhost` | No | + +`net.transport` MUST be one of the following: + +| Value | Description | +|---|---| +| `IP.TCP` | IP.TCP | +| `IP.UDP` | IP.UDP | +| `IP` | Another IP-based protocol | +| `Unix` | Unix Domain socket. See below. | +| `pipe` | Named or anonymous pipe. See note below. | +| `inproc` | In-process communication. [1] | +| `other` | Something else (non IP-based). | + +**[1]:** Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. + + For `Unix` and `pipe`, since the connection goes over the file system instead of being directly to a known peer, `net.peer.name` is the only attribute that usually makes sense (see description of `net.peer.name` below).
@@ -77,9 +78,11 @@ This attribute may be used for any operation that accesses some remote service. Users can define what the name of a service is based on their particular semantics in their distributed system. Instrumentations SHOULD provide a way for users to configure this name. -| Attribute name | Notes and examples | -| :-------------- | :-------------------------------------------------------------------------------- | -| `peer.service` | The [`service.name`](../../resource/semantic_conventions/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | + +| Attribute | Type | Description | Example | Required | +|---|---|---|---|---| +| `peer.service` | string | The [`service.name`](../../resource/semantic_conventions/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | No | + Examples of `peer.service` that users may specify: @@ -90,11 +93,13 @@ Examples of `peer.service` that users may specify: 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]. | + +| Attribute | Type | Description | Example | Required | +|---|---|---|---|---| +| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | No | +| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | No | +| `enduser.scope` | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | No | + 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