/Nestjs-OpenTelemetry

🔭 OpenTelemetry for Nestjs

Primary LanguageTypeScriptMIT LicenseMIT

NestJS OpenTelemetry logo

NestJS OpenTelemetry

This library provides OpenTelemetry SDK for Nestjs environment, TraceId injection, custom Span decorator, Logger and etc.

🚀 Installation

npm install @metinseylan/nestjs-opentelemetry --save

💾 Example Module Setup

According to your setup, dependencies may be different

npm install --save \
  @opentelemetry/instrumentation-http \
  @opentelemetry/context-async-hooks \
  @opentelemetry/propagator-b3 \
  @opentelemetry/tracing \
  @opentelemetry/exporter-zipkin \

Module should be imported to main nestjs module. Register method accepts OpenTelemetry NodeSDK configuration

OpenTelemetryModule.register({
  spanProcessor: new BatchSpanProcessor(
    new ZipkinExporter({ serviceName: 'MAVI_VATAN' }),
  ),
  contextManager: new AsyncLocalStorageContextManager(),
  textMapPropagator: new CompositePropagator({
    propagators: [
      new B3Propagator(),
      new B3Propagator({
        injectEncoding: B3InjectEncoding.MULTI_HEADER,
      }),
    ],
  }),
  instrumentations: [new HttpInstrumentation()],
});

🧐 Logging with TraceId

After module setup you can use LoggerService, it provides trace id with every logging like this

import { LoggerService } from '@metinseylan/nestjs-opentelemetry';

this.loggerService.log(
    'hello its firs logging with trace id',
    'AppService',
);

Logging with opentelemetry trace id

🥫 Span Decorator

If you need, you can define a custom Tracing Span for a method. It works async or normally. Span takes its name from the parameter; but by default, it is the same as the method's name

import { Span } from '@metinseylan/nestjs-opentelemetry';

@Span('CRITICAL_SECTION')
async getHello() {
    return 'Hello World!';
}

📬 Tracing Service

Sometimes you need to access native span methods for special logics in the method block. At that moment, Trace Service comes to help

@Injectable()
export class AppService {
  constructor(private readonly traceService: TraceService) {}

  @Span()
  async getHello() {
    const currentSpan = this.traceService.getSpan(); // --> retrives current span, comes from http or @Span
    await this.doSomething();
    currentSpan.addEvent('some event');
    currentSpan.end(); // current span end
    
    const span = this.traceService.startSpan('sub_span'); // start new span
    span.setAttributes({ userId: 1 });
    await this.blueHomeland();
    span.end(); // new span ends
    return 'Hello World!';
  }
}

final resuls in zipkin server looks like this

Nestjs opentelemetry zipkin result