Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ All notable changes to experimental packages in this project will be documented

### :rocket: (Enhancement)

* refactor(instr-http): use exported strings for semconv. [#4573](https://github.com/open-telemetry/opentelemetry-js/pull/4573/) @JamieDanielson

### :bug: (Bug Fix)

* fix(exporter-*-otlp-*): use parseHeaders() to ensure header-values are not 'undefined' #4540
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import {
} from '@opentelemetry/instrumentation';
import { RPCMetadata, RPCType, setRPCMetadata } from '@opentelemetry/core';
import { errorMonitor } from 'events';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';

/**
* Http instrumentation instrumentation for Opentelemetry
Expand Down Expand Up @@ -746,7 +746,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
code: utils.parseResponseStatus(SpanKind.SERVER, response.statusCode),
});

const route = attributes[SemanticAttributes.HTTP_ROUTE];
const route = attributes[SEMATTRS_HTTP_ROUTE];
if (route) {
span.updateName(`${request.method || 'GET'} ${route}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,30 @@ import {
SpanKind,
} from '@opentelemetry/api';
import {
NetTransportValues,
SemanticAttributes,
NETTRANSPORTVALUES_IP_TCP,
NETTRANSPORTVALUES_IP_UDP,
SEMATTRS_HTTP_CLIENT_IP,
SEMATTRS_HTTP_FLAVOR,
SEMATTRS_HTTP_HOST,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH,
SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,
SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH,
SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED,
SEMATTRS_HTTP_ROUTE,
SEMATTRS_HTTP_SCHEME,
SEMATTRS_HTTP_SERVER_NAME,
SEMATTRS_HTTP_STATUS_CODE,
SEMATTRS_HTTP_TARGET,
SEMATTRS_HTTP_URL,
SEMATTRS_HTTP_USER_AGENT,
SEMATTRS_NET_HOST_IP,
SEMATTRS_NET_HOST_NAME,
SEMATTRS_NET_HOST_PORT,
SEMATTRS_NET_PEER_IP,
SEMATTRS_NET_PEER_NAME,
SEMATTRS_NET_PEER_PORT,
SEMATTRS_NET_TRANSPORT,
} from '@opentelemetry/semantic-conventions';
import {
IncomingHttpHeaders,
Expand Down Expand Up @@ -167,10 +189,9 @@ export const setRequestContentLengthAttribute = (
if (length === null) return;

if (isCompressed(request.headers)) {
attributes[SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH] = length;
attributes[SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH] = length;
} else {
attributes[SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED] =
length;
attributes[SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED] = length;
}
};

Expand All @@ -187,10 +208,9 @@ export const setResponseContentLengthAttribute = (
if (length === null) return;

if (isCompressed(response.headers)) {
attributes[SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH] = length;
attributes[SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH] = length;
} else {
attributes[SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED] =
length;
attributes[SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED] = length;
}
};

Expand Down Expand Up @@ -343,20 +363,19 @@ export const getOutgoingRequestAttributes = (
const headers = requestOptions.headers || {};
const userAgent = headers['user-agent'];
const attributes: SpanAttributes = {
[SemanticAttributes.HTTP_URL]: getAbsoluteUrl(
[SEMATTRS_HTTP_URL]: getAbsoluteUrl(
requestOptions,
headers,
`${options.component}:`
),
[SemanticAttributes.HTTP_METHOD]: method,
[SemanticAttributes.HTTP_TARGET]: requestOptions.path || '/',
[SemanticAttributes.NET_PEER_NAME]: hostname,
[SemanticAttributes.HTTP_HOST]:
requestOptions.headers?.host ?? `${hostname}:${port}`,
[SEMATTRS_HTTP_METHOD]: method,
[SEMATTRS_HTTP_TARGET]: requestOptions.path || '/',
[SEMATTRS_NET_PEER_NAME]: hostname,
[SEMATTRS_HTTP_HOST]: requestOptions.headers?.host ?? `${hostname}:${port}`,
};

if (userAgent !== undefined) {
attributes[SemanticAttributes.HTTP_USER_AGENT] = userAgent;
attributes[SEMATTRS_HTTP_USER_AGENT] = userAgent;
}
return Object.assign(attributes, options.hookAttributes);
};
Expand All @@ -369,10 +388,9 @@ export const getOutgoingRequestMetricAttributes = (
spanAttributes: SpanAttributes
): MetricAttributes => {
const metricAttributes: MetricAttributes = {};
metricAttributes[SemanticAttributes.HTTP_METHOD] =
spanAttributes[SemanticAttributes.HTTP_METHOD];
metricAttributes[SemanticAttributes.NET_PEER_NAME] =
spanAttributes[SemanticAttributes.NET_PEER_NAME];
metricAttributes[SEMATTRS_HTTP_METHOD] = spanAttributes[SEMATTRS_HTTP_METHOD];
metricAttributes[SEMATTRS_NET_PEER_NAME] =
spanAttributes[SEMATTRS_NET_PEER_NAME];
//TODO: http.url attribute, it should substitute any parameters to avoid high cardinality.
return metricAttributes;
};
Expand All @@ -384,11 +402,11 @@ export const getOutgoingRequestMetricAttributes = (
export const getAttributesFromHttpKind = (kind?: string): SpanAttributes => {
const attributes: SpanAttributes = {};
if (kind) {
attributes[SemanticAttributes.HTTP_FLAVOR] = kind;
attributes[SEMATTRS_HTTP_FLAVOR] = kind;
if (kind.toUpperCase() !== 'QUIC') {
attributes[SemanticAttributes.NET_TRANSPORT] = NetTransportValues.IP_TCP;
attributes[SEMATTRS_NET_TRANSPORT] = NETTRANSPORTVALUES_IP_TCP;
} else {
attributes[SemanticAttributes.NET_TRANSPORT] = NetTransportValues.IP_UDP;
attributes[SEMATTRS_NET_TRANSPORT] = NETTRANSPORTVALUES_IP_UDP;
}
}
return attributes;
Expand All @@ -406,13 +424,13 @@ export const getOutgoingRequestAttributesOnResponse = (
const attributes: SpanAttributes = {};
if (socket) {
const { remoteAddress, remotePort } = socket;
attributes[SemanticAttributes.NET_PEER_IP] = remoteAddress;
attributes[SemanticAttributes.NET_PEER_PORT] = remotePort;
attributes[SEMATTRS_NET_PEER_IP] = remoteAddress;
attributes[SEMATTRS_NET_PEER_PORT] = remotePort;
}
setResponseContentLengthAttribute(response, attributes);

if (statusCode) {
attributes[SemanticAttributes.HTTP_STATUS_CODE] = statusCode;
attributes[SEMATTRS_HTTP_STATUS_CODE] = statusCode;
attributes[AttributeNames.HTTP_STATUS_TEXT] = (
statusMessage || ''
).toUpperCase();
Expand All @@ -430,12 +448,11 @@ export const getOutgoingRequestMetricAttributesOnResponse = (
spanAttributes: SpanAttributes
): MetricAttributes => {
const metricAttributes: MetricAttributes = {};
metricAttributes[SemanticAttributes.NET_PEER_PORT] =
spanAttributes[SemanticAttributes.NET_PEER_PORT];
metricAttributes[SemanticAttributes.HTTP_STATUS_CODE] =
spanAttributes[SemanticAttributes.HTTP_STATUS_CODE];
metricAttributes[SemanticAttributes.HTTP_FLAVOR] =
spanAttributes[SemanticAttributes.HTTP_FLAVOR];
metricAttributes[SEMATTRS_NET_PEER_PORT] =
spanAttributes[SEMATTRS_NET_PEER_PORT];
metricAttributes[SEMATTRS_HTTP_STATUS_CODE] =
spanAttributes[SEMATTRS_HTTP_STATUS_CODE];
metricAttributes[SEMATTRS_HTTP_FLAVOR] = spanAttributes[SEMATTRS_HTTP_FLAVOR];
return metricAttributes;
};

Expand Down Expand Up @@ -465,31 +482,31 @@ export const getIncomingRequestAttributes = (
'localhost';
const serverName = options.serverName;
const attributes: SpanAttributes = {
[SemanticAttributes.HTTP_URL]: getAbsoluteUrl(
[SEMATTRS_HTTP_URL]: getAbsoluteUrl(
requestUrl,
headers,
`${options.component}:`
),
[SemanticAttributes.HTTP_HOST]: host,
[SemanticAttributes.NET_HOST_NAME]: hostname,
[SemanticAttributes.HTTP_METHOD]: method,
[SemanticAttributes.HTTP_SCHEME]: options.component,
[SEMATTRS_HTTP_HOST]: host,
[SEMATTRS_NET_HOST_NAME]: hostname,
[SEMATTRS_HTTP_METHOD]: method,
[SEMATTRS_HTTP_SCHEME]: options.component,
};

if (typeof ips === 'string') {
attributes[SemanticAttributes.HTTP_CLIENT_IP] = ips.split(',')[0];
attributes[SEMATTRS_HTTP_CLIENT_IP] = ips.split(',')[0];
}

if (typeof serverName === 'string') {
attributes[SemanticAttributes.HTTP_SERVER_NAME] = serverName;
attributes[SEMATTRS_HTTP_SERVER_NAME] = serverName;
}

if (requestUrl) {
attributes[SemanticAttributes.HTTP_TARGET] = requestUrl.path || '/';
attributes[SEMATTRS_HTTP_TARGET] = requestUrl.path || '/';
}

if (userAgent !== undefined) {
attributes[SemanticAttributes.HTTP_USER_AGENT] = userAgent;
attributes[SEMATTRS_HTTP_USER_AGENT] = userAgent;
}
setRequestContentLengthAttribute(request, attributes);

Expand All @@ -506,14 +523,11 @@ export const getIncomingRequestMetricAttributes = (
spanAttributes: SpanAttributes
): MetricAttributes => {
const metricAttributes: MetricAttributes = {};
metricAttributes[SemanticAttributes.HTTP_SCHEME] =
spanAttributes[SemanticAttributes.HTTP_SCHEME];
metricAttributes[SemanticAttributes.HTTP_METHOD] =
spanAttributes[SemanticAttributes.HTTP_METHOD];
metricAttributes[SemanticAttributes.NET_HOST_NAME] =
spanAttributes[SemanticAttributes.NET_HOST_NAME];
metricAttributes[SemanticAttributes.HTTP_FLAVOR] =
spanAttributes[SemanticAttributes.HTTP_FLAVOR];
metricAttributes[SEMATTRS_HTTP_SCHEME] = spanAttributes[SEMATTRS_HTTP_SCHEME];
metricAttributes[SEMATTRS_HTTP_METHOD] = spanAttributes[SEMATTRS_HTTP_METHOD];
metricAttributes[SEMATTRS_NET_HOST_NAME] =
spanAttributes[SEMATTRS_NET_HOST_NAME];
metricAttributes[SEMATTRS_HTTP_FLAVOR] = spanAttributes[SEMATTRS_HTTP_FLAVOR];
//TODO: http.target attribute, it should substitute any parameters to avoid high cardinality.
return metricAttributes;
};
Expand All @@ -535,18 +549,18 @@ export const getIncomingRequestAttributesOnResponse = (
const attributes: SpanAttributes = {};
if (socket) {
const { localAddress, localPort, remoteAddress, remotePort } = socket;
attributes[SemanticAttributes.NET_HOST_IP] = localAddress;
attributes[SemanticAttributes.NET_HOST_PORT] = localPort;
attributes[SemanticAttributes.NET_PEER_IP] = remoteAddress;
attributes[SemanticAttributes.NET_PEER_PORT] = remotePort;
attributes[SEMATTRS_NET_HOST_IP] = localAddress;
attributes[SEMATTRS_NET_HOST_PORT] = localPort;
attributes[SEMATTRS_NET_PEER_IP] = remoteAddress;
attributes[SEMATTRS_NET_PEER_PORT] = remotePort;
}
attributes[SemanticAttributes.HTTP_STATUS_CODE] = statusCode;
attributes[SEMATTRS_HTTP_STATUS_CODE] = statusCode;
attributes[AttributeNames.HTTP_STATUS_TEXT] = (
statusMessage || ''
).toUpperCase();

if (rpcMetadata?.type === RPCType.HTTP && rpcMetadata.route !== undefined) {
attributes[SemanticAttributes.HTTP_ROUTE] = rpcMetadata.route;
attributes[SEMATTRS_HTTP_ROUTE] = rpcMetadata.route;
}
return attributes;
};
Expand All @@ -559,13 +573,12 @@ export const getIncomingRequestMetricAttributesOnResponse = (
spanAttributes: SpanAttributes
): MetricAttributes => {
const metricAttributes: MetricAttributes = {};
metricAttributes[SemanticAttributes.HTTP_STATUS_CODE] =
spanAttributes[SemanticAttributes.HTTP_STATUS_CODE];
metricAttributes[SemanticAttributes.NET_HOST_PORT] =
spanAttributes[SemanticAttributes.NET_HOST_PORT];
if (spanAttributes[SemanticAttributes.HTTP_ROUTE] !== undefined) {
metricAttributes[SemanticAttributes.HTTP_ROUTE] =
spanAttributes[SemanticAttributes.HTTP_ROUTE];
metricAttributes[SEMATTRS_HTTP_STATUS_CODE] =
spanAttributes[SEMATTRS_HTTP_STATUS_CODE];
metricAttributes[SEMATTRS_NET_HOST_PORT] =
spanAttributes[SEMATTRS_NET_HOST_PORT];
if (spanAttributes[SEMATTRS_HTTP_ROUTE] !== undefined) {
metricAttributes[SEMATTRS_HTTP_ROUTE] = spanAttributes[SEMATTRS_HTTP_ROUTE];
}
return metricAttributes;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ import {
SimpleSpanProcessor,
} from '@opentelemetry/sdk-trace-base';
import {
NetTransportValues,
SemanticAttributes,
NETTRANSPORTVALUES_IP_TCP,
SEMATTRS_HTTP_CLIENT_IP,
SEMATTRS_HTTP_FLAVOR,
SEMATTRS_HTTP_ROUTE,
SEMATTRS_HTTP_STATUS_CODE,
SEMATTRS_NET_HOST_PORT,
SEMATTRS_NET_PEER_PORT,
SEMATTRS_NET_TRANSPORT,
} from '@opentelemetry/semantic-conventions';
import * as assert from 'assert';
import * as nock from 'nock';
Expand Down Expand Up @@ -211,11 +217,11 @@ describe('HttpInstrumentation', () => {
assertSpan(incomingSpan, SpanKind.SERVER, validations);
assertSpan(outgoingSpan, SpanKind.CLIENT, validations);
assert.strictEqual(
incomingSpan.attributes[SemanticAttributes.NET_HOST_PORT],
incomingSpan.attributes[SEMATTRS_NET_HOST_PORT],
serverPort
);
assert.strictEqual(
outgoingSpan.attributes[SemanticAttributes.NET_PEER_PORT],
outgoingSpan.attributes[SEMATTRS_NET_PEER_PORT],
serverPort
);
});
Expand Down Expand Up @@ -329,28 +335,25 @@ describe('HttpInstrumentation', () => {

assert.strictEqual(spans.length, 2);
assert.strictEqual(
incomingSpan.attributes[SemanticAttributes.HTTP_CLIENT_IP],
incomingSpan.attributes[SEMATTRS_HTTP_CLIENT_IP],
'<client>'
);
assert.strictEqual(
incomingSpan.attributes[SemanticAttributes.NET_HOST_PORT],
incomingSpan.attributes[SEMATTRS_NET_HOST_PORT],
serverPort
);
assert.strictEqual(
outgoingSpan.attributes[SemanticAttributes.NET_PEER_PORT],
outgoingSpan.attributes[SEMATTRS_NET_PEER_PORT],
serverPort
);
[
{ span: incomingSpan, kind: SpanKind.SERVER },
{ span: outgoingSpan, kind: SpanKind.CLIENT },
].forEach(({ span, kind }) => {
assert.strictEqual(span.attributes[SEMATTRS_HTTP_FLAVOR], '1.1');
assert.strictEqual(
span.attributes[SemanticAttributes.HTTP_FLAVOR],
'1.1'
);
assert.strictEqual(
span.attributes[SemanticAttributes.NET_TRANSPORT],
NetTransportValues.IP_TCP
span.attributes[SEMATTRS_NET_TRANSPORT],
NETTRANSPORTVALUES_IP_TCP
);
assertSpan(span, kind, validations);
});
Expand All @@ -363,10 +366,7 @@ describe('HttpInstrumentation', () => {
const span = memoryExporter.getFinishedSpans()[0];

assert.strictEqual(span.kind, SpanKind.SERVER);
assert.strictEqual(
span.attributes[SemanticAttributes.HTTP_ROUTE],
'TheRoute'
);
assert.strictEqual(span.attributes[SEMATTRS_HTTP_ROUTE], 'TheRoute');
assert.strictEqual(span.name, 'GET TheRoute');
});

Expand Down Expand Up @@ -796,10 +796,7 @@ describe('HttpInstrumentation', () => {
const [span] = spans;
assert.strictEqual(spans.length, 1);
assert.ok(Object.keys(span.attributes).length > 6);
assert.strictEqual(
span.attributes[SemanticAttributes.HTTP_STATUS_CODE],
404
);
assert.strictEqual(span.attributes[SEMATTRS_HTTP_STATUS_CODE], 404);
assert.strictEqual(span.status.code, SpanStatusCode.ERROR);
done();
});
Expand Down
Loading