You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2020/07/26 03:51:32 UTC
[skywalking-nodejs] 07/23: Enhance http plugin and add validation
of carrier
This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-nodejs.git
commit f34f4be8f5e66951bb662daf3d7dec35c16af595
Author: kezhenxu94 <ke...@163.com>
AuthorDate: Tue Jun 23 20:55:06 2020 +0800
Enhance http plugin and add validation of carrier
---
src/core/PluginInstaller.ts | 2 +-
src/logging/index.ts | 21 +++++++++-------
src/plugins/HttpPlugin.ts | 50 ++++++++++++++++++++-----------------
src/trace/context/ContextCarrier.ts | 11 ++++++++
src/trace/context/SpanContext.ts | 7 +++---
src/tsconfig.json | 3 ++-
6 files changed, 56 insertions(+), 38 deletions(-)
diff --git a/src/core/PluginInstaller.ts b/src/core/PluginInstaller.ts
index 301849b..6ac4e08 100644
--- a/src/core/PluginInstaller.ts
+++ b/src/core/PluginInstaller.ts
@@ -33,7 +33,7 @@ class PluginInstaller {
install(): void {
fs.readdirSync(this.pluginDir)
- .filter((file) => !file.endsWith('.d.ts'))
+ .filter((file) => file.endsWith('.js'))
.forEach((file) => {
const plugin = require(path.join(this.pluginDir, file)).default as SwPlugin;
logger.info(`Installing plugin ${plugin.module} ${plugin.versions}`);
diff --git a/src/logging/index.ts b/src/logging/index.ts
index a779cfe..63fa15f 100644
--- a/src/logging/index.ts
+++ b/src/logging/index.ts
@@ -26,8 +26,7 @@ type LoggerLevelAware = Logger & {
};
export function createLogger(name: string): LoggerLevelAware {
- const loggingLevel = process.env.LOGGING_LEVEL
- || (process.env.NODE_ENV !== 'production' ? 'debug' : 'info');
+ const loggingLevel = process.env.LOGGING_LEVEL || (process.env.NODE_ENV !== 'production' ? 'debug' : 'info');
const logger = winston.createLogger({
level: loggingLevel,
@@ -36,14 +35,18 @@ export function createLogger(name: string): LoggerLevelAware {
file: name,
},
});
- if (process.env.NODE_ENV !== 'production') {
- logger.add(new winston.transports.Console({
- format: winston.format.prettyPrint(),
- }));
+ if (process.env.NODE_ENV !== 'production' || process.env.LOGGING_TARGET === 'console') {
+ logger.add(
+ new winston.transports.Console({
+ format: winston.format.prettyPrint(),
+ }),
+ );
} else {
- logger.add(new winston.transports.File({
- filename: 'skywalking.log',
- }));
+ logger.add(
+ new winston.transports.File({
+ filename: 'skywalking.log',
+ }),
+ );
}
const isDebugEnabled = (): boolean => logger.levels[logger.level] > logger.levels.debug;
diff --git a/src/plugins/HttpPlugin.ts b/src/plugins/HttpPlugin.ts
index 246f546..ce60d27 100644
--- a/src/plugins/HttpPlugin.ts
+++ b/src/plugins/HttpPlugin.ts
@@ -25,13 +25,16 @@ import { Component } from '../trace/Component';
import Tag from '../Tag';
import { SpanLayer } from '../proto/language-agent/Tracing_pb';
import { ContextCarrier } from '../trace/context/ContextCarrier';
+import { createLogger } from '../logging';
type RequestFunctionType = (
- url: string | URL,
+ url: string | URL | RequestOptions,
options: RequestOptions,
callback?: (res: IncomingMessage) => void,
) => ClientRequest;
+const logger = createLogger(__filename);
+
class HttpPlugin implements SwPlugin {
readonly module = 'http';
readonly versions = '';
@@ -41,10 +44,12 @@ class HttpPlugin implements SwPlugin {
const http = require('http');
- (original => {
- http.Server.prototype.emit = function(event: string | symbol, ...args: any[]): boolean {
+ ((original) => {
+ http.Server.prototype.emit = function (event: string | symbol, ...args: any[]): boolean {
+ logger.debug('Intercepting http.Server.prototype.emit');
if (event === 'request') {
if (!(args[0] instanceof IncomingMessage) && !(args[1] instanceof ServerResponse)) {
+ logger.debug('args[0] is not IncomingMessage or args[1] is not ServerResponse');
return original.apply(this, arguments);
}
const req = args[0] as IncomingMessage;
@@ -58,7 +63,7 @@ class HttpPlugin implements SwPlugin {
}
const carrier = new ContextCarrier();
- carrier.items.forEach(item => {
+ carrier.items.forEach((item) => {
if (headersMap.hasOwnProperty(item.key)) {
item.value = headersMap[item.key];
}
@@ -70,10 +75,7 @@ class HttpPlugin implements SwPlugin {
span.layer = SpanLayer.HTTP;
res.on('finish', () => {
- span
- .tag(Tag.httpStatusCode(res.statusCode))
- .tag(Tag.httpStatusMsg(res.statusMessage))
- .stop();
+ span.tag(Tag.httpStatusCode(res.statusCode)).tag(Tag.httpStatusMsg(res.statusMessage)).stop();
});
}
return original.apply(this, arguments);
@@ -93,14 +95,21 @@ class HttpPlugin implements SwPlugin {
private wrapHttpClientRequest(originalRequest: RequestFunctionType): RequestFunctionType {
return (
- url: string | URL,
+ url: string | URL | RequestOptions,
options: RequestOptions,
callback?: (res: IncomingMessage) => void,
): ClientRequest => {
- const {
- host: peer,
- pathname: operation,
- } = url instanceof URL ? url : new URL(url);
+ logger.debug(`url is ${typeof url}: ${url}`);
+
+ const { host: peer, pathname: operation } =
+ url instanceof URL
+ ? url
+ : typeof url === 'string'
+ ? new URL(url)
+ : {
+ host: url.host || url.hostname || 'unknown',
+ pathname: url.path || '/',
+ };
const span = ContextManager.current.newExitSpan(operation, peer).start();
span.component = Component.HTTP;
@@ -108,10 +117,8 @@ class HttpPlugin implements SwPlugin {
const snapshot = ContextManager.current.capture();
- const request = originalRequest(url, options, res => {
- span
- .tag(Tag.httpStatusCode(res.statusCode))
- .tag(Tag.httpStatusMsg(res.statusMessage));
+ const request = originalRequest(url, options, (res) => {
+ span.tag(Tag.httpStatusCode(res.statusCode)).tag(Tag.httpStatusMsg(res.statusMessage));
const callbackSpan = ContextManager.current.newLocalSpan('callback').start();
callbackSpan.layer = SpanLayer.HTTP;
@@ -126,12 +133,9 @@ class HttpPlugin implements SwPlugin {
callbackSpan.stop();
});
- span
- .extract()
- .items
- .forEach(item => {
- request.setHeader(item.key, item.value);
- });
+ span.extract().items.forEach((item) => {
+ request.setHeader(item.key, item.value);
+ });
span.stop();
diff --git a/src/trace/context/ContextCarrier.ts b/src/trace/context/ContextCarrier.ts
index 466db95..684ccf3 100644
--- a/src/trace/context/ContextCarrier.ts
+++ b/src/trace/context/ContextCarrier.ts
@@ -66,4 +66,15 @@ export class ContextCarrier extends CarrierItem {
this.endpoint = this.decode(parts[6]);
this.clientAddress = this.decode(parts[7]);
}
+
+ isValid(): boolean {
+ return (
+ this.traceId !== undefined &&
+ this.segmentId !== undefined &&
+ this.spanId !== undefined &&
+ this.service !== undefined &&
+ this.endpoint !== undefined &&
+ this.clientAddress !== undefined
+ );
+ }
}
diff --git a/src/trace/context/SpanContext.ts b/src/trace/context/SpanContext.ts
index e53a24a..55131e0 100644
--- a/src/trace/context/SpanContext.ts
+++ b/src/trace/context/SpanContext.ts
@@ -38,8 +38,7 @@ export default class SpanContext implements Context {
spans: Span[] = [];
segment: Segment = new Segment();
- constructor(public asyncId: number) {
- }
+ constructor(public asyncId: number) {}
get parent(): Span | null {
if (this.spans.length > 0) {
@@ -67,7 +66,7 @@ export default class SpanContext implements Context {
operation,
});
- if (carrier) {
+ if (carrier && carrier.isValid()) {
span.inject(carrier);
}
@@ -107,7 +106,7 @@ export default class SpanContext implements Context {
}
start(span: Span): Context {
- if (this.spans.every(s => s.id !== span.id)) {
+ if (this.spans.every((s) => s.id !== span.id)) {
this.spans.push(span);
}
diff --git a/src/tsconfig.json b/src/tsconfig.json
index fe65fba..c362071 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -13,7 +13,8 @@
"baseUrl": ".",
"resolveJsonModule": true,
"declaration": true,
- "allowJs": true
+ "allowJs": true,
+ "sourceMap": true
},
"references": [
{