Skip to content

Commit 0c21db4

Browse files
authored
feat(instrumentation-xml-http-request): support migration to stable HTTP semconv, v1.23.1 (#5662)
1 parent 0665c85 commit 0c21db4

File tree

7 files changed

+1312
-625
lines changed

7 files changed

+1312
-625
lines changed

experimental/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2
1212

1313
### :rocket: Features
1414

15+
* feat(instrumentation-xml-http-request): support migration to stable HTTP semconv, v1.23.1 [#5662](https://github.com/open-telemetry/opentelemetry-js/pull/5662) @trentm
16+
* Configure the instrumentation with `semconvStabilityOptIn: 'http'` to use the new, stable semconv v1.23.1 semantics or `'http/dup'` for both old (v1.7.0) and stable semantics. When `semconvStabilityOptIn` is not specified (or does not contain these values), it uses the old semconv v1.7.0. I.e. the default behavior is unchanged.
1517
* feat(instrumentation-fetch): support migration to stable HTTP semconv, v1.23.1 [#5651](https://github.com/open-telemetry/opentelemetry-js/pull/5651) @trentm
1618
* Configure the instrumentation with `semconvStabilityOptIn: 'http'` to use the new, stable semconv v1.23.1 semantics or `'http/dup'` for both old (v1.7.0) and stable semantics. When `semconvStabilityOptIn` is not specified (or does not contain these values), it uses the old semconv v1.7.0. I.e. the default behavior is unchanged.
1719
* feat(instrumentation): New utilities for semconv stability migration for instrumentations that produce 'http' and 'db' telemetry. [#5659](https://github.com/open-telemetry/opentelemetry-js/pull/5659) @trentm
1820
* See [semconv stability usage guide](./packages/opentelemetry-instrumentation/src/semconvStability.ts).
19-
* feat(instrumentation-http): capture synthetic source type on requests [#5488](https://github.com/open-telemetry/opentelemetry-js/pull/5488) @JacksonWeber
2021
* feat(instrumentation-grpc): support migration to stable HTTP semconv [#5653](https://github.com/open-telemetry/opentelemetry-js/pull/5653) @JamieDanielson
22+
* feat(instrumentation-http): capture synthetic source type on requests [#5488](https://github.com/open-telemetry/opentelemetry-js/pull/5488) @JacksonWeber
2123

2224
### :bug: Bug Fixes
2325

experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
[![NPM Published Version][npm-img]][npm-url]
44
[![Apache License][license-image]][license-image]
55

6-
**Note: This is an experimental package under active development. New releases may include breaking changes.**
6+
**Note: This is an experimental package. New releases may include breaking changes.**
77

8-
This module provides auto instrumentation for web using XMLHttpRequest .
8+
This module provides auto instrumentation for web using XMLHttpRequest.
99

1010
## Installation
1111

@@ -62,34 +62,48 @@ xmlHttpRequestInstrumentation.setTracerProvider(providerWithZone);
6262
const req = new XMLHttpRequest();
6363
req.open('GET', 'http://localhost:8090/xml-http-request.js', true);
6464
req.send();
65-
6665
```
6766

6867
### XHR Instrumentation options
6968

7069
XHR instrumentation plugin has few options available to choose from. You can set the following:
7170

72-
| Options | Type | Description |
73-
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|-----------------------------------------------------------------------------------------|
74-
| [`applyCustomAttributesOnSpan`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L85) | `XHRCustomAttributeFunction` | Function for adding custom attributes |
75-
| [`ignoreNetworkEvents`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L87) | `boolean` | Disable network events being added as span events (network events are added by default) |
76-
| [`measureRequestSize`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L89) | `boolean` | Measure outgoing request length (outgoing request length is not measured by default) |
71+
| Options | Type | Description |
72+
| ----------------------------- | ---------------------------- | ----------- |
73+
| `applyCustomAttributesOnSpan` | `XHRCustomAttributeFunction` | Function for adding custom attributes |
74+
| `ignoreNetworkEvents` | boolean | Disable network events being added as span events (network events are added by default) |
75+
| `measureRequestSize` | boolean | Measure outgoing request length (outgoing request length is not measured by default) |
76+
| `semconvStabilityOptIn` | string | A comma-separated string of tokens as described for `OTEL_SEMCONV_STABILITY_OPT_IN` in the [HTTP semantic convention stability migration](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md) guide. See the "Semantic Conventions" section below. |
7777

7878
## Semantic Conventions
7979

80-
This package uses `@opentelemetry/semantic-conventions` version `1.22+`, which implements Semantic Convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md)
80+
Up to and including v0.200.0, `instrumentation-xml-http-request` generates telemetry using [Semantic Conventions v1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md).
81+
82+
HTTP semantic conventions (semconv) were stabilized in semconv v1.23.0, and a [migration process](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#http-semantic-convention-stability-migration) was defined. `instrumentation-xml-http-request` versions 0.201.0 and later include support for migrating to stable HTTP semantic conventions, as described below. The intent is to provide an approximate 6 month time window for users of this instrumentation to migrate to the new HTTP semconv, after which a new minor version will change to use the *new* semconv by default and drop support for the old semconv. See the [HTTP semconv migration plan for OpenTelemetry JS instrumentations](https://github.com/open-telemetry/opentelemetry-js/issues/5646).
83+
84+
To select which semconv version(s) is emitted from this instrumentation, use the `semconvStabilityOptIn` configuration option. This option works [as described for `OTEL_SEMCONV_STABILITY_OPT_IN`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md):
85+
86+
- `http`: emit the new (stable) v1.23.0 semantics
87+
- `http/dup`: emit **both** the old v1.7.0 and the new (stable) v1.23.0 semantics
88+
- By default, if `semconvStabilityOptIn` includes neither of the above tokens, the old v1.7.0 semconv is used.
89+
90+
**Span status:** When the stable semconv is selected, the [span status](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#status) is set to ERROR when the response status code is `>=400` or when the response fails with an 'error' or 'timeout' XHR event. When just the old semconv is select, the span status is not set.
8191

82-
Attributes collected:
92+
**Span attributes:**
8393

84-
| Attribute | Short Description |
85-
| ------------------------------------------- | ------------------------------------------------------------------------------ |
86-
| `http.status_code` | HTTP response status code |
87-
| `http.host` | The value of the HTTP host header |
88-
| `http.user_agent` | Value of the HTTP User-Agent header sent by the client |
89-
| `http.scheme` | The URI scheme identifying the used protocol |
90-
| `http.url` | Full HTTP request URL |
91-
| `http.method` | HTTP request method |
92-
| `http.request_content_length_uncompressed` | Uncompressed size of the request body, if any body exists |
94+
| v1.7.0 semconv | v1.23.0 semconv | Notes |
95+
| ---------------------- | ---------------------------------- | ----- |
96+
| `http.method` | `http.request.method` | HTTP request method. With v1.23.0 semconv [`http.request.method_original` may also be included](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#common-attributes). |
97+
| `http.url` | `url.full` | Full HTTP request URL |
98+
| `http.host` | `server.address` and `server.port` | The hostname and port of the request URL |
99+
| `http.status_code` | `http.response.status_code` | HTTP response status code |
100+
| `http.request_content_length_uncompressed` | `http.request.body.size` | This is only added if `measureRequestSize` is `true`. |
101+
| `http.response_content_length_uncompressed` | (not included) | Stable HTTP semconv would use `http.response.body.size`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
102+
| `http.response_content_length` | (not included) | Stable HTTP semconv would use `http.response.header.<key>`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
103+
| (no equivalent) | `error.type` | The response status (as a string), if the response status was `>=400`, or one of these possible request errors: 'timeout' and 'error'.|
104+
| `http.user_agent` | (not included) | Stable HTTP semconv would use `user_agent.original`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
105+
| `http.scheme` | (not included) | Stable HTTP semconv would use `url.scheme`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
106+
| `http.status_text` | (not included) | This is no longer a documented semantic conventions attribute. |
93107

94108
## Example Screenshots
95109

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* This file contains a copy of unstable semantic convention definitions
19+
* used by this package.
20+
* @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv
21+
*/
22+
23+
/**
24+
* Deprecated, use one of `server.address`, `client.address` or `http.request.header.host` instead, depending on the usage.
25+
*
26+
* @example www.example.org
27+
*
28+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
29+
*
30+
* @deprecated Replaced by one of `server.address`, `client.address` or `http.request.header.host`, depending on the usage.
31+
*/
32+
export const ATTR_HTTP_HOST = 'http.host' as const;
33+
34+
/**
35+
* Deprecated, use `http.request.method` instead.
36+
*
37+
* @example GET
38+
* @example POST
39+
* @example HEAD
40+
*
41+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
42+
*
43+
* @deprecated Replaced by `http.request.method`.
44+
*/
45+
export const ATTR_HTTP_METHOD = 'http.method' as const;
46+
47+
/**
48+
* 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://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.
49+
*
50+
* @example 3495
51+
*
52+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
53+
*/
54+
export const ATTR_HTTP_REQUEST_BODY_SIZE = 'http.request.body.size' as const;
55+
56+
/**
57+
* Deprecated, use `http.request.body.size` instead.
58+
*
59+
* @example 5493
60+
*
61+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
62+
*
63+
* @deprecated Replaced by `http.request.body.size`.
64+
*/
65+
export const ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED =
66+
'http.request_content_length_uncompressed' as const;
67+
68+
/**
69+
* Deprecated, use `http.response.header.<key>` instead.
70+
*
71+
* @example 3495
72+
*
73+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
74+
*
75+
* @deprecated Replaced by `http.response.header.<key>`.
76+
*/
77+
export const ATTR_HTTP_RESPONSE_CONTENT_LENGTH =
78+
'http.response_content_length' as const;
79+
80+
/**
81+
* Deprecated, use `url.scheme` instead.
82+
*
83+
* @example http
84+
* @example https
85+
*
86+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
87+
*
88+
* @deprecated Replaced by `url.scheme` instead.
89+
*/
90+
export const ATTR_HTTP_SCHEME = 'http.scheme' as const;
91+
92+
/**
93+
* Deprecated, use `http.response.status_code` instead.
94+
*
95+
* @example 200
96+
*
97+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
98+
*
99+
* @deprecated Replaced by `http.response.status_code`.
100+
*/
101+
export const ATTR_HTTP_STATUS_CODE = 'http.status_code' as const;
102+
103+
/**
104+
* Deprecated, use `url.full` instead.
105+
*
106+
* @example https://www.foo.bar/search?q=OpenTelemetry#SemConv
107+
*
108+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
109+
*
110+
* @deprecated Replaced by `url.full`.
111+
*/
112+
export const ATTR_HTTP_URL = 'http.url' as const;
113+
114+
/**
115+
* Deprecated, use `user_agent.original` instead.
116+
*
117+
* @example CERN-LineMode/2.15 libwww/2.17b3
118+
* @example Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1
119+
*
120+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
121+
*
122+
* @deprecated Replaced by `user_agent.original`.
123+
*/
124+
export const ATTR_HTTP_USER_AGENT = 'http.user_agent' as const;

experimental/packages/opentelemetry-instrumentation-xml-http-request/src/utils.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
// These may be unified in the future.
1919

2020
import * as api from '@opentelemetry/api';
21+
import { getStringListFromEnv } from '@opentelemetry/core';
22+
import { URLLike } from '@opentelemetry/sdk-trace-web';
2123

2224
const DIAG_LOGGER = api.diag.createComponentLogger({
2325
namespace:
@@ -83,3 +85,60 @@ function getFormDataSize(formData: FormData): number {
8385
}
8486
return size;
8587
}
88+
89+
/**
90+
* Normalize an HTTP request method string per `http.request.method` spec
91+
* https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-client-span
92+
*/
93+
export function normalizeHttpRequestMethod(method: string): string {
94+
const knownMethods = getKnownMethods();
95+
const methUpper = method.toUpperCase();
96+
if (methUpper in knownMethods) {
97+
return methUpper;
98+
} else {
99+
return '_OTHER';
100+
}
101+
}
102+
103+
const DEFAULT_KNOWN_METHODS = {
104+
CONNECT: true,
105+
DELETE: true,
106+
GET: true,
107+
HEAD: true,
108+
OPTIONS: true,
109+
PATCH: true,
110+
POST: true,
111+
PUT: true,
112+
TRACE: true,
113+
};
114+
let knownMethods: { [key: string]: boolean };
115+
function getKnownMethods() {
116+
if (knownMethods === undefined) {
117+
const cfgMethods = getStringListFromEnv(
118+
'OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS'
119+
);
120+
if (cfgMethods && cfgMethods.length > 0) {
121+
knownMethods = {};
122+
cfgMethods.forEach(m => {
123+
knownMethods[m] = true;
124+
});
125+
} else {
126+
knownMethods = DEFAULT_KNOWN_METHODS;
127+
}
128+
}
129+
return knownMethods;
130+
}
131+
132+
const HTTP_PORT_FROM_PROTOCOL: { [key: string]: string } = {
133+
'https:': '443',
134+
'http:': '80',
135+
};
136+
export function serverPortFromUrl(url: URLLike): number | undefined {
137+
const serverPort = Number(url.port || HTTP_PORT_FROM_PROTOCOL[url.protocol]);
138+
// Guard with `if (serverPort)` because `Number('') === 0`.
139+
if (serverPort && !isNaN(serverPort)) {
140+
return serverPort;
141+
} else {
142+
return undefined;
143+
}
144+
}

0 commit comments

Comments
 (0)