Code Monkey home page Code Monkey logo

nestjs-otel's Introduction

Nest Logo

NestJS OpenTelemetry (OTEL)

Build Status NPM

Description

OpenTelemetry module for Nest.

Why

Setting up observability metrics with nestjs requires multiple libraries and patterns. OpenTelemetry has support for multiple exporters and types of metrics such as Prometheus Metrics.

Installation

$ npm i nestjs-otel --save

Setup

Some peers dependencies are required when some configurations are enabled.

@opentelemetry/exporter-prometheus
@opentelemetry/host-metrics
@opentelemetry/metrics
opentelemetry-node-metrics

nodeSDKConfiguration property accepts OpenTelemetry NodeSDK configuration.

const OpenTelemetryModuleConfig = OpenTelemetryModule.forRoot({
  metrics: {
    hostMetrics: true, // Includes Host Metrics
    defaultMetrics: true, // Includes Default Metrics
    apiMetrics: {
      enable: true, // Includes api metrics
      timeBuckets: [],
    },
  },
  nodeSDKConfiguration: {
    metricExporter: new PrometheusExporter({
      port: 8081,
    }),
    spanProcessor: new BatchSpanProcessor(new JaegerExporter()),
    contextManager: new AsyncLocalStorageContextManager(),
    textMapPropagator: new CompositePropagator({
      propagators: [
        new JaegerPropagator(),
        new HttpTraceContextPropagator(),
        new HttpBaggagePropagator(),
        new B3Propagator(),
        new B3Propagator({
          injectEncoding: B3InjectEncoding.MULTI_HEADER,
        }),
      ],
    }),
    instrumentations: [getNodeAutoInstrumentations()],
  },
});

@Module({
  imports: [
    OpenTelemetryModuleConfig,
  ],
})
export class AppModule {}

Span Decorator

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

import { Span } from 'nestjs-otel';

@Span('CRITICAL_SECTION')
async getBooks() {
    return [`Harry Potter and the Philosopher's Stone`];
}

Tracing Service

In case you need to access native span methods for special logics in the method block:

import { TraceService } from 'nestjs-otel';

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

  @Span()
  async getBooks() {
    const currentSpan = this.traceService.getSpan(); // --> retrives current span, comes from http or @Span
    await this.doSomething();
    currentSpan.addEvent('event 1');
    currentSpan.end(); // current span end

    const span = this.traceService.startSpan('sub_span'); // start new span
    span.setAttributes({ userId: 1 });
    await this.doSomethingElse();
    span.end(); // new span ends
    return [`Harry Potter and the Philosopher's Stone`];
  }
}

Metric Service

OpenTelemetry Metrics allow a user to collect data and export it to metrics backend like Prometheus.

import { MetricService } from 'nestjs-otel';
import { Counter } from '@opentelemetry/api-metrics';

@Injectable()
export class BookService {
  private customMetricCounter: Counter;

  constructor(private readonly metricService: MetricService) {
    this.customMetricCounter = this.metricService.getCounter('custom_counter', {
      description: 'Description for counter',
    });
  }

  async getBooks() {
    this.customMetricCounter.add(1);
    return [`Harry Potter and the Philosopher's Stone`];
  }
}

API Metrics with Middleware

Impl Metric Description Labels Metric Type
โœ… http_request_total Total number of HTTP requests. method, path Counter
โœ… http_response_total Total number of HTTP responses. method, status, path Counter
โœ… http_response_success_total Total number of all successful responses. - Counter
โœ… http_response_error_total Total number of all response errors. - Counter
โœ… http_request_duration_seconds HTTP latency value recorder in seconds. method, status, path ValueRecorder
โœ… http_client_error_total Total number of client error requests. - Counter
โœ… http_server_error_total Total number of server error requests. - Counter
http_server_aborts_total Total number of data transfers aborted by the client. - Counter
http_client_aborts_total Total number of data transfers aborted by the server. - Counter
http_connection_error_total Total of connection errors. - Counter
http_request_size_bytes Current total of incoming bytes. - ValueRecorder
http_response_size_bytes Current total of outgoing bytes. - ValueRecorder
http_slow_request_total The server handled slow requests counter - t=%d. - Counter

Prometheus Metrics

When nodeSDKConfiguration.metricExporter is defined with a PrometheusExporterit will start a new process on port 8081 (default port) and metrics will be available at http://localhost:8081/metrics.

Using with a logger

Pino

import Pino, { Logger } from 'pino';
import { LoggerOptions } from 'pino';
import { trace, context } from '@opentelemetry/api';

export const loggerOptions: LoggerOptions = {
  formatters: {
    log(object) {
      const span = trace.getSpan(context.active());
      if (!span) return { ...object };
      const { spanId, traceId } = trace.getSpan(context.active())?.spanContext();
      return { ...object, spanId, traceId };
    },
  },
};

export const logger: Logger = Pino(loggerOptions);

Inspiration

nestjs-otel's People

Contributors

pragmaticivan avatar github-actions[bot] avatar dependabot[bot] avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.