Skip to content

Commit

Permalink
chore: cleaning up code
Browse files Browse the repository at this point in the history
  • Loading branch information
carolinee21 committed Jul 10, 2020
1 parent 19ad821 commit fe75b18
Show file tree
Hide file tree
Showing 11 changed files with 372 additions and 436 deletions.
1 change: 1 addition & 0 deletions plugins/node/opentelemetry-plugin-koa/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
7 changes: 7 additions & 0 deletions plugins/node/opentelemetry-plugin-koa/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
"env": {
"mocha": true,
"node": true
},
...require('../../../eslint.config.js')
}
5 changes: 3 additions & 2 deletions plugins/node/opentelemetry-plugin-koa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../",
"tdd": "yarn test -- --watch-extensions ts --watch",
"clean": "rimraf build/*",
"lint": "gts check",
"lint:fix": "gts fix",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"precompile": "tsc --version",
"version:update": "node ../../../scripts/version-update.js",
"compile": "npm run version:update && tsc -p .",
Expand Down Expand Up @@ -65,6 +65,7 @@
"dependencies": {
"@opentelemetry/api": "^0.9.0",
"@opentelemetry/core": "^0.9.0",
"eslint": "^7.4.0",
"shimmer": "^1.2.1"
}
}
4 changes: 2 additions & 2 deletions plugins/node/opentelemetry-plugin-koa/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2020, OpenTelemetry Authors
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
178 changes: 88 additions & 90 deletions plugins/node/opentelemetry-plugin-koa/src/koa.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2020, OpenTelemetry Authors
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,128 +17,126 @@
import { BasePlugin, hrTime } from '@opentelemetry/core';
import * as koa from 'koa';
import * as shimmer from 'shimmer';
import { Parameters, KoaMiddleware, KoaContext, KoaComponentName } from './types';
import {
Parameters,
KoaMiddleware,
KoaContext,
KoaComponentName,
} from './types';
import { VERSION } from './version';
import { getMiddlewareMetadata } from './utils';
import Router = require('@koa/router');


/**
* This symbol is used to mark a Koa layer as being already instrumented
* since its possible to use a given layer multiple times (ex: middlewares)
*/
export const kLayerPatched: unique symbol = Symbol('koa-layer-patched');


