Code Monkey home page Code Monkey logo

nestjs-opentelemetry's Introduction

NestJS OpenTelemetry logo

NestJS OpenTelemetry

This library provides deeply integrated protocol-agnostic Nestjs OpenTelemetry instrumentations, metrics and SDK.

Description

Nestjs is a protocol-agnostic framework. That's why this library can able to work with different protocols like RabbitMQ, GRPC and HTTP. Also you can observe and trace Nestjs specific layers like Pipe, Guard, Controller and Provider.

It also includes auto trace and metric instrumentations for some popular Nestjs libraries.

OpenTelemetry Metrics currently experimental. So, this library doesn't support metric decorators and Auto Observers until it's stable. but if you want to use it, you can use OpenTelemetry API directly.

Competability table for Nestjs versions.

Nestjs Nestjs-OpenTelemetry
9.x 3.x.x
8.x 2.x.x

Installation

npm install @metinseylan/nestjs-opentelemetry --save

Configuration

This is a basic configuration without any trace and metric exporter, but includes default metrics and injectors

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

@Module({
  imports: [
    OpenTelemetryModule.forRoot({
      serviceName: 'nestjs-opentelemetry-example',
    })
  ]
})
export class AppModule {}

Async configuration example

import { OpenTelemetryModule } from '@metinseylan/nestjs-opentelemetry';
import {ConfigModule, ConfigService} from '@nestjs/config';

@Module({
  imports: [
    OpenTelemetryModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        serviceName: configService.get('SERVICE_NAME'),
      }),
      inject: [ConfigService]
    })
  ]
})
export class AppModule {}

Default Parameters

key value description
traceAutoInjectors ControllerInjector, GuardInjector, EventEmitterInjector, ScheduleInjector, PipeInjector, LoggerInjector default auto trace instrumentations
metricAutoObservers ResourceMetric, ProcessStartTimeMetric, ProcessOpenFdsMetric, ProcessMaxFdsMetric, ActiveHandlesMetric, ActiveHandlesTotalMetric, HttpRequestDurationSeconds, GrpcRequestDurationSeconds, RabbitMqRequestDurationSeconds default auto metric collectors
contextManager AsyncLocalStorageContextManager default trace context manager inherited from NodeSDKConfiguration
instrumentations AutoInstrumentations default instrumentations inherited from NodeSDKConfiguration
spanProcessor NoopSpanProcessor default spanProcessor inherited from NodeSDKConfiguration
textMapPropagator JaegerPropagator, B3Propagator default textMapPropagator inherited from NodeSDKConfiguration

OpenTelemetryModule.forRoot() takes OpenTelemetryModuleConfig as a parameter, this type is inherited by NodeSDKConfiguration so you can use same OpenTelemetry SDK parameter.


Distributed Tracing

Simple setup with Zipkin exporter, including with default trace instrumentations.

import { OpenTelemetryModule } from '@metinseylan/nestjs-opentelemetry';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';

@Module({
  imports: [
    OpenTelemetryModule.forRoot({
      spanProcessor: new SimpleSpanProcessor(
        new ZipkinExporter({
          url: 'your-zipkin-url',
        })
      ),
    }),
  ],
})
export class AppModule {}

After setup, your application will be instrumented, so that you can see almost every layer of application in ZipkinUI, including Guards, Pipes, Controllers even global layers like this

Example trace output

List of supported official exporters here.


Trace Decorators

This library supports auto instrumentations for Nestjs layers, but sometimes you need to define custom span for specific method blocks like providers methods. In this case @Span decorator will help you.

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

@Injectable()
export class AppService {
  @Span()
  getHello(): string {
    return 'Hello World!';
  }
}

Also @Span decorator takes name field as a parameter

@Span('hello')

Trace Providers

In an advanced usage case, you need to access the native OpenTelemetry Trace provider to access them from Nestjs application context.

import { Injectable } from '@nestjs/common';
import { Tracer } from '@opentelemetry/sdk-trace-base';

@Injectable()
export class AppService {
  constructor(private readonly tracer: Tracer) {}

  getHello(): string {
    const span = this.tracer.startSpan('important_section_start');
    // do something important
    span.setAttributes({ userId: 1150 });
    span.end();
    return 'Hello World!';
  }
}

TraceService can access directly current span context and start new span.

import { Injectable } from '@nestjs/common';
import { TraceService } from '@metinseylan/nestjs-opentelemetry';

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

  getHello(): string {
    const span = this.traceService.startSpan('hello');
    // do something
    span.end();
    return 'Hello World!';
  }
}

Auto Trace Instrumentations

The most helpful part of this library is that you already get all of the instrumentations by default if you set up a module without any extra configuration. If you need to avoid some of them, you can use the traceAutoInjectors parameter.

import { Module } from '@nestjs/common';
import {
  OpenTelemetryModule,
  ControllerInjector,
  EventEmitterInjector,
  GuardInjector,
  LoggerInjector,
  PipeInjector,
  ScheduleInjector,
} from '@metinseylan/nestjs-opentelemetry';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';

@Module({
  imports: [
    OpenTelemetryModule.forRoot({
      traceAutoInjectors: [
        ControllerInjector,
        GuardInjector,
        EventEmitterInjector,
        ScheduleInjector,
        PipeInjector,
        LoggerInjector,
      ],
      spanProcessor: new SimpleSpanProcessor(
        new ZipkinExporter({
          url: 'your-zipkin-url',
        }),
      ),
    }),
  ]
})
export class AppModule {}

List of Trace Injectors

Instance Description
ControllerInjector Auto trace all of module controllers
GuardInjector Auto trace all of module guards including global guards
PipeInjector Auto trace all of module pipes including global pipes
EventEmitterInjector Auto trace for @nestjs/event-emitter library, supports all features
ScheduleInjector Auto trace for @nestjs/schedule library, supports all features
LoggerInjector ConsoleLogger and Logger class tracer, logs with traceId

Distributed Logging with Trace ID

When you set up your environment with the LoggerInjector class or default configuration, you can see trace id with every log.

Example trace output


Metrics

Simple setup with Prometheus exporter, you need install @opentelemetry/exporter-prometheus

import { OpenTelemetryModule } from '@metinseylan/nestjs-opentelemetry';
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';

@Module({
  imports: [OpenTelemetryModule.forRoot({
    serviceName: 'nestjs-opentelemetry-example',
    metricReader: new PrometheusExporter({
      endpoint: 'metrics',
      port: 9464,
    })
  })]
})
export class AppModule {}

Now you can access Prometheus exporter with auto collected metrics http://localhost:9464/metrics. Also, you can find different exporters here


Metric Decorators (Deprecated)

If you need to observe simple block of function, you can use some basic decorators like @Counter and @Observer

Counter

import { Injectable } from '@nestjs/common';
import { Counter } from '@metinseylan/nestjs-opentelemetry';

@Injectable()
export class AppService {
  @Counter()
  getHello(): string {
    return 'Hello World!';
  }
}

@Counter decorator is uses OpenTelemetry Counter metric, If you check prometheus exporter you will see metric appservice_gethello_total

@Counter('call_me_mr_fahrenheit', {
  description: 'important function call counting here.'
})

And of course, you can configure your decorator metric, the first parameter is "name" and the second one is MetricOptions

Observer (Deprecated)

import {Injectable} from '@nestjs/common';
import {Observer} from "./Observer";

@Injectable()
export class AppService {
  @Observer('nice_one_observer', {
    description: 'some description here.',
    boundaries: [10, 20, 30],
  })
  getHello(): string {
    return 'Hello World!';
  }
}

@Observer decorator uses OpenTelemetry ValueRecorder metric. If you check Prometheus exporter, you will see metric and configuration parameters same as @Counter.


Metric Providers (Deprecated)

In advanced usage cases, you need to access the native OpenTelemetry Metric provider to access them from the Nestjs application context.

import { Injectable } from '@nestjs/common';
import { Meter } from '@opentelemetry/sdk-metrics-base';
import { Counter } from '@opentelemetry/api-metrics';

