Skip to content

Commit 572ed66

Browse files
feat(koa): add a config option to allow layers to be ignored by type (open-telemetry#646)
* feat(koa): Adds config option to allow selected layers to be ignored * Fixes linting errors
1 parent aff24b8 commit 572ed66

File tree

5 files changed

+113
-5
lines changed

5 files changed

+113
-5
lines changed

plugins/node/opentelemetry-instrumentation-koa/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ registerInstrumentations({
4343

4444
See [examples/koa](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/examples/koa) for a short example using both Koa and @koa/router
4545

46+
### Koa Instrumentation Options
47+
48+
| Options | Type | Example | Description |
49+
| ------- | ---- | ------- | ----------- |
50+
| `ignoreLayersType`| `KoaLayerType[]` | `['middleware']` | Ignore layers of specified type. |
51+
52+
`ignoreLayersType` accepts an array of `KoaLayerType` which can take the following string values:
53+
54+
- `router`,
55+
- `middleware`.
56+
4657
## Koa Packages
4758

4859
This package provides automatic tracing for middleware added using either the core [`Koa`](https://github.com/koajs/koa) package or the [`@koa/router`](https://github.com/koajs/router) package.

plugins/node/opentelemetry-instrumentation-koa/src/instrumentation.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import * as api from '@opentelemetry/api';
1818
import {
1919
isWrapped,
2020
InstrumentationBase,
21-
InstrumentationConfig,
2221
InstrumentationNodeModuleDefinition,
2322
} from '@opentelemetry/instrumentation';
2423

@@ -29,16 +28,17 @@ import {
2928
KoaComponentName,
3029
kLayerPatched,
3130
KoaLayerType,
31+
KoaInstrumentationConfig,
3232
} from './types';
3333
import { AttributeNames } from './enums/AttributeNames';
3434
import { VERSION } from './version';
35-
import { getMiddlewareMetadata } from './utils';
35+
import { getMiddlewareMetadata, isLayerIgnored } from './utils';
3636
import { getRPCMetadata, RPCType, setRPCMetadata } from '@opentelemetry/core';
3737

3838
/** Koa instrumentation for OpenTelemetry */
3939
export class KoaInstrumentation extends InstrumentationBase<typeof koa> {
4040
static readonly component = KoaComponentName;
41-
constructor(config?: InstrumentationConfig) {
41+
constructor(config?: KoaInstrumentationConfig) {
4242
super('@opentelemetry/instrumentation-koa', VERSION, config);
4343
}
4444
protected init() {
@@ -126,7 +126,13 @@ export class KoaInstrumentation extends InstrumentationBase<typeof koa> {
126126
isRouter: boolean,
127127
layerPath?: string
128128
): KoaMiddleware {
129-
if (middlewareLayer[kLayerPatched] === true) return middlewareLayer;
129+
const layerType = isRouter ? KoaLayerType.ROUTER : KoaLayerType.MIDDLEWARE;
130+
// Skip patching layer if its ignored in the config
131+
if (
132+
middlewareLayer[kLayerPatched] === true ||
133+
isLayerIgnored(layerType, this._config)
134+
)
135+
return middlewareLayer;
130136
middlewareLayer[kLayerPatched] = true;
131137
api.diag.debug('patching Koa middleware layer');
132138
return async (context: KoaContext, next: koa.Next) => {

plugins/node/opentelemetry-instrumentation-koa/src/types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import type { Middleware, ParameterizedContext, DefaultState } from 'koa';
1717
import type { RouterParamContext } from '@koa/router';
1818
import type * as Router from '@koa/router';
19+
import { InstrumentationConfig } from '@opentelemetry/instrumentation';
1920

2021
/**
2122
* This symbol is used to mark a Koa layer as being already instrumented
@@ -30,6 +31,14 @@ export type KoaMiddleware = Middleware<DefaultState, KoaContext> & {
3031

3132
export type KoaContext = ParameterizedContext<DefaultState, RouterParamContext>;
3233

34+
/**
35+
* Options available for the Koa Instrumentation (see [documentation](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-Instrumentation-koa#koa-Instrumentation-options))
36+
*/
37+
export interface KoaInstrumentationConfig extends InstrumentationConfig {
38+
/** Ignore specific layers based on their type */
39+
ignoreLayersType?: KoaLayerType[];
40+
}
41+
3342
export enum KoaLayerType {
3443
ROUTER = 'router',
3544
MIDDLEWARE = 'middleware',

plugins/node/opentelemetry-instrumentation-koa/src/utils.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { KoaContext, KoaMiddleware, KoaLayerType } from './types';
16+
import {
17+
KoaContext,
18+
KoaMiddleware,
19+
KoaLayerType,
20+
KoaInstrumentationConfig,
21+
} from './types';
1722
import { AttributeNames } from './enums/AttributeNames';
1823
import { SpanAttributes } from '@opentelemetry/api';
1924
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
@@ -46,3 +51,19 @@ export const getMiddlewareMetadata = (
4651
};
4752
}
4853
};
54+
55+
/**
56+
* Check whether the given request is ignored by configuration
57+
* @param [list] List of ignore patterns
58+
* @param [onException] callback for doing something when an exception has
59+
* occurred
60+
*/
61+
export const isLayerIgnored = (
62+
type: KoaLayerType,
63+
config?: KoaInstrumentationConfig
64+
): boolean => {
65+
return !!(
66+
Array.isArray(config?.ignoreLayersType) &&
67+
config?.ignoreLayersType?.includes(type)
68+
);
69+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
import * as utils from '../src/utils';
18+
import * as assert from 'assert';
19+
import { KoaInstrumentationConfig, KoaLayerType } from '../src/types';
20+
21+
describe('Utils', () => {
22+
describe('isLayerIgnored()', () => {
23+
it('should not fail with invalid config', () => {
24+
assert.strictEqual(utils.isLayerIgnored(KoaLayerType.MIDDLEWARE), false);
25+
assert.strictEqual(
26+
utils.isLayerIgnored(
27+
KoaLayerType.MIDDLEWARE,
28+
{} as KoaInstrumentationConfig
29+
),
30+
false
31+
);
32+
assert.strictEqual(
33+
utils.isLayerIgnored(KoaLayerType.MIDDLEWARE, {
34+
ignoreLayersType: {},
35+
} as KoaInstrumentationConfig),
36+
false
37+
);
38+
assert.strictEqual(
39+
utils.isLayerIgnored(KoaLayerType.ROUTER, {
40+
ignoreLayersType: {},
41+
} as KoaInstrumentationConfig),
42+
false
43+
);
44+
});
45+
46+
it('should ignore based on type', () => {
47+
assert.strictEqual(
48+
utils.isLayerIgnored(KoaLayerType.MIDDLEWARE, {
49+
ignoreLayersType: [KoaLayerType.MIDDLEWARE],
50+
}),
51+
true
52+
);
53+
assert.strictEqual(
54+
utils.isLayerIgnored(KoaLayerType.ROUTER, {
55+
ignoreLayersType: [KoaLayerType.MIDDLEWARE],
56+
}),
57+
false
58+
);
59+
});
60+
});
61+
});

0 commit comments

Comments
 (0)