Skip to content
This repository was archived by the owner on Jan 21, 2026. It is now read-only.

Commit 497c760

Browse files
authored
fix: enable tracing on original client method names (#874)
1 parent 23a0616 commit 497c760

3 files changed

Lines changed: 50 additions & 13 deletions

File tree

src/plugins/plugin-grpc.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type Metadata = grpcModule.Metadata&{
2929
type MetadataModule = typeof grpcModule.Metadata;
3030
// Type of makeClientConstructor as exported from client.js
3131
type MakeClientConstructorFunction =
32-
(methods: {[key: string]: never;}, serviceName: string,
32+
(methods: {[key: string]: {originalName?: string;};}, serviceName: string,
3333
classOptions: never) => typeof Client;
3434
// Meta-type of client-side handlers
3535
type ClientMethod<S, T> = ((typeof Client.prototype.makeUnaryRequest)|
@@ -265,8 +265,16 @@ function patchClient(client: ClientModule, api: Tracer) {
265265
// Client is a class.
266266
// tslint:disable-next-line:variable-name
267267
const Client = makeClientConstructor.apply(this, arguments);
268-
shimmer.massWrap(
269-
[Client.prototype], Object.keys(methods), makeClientMethod);
268+
const methodsToWrap = [
269+
...Object.keys(methods),
270+
...Object.keys(methods)
271+
.map(methodName => methods[methodName].originalName)
272+
.filter(
273+
originalName => !!originalName &&
274+
Client.prototype.hasOwnProperty(originalName)) as
275+
string[]
276+
];
277+
shimmer.massWrap([Client.prototype], methodsToWrap, makeClientMethod);
270278
return Client;
271279
};
272280
}

test/plugins/common.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ if (semver.satisfies(process.version, '>=8')) {
3030
// Monkeypatch Mocha's it() to create a fresh context with each test case.
3131
var oldIt = global.it;
3232
global.it = Object.assign(function it(title, fn) {
33+
// it.skip calls it without a function argument
34+
if (!fn) {
35+
return oldIt.call(this, title);
36+
}
3337
function wrappedFn() {
3438
if (cls.exists()) {
3539
return cls.get().runWithContext(() => fn.apply(this, arguments), TraceCLS.UNCORRELATED);

test/plugins/test-trace-grpc.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ Object.keys(versions).forEach(function(version) {
278278
var client;
279279
var shouldTraceArgs: any[] = [];
280280
describe(version, function() {
281+
const skipFor1_6 = version === 'grpc1_6' ? it.skip : it;
282+
281283
before(function() {
282284
// Set up to record invocations of shouldTrace
283285
shimmer.wrap(TracingPolicy, 'createTracePolicy', function(original) {
@@ -356,16 +358,6 @@ Object.keys(versions).forEach(function(version) {
356358
});
357359
});
358360

359-
it('should propagate context', function(done) {
360-
common.runInTransaction(function(endTransaction) {
361-
callUnary(client, grpc, {}, function() {
362-
assert.ok(common.hasContext());
363-
endTransaction();
364-
done();
365-
});
366-
});
367-
});
368-
369361
it('should accurately measure time for client streaming requests', function(done) {
370362
var start = Date.now();
371363
common.runInTransaction(function(endTransaction) {
@@ -431,6 +423,39 @@ Object.keys(versions).forEach(function(version) {
431423
});
432424
});
433425

426+
// Older versions of gRPC (<1.7) do not add original names.
427+
skipFor1_6('should trace client requests using the original method name', (done) => {
428+
common.runInTransaction((endTransaction) => {
429+
// The original method name is TestUnary.
430+
client.TestUnary({n: 10}, (err, result) => {
431+
assert.ifError(err);
432+
assert.strictEqual(result.n, 10);
433+
endTransaction();
434+
var assertTraceProperties = function(predicate) {
435+
var trace = common.getMatchingSpan(predicate);
436+
assert.ok(trace);
437+
assert.strictEqual(trace.labels.argument, '{"n":10}');
438+
assert.strictEqual(trace.labels.result, '{"n":10}');
439+
};
440+
assertTraceProperties(grpcClientPredicate);
441+
assertTraceProperties(grpcServerOuterPredicate);
442+
// Check that a child span was created in gRPC root span
443+
assert.ok(common.getMatchingSpan(grpcServerInnerPredicate));
444+
done();
445+
});
446+
});
447+
});
448+
449+
it('should propagate context', function(done) {
450+
common.runInTransaction(function(endTransaction) {
451+
callUnary(client, grpc, {}, function() {
452+
assert.ok(common.hasContext());
453+
endTransaction();
454+
done();
455+
});
456+
});
457+
});
458+
434459
it('should not break if no parent transaction', function(done) {
435460
callUnary(client, grpc, {}, function() {
436461
assert.strictEqual(common.getMatchingSpans(grpcClientPredicate).length, 0);

0 commit comments

Comments
 (0)