Skip to content
Closed
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
113 changes: 54 additions & 59 deletions src/plugins/ExpressPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"use strict";
/*!
*
* Licensed to the Apache Software Foundation (ASF) under one or more
Expand All @@ -16,64 +17,58 @@
* limitations under the License.
*
*/

import SwPlugin from '../core/SwPlugin';
import { ServerResponse } from 'http';
import ContextManager from '../trace/context/ContextManager';
import { Component } from '../trace/Component';
import Tag from '../Tag';
import { ContextCarrier } from '../trace/context/ContextCarrier';
import DummySpan from '../trace/span/DummySpan';
import { ignoreHttpMethodCheck } from '../config/AgentConfig';
import PluginInstaller from '../core/PluginInstaller';
import HttpPlugin from './HttpPlugin';
import { Request } from 'express';

class ExpressPlugin implements SwPlugin {
readonly module = 'express';
readonly versions = '*';

install(installer: PluginInstaller): void {
this.interceptServerRequest(installer);
}

private interceptServerRequest(installer: PluginInstaller) {
const router = installer.require?.('express/lib/router') ?? require('express/lib/router');
const _handle = router.handle;

router.handle = function (req: Request, res: ServerResponse, next: any) {
const carrier = ContextCarrier.from((req as any).headers || {});
const reqMethod = req.method ?? 'GET';
const operation = reqMethod + ':' + (req.originalUrl || req.url || '/').replace(/\?.*/g, '');
const span = ignoreHttpMethodCheck(reqMethod)
? DummySpan.create()
: ContextManager.current.newEntrySpan(operation, carrier, [Component.HTTP_SERVER, Component.EXPRESS]);

span.component = Component.EXPRESS;

if (span.depth)
// if we inherited from http then just change component ID and let http do the work
return _handle.apply(this, arguments);

return HttpPlugin.wrapHttpResponse(span, req, res, () => {
// http plugin disabled, we use its mechanism anyway
try {
return _handle.call(this, req, res, (err: Error) => {
span.error(err);
next.call(this, err);
});
} finally {
// req.protocol is only possibly available after call to _handle()
span.tag(
Tag.httpURL(
((req as any).protocol ? (req as any).protocol + '://' : '') + (req.headers.host || '') + req.url,
),
);
}
});
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var ContextManager_1 = tslib_1.__importDefault(require("../trace/context/ContextManager"));
var Component_1 = require("../trace/Component");
var Tag_1 = tslib_1.__importDefault(require("../Tag"));
var ContextCarrier_1 = require("../trace/context/ContextCarrier");
var DummySpan_1 = tslib_1.__importDefault(require("../trace/span/DummySpan"));
var AgentConfig_1 = require("../config/AgentConfig");
var HttpPlugin_1 = tslib_1.__importDefault(require("./HttpPlugin"));
var ExpressPlugin = /** @class */ (function () {
function ExpressPlugin() {
this.module = 'express';
this.versions = '*';
}
ExpressPlugin.prototype.install = function (installer) {
this.interceptServerRequest(installer);
};
}
}

ExpressPlugin.prototype.interceptServerRequest = function (installer) {
var _a, _b;
var express = require('express');
var router = express.Router ? express.Router() : require('express/lib/router');
var _handle = router.handle;
router.handle = function (req, res, next) {
var _this = this;
var _a;
var carrier = ContextCarrier_1.ContextCarrier.from(req.headers || {});
var reqMethod = (_a = req.method) !== null && _a !== void 0 ? _a : 'GET';
var operation = reqMethod + ':' + (req.originalUrl || req.url || '/').replace(/\?.*/g, '');
var span = AgentConfig_1.ignoreHttpMethodCheck(reqMethod)
? DummySpan_1.default.create()
: ContextManager_1.default.current.newEntrySpan(operation, carrier, [Component_1.Component.HTTP_SERVER, Component_1.Component.EXPRESS]);
span.component = Component_1.Component.EXPRESS;
if (span.depth)
// if we inherited from http then just change component ID and let http do the work
return _handle.apply(this, arguments);
return HttpPlugin_1.default.wrapHttpResponse(span, req, res, function () {
// http plugin disabled, we use its mechanism anyway
try {
return _handle.call(_this, req, res, function (err) {
span.error(err);
next.call(_this, err);
});
}
finally {
// req.protocol is only possibly available after call to _handle()
span.tag(Tag_1.default.httpURL((req.protocol ? req.protocol + '://' : '') + (req.headers.host || '') + req.url));
}
});
};
};
return ExpressPlugin;
}());
// noinspection JSUnusedGlobalSymbols
export default new ExpressPlugin();
exports.default = new ExpressPlugin();
//# sourceMappingURL=ExpressPlugin.js.map