/** Koa instrumentation plugin for OpenTelemetry */
export class KoaPlugin extends BasePlugin<typeof koa> {
static readonly component = KoaComponentName;

constructor(readonly moduleName: string) {
super('@opentelemetry/plugin-koa', VERSION);
}

protected patch(): typeof koa {
if (this._moduleExports === undefined || this._moduleExports === null) {
return this._moduleExports;
}
var appProto = this._moduleExports.prototype;
shimmer.wrap(
appProto,
'use',
this._getAppUsePatch.bind(this)
);
constructor(readonly moduleName: string) {
super('@opentelemetry/plugin-koa', VERSION);
}

return this._moduleExports;
protected patch(): typeof koa {
this._logger.debug('Patching Koa');

if (this._moduleExports === undefined || this._moduleExports === null) {
return this._moduleExports;
}
protected unpatch(): void {
var appProto = this._moduleExports.prototype;
shimmer.unwrap(appProto, 'use');
}
this._logger.debug('Patching Koa.use');
const appProto = this._moduleExports.prototype;
shimmer.wrap(appProto, 'use', this._getKoaUsePatch.bind(this));

/**
* Patches the Application.use function in order to instrument each original
return this._moduleExports;
}
protected unpatch(): void {
const appProto = this._moduleExports.prototype;
shimmer.unwrap(appProto, 'use');
}

/**
* Patches the Koa.use function in order to instrument each original
* middleware layer which is introduced
* @param original
*/
private _getAppUsePatch( original: Function )
{
const plugin = this;

private _getKoaUsePatch(original: (middleware: KoaMiddleware) => koa) {
return function use(
this : koa,
middlewareFunction : KoaMiddleware,
...args: Parameters<typeof original>
) {
this: koa,
middlewareFunction: KoaMiddleware,
...args: Parameters<typeof original>
) {
let patchedFunction;
if (middlewareFunction.router) {
patchedFunction = plugin._patchRouterDispatch(middlewareFunction);
} else {
patchedFunction = plugin._patchLayer(middlewareFunction, false);
}

args[0] = patchedFunction;
const res = original.apply(this, args);

return res;

var isRouterDispatch = middlewareFunction.name == "dispatch";
isRouterDispatch = (middlewareFunction as any).router;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any;
}

var patchedFunction;
if (isRouterDispatch) {
patchedFunction = plugin._patchRoutes(middlewareFunction);
} else {
patchedFunction = plugin._patchLayer(middlewareFunction, false);
}
private _patchRouterDispatch(dispatchLayer: KoaMiddleware) {
this._logger.debug('Patching @koa/router dispatch');

args[0] = patchedFunction;
const res = original.apply(this, args);
const router = dispatchLayer.router;

return res;
const routesStack = router?.stack ?? [];
for (let i = 0; i < routesStack.length; i++) {
const pathLayer: Router.Layer = routesStack[i];
const path = pathLayer.path;
const pathStack = pathLayer.stack;
for (let j = 0; j < pathStack.length; j++) {
const routedMiddleware: KoaMiddleware = pathStack[j];
pathStack[j] = this._patchLayer(routedMiddleware, true, path);
}
}

// tslint:disable-next-line:no-any
} as any;

const dispatcher = (context: KoaContext, next: koa.Next) => {
const result = dispatchLayer(context, next);
return result;
};
return dispatcher;
}

private _patchLayer (middlewareLayer: KoaMiddleware, isRouter: boolean, layerPath?: string) : KoaMiddleware {
const plugin = this;
private _patchLayer(
middlewareLayer: KoaMiddleware,
isRouter: boolean,
layerPath?: string
): KoaMiddleware {
if (middlewareLayer[kLayerPatched] === true) return middlewareLayer;
middlewareLayer[kLayerPatched] = true;
this._logger.debug('patching Koa middleware layer');

const patchedLayer = (context: KoaContext, next: koa.Next) => {
if (plugin._tracer.getCurrentSpan() === undefined) {

return middlewareLayer(context, next);
}
const metadata = getMiddlewareMetadata(context, middlewareLayer, isRouter, layerPath);
const span = plugin._tracer.startSpan(metadata.name, {
attributes: metadata.attributes,
});
const startTime = hrTime();

var result = middlewareLayer(context, next);
span.end(startTime);
return result;
}
return patchedLayer;
}


private _patchRoutes (dispatchLayer: KoaMiddleware) {
const plugin = this;

var smth = (dispatchLayer as any);
var router = smth.router as Router;

var routesStack = router.stack;
for (var i = 0; i < routesStack.length; i++) {
var pathLayer : Router.Layer = routesStack[i];
var path = pathLayer.path;
var pathStack = pathLayer.stack;
for (var j = 0; j < pathStack.length; j++) {
var routedMiddleware : KoaMiddleware = pathStack[j];
pathStack[j] = plugin._patchLayer(routedMiddleware, true, path);;
return (context: KoaContext, next: koa.Next) => {
if (this._tracer.getCurrentSpan() === undefined) {
return middlewareLayer(context, next);
}
}

const dispatcher = (context: KoaContext, next: koa.Next) => {
var result = smth(context, next);
const metadata = getMiddlewareMetadata(
context,
middlewareLayer,
isRouter,
layerPath
);
const span = this._tracer.startSpan(metadata.name, {
attributes: metadata.attributes,
});
const startTime = hrTime();

const result = middlewareLayer(context, next);
span.end(startTime);
return result;
}
return dispatcher;
}
};
}
}

export const plugin = new KoaPlugin(KoaPlugin.component);
66 changes: 17 additions & 49 deletions plugins/node/opentelemetry-plugin-koa/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2019, OpenTelemetry Authors
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,63 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Middleware, ParameterizedContext} from 'koa';
import { RouterParamContext} from '@koa/router';
import { Middleware, ParameterizedContext, DefaultState } from 'koa';
import { RouterParamContext } from '@koa/router';
import { kLayerPatched } from './koa';
import Router = require('@koa/router');

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Parameters<T> = T extends (...args: infer T) => any ? T : unknown[];

export type KoaMiddleware = Middleware<any, RouterParamContext> & {[kLayerPatched]?: boolean;};
export type KoaMiddleware = Middleware<DefaultState, KoaContext> & {
[kLayerPatched]?: boolean;
router?: Router;
};

// export type KoaContext = ParameterizedContext<ParameterizedContext<any, DefaultContext>, DefaultContext>;
export type KoaContext = ParameterizedContext<ParameterizedContext<any, any>, any>;
export type KoaContext = ParameterizedContext<DefaultState, RouterParamContext>;

export enum AttributeNames {
COMPONENT = 'component',
HTTP_ROUTE = 'http.route',
// PATH = 'http.path',
// STATUS = 'http.status_code',
// PROTOCOL = 'http.protocol',
// HOST = 'http.host',
// METHOD = 'http.method',
KOA_TYPE = 'koa.type',
KOA_NAME = 'koa.name'
};
COMPONENT = 'component',
HTTP_ROUTE = 'http.route',
KOA_TYPE = 'koa.type',
KOA_NAME = 'koa.name',
}

export enum KoaLayerType {
ROUTER = 'router',
MIDDLEWARE = 'middleware',
}

export const KoaComponentName : string = 'koa';

/*
Argument of type
'Middleware<ParameterizedContext<any, RouterParamContext<any, {}>>>'
is not assignable to parameter of type
'Middleware<ParameterizedContext<ParameterizedContext<any, DefaultContext>, DefaultContext>>'.
Type
'ParameterizedContext<ParameterizedContext<any, DefaultContext>, DefaultContext>'
is not assignable to type
'ParameterizedContext<any, RouterParamContext<any, {}>>'.
Type 'ExtendableContext & { state: ParameterizedContext<any, DefaultContext>; } & DefaultContext' is missing the following properties from type 'RouterParamContext<any, {}>': params, router, _matchedRoute, _matchedRouteNamez
Argument of type
'Middleware<ParameterizedContext<any, RouterParamContext<any, {}>>>'
is not assignable to parameter of type
'Middleware<ParameterizedContext<ParameterizedContext<string, DefaultContext>, DefaultContext>>'.
Type
'ParameterizedContext<ParameterizedContext<string, DefaultContext>, DefaultContext>'
is not assignable to type
'ParameterizedContext<any, RouterParamContext<any, {}>>'.
*/
export const KoaComponentName = 'koa';
Loading

0 comments on commit fe75b18

Please sign in to comment.