Skip to content

Commit 5c5678d

Browse files
authored
Merge branch 'main' into event-payload
2 parents 712493e + f3aedb7 commit 5c5678d

File tree

9 files changed

+565
-200
lines changed

9 files changed

+565
-200
lines changed

experimental/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ and AnyValueMap types [#4575](https://github.com/open-telemetry/opentelemetry-js
2626

2727
### :rocket: (Enhancement)
2828

29+
* feat(opentelemetry-instrumentation-xhr): optionally ignore network events [#4571](https://github.com/open-telemetry/opentelemetry-js/pull/4571/) @mustafahaddara
2930
* refactor(instr-http): use exported strings for semconv. [#4573](https://github.com/open-telemetry/opentelemetry-js/pull/4573/) @JamieDanielson
31+
* perf(instrumentation-http): remove obvious temp allocations [#4576](https://github.com/open-telemetry/opentelemetry-js/pull/4576) @Samuron
3032
* feat(sdk-node): add `HostDetector` as default resource detector
3133
* feat(api-events): added data field to the Event interface [4575](https://github.com/open-telemetry/opentelemetry-js/pull/4575)
3234

@@ -38,6 +40,8 @@ and AnyValueMap types [#4575](https://github.com/open-telemetry/opentelemetry-js
3840

3941
### :books: (Refine Doc)
4042

43+
* docs(instr-http): document semantic conventions and attributes in use. [#4587](https://github.com/open-telemetry/opentelemetry-js/pull/4587/) @JamieDanielson
44+
4145
### :house: (Internal)
4246

4347
## 0.49.1

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

+33-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,39 @@ The following options are deprecated:
6767
| Options | Type | Description |
6868
| ------- | ---- | ----------- |
6969
| `ignoreIncomingPaths` | `IgnoreMatcher[]` | Http instrumentation will not trace all incoming requests that match paths |
70-
| `ignoreOutgoingUrls` | `IgnoreMatcher[]` | Http instrumentation will not trace all outgoing requests that match URLs |
70+
71+
## Semantic Conventions
72+
73+
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)
74+
75+
Attributes collected:
76+
77+
| Attribute | Short Description | Notes |
78+
| ------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------- |
79+
| `ip_tcp` | Transport protocol used | Key: `NETTRANSPORTVALUES_IP_TCP` |
80+
| `ip_udp` | Transport protocol used | Key: `NETTRANSPORTVALUES_IP_UDP` |
81+
| `http.client_ip` | The IP address of the original client behind all proxies, if known | Key: `SEMATTRS_HTTP_CLIENT_IP` |
82+
| `http.flavor` | Kind of HTTP protocol used | Key: `SEMATTRS_HTTP_FLAVOR` |
83+
| `http.host` | The value of the HTTP host header | Key: `SEMATTRS_HTTP_HOST` |
84+
| `http.method` | HTTP request method | Key: `SEMATTRS_HTTP_METHOD` |
85+
| `http.request_content_length` | The size of the request payload body in bytes | Key: `SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH` |
86+
| `http.request_content_length_uncompressed` | The size of the uncompressed request payload body after transport decoding | Key: `SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED` |
87+
| `http.response_content_length` | The size of the response payload body in bytes | Key: `SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH` |
88+
| `http.response_content_length_uncompressed` | The size of the uncompressed response payload body after transport decoding | Key: `SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED` |
89+
| `http.route` | The matched route (path template). | Key: `SEMATTRS_HTTP_ROUTE` |
90+
| `http.scheme` | The URI scheme identifying the used protocol | Key: `SEMATTRS_HTTP_SCHEME` |
91+
| `http.server_name` | The primary server name of the matched virtual host | Key: `SEMATTRS_HTTP_SERVER_NAME` |
92+
| `http.status_code` | HTTP response status code | Key: `SEMATTRS_HTTP_STATUS_CODE` |
93+
| `http.target` | The full request target as passed in a HTTP request line or equivalent | Key: `SEMATTRS_HTTP_TARGET` |
94+
| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]` | Key: `SEMATTRS_HTTP_URL` |
95+
| `http.user_agent` | Value of the HTTP User-Agent header sent by the client | Key: `SEMATTRS_HTTP_USER_AGENT` |
96+
| `net.host.ip` | Like net.peer.ip but for the host IP. Useful in case of a multi-IP host | Key: `SEMATTRS_NET_HOST_IP` |
97+
| `net.host.name` | Local hostname or similar | Key: `SEMATTRS_NET_HOST_NAME` |
98+
| `net.host.port` | Like net.peer.port but for the host port | Key: `SEMATTRS_NET_HOST_PORT` |
99+
| `net.peer.ip.` | Remote address of the peer (dotted decimal for IPv4 or RFC5952 for IPv6) | Key: `SEMATTRS_NET_PEER_IP` |
100+
| `net.peer.name` | Remote hostname or similar | Key: `SEMATTRS_NET_PEER_NAME` |
101+
| `net.peer.port` | Remote port number | Key: `SEMATTRS_NET_PEER_PORT` |
102+
| `net.transport` | Transport protocol used | Key: `SEMATTRS_NET_TRANSPORT` |
71103

72104
## Useful links
73105

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

+18-21
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,8 @@ export const isIgnored = (
167167
export const setSpanWithError = (span: Span, error: Err): void => {
168168
const message = error.message;
169169

170-
span.setAttributes({
171-
[AttributeNames.HTTP_ERROR_NAME]: error.name,
172-
[AttributeNames.HTTP_ERROR_MESSAGE]: message,
173-
});
174-
170+
span.setAttribute(AttributeNames.HTTP_ERROR_NAME, error.name);
171+
span.setAttribute(AttributeNames.HTTP_ERROR_MESSAGE, message);
175172
span.setStatus({ code: SpanStatusCode.ERROR, message });
176173
span.recordException(error);
177174
};
@@ -371,7 +368,7 @@ export const getOutgoingRequestAttributes = (
371368
[SEMATTRS_HTTP_METHOD]: method,
372369
[SEMATTRS_HTTP_TARGET]: requestOptions.path || '/',
373370
[SEMATTRS_NET_PEER_NAME]: hostname,
374-
[SEMATTRS_HTTP_HOST]: requestOptions.headers?.host ?? `${hostname}:${port}`,
371+
[SEMATTRS_HTTP_HOST]: headers.host ?? `${hostname}:${port}`,
375372
};
376373

377374
if (userAgent !== undefined) {
@@ -399,8 +396,10 @@ export const getOutgoingRequestMetricAttributes = (
399396
* Returns attributes related to the kind of HTTP protocol used
400397
* @param {string} [kind] Kind of HTTP protocol used: "1.0", "1.1", "2", "SPDY" or "QUIC".
401398
*/
402-
export const getAttributesFromHttpKind = (kind?: string): SpanAttributes => {
403-
const attributes: SpanAttributes = {};
399+
export const setAttributesFromHttpKind = (
400+
kind: string | undefined,
401+
attributes: SpanAttributes
402+
): void => {
404403
if (kind) {
405404
attributes[SEMATTRS_HTTP_FLAVOR] = kind;
406405
if (kind.toUpperCase() !== 'QUIC') {
@@ -409,7 +408,6 @@ export const getAttributesFromHttpKind = (kind?: string): SpanAttributes => {
409408
attributes[SEMATTRS_NET_TRANSPORT] = NETTRANSPORTVALUES_IP_UDP;
410409
}
411410
}
412-
return attributes;
413411
};
414412

415413
/**
@@ -436,8 +434,8 @@ export const getOutgoingRequestAttributesOnResponse = (
436434
).toUpperCase();
437435
}
438436

439-
const httpKindAttributes = getAttributesFromHttpKind(httpVersion);
440-
return Object.assign(attributes, httpKindAttributes);
437+
setAttributesFromHttpKind(httpVersion, attributes);
438+
return attributes;
441439
};
442440

443441
/**
@@ -509,9 +507,8 @@ export const getIncomingRequestAttributes = (
509507
attributes[SEMATTRS_HTTP_USER_AGENT] = userAgent;
510508
}
511509
setRequestContentLengthAttribute(request, attributes);
512-
513-
const httpKindAttributes = getAttributesFromHttpKind(httpVersion);
514-
return Object.assign(attributes, httpKindAttributes, options.hookAttributes);
510+
setAttributesFromHttpKind(httpVersion, attributes);
511+
return Object.assign(attributes, options.hookAttributes);
515512
};
516513

517514
/**
@@ -584,24 +581,24 @@ export const getIncomingRequestMetricAttributesOnResponse = (
584581
};
585582

586583
export function headerCapture(type: 'request' | 'response', headers: string[]) {
587-
const normalizedHeaders = new Map(
588-
headers.map(header => [
589-
header.toLowerCase(),
590-
header.toLowerCase().replace(/-/g, '_'),
591-
])
592-
);
584+
const normalizedHeaders = new Map<string, string>();
585+
for (let i = 0, len = headers.length; i < len; i++) {
586+
const capturedHeader = headers[i].toLowerCase();
587+
normalizedHeaders.set(capturedHeader, capturedHeader.replace(/-/g, '_'));
588+
}
593589

594590
return (
595591
span: Span,
596592
getHeader: (key: string) => undefined | string | string[] | number
597593
) => {
598-
for (const [capturedHeader, normalizedHeader] of normalizedHeaders) {
594+
for (const capturedHeader of normalizedHeaders.keys()) {
599595
const value = getHeader(capturedHeader);
600596

601597
if (value === undefined) {
602598
continue;
603599
}
604600

601+
const normalizedHeader = normalizedHeaders.get(capturedHeader);
605602
const key = `http.${type}.header.${normalizedHeader}`;
606603

607604
if (typeof value === 'string') {

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

+9
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ req.send();
6464

6565
```
6666

67+
### XHR Instrumentation options
68+
69+
XHR instrumentation plugin has few options available to choose from. You can set the following:
70+
71+
| Options | Type | Description |
72+
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|-----------------------------------------------------------------------------------------|
73+
| [`applyCustomAttributesOnSpan`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L76) | `XHRCustomAttributeFunction` | Function for adding custom attributes |
74+
| [`ignoreNetworkEvents`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L78) | `boolean` | Disable network events being added as span events (network events are added by default) |
75+
6776
## Example Screenshots
6877

6978
![Screenshot of the running example](images/main.jpg)

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ export interface XMLHttpRequestInstrumentationConfig
7474
ignoreUrls?: Array<string | RegExp>;
7575
/** Function for adding custom attributes on the span */
7676
applyCustomAttributesOnSpan?: XHRCustomAttributeFunction;
77+
/** Ignore adding network events as span events */
78+
ignoreNetworkEvents?: boolean;
7779
}
7880

7981
/**
@@ -140,7 +142,9 @@ export class XMLHttpRequestInstrumentation extends InstrumentationBase<XMLHttpRe
140142
const childSpan = this.tracer.startSpan('CORS Preflight', {
141143
startTime: corsPreFlightRequest[PTN.FETCH_START],
142144
});
143-
addSpanNetworkEvents(childSpan, corsPreFlightRequest);
145+
if (!this._getConfig().ignoreNetworkEvents) {
146+
addSpanNetworkEvents(childSpan, corsPreFlightRequest);
147+
}
144148
childSpan.end(corsPreFlightRequest[PTN.RESPONSE_END]);
145149
});
146150
}
@@ -292,7 +296,9 @@ export class XMLHttpRequestInstrumentation extends InstrumentationBase<XMLHttpRe
292296
this._addChildSpan(span, corsPreFlightRequest);
293297
this._markResourceAsUsed(corsPreFlightRequest);
294298
}
295-
addSpanNetworkEvents(span, mainRequest);
299+
if (!this._getConfig().ignoreNetworkEvents) {
300+
addSpanNetworkEvents(span, mainRequest);
301+
}
296302
}
297303
}
298304

experimental/packages/opentelemetry-instrumentation-xml-http-request/test/xhr.test.ts

+14
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,20 @@ describe('xhr', () => {
783783
);
784784
});
785785
});
786+
787+
describe('when network events are ignored', () => {
788+
beforeEach(done => {
789+
clearData();
790+
prepareData(done, url, {
791+
ignoreNetworkEvents: true,
792+
});
793+
});
794+
it('should NOT add network events', () => {
795+
const span: tracing.ReadableSpan = exportSpy.args[1][0][0];
796+
const events = span.events;
797+
assert.strictEqual(events.length, 3, 'number of events is wrong');
798+
});
799+
});
786800
});
787801

788802
describe('when request is NOT successful', () => {

integration-tests/propagation-validation-server/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"@opentelemetry/sdk-trace-base": "1.22.0",
1818
"axios": "1.5.1",
1919
"body-parser": "1.19.0",
20-
"express": "4.17.3"
20+
"express": "4.19.2"
2121
},
2222
"devDependencies": {
2323
"typescript": "4.4.4"

0 commit comments

Comments
 (0)