Skip to content

Commit

Permalink
Merge pull request #33 from peternewnham/fix-span-parent-ids
Browse files Browse the repository at this point in the history
fix: spans not taking the parentId of their parent
  • Loading branch information
MetinSeylan authored Apr 5, 2022
2 parents 01065d6 + 3f13a97 commit aeaf325
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
16 changes: 7 additions & 9 deletions src/Trace/Injectors/BaseTraceInjector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,30 @@ export class BaseTraceInjector {
const method = {
[prototype.name]: function (...args: any[]) {
const tracer = trace.getTracer('default');
const currentSpan =
trace.getSpan(context.active()) ?? tracer.startSpan('default');
const currentSpan = tracer.startSpan(traceName);

return context.with(
trace.setSpan(context.active(), currentSpan),
() => {
const span = tracer.startSpan(traceName);
span.setAttributes(attributes);
currentSpan.setAttributes(attributes);
if (prototype.constructor.name === 'AsyncFunction') {
return prototype
.apply(this, args)
.catch((error) =>
BaseTraceInjector.recordException(error, span),
BaseTraceInjector.recordException(error, currentSpan),
)
.finally(() => {
span.end();
currentSpan.end();
});
} else {
try {
const result = prototype.apply(this, args);
span.end();
currentSpan.end();
return result;
} catch (error) {
BaseTraceInjector.recordException(error, span);
BaseTraceInjector.recordException(error, currentSpan);
} finally {
span.end();
currentSpan.end();
}
}
},
Expand Down
63 changes: 63 additions & 0 deletions src/Trace/Tests/BaseTraceInjectorTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Test } from '@nestjs/testing';
import { OpenTelemetryModule } from '../../OpenTelemetryModule';
import { NoopSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { Controller, Get, Injectable } from '@nestjs/common';
import { Span } from '../Decorators/Span';
import * as request from 'supertest';
import { ControllerInjector } from '../Injectors/ControllerInjector';

describe('Base Trace Injector Test', () => {
const exporter = new NoopSpanProcessor();
const exporterSpy = jest.spyOn(exporter, 'onStart');

const sdkModule = OpenTelemetryModule.forRoot({
spanProcessor: exporter,
traceAutoInjectors: [ControllerInjector],
});

beforeEach(() => {
exporterSpy.mockClear();
exporterSpy.mockReset();
});

it('should create spans that inherit the ids of their parents', async () => {
// given
@Injectable()
class HelloService {
@Span()
hello() {
this.helloAgain();
}
@Span()
helloAgain() {} // eslint-disable-line @typescript-eslint/no-empty-function
}

@Controller('hello')
class HelloController {
constructor(private service: HelloService) {}
@Get()
hi() {
return this.service.hello();
}
}

const context = await Test.createTestingModule({
imports: [sdkModule],
providers: [HelloService],
controllers: [HelloController],
}).compile();
const app = context.createNestApplication();
await app.init();

//when
await request(app.getHttpServer()).get('/hello').send().expect(200);

//then
const [[parent], [childOfParent], [childOfChild]] = exporterSpy.mock.calls;
expect(parent.parentSpanId).toBeUndefined();
expect(childOfParent.parentSpanId).toBe(parent.spanContext().spanId);
expect(childOfChild.parentSpanId).toBe(childOfParent.spanContext().spanId);

await app.close();
});
});

0 comments on commit aeaf325

Please sign in to comment.