Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit cae7ff8

Browse files
authored
refactor: privatize non-user-facing methods (#40)
1 parent 09d4cf5 commit cae7ff8

8 files changed

Lines changed: 144 additions & 122 deletions

File tree

packages/opencensus-instrumentation-http/src/http.ts

Lines changed: 102 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,21 @@ export class HttpPlugin extends classes.BasePlugin {
6565

6666
this.logger.debug('applying pacth to %s@%s', this.moduleName, this.version);
6767

68-
shimmer.wrap(moduleExports, 'request', this.patchOutgoingRequest());
68+
shimmer.wrap(
69+
moduleExports, 'request', this.getPatchOutgoingRequestFunction());
6970

7071
// In Node 8, http.get calls a private request method, therefore we patch it
7172
// here too.
7273
if (semver.satisfies(version, '>=8.0.0')) {
73-
shimmer.wrap(moduleExports, 'get', this.patchOutgoingRequest());
74+
shimmer.wrap(
75+
moduleExports, 'get', this.getPatchOutgoingRequestFunction());
7476
}
7577

7678
if (moduleExports && moduleExports.Server &&
7779
moduleExports.Server.prototype) {
7880
shimmer.wrap(
79-
moduleExports && moduleExports.Server &&
80-
moduleExports.Server.prototype,
81-
'emit' as never, this.patchIncomingRequest());
81+
moduleExports.Server.prototype, 'emit',
82+
this.getPatchIncomingRequestFunction());
8283
} else {
8384
this.logger.error(
8485
'Could not apply patch to %s.emit. Interface is not as expected.',
@@ -97,95 +98,96 @@ export class HttpPlugin extends classes.BasePlugin {
9798
}
9899
if (this.moduleExports && this.moduleExports.Server &&
99100
this.moduleExports.Server.prototype) {
100-
shimmer.unwrap(
101-
this.moduleExports && this.moduleExports.Server &&
102-
this.moduleExports.Server.prototype,
103-
'emit');
101+
shimmer.unwrap(this.moduleExports.Server.prototype, 'emit');
104102
}
105103
}
106104

107105

108106
/**
109107
* Creates spans for incoming requests, restoring spans' context if applied.
110108
*/
111-
protected patchIncomingRequest() {
112-
return (original: RequestFunction) => {
109+
protected getPatchIncomingRequestFunction() {
110+
return (original: (event: string) => boolean) => {
113111
const plugin = this;
114-
return function incomingRequest(
115-
event: string, request: httpModule.IncomingMessage,
116-
response: httpModule.ServerResponse):
117-
httpModule.ClientRequest {
118-
// Only traces request events
119-
if (event !== 'request') {
120-
return original.apply(this, arguments);
121-
}
122-
123-
plugin.logger.debug('%s plugin incomingRequest', plugin.moduleName);
124-
const propagation = plugin.tracer.propagation;
125-
const headers = request.headers;
126-
const getter: types.HeaderGetter = {
127-
getHeader(name: string) {
128-
return headers[name];
129-
}
130-
};
131-
132-
const traceOptions = {
133-
name: url.parse(request.url).pathname,
134-
type: 'SERVER',
135-
spanContext: propagation ? propagation.extract(getter) : null
136-
};
137-
138-
return plugin.tracer.startRootSpan(traceOptions, rootSpan => {
139-
if (!rootSpan) return original.apply(this, arguments);
140-
141-
plugin.tracer.wrapEmitter(request);
142-
plugin.tracer.wrapEmitter(response);
143-
144-
// Wraps end (inspired by:
145-
// https://github.com/GoogleCloudPlatform/cloud-trace-nodejs/blob/master/src/plugins/plugin-connect.ts#L75)
146-
const originalEnd = response.end;
147-
148-
response.end = function(this: httpModule.ServerResponse) {
149-
response.end = originalEnd;
150-
const returned = response.end.apply(this, arguments);
151-
152-
const requestUrl = url.parse(request.url);
153-
const host = headers.host || 'localhost';
154-
const userAgent =
155-
(headers['user-agent'] || headers['User-Agent']) as string;
156-
157-
rootSpan.addAttribute(
158-
HttpPlugin.ATTRIBUTE_HTTP_HOST,
159-
host.replace(
160-
/^(.*)(\:[0-9]{1,5})/,
161-
'$1',
162-
));
163-
rootSpan.addAttribute(
164-
HttpPlugin.ATTRIBUTE_HTTP_METHOD, request.method);
165-
rootSpan.addAttribute(
166-
HttpPlugin.ATTRIBUTE_HTTP_PATH, requestUrl.pathname);
167-
rootSpan.addAttribute(
168-
HttpPlugin.ATTRIBUTE_HTTP_ROUTE, requestUrl.path);
169-
rootSpan.addAttribute(
170-
HttpPlugin.ATTRIBUTE_HTTP_USER_AGENT, userAgent);
171-
172-
rootSpan.addAttribute(
173-
HttpPlugin.ATTRIBUTE_HTTP_STATUS_CODE,
174-
response.statusCode.toString());
175-
176-
rootSpan.status = plugin.traceStatus(response.statusCode);
177-
178-
// Message Event ID is not defined
179-
rootSpan.addMessageEvent(
180-
'MessageEventTypeRecv', uuid.v4().split('-').join(''));
181-
182-
rootSpan.end();
183-
return returned;
184-
};
185-
186-
return original.apply(this, arguments);
187-
});
112+
// This function's signature is that of an event listener, which can have
113+
// any number of variable-type arguments.
114+
// tslint:disable-next-line:no-any
115+
return function incomingRequest(event: string, ...args: any[]): boolean {
116+
// Only traces request events
117+
if (event !== 'request') {
118+
return original.apply(this, arguments);
119+
}
120+
121+
const request: httpModule.IncomingMessage = args[0];
122+
const response: httpModule.ServerResponse = args[1];
123+
124+
plugin.logger.debug('%s plugin incomingRequest', plugin.moduleName);
125+
const propagation = plugin.tracer.propagation;
126+
const headers = request.headers;
127+
const getter: types.HeaderGetter = {
128+
getHeader(name: string) {
129+
return headers[name];
130+
}
131+
};
132+
133+
const traceOptions = {
134+
name: url.parse(request.url).pathname,
135+
type: 'SERVER',
136+
spanContext: propagation ? propagation.extract(getter) : null
137+
};
138+
139+
return plugin.tracer.startRootSpan(traceOptions, rootSpan => {
140+
if (!rootSpan) return original.apply(this, arguments);
141+
142+
plugin.tracer.wrapEmitter(request);
143+
plugin.tracer.wrapEmitter(response);
144+
145+
// Wraps end (inspired by:
146+
// https://github.com/GoogleCloudPlatform/cloud-trace-nodejs/blob/master/src/plugins/plugin-connect.ts#L75)
147+
const originalEnd = response.end;
148+
149+
response.end = function(this: httpModule.ServerResponse) {
150+
response.end = originalEnd;
151+
const returned = response.end.apply(this, arguments);
152+
153+
const requestUrl = url.parse(request.url);
154+
const host = headers.host || 'localhost';
155+
const userAgent =
156+
(headers['user-agent'] || headers['User-Agent']) as string;
157+
158+
rootSpan.addAttribute(
159+
HttpPlugin.ATTRIBUTE_HTTP_HOST,
160+
host.replace(
161+
/^(.*)(\:[0-9]{1,5})/,
162+
'$1',
163+
));
164+
rootSpan.addAttribute(
165+
HttpPlugin.ATTRIBUTE_HTTP_METHOD, request.method);
166+
rootSpan.addAttribute(
167+
HttpPlugin.ATTRIBUTE_HTTP_PATH, requestUrl.pathname);
168+
rootSpan.addAttribute(
169+
HttpPlugin.ATTRIBUTE_HTTP_ROUTE, requestUrl.path);
170+
rootSpan.addAttribute(
171+
HttpPlugin.ATTRIBUTE_HTTP_USER_AGENT, userAgent);
172+
173+
rootSpan.addAttribute(
174+
HttpPlugin.ATTRIBUTE_HTTP_STATUS_CODE,
175+
response.statusCode.toString());
176+
177+
rootSpan.status =
178+
HttpPlugin.convertTraceStatus(response.statusCode);
179+
180+
// Message Event ID is not defined
181+
rootSpan.addMessageEvent(
182+
'MessageEventTypeRecv', uuid.v4().split('-').join(''));
183+
184+
rootSpan.end();
185+
return returned;
188186
};
187+
188+
return original.apply(this, arguments);
189+
});
190+
};
189191
};
190192
}
191193

@@ -194,7 +196,7 @@ export class HttpPlugin extends classes.BasePlugin {
194196
* Creates spans for outgoing requests, sending spans' context for distributed
195197
* tracing.
196198
*/
197-
protected patchOutgoingRequest() {
199+
protected getPatchOutgoingRequestFunction() {
198200
return (original: types.Func<httpModule.ClientRequest>):
199201
types.Func<httpModule.ClientRequest> => {
200202
const plugin = this;
@@ -237,12 +239,14 @@ export class HttpPlugin extends classes.BasePlugin {
237239
if (!plugin.tracer.currentRootSpan) {
238240
plugin.logger.debug('outgoingRequest starting a root span');
239241
return plugin.tracer.startRootSpan(
240-
traceOptions, plugin.makeRequestTrace(request, options, plugin));
242+
traceOptions,
243+
plugin.getMakeRequestTraceFunction(request, options, plugin));
241244
} else {
242245
plugin.logger.debug('outgoingRequest starting a child span');
243246
const span = plugin.tracer.startChildSpan(
244247
traceOptions.name, traceOptions.type);
245-
return (plugin.makeRequestTrace(request, options, plugin))(span);
248+
return (plugin.getMakeRequestTraceFunction(request, options, plugin))(
249+
span);
246250
}
247251
};
248252
};
@@ -254,7 +258,7 @@ export class HttpPlugin extends classes.BasePlugin {
254258
* @param original The original patched function.
255259
* @param options The arguments to the original function.
256260
*/
257-
private makeRequestTrace(
261+
private getMakeRequestTraceFunction(
258262
// tslint:disable-next-line:no-any
259263
request: httpModule.ClientRequest, options: httpModule.RequestOptions,
260264
plugin: HttpPlugin): types.Func<httpModule.ClientRequest> {
@@ -300,7 +304,7 @@ export class HttpPlugin extends classes.BasePlugin {
300304
HttpPlugin.ATTRIBUTE_HTTP_STATUS_CODE,
301305
response.statusCode.toString());
302306

303-
span.status = plugin.traceStatus(response.statusCode);
307+
span.status = HttpPlugin.convertTraceStatus(response.statusCode);
304308

305309
// Message Event ID is not defined
306310
span.addMessageEvent(
@@ -323,7 +327,11 @@ export class HttpPlugin extends classes.BasePlugin {
323327
};
324328
}
325329

326-
traceStatus(statusCode: number): number {
330+
/**
331+
* Converts an HTTP status code to an OpenCensus Trace status code.
332+
* @param statusCode The HTTP status code to convert.
333+
*/
334+
static convertTraceStatus(statusCode: number): number {
327335
if (statusCode < 200 || statusCode > 504) {
328336
return TraceStatusCodes.UNKNOWN;
329337
} else if (statusCode >= 200 && statusCode < 400) {
@@ -353,6 +361,9 @@ export class HttpPlugin extends classes.BasePlugin {
353361
}
354362
}
355363

364+
/**
365+
* An enumeration of OpenCensus Trace status codes.
366+
*/
356367
export enum TraceStatusCodes {
357368
UNKNOWN = 2,
358369
OK = 0,

packages/opencensus-instrumentation-http/test/test-http.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ class RootSpanVerifier implements types.SpanEventListener {
6868
function assertSpanAttributes(
6969
span: types.Span, httpStatusCode: number, httpMethod: string,
7070
hostName: string, path: string, userAgent: string) {
71-
assert.strictEqual(span.status, plugin.traceStatus(httpStatusCode));
71+
assert.strictEqual(
72+
span.status, HttpPlugin.convertTraceStatus(httpStatusCode));
7273
assert.strictEqual(span.attributes[HttpPlugin.ATTRIBUTE_HTTP_HOST], hostName);
7374
assert.strictEqual(
7475
span.attributes[HttpPlugin.ATTRIBUTE_HTTP_METHOD], httpMethod);

packages/opencensus-instrumentation-http2/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)