@Injectable()
export class AppService {
  private readonly counter: Counter;

  constructor(private readonly meter: Meter) {
    this.counter = this.meter.createCounter('handsome_counter');
  }

  getHello(): string {
    this.counter.add(1);
    return 'Hello World!';
  }
}

Auto Metric Observers (Deprecated)

This library has extendable resource and protocol-specific Auto Observers. All of them come with default module configuration, which you can extend and configure.

import { Module } from '@nestjs/common';
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
import {
  ActiveHandlesMetric,
  HttpRequestDurationSeconds,
  OpenTelemetryModule,
} from '@metinseylan/nestjs-opentelemetry';

@Module({
  imports: [
    OpenTelemetryModule.forRoot({
      serviceName: 'nestjs-opentelemetry-example',
      metricAutoObservers: [
        HttpRequestDurationSeconds.build({
          boundaries: [20, 30, 100],
        }),
        ActiveHandlesMetric,
      ],
      metricReader: new PrometheusExporter({
        endpoint: 'metrics',
        port: 9464,
      }),
    }),
  ],
})
export class AppModule {}

.build function takes MetricOptions as a parameter.

List Of Auto Observers (Deprecated)

Metric Observer Provider Description Configurable
HttpRequestDurationSeconds Observe http request duration yes
GrpcRequestDurationSeconds Observe grpc request duration yes
RabbitMqRequestDurationSeconds Observe rabbitmq request duration yes
ResourceMetric Metrics of cpu, memory usage no
ProcessStartTimeMetric Start time of the process since unix epoch in seconds. no
ProcessOpenFdsMetric Number of open file descriptors. no
ProcessMaxFdsMetric Maximum number of open file descriptors. no
ActiveHandlesMetric Number of active libuv handles grouped by handle type. Every handle type is C++ class name. no
ActiveHandlesTotalMetric Total number of active handles. no

Example Output for HttpRequestDurationSeconds

Key Value
exception Empty string or exception instance name
method GET, POST, PUT, PATCH, DELETE
outcome INFORMATIONAL, SUCCESS, REDIRECTION, CLIENT_ERROR, SERVER_ERROR
status number of HttpStatus
uri url path

Let's Combine All of them

import { Module } from '@nestjs/common';
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
import { OpenTelemetryModule } from '@metinseylan/nestjs-opentelemetry';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';

@Module({
  imports: [
    OpenTelemetryModule.forRoot({
      serviceName: 'nestjs-opentelemetry-example',
      metricReader: new PrometheusExporter({
        endpoint: 'metrics',
        port: 9464,
      }),
      spanProcessor: new SimpleSpanProcessor(
        new ZipkinExporter({
          url: 'your-zipkin-url',
        })
      ),
    }),
  ],
})
export class AppModule {}

nestjs-opentelemetry's People

Contributors

asaphaaning avatar aybukecaliskan avatar dependabot[bot] avatar leosuncin avatar metinseylan avatar peternewnham avatar queicherius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nestjs-opentelemetry's Issues

Just getting path logs

I see all these logs like Controller -> HealthCheckController.get

but would be nice to (also maybe) have just like in the jaeger example just /v1/health

How would I go about have all the controllers/paths like that

Thanks in advance.

MetricHttpEventProducer => response.once is not defined

Hi,

I am using nestjs with fastify adapter. Integrated this in my application.

Whenever i hit my api i get response.once is not defined. I believe this does not supports Fastify or may be i am doing configuration wrong.

I was able to debug and came to this class MetricHttpEventProducer which was giving error. line no 14.

response.once('finish', () =>
  this.publish(request, response, startAt, exception),
);

Please help me in getting this fix.

It gets messy debugging with open telemetry enable

I"m using VSCode and every time that I step into a method the debugger jumps to base.injector.js inside of node_modules. More over, it also mess up the source maps - the VScode shows a line that does not match with the code running.

I also tried to debug using Chrome, but it stills the same.

Any clue on how to combine Debugger and OpenTelemetry?

Type 'SimpleSpanProcessor' is not assignable to type 'SpanProcessor'. Type 'SimpleSpanProcessor' is not assignable to type 'SpanProcessor'

i am facing a type error in the tracing.ts file

import { OpenTelemetryModule } from '@metinseylan/nestjs-opentelemetry';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';

@module({
imports: [
OpenTelemetryModule.forRoot({
spanProcessor: new SimpleSpanProcessor(
new ZipkinExporter({
url: 'your-zipkin-url',
})
),
}),
],
})
export class AppModule {}

Production build error

When I try to run this project in production mode

export NODE_ENV=production
npm install --only-production
npm run start:dev

The project build failed
There a 100's of error related to types


> @metinseylan/[email protected] start:dev
> nest start --watch

