# @cherie-xf/nestjs-microservice-otel

> deeply integrated OpenTelemetry module for Nestjs Microservice

Latest version **1.0.2-beta.1** (published 2022-12-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install @cherie-xf/nestjs-microservice-otel
pnpm add @cherie-xf/nestjs-microservice-otel
yarn add @cherie-xf/nestjs-microservice-otel
bun add @cherie-xf/nestjs-microservice-otel
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.2-beta.1 |
| Published | 2022-12-18 |
| First published | 2022-04-05 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 22 |
| Unpacked size | 780.4 KB |
| Known vulnerabilities | 0 (+9 in 7 direct dependencies) |
| Install scripts | no |
| Author | cherie.x.fu@gmail.com |
| Maintainers | cherie-xf |
| Keywords | nestjs, opentelemetry, tracing, observability, metric, prometheus, zipkin, jaeger |

## Links

- npm: https://www.npmjs.com/package/@cherie-xf/nestjs-microservice-otel
- Repository: https://github.com/cherie-xf/nestjs-microservice-otel
- Homepage: https://github.com/cherie-xf/nestjs-microservice-otel/#readme
- Issues: https://github.com/cherie-xf/nestjs-microservice-otel/issues
- npm.io page: https://npm.io/package/@cherie-xf/nestjs-microservice-otel

## Dependencies (22)

- [rxjs](https://npm.io/package/rxjs.md) ^7.8.0
- [rimraf](https://npm.io/package/rimraf.md) ^3.0.2
- [@nestjs/core](https://npm.io/package/@nestjs/core.md) ^9.2.1
- [@nestjs/common](https://npm.io/package/@nestjs/common.md) ^9.2.1
- [@nestjs/schedule](https://npm.io/package/@nestjs/schedule.md) ^2.1.0
- [reflect-metadata](https://npm.io/package/reflect-metadata.md) ^0.1.13
- [@opentelemetry/api](https://npm.io/package/@opentelemetry/api.md) ^1.3.0
- [@opentelemetry/core](https://npm.io/package/@opentelemetry/core.md) ^1.8.0
- [@nestjs/event-emitter](https://npm.io/package/@nestjs/event-emitter.md) ^1.3.1
- [@nestjs/microservices](https://npm.io/package/@nestjs/microservices.md) ^9.2.1
- [@opentelemetry/sdk-node](https://npm.io/package/@opentelemetry/sdk-node.md) ^0.34.0
- [@opentelemetry/resources](https://npm.io/package/@opentelemetry/resources.md) ^1.8.0
- [@opentelemetry/propagator-b3](https://npm.io/package/@opentelemetry/propagator-b3.md) ^1.8.0
- [@opentelemetry/sdk-trace-base](https://npm.io/package/@opentelemetry/sdk-trace-base.md) ^1.8.0
- [@opentelemetry/sdk-trace-node](https://npm.io/package/@opentelemetry/sdk-trace-node.md) ^1.8.0
- [@opentelemetry/instrumentation](https://npm.io/package/@opentelemetry/instrumentation.md) ^0.34.0
- [@opentelemetry/propagator-jaeger](https://npm.io/package/@opentelemetry/propagator-jaeger.md) ^1.8.0
- [@opentelemetry/context-async-hooks](https://npm.io/package/@opentelemetry/context-async-hooks.md) ^1.8.0
- [@opentelemetry/instrumentation-http](https://npm.io/package/@opentelemetry/instrumentation-http.md) ^0.34.0
- [@opentelemetry/semantic-conventions](https://npm.io/package/@opentelemetry/semantic-conventions.md) ^1.8.0
- [@opentelemetry/auto-instrumentations-node](https://npm.io/package/@opentelemetry/auto-instrumentations-node.md) ^0.35.0
- [@opentelemetry/instrumentation-nestjs-core](https://npm.io/package/@opentelemetry/instrumentation-nestjs-core.md) ^0.32.0

## Alternatives

- [lodash.startswith](https://npm.io/package/lodash.startswith.md) — 769.7K weekly downloads
- [@tarojs/service](https://npm.io/package/@tarojs/service.md) — 33.9K weekly downloads
- [io.extendreality.tilia.indicators.spatialtargets.unity](https://npm.io/package/io.extendreality.tilia.indicators.spatialtargets.unity.md) — 131 weekly downloads
- [@rtarojs/taro](https://npm.io/package/@rtarojs/taro.md) — 90 weekly downloads
- [node-branch-io](https://npm.io/package/node-branch-io.md) — 50 weekly downloads

## Recent versions

- 1.0.2-beta.1 (latest) — 2022-12-18
- 1.0.2-beta.0 — 2022-12-18
- 1.0.1 — 2022-04-06
- 1.0.0 — 2022-04-05

## README

<h1 align="center">NestJS Microservice OpenTelemetry</h1>

This library provides a smimple way to automatically for collecting traces from NestJS applications with Microservice architecture. This library integrated [NestJS Microservice](https://github.com/nestjs/nest/tree/master/packages/microservices), [OpenTelemetry-js](https://github.com/open-telemetry/opentelemetry-js) and Nodejs instrumentations

### Description

Nestjs is a protocol-agnostic framework. That's why this library can able to work with different protocols like TCP,RabbitMQ, GRPC and HTTP. Also you can observe and trace Nestjs specific layers like [Pipe](https://docs.nestjs.com/pipes), [Guard](https://docs.nestjs.com/guards), [Controller](https://docs.nestjs.com/controllers) and [Provider](https://docs.nestjs.com/providers).


- #### Distributed Tracing
  - [Setup](#distributed-tracing-setup)
  - [Trace Interceptor](#trace-interceptor)
  - [Microserve RPC Customized ClientProxy](#microserve-rpc-customized-clientproxy-traceclientproxy)
  - [Trace Decorators](#trace-decorators)
  - [Trace Providers](#trace-providers)

### Installation
``` bash
npm install @/cherie-xf/nestjs-microservice-otel --save
```
***
### Introduce
This is a basic configuration without any trace exporter, but includes default injectors
```ts
import { OpenTelemetryModule } from '@cherie-xf/nestjs-microservice-otel';

@Module({
  imports: [OpenTelemetryModule.forRoot()]
})
export class AppModule {}
```
#### Default Parameters
| key                 | value                                                                                                                                                                                                                    | description                                                                                                                                                                                                                                                               |
|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| spanProcessor       | NoopSpanProcessor                                                                                                                                                                                                        | default spanProcessor inherited from  <a href="https://github.com/open-telemetry/opentelemetry-js/blob/745bd5c34d3961dc73873190adc763747e5e026d/experimental/packages/opentelemetry-sdk-node/src/types.ts#:~:text=NodeSDKConfiguration"> NodeSDKConfiguration </a>        |
| serviceName       | String                                                                                                                                                                                                        | set to resource attribute : SemanticResourceAttributes.SERVICE_NAME        |
| textMapPropagator   | JaegerPropagator, B3Propagator                                                                                                                                                                                           | default textMapPropagator inherited from <a href="https://github.com/open-telemetry/opentelemetry-js/blob/745bd5c34d3961dc73873190adc763747e5e026d/experimental/packages/opentelemetry-sdk-node/src/types.ts#:~:text=NodeSDKConfiguration"> NodeSDKConfiguration </a>     |

`OpenTelemetryModule.forRoot()` takes [OpenTelemetryModuleConfig](https://github.com/MetinSeylan/Nestjs-OpenTelemetry/blob/main/src/OpenTelemetryModuleConfig.ts#L25) as a parameter, this type is inherited by [NodeSDKConfiguration](https://github.com/open-telemetry/opentelemetry-js/blob/745bd5c34d3961dc73873190adc763747e5e026d/experimental/packages/opentelemetry-sdk-node/src/types.ts#:~:text=NodeSDKConfiguration) so you can use same OpenTelemetry SDK parameter.
***
### Distributed Tracing Setup
Simple setup with Jaeger exporter, including with default trace instrumentations.
```ts
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OpenTelemetryModule } from '@cherie-xf/nestjs-microservice-otel';

@Module({
  imports: [
    OpenTelemetryModule.forRoot({
      spanProcessor: new BatchSpanProcessor(
        new JaegerExporter({
          endpoint: `http://${jaeger.host}:14268/api/traces`,
        }),
      ),
      serviceName: `${myServiceName}`,
    }),
  ],
})
export class AppModule {}
```
After setup, your application will be instrumented, so that you can see almost every layer of application in JeagerUI, including Guards, Pipes, Controllers even global layers like this

![Example trace output](./docs/jaeger-ui.png)
![Example trace detail output](./docs/jaeger-ui-detail.png)

List of supported official exporters [here](https://opentelemetry.io/docs/js/exporters/).
***
### Trace Interceptor
This library supports: rename trace span name to meaningful name for both http and rpc; propagation extract parent spanContext of RPC type context

main.ts
```ts
import { TraceInterceptor } from '@cherie-xf/nestjs-microservice-otel';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // set up global interceptor
  app.useGlobalInterceptors(new TraceInterceptor());

  await app.listen(port);
}

bootstrap();

```

api.controller.ts
```ts
import {
  TraceInterceptor,
} from '@cherie-xf/nestjs-microservice-otel';

@Controller('api')
@UseInterceptors(TraceInterceptor)
export class ApiController {
  constructor(
    private readonly apiService: ApiService,
  ) {}
  @Get('get-hello')
  getHello(@Res() res): string {
    return res.status(200).send('Hello World!');
  }
}
```
***
### Microserve RPC Customized ClientProxy: TraceClientProxy
This libary provide customized TraceClientProxy to automatically propagation.inject while making RPC microservice request

```ts
import { Inject, Injectable, Logger } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { TraceClientProxy } from '@cherie-xf/nestjs-microservice-otel';

@Injectable()
export class ApiService {
  private readonly _logger = new Logger(ApiService.name);
  constructor(
    @Inject('USER_CLIENT')
    private readonly user_client: ClientProxy,
    private traceClient: TraceClientProxy,
  ) {}

  async createUser(data: any) {
    const pattern = { name: 'user', cmd: 'create.user' };
    const payload = {
      user_name: data.user_name,
      user_email: data.user_email,
    };
    return await this.traceClient.send(this.user_client, pattern, payload);
  }

```
#### 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.
```ts
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
```ts
@Span('hello')
```
***
#### Trace Providers
You can use Decorators to trace Services, or you can access the native OpenTelemetry Trace api to manually handle span.
```ts
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.
```ts
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!';
  }
}
```
***

---
_Source: https://npm.io/package/@cherie-xf/nestjs-microservice-otel · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
