diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index c6b64299f00..696643c81f9 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -10,6 +10,8 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* feat(http-instrumentation): record exceptions in http instrumentation #3008 @luismiramirez + ### :bug: (Bug Fix) * fix(otlp-transformer): remove type dependency on Long #3022 @legendecas diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts index e1e98209dba..d21dd105a90 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts @@ -150,6 +150,7 @@ export const setSpanWithError = ( }); span.setStatus({ code: SpanStatusCode.ERROR, message }); + span.recordException(error); }; /** diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts index 1ca36d22470..d074097472f 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts @@ -570,6 +570,7 @@ describe('HttpInstrumentation', () => { }, component: 'http', noNetPeer: true, + error: err, }; assertSpan(spans[0], SpanKind.CLIENT, validations); return true; diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts index 52211abadc1..545ad567423 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts @@ -259,6 +259,8 @@ describe('Utility', () => { attributes[AttributeNames.HTTP_ERROR_MESSAGE], errorMessage ); + assert.strictEqual(span.events.length, 1); + assert.strictEqual(span.events[0].name, 'exception'); assert.ok(attributes[AttributeNames.HTTP_ERROR_NAME]); }); }); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts b/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts index 1afbffc0294..db0d0d1ea0f 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { isValidSpanId, SpanKind, SpanStatus } from '@opentelemetry/api'; +import { isValidSpanId, SpanKind, SpanStatus, Exception } from '@opentelemetry/api'; import { hrTimeToNanoseconds } from '@opentelemetry/core'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; @@ -38,6 +38,7 @@ export const assertSpan = ( serverName?: string; component: string; noNetPeer?: boolean; // we don't expect net peer info when request throw before being sent + error?: Exception; } ) => { assert.strictEqual(span.spanContext().traceId.length, 32); @@ -65,7 +66,20 @@ export const assertSpan = ( ); assert.strictEqual(span.links.length, 0); - assert.strictEqual(span.events.length, 0); + + if (validations.error) { + assert.strictEqual(span.events.length, 1); + assert.strictEqual(span.events[0].name, 'exception'); + + const eventAttributes = span.events[0].attributes; + assert.ok(eventAttributes != null); + assert.deepStrictEqual( + Object.keys(eventAttributes), + ['exception.type', 'exception.message', 'exception.stacktrace'] + ); + } else { + assert.strictEqual(span.events.length, 0); + } assert.deepStrictEqual( span.status,