From 8e7b8fd8874780d6800804bceaa30174c70df173 Mon Sep 17 00:00:00 2001 From: "Fabio.Gomes" Date: Wed, 20 Mar 2024 19:24:27 +0000 Subject: [PATCH] feat(koa): Adds support to ignore a span by its layer name --- .../README.md | 1 + .../src/instrumentation.ts | 11 ++++- .../src/types.ts | 2 + .../src/utils.ts | 19 ++++++++ .../test/koa.test.ts | 2 +- .../test/utils.test.ts | 43 +++++++++++++++++++ 6 files changed, 76 insertions(+), 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-koa/README.md b/plugins/node/opentelemetry-instrumentation-koa/README.md index 43e717a171..72d6b9a2a8 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/README.md +++ b/plugins/node/opentelemetry-instrumentation-koa/README.md @@ -54,6 +54,7 @@ Note that generator-based middleware are deprecated and won't be instrumented. | Options | Type | Example | Description | | ------------------ | ----------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------- | | `ignoreLayersType` | `KoaLayerType[]` | `['middleware']` | Ignore layers of specified type. | +| `ignoreLayersName` | `string[]` | `['logger']` | Ignore layers with specified names. | | `requestHook` | `KoaRequestCustomAttributeFunction` | `(span, info) => {}` | Function for adding custom attributes to Koa middleware layers. Receives params: `Span, KoaRequestInfo`. | `ignoreLayersType` accepts an array of `KoaLayerType` which can take the following string values: diff --git a/plugins/node/opentelemetry-instrumentation-koa/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-koa/src/instrumentation.ts index 6dd6c86021..bc0b645597 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/src/instrumentation.ts @@ -25,7 +25,11 @@ import { import type * as koa from 'koa'; import { KoaLayerType, KoaInstrumentationConfig } from './types'; import { PACKAGE_NAME, PACKAGE_VERSION } from './version'; -import { getMiddlewareMetadata, isLayerIgnored } from './utils'; +import { + getMiddlewareMetadata, + isLayerIgnored, + isLayerNameIgnored, +} from './utils'; import { getRPCMetadata, RPCType } from '@opentelemetry/core'; import { kLayerPatched, @@ -161,6 +165,11 @@ export class KoaInstrumentation extends InstrumentationBase extends InstrumentationConfig { /** Ignore specific layers based on their type */ ignoreLayersType?: KoaLayerType[]; + /** Ignore specific layers based on their name */ + ignoreLayersName?: string[]; /** Function for adding custom attributes to each middleware layer span */ requestHook?: KoaRequestCustomAttributeFunction< KoaContextType, diff --git a/plugins/node/opentelemetry-instrumentation-koa/src/utils.ts b/plugins/node/opentelemetry-instrumentation-koa/src/utils.ts index 2bbfd027ef..456d1c5b86 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/src/utils.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/src/utils.ts @@ -27,6 +27,7 @@ export const getMiddlewareMetadata = ( ): { attributes: Attributes; name: string; + layerName: string; } => { if (isRouter) { return { @@ -36,6 +37,7 @@ export const getMiddlewareMetadata = ( [SEMATTRS_HTTP_ROUTE]: layerPath?.toString(), }, name: context._matchedRouteName || `router - ${layerPath}`, + layerName: context._matchedRouteName || layerPath?.toString() || '', }; } else { return { @@ -44,6 +46,7 @@ export const getMiddlewareMetadata = ( [AttributeNames.KOA_TYPE]: KoaLayerType.MIDDLEWARE, }, name: `middleware - ${layer.name}`, + layerName: layer.name, }; } }; @@ -63,3 +66,19 @@ export const isLayerIgnored = ( config?.ignoreLayersType?.includes(type) ); }; + +/** + * Check whether the given request name is ignored by configuration + * @param [list] List of ignore name patterns + * @param [onException] callback for doing something when an exception has + * occurred + */ +export const isLayerNameIgnored = ( + layerName: string, + config?: KoaInstrumentationConfig +): boolean => { + return !!( + Array.isArray(config?.ignoreLayersName) && + config?.ignoreLayersName?.includes(layerName) + ); +}; diff --git a/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts b/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts index a40cd033c1..984baa500d 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts @@ -730,7 +730,7 @@ describe('Koa Instrumentation', () => { '--experimental-loader=@opentelemetry/instrumentation/hook.mjs', NODE_NO_WARNINGS: '1', }, - checkResult: (err, stdout, stderr) => { + checkResult: (err: any, stdout: any, stderr: any) => { assert.ifError(err); }, checkCollector: (collector: testUtils.TestCollector) => { diff --git a/plugins/node/opentelemetry-instrumentation-koa/test/utils.test.ts b/plugins/node/opentelemetry-instrumentation-koa/test/utils.test.ts index b9a1ab4160..85b6ba0af9 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/test/utils.test.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/test/utils.test.ts @@ -58,4 +58,47 @@ describe('Utils', () => { ); }); }); + describe('isLayerNameIgnored()', () => { + it('should not fail with invalid config', () => { + assert.strictEqual(utils.isLayerNameIgnored(''), false); + assert.strictEqual( + utils.isLayerNameIgnored('', {} as KoaInstrumentationConfig), + false + ); + assert.strictEqual( + utils.isLayerNameIgnored('', { + ignoreLayersName: {}, + } as KoaInstrumentationConfig), + false + ); + assert.strictEqual( + utils.isLayerNameIgnored('logger', { + ignoreLayersName: {}, + } as KoaInstrumentationConfig), + false + ); + assert.strictEqual(utils.isLayerNameIgnored('logger'), false); + assert.strictEqual( + utils.isLayerNameIgnored('', { + ignoreLayersName: [], + } as KoaInstrumentationConfig), + false + ); + }); + + it('should ignore based on type', () => { + assert.strictEqual( + utils.isLayerNameIgnored('logger', { + ignoreLayersName: ['logger'], + }), + true + ); + assert.strictEqual( + utils.isLayerNameIgnored('', { + ignoreLayersName: ['logger'], + }), + false + ); + }); + }); });