๏ฟฝc[๏ฟฝ[90m12:49:52๏ฟฝ[0m] Starting compilation in watch mode...

node_modules/@nestjs/microservices/helpers/json-socket.d.ts:2:24 - error TS2307: Cannot find module 'buffer' or its corresponding type declarations.

2 import { Buffer } from 'buffer';
                         ~~~~~~~~

node_modules/@nestjs/microservices/helpers/kafka-parser.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@nestjs/microservices/helpers/kafka-parser.d.ts:7:19 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

7     decode(value: Buffer): object | string | null | Buffer;
                    ~~~~~~

node_modules/@nestjs/microservices/helpers/kafka-parser.d.ts:7:53 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

7     decode(value: Buffer): object | string | null | Buffer;
                                                      ~~~~~~

node_modules/@nestjs/microservices/helpers/kafka-reply-partition-assigner.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@nestjs/microservices/helpers/kafka-reply-partition-assigner.d.ts:25:19 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

25         userData: Buffer;
                     ~~~~~~

node_modules/@nestjs/microservices/helpers/tcp-socket.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@nestjs/microservices/helpers/tcp-socket.d.ts:2:24 - error TS2307: Cannot find module 'buffer' or its corresponding type declarations.

2 import { Buffer } from 'buffer';
                         ~~~~~~~~

node_modules/@nestjs/microservices/helpers/tcp-socket.d.ts:3:24 - error TS2307: Cannot find module 'net' or its corresponding type declarations.

3 import { Socket } from 'net';
                         ~~~~~

node_modules/@nestjs/microservices/record-builders/mqtt.record-builder.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@nestjs/microservices/record-builders/mqtt.record-builder.d.ts:20:27 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

20         correlationData?: Buffer;
                             ~~~~~~

node_modules/@nestjs/microservices/server/server-mqtt.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@nestjs/microservices/server/server-mqtt.d.ts:19:44 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

19     handleMessage(channel: string, buffer: Buffer, pub: MqttClient, originalPacket?: Record<string, any>): Promise<any>;
                                              ~~~~~~

node_modules/@nestjs/microservices/server/server-tcp.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@nestjs/microservices/server/server-tcp.d.ts:2:24 - error TS2307: Cannot find module 'net' or its corresponding type declarations.

2 import { Socket } from 'net';
                         ~~~~~

node_modules/@nestjs/microservices/server/server-tcp.d.ts:22:41 - error TS2503: Cannot find namespace 'NodeJS'.

22     handleClose(): undefined | number | NodeJS.Timer;
                                           ~~~~~~

node_modules/@opentelemetry/core/build/src/platform/node/performance.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@opentelemetry/core/build/src/platform/node/performance.d.ts:2:44 - error TS2307: Cannot find module 'perf_hooks' or its corresponding type declarations.

2 export declare const otperformance: import("perf_hooks").Performance;
                                             ~~~~~~~~~~~~

node_modules/@opentelemetry/core/build/src/platform/node/timer-util.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@opentelemetry/core/build/src/platform/node/timer-util.d.ts:2:43 - error TS2503: Cannot find namespace 'NodeJS'.

2 export declare function unrefTimer(timer: NodeJS.Timer): void;
                                            ~~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/http.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/http.d.ts:2:28 - error TS2307: Cannot find module 'http' or its corresponding type declarations.

2 import type * as http from 'http';
                             ~~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/http.d.ts:3:22 - error TS2307: Cannot find module 'url' or its corresponding type declarations.

3 import * as url from 'url';
                       ~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/types.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/types.d.ts:3:28 - error TS2307: Cannot find module 'http' or its corresponding type declarations.

3 import type * as http from 'http';
                             ~~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/types.d.ts:4:29 - error TS2307: Cannot find module 'https' or its corresponding type declarations.

4 import type * as https from 'https';
                              ~~~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/types.d.ts:5:94 - error TS2307: Cannot find module 'http' or its corresponding type declarations.

5 import { ClientRequest, get, IncomingMessage, request, ServerResponse, RequestOptions } from 'http';
                                                                                               ~~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/types.d.ts:6:22 - error TS2307: Cannot find module 'url' or its corresponding type declarations.

6 import * as url from 'url';
                       ~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/utils.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.

1 /// <reference types="node" />
                        ~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/utils.d.ts:3:122 - error TS2307: Cannot find module 'http' or its corresponding type declarations.

3 import { ClientRequest, IncomingHttpHeaders, IncomingMessage, OutgoingHttpHeaders, RequestOptions, ServerResponse } from 'http';
                                                                                                                           ~~~~~~

node_modules/@opentelemetry/instrumentation-http/build/src/utils.d.ts:4:22 - error TS2307: Cannot find module 'url' or its corresponding type declarations.

4 import * as url from 'url';
                       ~~~~~

src/Metric/Interceptors/Grpc/MetricGrpcEventProducer.ts:21:18 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

21     const diff = process.hrtime(startAt);
                    ~~~~~~~

src/Metric/Interceptors/Http/MetricHttpEventProducer.ts:20:18 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

20     const diff = process.hrtime(startAt);
                    ~~~~~~~

src/Metric/Interceptors/Http/MetricHttpMiddleware.ts:6:22 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

6     req['startAt'] = process.hrtime();
                       ~~~~~~~

src/Metric/Interceptors/MetricInterceptor.ts:70:12 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

70     return process.hrtime();
              ~~~~~~~

src/Metric/Interceptors/RabbitMQ/MetricRabbitMQEventProducer.ts:16:18 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

16     const diff = process.hrtime(startAt);
                    ~~~~~~~

src/Metric/Metrics/ActiveHandlesMetric.ts:17:16 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

17     if (typeof process['_getActiveHandles'] !== 'function') {
                  ~~~~~~~

src/Metric/Metrics/ActiveHandlesTotalMetric.ts:16:16 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

16     if (typeof process['_getActiveHandles'] !== 'function') {
                  ~~~~~~~

src/Metric/Metrics/ProcessMaxFdsMetric.ts:5:21 - error TS2307: Cannot find module 'fs' or its corresponding type declarations.

5 import * as fs from 'fs';
                      ~~~~

src/Metric/Metrics/ProcessOpenFdsMetric.ts:5:21 - error TS2307: Cannot find module 'fs' or its corresponding type declarations.

5 import * as fs from 'fs';
                      ~~~~

src/Metric/Metrics/ProcessOpenFdsMetric.ts:17:9 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

17     if (process.platform !== 'linux') {
           ~~~~~~~

src/Metric/Metrics/ProcessStartTimeMetric.ts:16:25 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.

16     Date.now() / 1000 - process.uptime(),
                           ~~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:6:27 - error TS2307: Cannot find module 'wait-for-expect' or its corresponding type declarations.

6 import waitForExpect from 'wait-for-expect';
                            ~~~~~~~~~~~~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:8:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

8 describe('Decorator Counter Injector Test', () => {
  ~~~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:9:20 - error TS2304: Cannot find name 'jest'.

9   const exporter = jest.fn();
                     ~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:11:51 - error TS2304: Cannot find name 'jest'.

11     metricExporter: { export: exporter, shutdown: jest.fn() },
                                                     ~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:16:3 - error TS2304: Cannot find name 'beforeEach'.

16   beforeEach(() => {
     ~~~~~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:21:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

21   it(`should count decorated provider method`, async () => {
     ~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:40:7 - error TS2304: Cannot find name 'expect'.

40       expect(exporter).toHaveBeenCalledWith(
         ~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:41:9 - error TS2304: Cannot find name 'expect'.

41         expect.arrayContaining([
           ~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:42:11 - error TS2304: Cannot find name 'expect'.

42           expect.objectContaining({
             ~~~~~~

src/Metric/Tests/DecoratorCounterInjectorTest.ts:52:9 - error TS2304: Cannot find name 'expect'.

52         expect.any(Function),
           ~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:5:27 - error TS2307: Cannot find module 'wait-for-expect' or its corresponding type declarations.

5 import waitForExpect from 'wait-for-expect';
                            ~~~~~~~~~~~~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:8:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

8 describe('Decorator Observer Injector Test', () => {
  ~~~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:9:20 - error TS2304: Cannot find name 'jest'.

9   const exporter = jest.fn();
                     ~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:11:51 - error TS2304: Cannot find name 'jest'.

11     metricExporter: { export: exporter, shutdown: jest.fn() },
                                                     ~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:16:3 - error TS2304: Cannot find name 'beforeEach'.

16   beforeEach(() => {
     ~~~~~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:21:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

21   it(`should observe decorated provider method`, async () => {
     ~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:40:7 - error TS2304: Cannot find name 'expect'.

40       expect(exporter).toHaveBeenCalledWith(
         ~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:41:9 - error TS2304: Cannot find name 'expect'.

41         expect.arrayContaining([
           ~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:42:11 - error TS2304: Cannot find name 'expect'.

42           expect.objectContaining({
             ~~~~~~

src/Metric/Tests/DecoratorObserverInjectorTest.ts:52:9 - error TS2304: Cannot find name 'expect'.

52         expect.any(Function),
           ~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:6:27 - error TS2307: Cannot find module 'wait-for-expect' or its corresponding type declarations.

6 import waitForExpect from 'wait-for-expect';
                            ~~~~~~~~~~~~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:7:26 - error TS2307: Cannot find module 'supertest' or its corresponding type declarations.

7 import * as request from 'supertest';
                           ~~~~~~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:9:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

9 describe('Metric Http Test', () => {
  ~~~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:10:20 - error TS2304: Cannot find name 'jest'.

10   const exporter = jest.fn();
                      ~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:13:51 - error TS2304: Cannot find name 'jest'.

13     metricExporter: { export: exporter, shutdown: jest.fn() },
                                                     ~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:18:3 - error TS2304: Cannot find name 'beforeEach'.

18   beforeEach(() => {
     ~~~~~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:23:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

23   it(`should generate http metric`, async () => {
     ~~

src/Metric/Tests/HttpRequestDurationIT.ts:42:7 - error TS2304: Cannot find name 'expect'.

42       expect(exporter).toHaveBeenCalledWith(
         ~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:43:9 - error TS2304: Cannot find name 'expect'.

43         expect.arrayContaining([
           ~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:44:11 - error TS2304: Cannot find name 'expect'.

44           expect.objectContaining({
             ~~~~~~

src/Metric/Tests/HttpRequestDurationIT.ts:57:9 - error TS2304: Cannot find name 'expect'.

57         expect.any(Function),
           ~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:6:26 - error TS2307: Cannot find module 'supertest' or its corresponding type declarations.

6 import * as request from 'supertest';
                           ~~~~~~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:9:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

9 describe('Base Trace Injector Test', () => {
  ~~~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:11:23 - error TS2304: Cannot find name 'jest'.

11   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:18:3 - error TS2304: Cannot find name 'beforeEach'.

18   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:23:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

23   it('should create spans that inherit the ids of their parents', async () => {
     ~~

src/Trace/Tests/BaseTraceInjectorTest.ts:57:5 - error TS2304: Cannot find name 'expect'.

57     expect(parent.parentSpanId).toBeUndefined();
       ~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:58:5 - error TS2304: Cannot find name 'expect'.

58     expect(childOfParent.parentSpanId).toBe(parent.spanContext().spanId);
       ~~~~~~

src/Trace/Tests/BaseTraceInjectorTest.ts:59:5 - error TS2304: Cannot find name 'expect'.

59     expect(childOfChild.parentSpanId).toBe(childOfParent.spanContext().spanId);
       ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:6:26 - error TS2307: Cannot find module 'supertest' or its corresponding type declarations.

6 import * as request from 'supertest';
                           ~~~~~~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:8:27 - error TS2307: Cannot find module 'wait-for-expect' or its corresponding type declarations.

8 import waitForExpect from 'wait-for-expect';
                            ~~~~~~~~~~~~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:10:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

10 describe('Tracing Controller Injector Test', () => {
   ~~~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:12:23 - error TS2304: Cannot find name 'jest'.

12   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/ControllerInjectorTest.ts:19:3 - error TS2304: Cannot find name 'beforeEach'.

19   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:24:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

24   it(`should trace controller method`, async () => {
     ~~

src/Trace/Tests/ControllerInjectorTest.ts:45:7 - error TS2304: Cannot find name 'expect'.

45       expect(exporterSpy).toHaveBeenCalledWith(
         ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:46:9 - error TS2304: Cannot find name 'expect'.

46         expect.objectContaining({ name: 'Controller->HelloController.hi' }),
           ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:47:9 - error TS2304: Cannot find name 'expect'.

47         expect.any(Object),
           ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:54:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

54   it(`should trace controller method exception`, async () => {
     ~~

src/Trace/Tests/ControllerInjectorTest.ts:76:7 - error TS2304: Cannot find name 'expect'.

76       expect(exporterSpy).toHaveBeenCalledWith(
         ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:77:9 - error TS2304: Cannot find name 'expect'.

77         expect.objectContaining({
           ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:84:9 - error TS2304: Cannot find name 'expect'.

84         expect.any(Object),
           ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:91:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

91   it(`should not trace controller method if there is no path`, async () => {
     ~~

src/Trace/Tests/ControllerInjectorTest.ts:112:7 - error TS2304: Cannot find name 'expect'.

112       expect(exporterSpy).not.toHaveBeenCalledWith(
          ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:113:9 - error TS2304: Cannot find name 'expect'.

113         expect.objectContaining({ name: 'Controller->HelloController.hi' }),
            ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:114:9 - error TS2304: Cannot find name 'expect'.

114         expect.any(Object),
            ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:121:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

121   it(`should not trace controller method if already decorated`, async () => {
      ~~

src/Trace/Tests/ControllerInjectorTest.ts:144:7 - error TS2304: Cannot find name 'expect'.

144       expect(exporterSpy).toHaveBeenCalledWith(
          ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:145:9 - error TS2304: Cannot find name 'expect'.

145         expect.objectContaining({
            ~~~~~~

src/Trace/Tests/ControllerInjectorTest.ts:148:9 - error TS2304: Cannot find name 'expect'.

148         expect.any(Object),
            ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:6:26 - error TS2307: Cannot find module 'supertest' or its corresponding type declarations.

6 import * as request from 'supertest';
                           ~~~~~~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:9:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

9 describe('Tracing Decorator Injector Test', () => {
  ~~~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:11:23 - error TS2304: Cannot find name 'jest'.

11   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:17:3 - error TS2304: Cannot find name 'beforeEach'.

17   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:22:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

22   it(`should trace decorated provider method`, async () => {
     ~~

src/Trace/Tests/DecoratorInjectorTest.ts:41:5 - error TS2304: Cannot find name 'expect'.

41     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:42:7 - error TS2304: Cannot find name 'expect'.

42       expect.objectContaining({ name: 'Provider->HelloService.hi' }),
         ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:43:7 - error TS2304: Cannot find name 'expect'.

43       expect.any(Object),
         ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:49:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

49   it(`should trace decorated controller method`, async () => {
     ~~

src/Trace/Tests/DecoratorInjectorTest.ts:69:5 - error TS2304: Cannot find name 'expect'.

69     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:70:7 - error TS2304: Cannot find name 'expect'.

70       expect.objectContaining({ name: 'Controller->HelloController.hi' }),
         ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:71:7 - error TS2304: Cannot find name 'expect'.

71       expect.any(Object),
         ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:77:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

77   it(`should throw exception when Injectable and Span used same time`, async () => {
     ~~

src/Trace/Tests/DecoratorInjectorTest.ts:88:11 - error TS2304: Cannot find name 'expect'.

88     await expect(context.compile()).rejects.toThrow(
             ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:93:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

93   it(`should trace decorated controller method with custom trace name`, async () => {
     ~~

src/Trace/Tests/DecoratorInjectorTest.ts:113:5 - error TS2304: Cannot find name 'expect'.

113     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:114:7 - error TS2304: Cannot find name 'expect'.

114       expect.objectContaining({
          ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:117:7 - error TS2304: Cannot find name 'expect'.

117       expect.any(Object),
          ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:123:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

123   it(`should not trace already tracing prototype`, async () => {
      ~~

src/Trace/Tests/DecoratorInjectorTest.ts:148:5 - error TS2304: Cannot find name 'expect'.

148     expect(exporterSpy).not.toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:149:7 - error TS2304: Cannot find name 'expect'.

149       expect.objectContaining({ name: 'Provider->HelloService.hi' }),
          ~~~~~~

src/Trace/Tests/DecoratorInjectorTest.ts:150:7 - error TS2304: Cannot find name 'expect'.

150       expect.any(Object),
          ~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:9:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

9 describe('Tracing Event Emitter Injector Test', () => {
  ~~~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:11:23 - error TS2304: Cannot find name 'jest'.

11   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:18:3 - error TS2304: Cannot find name 'beforeEach'.

18   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:23:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

23   it(`should trace event consumer method`, async () => {
     ~~

src/Trace/Tests/EventEmitterInjectorTest.ts:43:5 - error TS2304: Cannot find name 'expect'.

43     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:44:7 - error TS2304: Cannot find name 'expect'.

44       expect.objectContaining({ name: 'Event->HelloService.selam' }),
         ~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:45:7 - error TS2304: Cannot find name 'expect'.

45       expect.any(Object),
         ~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:51:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

51   it(`should not trace already decorated event consumer method`, async () => {
     ~~

src/Trace/Tests/EventEmitterInjectorTest.ts:72:5 - error TS2304: Cannot find name 'expect'.

72     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:73:7 - error TS2304: Cannot find name 'expect'.

73       expect.objectContaining({ name: 'Provider->HelloService.untraceable' }),
         ~~~~~~

src/Trace/Tests/EventEmitterInjectorTest.ts:74:7 - error TS2304: Cannot find name 'expect'.

74       expect.any(Object),
         ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:11:26 - error TS2307: Cannot find module 'supertest' or its corresponding type declarations.

11 import * as request from 'supertest';
                            ~~~~~~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:16:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

16 describe('Tracing Guard Injector Test', () => {
   ~~~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:18:23 - error TS2304: Cannot find name 'jest'.

18   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/GuardInjectorTest.ts:25:3 - error TS2304: Cannot find name 'beforeEach'.

25   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:30:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

30   it(`should trace guarded controller`, async () => {
     ~~

src/Trace/Tests/GuardInjectorTest.ts:56:5 - error TS2304: Cannot find name 'expect'.

56     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:57:7 - error TS2304: Cannot find name 'expect'.

57       expect.objectContaining({ name: 'Guard->HelloController.VeyselEfendi' }),
         ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:58:7 - error TS2304: Cannot find name 'expect'.

58       expect.any(Object),
         ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:64:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

64   it(`should trace guarded controller method`, async () => {
     ~~

src/Trace/Tests/GuardInjectorTest.ts:90:5 - error TS2304: Cannot find name 'expect'.

90     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:91:7 - error TS2304: Cannot find name 'expect'.

91       expect.objectContaining({
         ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:94:7 - error TS2304: Cannot find name 'expect'.

94       expect.any(Object),
         ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:100:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

100   it(`should trace guarded and decorated controller method`, async () => {
      ~~

src/Trace/Tests/GuardInjectorTest.ts:127:5 - error TS2304: Cannot find name 'expect'.

127     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:128:7 - error TS2304: Cannot find name 'expect'.

128       expect.objectContaining({
          ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:131:7 - error TS2304: Cannot find name 'expect'.

131       expect.any(Object),
          ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:137:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

137   it(`should trace global guard`, async () => {
      ~~

src/Trace/Tests/GuardInjectorTest.ts:167:5 - error TS2304: Cannot find name 'expect'.

167     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:168:7 - error TS2304: Cannot find name 'expect'.

168       expect.objectContaining({ name: 'Guard->Global->VeyselEfendi' }),
          ~~~~~~

src/Trace/Tests/GuardInjectorTest.ts:169:7 - error TS2304: Cannot find name 'expect'.

169       expect.any(Object),
          ~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:15:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

15 describe('Tracing Pipe Injector Test', () => {
   ~~~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:17:23 - error TS2304: Cannot find name 'jest'.

17   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/PipeInjectorTest.ts:24:3 - error TS2304: Cannot find name 'beforeEach'.

24   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:29:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

29   it(`should trace global pipe`, async function () {
     ~~

src/Trace/Tests/PipeInjectorTest.ts:57:5 - error TS2304: Cannot find name 'expect'.

57     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:58:7 - error TS2304: Cannot find name 'expect'.

58       expect.objectContaining({ name: 'Pipe->Global->HelloPipe' }),
         ~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:59:7 - error TS2304: Cannot find name 'expect'.

59       expect.any(Object),
         ~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:65:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

65   it(`should trace controller pipe`, async function () {
     ~~

src/Trace/Tests/PipeInjectorTest.ts:91:5 - error TS2304: Cannot find name 'expect'.

91     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:92:7 - error TS2304: Cannot find name 'expect'.

92       expect.objectContaining({ name: 'Pipe->HelloController.hi.HelloPipe' }),
         ~~~~~~

src/Trace/Tests/PipeInjectorTest.ts:93:7 - error TS2304: Cannot find name 'expect'.

93       expect.any(Object),
         ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:1:22 - error TS2307: Cannot find module '@nestjs/testing' or its corresponding type declarations.

1 import { Test } from '@nestjs/testing';
                       ~~~~~~~~~~~~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:9:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

9 describe('Tracing Scheduler Injector Test', () => {
  ~~~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:11:23 - error TS2304: Cannot find name 'jest'.

11   const exporterSpy = jest.spyOn(exporter, 'onStart');
                         ~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:18:3 - error TS2304: Cannot find name 'beforeEach'.

18   beforeEach(() => {
     ~~~~~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:23:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

23   it(`should trace scheduled cron method`, async () => {
     ~~

src/Trace/Tests/SchedulerInjectorTest.ts:43:5 - error TS2304: Cannot find name 'expect'.

43     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:44:7 - error TS2304: Cannot find name 'expect'.

44       expect.objectContaining({ name: 'Scheduler->Cron->HelloService.hi' }),
         ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:45:7 - error TS2304: Cannot find name 'expect'.

45       expect.any(Object),
         ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:51:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

51   it(`should trace scheduled and named cron method`, async () => {
     ~~

src/Trace/Tests/SchedulerInjectorTest.ts:71:5 - error TS2304: Cannot find name 'expect'.

71     expect(exporterSpy).toHaveBeenCalledWith(
       ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:72:7 - error TS2304: Cannot find name 'expect'.

72       expect.objectContaining({
         ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:75:7 - error TS2304: Cannot find name 'expect'.

75       expect.any(Object),
         ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:81:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

81   it(`should not trace already decorated cron method`, async () => {
     ~~

src/Trace/Tests/SchedulerInjectorTest.ts:102:5 - error TS2304: Cannot find name 'expect'.

102     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:103:7 - error TS2304: Cannot find name 'expect'.

103       expect.objectContaining({ name: 'Provider->HelloService.ORUC_REIS' }),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:104:7 - error TS2304: Cannot find name 'expect'.

104       expect.any(Object),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:110:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

110   it(`should trace scheduled interval method`, async () => {
      ~~

src/Trace/Tests/SchedulerInjectorTest.ts:130:5 - error TS2304: Cannot find name 'expect'.

130     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:131:7 - error TS2304: Cannot find name 'expect'.

131       expect.objectContaining({ name: 'Scheduler->Interval->HelloService.hi' }),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:132:7 - error TS2304: Cannot find name 'expect'.

132       expect.any(Object),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:138:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

138   it(`should trace scheduled and named interval method`, async () => {
      ~~

src/Trace/Tests/SchedulerInjectorTest.ts:158:5 - error TS2304: Cannot find name 'expect'.

158     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:159:7 - error TS2304: Cannot find name 'expect'.

159       expect.objectContaining({
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:162:7 - error TS2304: Cannot find name 'expect'.

162       expect.any(Object),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:168:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

168   it(`should trace scheduled timeout method`, async () => {
      ~~

src/Trace/Tests/SchedulerInjectorTest.ts:188:5 - error TS2304: Cannot find name 'expect'.

188     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:189:7 - error TS2304: Cannot find name 'expect'.

189       expect.objectContaining({ name: 'Scheduler->Timeout->HelloService.hi' }),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:190:7 - error TS2304: Cannot find name 'expect'.

190       expect.any(Object),
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:196:3 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.

196   it(`should trace scheduled and named timeout method`, async () => {
      ~~

src/Trace/Tests/SchedulerInjectorTest.ts:216:5 - error TS2304: Cannot find name 'expect'.

216     expect(exporterSpy).toHaveBeenCalledWith(
        ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:217:7 - error TS2304: Cannot find name 'expect'.

217       expect.objectContaining({
          ~~~~~~

src/Trace/Tests/SchedulerInjectorTest.ts:220:7 - error TS2304: Cannot find name 'expect'.

220       expect.any(Object),
          ~~~~~~

[12:55:09] Found 242 errors. Watching for file changes.


Question: How does this module work?

My understanding is that the NodeJS OTEL implementation has to monkey patch the instrumented modules BEFORE any other modules require them.

This module only initialises the SDK after bootstrapping the app, which means that all modules must have been imported into the app module already.

Am I misunderstanding something here?

Asking more out of curiosity than anything.

Nest can't resolve dependencies of the EventSubscribersLoader

If I'm not mistaken, the current module was broken after @opentelemetry/core 1.6.0 release

But maybe I'm wrong, and it's happened after some of @nestjs/event-emitter update

The next error happens

ERROR [ExceptionHandler] Nest can't resolve dependencies of the EventSubscribersLoader (DiscoveryService,
EventEmitter, EventsMetadataAccessor, MetadataScanner, ?).
Please make sure that the argument ModuleRef at index [4] is available in the EventEmitterModule context.

Modify log message

Is there any way to modify log message format?
For example I want a log to be in gofmt or json format with ability to modify traceID field name

traceID=xyz msg=hello
private static getMessage(message: string) {
    const currentSpan = trace.getSpan(context.active());
    if (!currentSpan) return message;

    const spanContext = trace.getSpan(context.active()).spanContext();
    currentSpan.addEvent(message);

    return `[${spanContext.traceId}] ${message}`;
  }

Build Issues when use pnpm

The follow error is thrown when using pnpm

[ExceptionHandler] Nest can't resolve dependencies of the SDK_INJECTORS (OPEN_TELEMETRY_SDK_CONFIG, ?). Please make sure that the argument ModuleRef at index [1] is available in the OpenTelemetryModule context.

Potential solutions:
- If ModuleRef is a provider, is it part of the current OpenTelemetryModule?
- If ModuleRef is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModuleRef */ ]
  })

package.json

  "dependencies": {
    "@metinseylan/nestjs-opentelemetry": "^2.0.2",
    "@nestjs/common": "^8.2.2",
    "@nestjs/core": "^8.2.2",
    "@nestjs/platform-express": "^8.2.2",
    "@opentelemetry/api": "^1.0.3",
    "@opentelemetry/exporter-jaeger": "^1.0.1",
    "@opentelemetry/sdk-trace-base": "^1.0.1",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0"
  },

http_request_duration_seconds reports milliseconds

Hey!
This produces values in milliseconds:
https://github.com/MetinSeylan/Nestjs-OpenTelemetry/blob/main/src/Metric/Interceptors/Http/MetricHttpEventProducer.ts#L20-L21

Besides wrong metric name, default buckets configuration ([0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]) also makes this metric unusable.

I think seconds is a commonly accepted unit for request duration histograms, so that value should probably be adjusted accordingly.

`MetricAutoObserver` doesn't work when I register module using `forRootAsync`

Hi, thanks for making this amazing library.

It was working perfectly when I register module using the 'forRoot' but if I change to 'forRootAsync', it doesn't. Anyone knows the reason for this?

Here's the code I used.

OpenTelemetryModule.forRootAsync({
      imports: [],
      useFactory: () => ({
        applicationName: "helloworld",
        metricAutoObservers: [
          HttpRequestDurationSeconds.build({
            // unit is milliseconds, 0.1 seconds ~ 8 seconds.
            boundaries: [100, 300, 500, 1000, 2000, 4000, 8000],
          }),
          ActiveHandlesMetric,
        ],
        metricExporter: new PrometheusExporter({
          endpoint: "metrics",
          port: 9464,
        }),
        metricInterval: 1000,
      }),
    }),

Thanks in advance!

what is the unit of the HttpRequestDurationSeconds?

From the sample code below, I don't get the exact unit of the bucket boundaries.

HttpRequestDurationSeconds.build({
  boundaries: [20, 30, 100],
}),

I guess it's miliseconds? Anyone know the answer for that?

Build Issues After Upgrading to NestJS v8.2.0

The follow error is thrown when using the latest nestjs version using a fresh nx/nestj workspace

[Nest] 95900  - 11/09/2021, 7:53:08 PM     LOG [NestFactory] Starting Nest application...
[Nest] 95900  - 11/09/2021, 7:53:08 PM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the GuardInjector (?). Please make sure that the argument ModulesContainer at index [0] is available in the OpenTelemetryModule context.

Potential solutions:
- If ModulesContainer is a provider, is it part of the current OpenTelemetryModule?
- If ModulesContainer is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModulesContainer */ ]
  })

Error: Nest can't resolve dependencies of the GuardInjector (?). Please make sure that the argument ModulesContainer at index [0] is available in the OpenTelemetryModule context.

package.json

  "dependencies": {
    "@metinseylan/nestjs-opentelemetry": "^2.0.0",
    "@nestjs/common": "^8.2.0",
    "@nestjs/core": "^8.2.0",
    "@nestjs/platform-express": "^8.2.0",
    "@opentelemetry/api": "^1.0.3",
    "@opentelemetry/sdk-trace-base": "^1.0.0",
    "eventemitter2": "^6.4.5",
    "reflect-metadata": "^0.1.13",
    "rxjs": "~7.4.0",
    "tslib": "^2.0.0"
  },

(node:29035) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

(node:29035) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:561:11)
    at ServerResponse.header (node_modules/express/lib/response.js:771:10)
    at TraceExceptionFilter.catch (node_modules/@metinseylan/nestjs-opentelemetry/src/Tracing/TraceExceptionFilter.ts:20:16)
    at ExceptionsHandler.invokeCustomFilters (node_modules/@nestjs/core/exceptions/exceptions-handler.js:33:26)
    at ExceptionsHandler.next (node_modules/@nestjs/core/exceptions/exceptions-handler.js:13:18)
    at node_modules/@nestjs/core/router/router-proxy.js:13:35
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

Unable to use with @opentelemetry/exporter-prometheus

Probably a version mismatch (@opentelemetry/exporter-prometheus has been updated pretty recently).

"@metinseylan/nestjs-opentelemetry": "^3.0.0"
"@opentelemetry/exporter-prometheus": "^0.35.0"

But here is there error I am getting:

OpenTelemetryModule.forRoot({
  serviceName: process.env.POD_NAMESPACE,
  metricReader: new PrometheusExporter({
    endpoint: 'metrics',
    port: 8080
  }),
  metricInterval: 100
})
Type 'PrometheusExporter' is not assignable to type 'MetricReader'.
Types have separate declarations of a private property '_shutdown'.

Also as a minor sidenote, it looks like the async configuration of this doesn't work for other reasons..

OpenTelemetryModule.forRootAsync({
  imports: [],
  useFactory: async (config: Config) => ({
    applicationName: config.POD_NAMESPACE,
    metricExporter: new PrometheusExporter({
      endpoint: 'metrics',
      port: 8080
    }),
    metricInterval: 100,
  }),
  inject: [Config]
})
Type '(config: Config) => Promise<{ applicationName: string; metricExporter: PrometheusExporter; metricInterval: number; }>' is not assignable to type '(...args: any[]) => Partial<OpenTelemetryModuleConfig> | Promise<Partial<OpenTelemetryModuleConfig>>'.
Type 'Promise<{ applicationName: string; metricExporter: PrometheusExporter; metricInterval: number; }>' is not assignable to type 'Partial<OpenTelemetryModuleConfig> | Promise<Partial<OpenTelemetryModuleConfig>>'.
Type 'Promise<{ applicationName: string; metricExporter: PrometheusExporter; metricInterval: number; }>' is not assignable to type 'Promise<Partial<OpenTelemetryModuleConfig>>'.

Typescript issues like "Type 'BatchSpanProcessor' is not assignable to type 'SpanProcessor'" since update to last OpenTelemetry packages

Nestjs-OpenTelemetry seems not working with last opentelemetry packages like @opentelemetry/sdk-trace-base

I try to update Nestjs-OpenTelemetry to offer a fix but tests are not working

Here a sample of typescript issues:

error TS2322: Type 'BatchSpanProcessor' is not assignable to type 'SpanProcessor'.
  Types of property 'onStart' are incompatible.
    Type '(_span: Span, _parentContext: Context) => void' is not assignable to type '(span: Span, parentContext: Context) => void'.
      Types of parameters '_span' and 'span' are incompatible.
        Type 'import("node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/sdk-trace-base/build/src/Span").Span' is not assignable to type 'import("node_modules/@opentelemetry/sdk-trace-base/build/src/Span").Span'.
          Types have separate declarations of a private property '_spanContext'.

error TS2322: Type 'HttpInstrumentation' is not assignable to type 'InstrumentationOption'.
  Type 'HttpInstrumentation' is not assignable to type 'Instrumentation'.
    Types of property 'setMeterProvider' are incompatible.
      Type '(meterProvider: import("node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-metrics/build/src/types/MeterProvider").MeterProvider) => void' is not assignable to type '(meterProvider: import("node_modules/@opentelemetry/api-metrics/build/src/types/MeterProvider").MeterProvider) => void'.
        Types of parameters 'meterProvider' and 'meterProvider' are incompatible.
          Type 'import("node_modules/@opentelemetry/api-metrics/build/src/types/MeterProvider").MeterProvider' is not assignable to type 'import("node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-metrics/build/src/types/MeterProvider").MeterProvider'.
            The types returned by 'getMeter(...)' are incompatible between these types.
              Type 'Meter' is missing the following properties from type 'Meter': addBatchObservableCallback, removeBatchObservableCallback

this.metricService.getProvider(...).getMeter(...).createObservableGauge is not a function

i got a error

[Nest] 391906  - 04/27/2022, 10:13:18 AM   ERROR [ExceptionHandler] this.metricService.getProvider(...).getMeter(...).createObservableGauge is not a function
TypeError: this.metricService.getProvider(...).getMeter(...).createObservableGauge is not a function
    at ProcessStartTimeMetric.inject (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_8a3f4045e53a03a04c90c8adfa35dfce/node_modules/@metinseylan/nestjs-opentelemetry/src/Metric/Metrics/ProcessStartTimeMetric.ts:25:8)
    at InstanceWrapper.useFactory [as metatype] (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_8a3f4045e53a03a04c90c8adfa35dfce/node_modules/@metinseylan/nestjs-opentelemetry/src/OpenTelemetryModule.ts:93:50)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Injector.instantiateClass (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_b63c269346792a9d57cfab86d23050d2/node_modules/@nestjs/core/injector/injector.js:334:37)
    at callback (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_b63c269346792a9d57cfab86d23050d2/node_modules/@nestjs/core/injector/injector.js:48:30)
    at Injector.resolveConstructorParams (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_b63c269346792a9d57cfab86d23050d2/node_modules/@nestjs/core/injector/injector.js:122:24)
    at Injector.loadInstance (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_b63c269346792a9d57cfab86d23050d2/node_modules/@nestjs/core/injector/injector.js:52:9)
    at Injector.loadProvider (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_b63c269346792a9d57cfab86d23050d2/node_modules/@nestjs/core/injector/injector.js:74:9)
    at async Promise.all (index 29)
    at InstanceLoader.createInstancesOfProviders (/srv/apps/npns/npns-service/node_modules/.pnpm/@[email protected]_b63c269346792a9d57cfab86d23050d2/node_modules/@nestjs/core/injector/instance-loader.js:44:9)

GuardInjector seems to break @nestjs/passport

I'm still trying to figure out why, but if you use the GuardInjector w/ @nestjs/passport package, you get an error this.getAuthenticateOptions is not a function but if you remove the GuardInjector, everything works fine.

ERROR [ExceptionHandler] Nest can't resolve dependencies of the SDK_INJECTORS (OPEN_TELEMETRY_SDK_CONFIG, ?)

The follow error is thrown when start nestjs app:

[Nest] 16239  - 07/18/2023, 3:15:28 PM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the SDK_INJECTORS (OPEN_TELEMETRY_SDK_CONFIG, ?). Please make sure that the argument ModuleRef at index [1] is available in the OpenTelemetryModule context.

Potential solutions:
- Is OpenTelemetryModule a valid NestJS module?
- If ModuleRef is a provider, is it part of the current OpenTelemetryModule?
- If ModuleRef is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModuleRef */ ]
  })


Error: Nest can't resolve dependencies of the SDK_INJECTORS (OPEN_TELEMETRY_SDK_CONFIG, ?). Please make sure that the argument ModuleRef at index [1] is available in the OpenTelemetryModule context.

Potential solutions:
- Is OpenTelemetryModule a valid NestJS module?
- If ModuleRef is a provider, is it part of the current OpenTelemetryModule?
- If ModuleRef is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModuleRef */ ]
  })

I'm using NestJS v10.

Type 'SimpleSpanProcessor' is not assignable to type 'SpanProcessor'

I'm getting the following error. I'm using the sample code from the README. I believe it's version dependency conflicts.

Type 'SimpleSpanProcessor' is not assignable to type 'SpanProcessor'.
  Types of property 'onStart' are incompatible.
    Type '(_span: Span, _parentContext: Context) => void' is not assignable to type '(span: Span, parentContext: Context) => void'.
      Types of parameters '_span' and 'span' are incompatible.
        Property '_clock' is missing in type 'import("/<snip>/node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/sdk-trace-base/build/src/Span").Span' but required in type 'import("/<snip>r/node_modules/@opentelemetry/sdk-trace-base/build/src/Span").Span'.ts(2322)

Span.d.ts(29, 22): '_clock' is declared here.

This is the example code I'm using:

    OpenTelemetryModule.forRoot({
      spanProcessor: new SimpleSpanProcessor(
        new ZipkinExporter({
          url: 'your-zipkin-url',
        })
      ),
    }),

Disable Http Instrumentation

Hi,

I search since few days how to disable http instrumentation but without success.

Do you have an idea to do this ?

I've try to :

  • add an empty instrumentations array in module configuration
  • add a new HttpInstrumentation({ enabled: false }) in the instrumentations array

This is my current module configuration

...
return {
      module: TelemetryModule,
      exports: [TelemetryService],
      imports: [
        OpenTelemetryModule.forRoot({
          applicationName: options.applicationName,
          spanProcessor: new BatchSpanProcessor(
            getSpanExporter(options.transport),
          ) as any,
          resource: new Resource({
            [SemanticResourceAttributes.SERVICE_NAME]: options.serviceName,
          }) as any,
          traceAutoInjectors: [
            ControllerInjector,
            GuardInjector,
            EventEmitterInjector,
            ScheduleInjector,
            PipeInjector,
            ResolverInjector,
            TelemetryInjector,
          ],
          metricAutoObservers: [
            GqlIncomingRequestCounterMetric,
            HttpIncomingRequestMetric,
          ],
        }),
      ],
      providers: [
        {
          provide: TelemetryConstants.TELEMETRY_CONFIGURATION,
          useValue: options,
        },
        {
          provide: TelemetryService,
          useClass: TelemetryOpenTelemetryService,
        },
        {
          provide: APP_INTERCEPTOR,
          useClass: HttpFastifyAdapterInterceptor,
        },
        {
          provide: APP_INTERCEPTOR,
          useClass: GraphqlInterceptor,
        },
        {
          provide: APP_INTERCEPTOR,
          useClass: HttpInterceptor,
        },
      ],
    };

Thx !

Question: plan to re-introduce Auto Metric Observers?

I see that recently with #49 support for Auto Metric Observers was dropped. I'm assuming this is mostly due the dependency on experimental @opentelemetry packages which constantly introduce breaking changes.

Is there a plan to re-introduce these Auto Metrics Observers once the now experimental dependencies are stable?

Span parent ids not being allocated correctly

I'm using the module (which is great btw), however I've noticed that parent ids are not being allocated correctly to nested spans.

With a simple app that imports the default OpenTelemetryModule module and has a controller that calls some service methods, the spans that are generated all have a parentId of the root span instead of their actual parents:

HTTP (id: 1, parentId: undefined)
-> Controller (id: 2, parentId: 1)
  -> Service1 (id: 3, parentId: 1)    - parentId should be 2
    -> Service3 (id: 5, parentId: 1)  - parentId should be 3
  -> Service2 (id: 4, parentId: 1)    - parentId should be 2

This means that spans aren't being grouped correctly.

I've applied a patch to my local version which corrects this behaviour and am happy to submit a PR here as well but wanted to get an opinion on it first in case there's something fundamentally wrong with what i'm doing that i'm not aware of ๐Ÿ˜„

class BaseTraceInjector {
  protected wrap() {
    const method = {
      [prototype.name]: function (...args: any[]) {
        const tracer = trace.getTracer('default');

        // this is the offender - trace.getSpan(context.active()) always returns the top level 'default' span
        //const currentSpan = trace.getSpan(context.active()) ?? tracer.startSpan('default');

        // instead create the new span with the traceName outside of context.with and use that to create the context
        // all nested spans will now be allocated this span as their parent
        const span = tracer.startSpan(traceName);

        return context.with(
          trace.setSpan(context.active(), span),
          () => {
            // no need to create the span inside here now
            //const span = tracer.startSpan(traceName);

           // everything else stays the same
  }
}

The library stop working after update to nest 8

Hi, I have an app that was written in version 6 of nest. I have migrated the app to the nest 8, but now I am receiving an error that I think is connected to the library:

[Nest] 1  - 04/28/2022, 10:53:22 AM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the EventEmitterInjector (?). Please make sure that the argument ModulesContainer at index [0] is available in the OpenTelemetryModule context.

Potential solutions:
- If ModulesContainer is a provider, is it part of the current OpenTelemetryModule?
- If ModulesContainer is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModulesContainer */ ]
  })

Error: Nest can't resolve dependencies of the EventEmitterInjector (?). Please make sure that the argument ModulesContainer at index [0] is available in the OpenTelemetryModule context.

Potential solutions:
- If ModulesContainer is a provider, is it part of the current OpenTelemetryModule?
- If ModulesContainer is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModulesContainer */ ]
  })

    at Injector.lookupComponentInParentModules (/usr/app/node_modules/@nestjs/core/injector/injector.js:231:19)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async Injector.resolveComponentInstance (/usr/app/node_modules/@nestjs/core/injector/injector.js:184:33)
    at async resolveParam (/usr/app/node_modules/@nestjs/core/injector/injector.js:106:38)
    at async Promise.all (index 0)
    at async Injector.resolveConstructorParams (/usr/app/node_modules/@nestjs/core/injector/injector.js:121:27)
    at async Injector.loadInstance (/usr/app/node_modules/@nestjs/core/injector/injector.js:52:9)
    at async Injector.loadProvider (/usr/app/node_modules/@nestjs/core/injector/injector.js:74:9)
    at async Promise.all (index 3)
    at async InstanceLoader.createInstancesOfProviders (/usr/app/node_modules/@nestjs/core/injector/instance-loader.js:44:9)
    at async /usr/app/node_modules/@nestjs/core/injector/instance-loader.js:29:13
    at async Promise.all (index 9)
    at async InstanceLoader.createInstances (/usr/app/node_modules/@nestjs/core/injector/instance-loader.js:28:9)
    at async InstanceLoader.createInstancesOfDependencies (/usr/app/node_modules/@nestjs/core/injector/instance-loader.js:18:9)
    at async /usr/app/node_modules/@nestjs/core/nest-factory.js:96:17
    at async Function.asyncRun (/usr/app/node_modules/@nestjs/core/errors/exceptions-zone.js:22:13)
    at async NestFactoryStatic.initialize (/usr/app/node_modules/@nestjs/core/nest-factory.js:94:13)
    at async NestFactoryStatic.create (/usr/app/node_modules/@nestjs/core/nest-factory.js:37:9)
    at async bootstrap (/usr/app/dist/src/main.js:9:17

Does anyone meet similar problem before?

I use @metinseylan/nestjs-opentelemetry in version 2.0.0.

Build issue when using latest version of nestjs/core package

Description

After updating to the latest version of @nestjs/[email protected] (from version 8.1.1) I am running into the following error

[Nest] 95411  - 2022-01-21, 9:42:21 a.m.   ERROR [ExceptionHandler] Nest can't resolve dependencies of the ControllerInjector (?). Please make sure that the argument ModulesContainer at index [0] is available in the OpenTelemetryModule context.

Potential solutions:
- If ModulesContainer is a provider, is it part of the current OpenTelemetryModule?
- If ModulesContainer is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModulesContainer */ ]
  })

Error: Nest can't resolve dependencies of the ControllerInjector (?). Please make sure that the argument ModulesContainer at index [0] is available in the OpenTelemetryModule context.

Potential solutions:
- If ModulesContainer is a provider, is it part of the current OpenTelemetryModule?
- If ModulesContainer is exported from a separate @Module, is that module imported within OpenTelemetryModule?
  @Module({
    imports: [ /* the Module containing ModulesContainer */ ]
  })

Issue in OpenTelemetryModule after import with forRoot inside NestJS 8 project

I just added this dependency into my NestJS 8 project, but when I add the OpenTelemetryModule to an specific module as following:

OpenTelemetryModule.forRoot({
      spanProcessor: new BatchSpanProcessor(
        new ZipkinExporter({
          url: "http://127.0.0.1:9411/api/v2/spans",
        })
      ),
      applicationName: "treasury-api-identity",
    }),

, I get the following error:

const injectors = configuration?.traceAutoInjectors ?? [];
SyntaxError: Unexpected token '.'

How can be solved it?

@Counter is registered as @Observer

The DecoratorObserverMetricInjector and DecoratorCounterMetricInjector lack checks for decorator type in some places. Because of this @Counter functions can register as @Observer and export Histogram instead of Counter

The opposite situation is also possible, I think

How to send the deployment.environment attribute?

I need to filter my service by environment in the Aspecto, but I dont know to send the deployment.environment attribute.
I could send in the defaultAttributes configuration this: { 'deployment.environment': process.env.NODE_ENV }?

Bug: Parent span duration is not correctly calculated

As you can see on the screenshot below, the parent span duration is not calculated correctly.
Parent span (provider->identityservice.get) should also include the duration of child spans in its own duration. The same goes for controller->identitycontroller.profile.
I am using nestjs version 9 and zipkin in order to visualize traces.

Screenshot 2023-06-30 at 13 41 09

I think the issue is in this line: https://github.com/MetinSeylan/Nestjs-OpenTelemetry/blob/main/src/Trace/Injectors/BaseTraceInjector.ts#L68C13-L68C13
because this issue occurs with async functions. There should be other check to determine if the function is async.

'SimpleSpanProcessor' is not assignable to type 'SpanProcessor'.

src/app.module.ts:83:7 - error TS2322: Type 'SimpleSpanProcessor' is not assignable to type 'SpanProcessor'.
  Types of property 'onStart' are incompatible.
    Type '(_span: Span) => void' is not assignable to type '(span: Span, parentContext: Context) => void'.
      Types of parameters '_span' and 'span' are incompatible.
        Type 'import("node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/sdk-trace-base/build/src/Span").Span' is not assignable to type 'import("node_modules/@opentelemetry/sdk-trace-base/build/src/Span").Span'.
          Types have separate declarations of a private property '_spanContext'.

83       spanProcessor: new SimpleSpanProcessor(
         ~~~~~~~~~~~~~

Type signatures mismatching, might relate to #15

Error in configuring for PrometheusExporter

According to the README, the code below should result in configuring a PrometheusExporter, but perhaps there is a missing step or the versions with the required libraries are a little out of alignment? The IDE reports an error.

        OpenTelemetryModule.forRoot({
            applicationName: 'myApplicationName',
            metricExporter: new PrometheusExporter({
                endpoint: 'metrics',
                port: 9464,
            }),
            metricInterval: 1000,
        })

Error

Property 'export' is missing in type 'PrometheusExporter' but required in type 'MetricExporter'.ts(2741)
types.d.ts(71, 5): 'export' is declared here.
types.d.ts(13, 5): The expected type comes from property 'metricExporter' which is declared here on type 'Partial<OpenTelemetryModuleConfig>'

It seems that the PrometheusExporter extends MetricReader (now?) while the OpenTelemetryModule is expecting to have a MetricExporter.

Asynchronous configuration not working

Configuring the module using OpenTelemetryModule.forRoot works without any issues (thanks for your work), trying to configure it using OpenTelemetryModule.forRootAsync so that I can provide a configuration service (@nestjs/config to be exact, but the problem persists even without anything) I get the following error:

TypeError: (intermediate value) is not iterable
    at Function.forRootAsync (/data/test-otel/node_modules/@metinseylan/nestjs-opentelemetry/dist/OpenTelemetryModule.js:1:1)
    at Object.<anonymous> (/data/test-otel/src/app.module.ts:8:25)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/data/test-otel/src/main.ts:2:1)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)

Also tried:

  • with or without webpack (in a monorepo environment)
  • a brand new Nest project (using both yarn and npm) and installing just the module (not even the configuration module)

problem remains, and is always the same.

Environment

  • MacOS 12.3.1
  • node 16.14.2
  • yarn 1.22.15

Some issue when record tracing log on guard

Hey owner,
I found some problem. It's happend when same guard been use on different controller.
my zipkin will receive so many guard event, like following.
image
image
The root cause is rewrite "canActivate" which been used on guard instance.
image
It will loop rewriting until load all controller.

Interceptor and Filter implementation considerations

Looking at Interceptor and Filter implementation. I have couple considerations.

  1. @opentelemetry/instrumentation-http and @opentelemetry/instrumentation-grpc handle "get trace id from header" and "set trace id to header" automatically. So for http/grpc/graphql there is already existing instrumentation that handles this. Which means that "interceptor" shouldn't be needed.
  2. For Filter, there is the same idea as 1, it's already being handled by the other instrumentation and we shouldn't re-implement that logic for NestJS.
  3. Both Interceptor and Filter currently have hard-coded support only for b3 style headers. Which breaks usage for AWS X-Ray (as an example). Same as 1 and 2, this is not something that should be handled by this library but by propagators whose only job is to extract/inject trace id's from/to headers. As is the case for b3 in @opentelemetry/propagator-b3. This library should work regardless of what propagator is used.

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.