> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8a08bda2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> NestJS SDK for ClickStack - The ClickHouse Observability Stack

# NestJS

The ClickStack NestJS integration allows you to create a logger or use the default
logger to send logs to ClickStack (powered by [nest-winston](https://www.npmjs.com/package/nest-winston?activeTab=readme)).

**This guide integrates:**

<table>
  <tbody>
    <tr>
      <td className="pe-2">✅ Logs</td>
      <td className="pe-2">✖️ Metrics</td>
      <td className="pe-2">✖️ Traces</td>
    </tr>
  </tbody>
</table>

*To send over metrics or APM/traces, you'll need to add the corresponding language
integration to your application as well.*

<h2 id="getting-started">
  Getting started
</h2>

Import `HyperDXNestLoggerModule` into the root `AppModule` and use the `forRoot()`
method to configure it.

```javascript theme={null}
import { Module } from '@nestjs/common';
import { HyperDXNestLoggerModule } from '@hyperdx/node-logger';

@Module({
  imports: [
    HyperDXNestLoggerModule.forRoot({
      url: 'http://your-otel-collector:4318',
      apiKey: ***YOUR_INGESTION_API_KEY***, // Not need for Managed ClickStack
      maxLevel: 'info',
      service: 'my-app',
    }),
  ],
})
export class AppModule {}
```

Afterward, the winston instance will be available to inject across the entire
project using the `HDX_LOGGER_MODULE_PROVIDER` injection token:

```javascript theme={null}
import { Controller, Inject } from '@nestjs/common';
import { HyperDXNestLoggerModule, HyperDXNestLogger } from '@hyperdx/node-logger';

@Controller('cats')
export class CatsController {
  constructor(
    @Inject(HyperDXNestLoggerModule.HDX_LOGGER_MODULE_PROVIDER)
    private readonly logger: HyperDXNestLogger,
  ) { }

  meow() {
    this.logger.info({ message: '🐱' });
  }
}
```

<h3 id="replacing-the-nest-logger">
  Replacing the Nest logger (also for bootstrapping)
</h3>

<Info>
  **Important**

  By doing this, you give up the dependency injection, meaning that `forRoot` and `forRootAsync` aren't needed and shouldn't be used. Remove them from your main module.
</Info>

Using the dependency injection has one minor drawback. Nest has to bootstrap the
application first (instantiating modules and providers, injecting dependencies,
etc.) and during this process the instance of `HyperDXNestLogger` isn't yet
available, which means that Nest falls back to the internal logger.

One solution is to create the logger outside of the application lifecycle, using
the `createLogger` function, and pass it to `NestFactory.create`. Nest will then
wrap our custom logger (the same instance returned by the `createLogger` method)
into the Logger class, forwarding all calls to it:

Create the logger in the `main.ts` file

```javascript theme={null}
import { HyperDXNestLoggerModule } from '@hyperdx/node-logger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: HyperDXNestLoggerModule.createLogger({
      url: 'http://your-otel-collector:4318',
      apiKey: ***YOUR_INGESTION_API_KEY***, // Not needed for Managed ClickStack
      maxLevel: 'info',
      service: 'my-app',
    })
  });
  await app.listen(3000);
}
bootstrap();
```

Change your main module to provide the Logger service:

```javascript theme={null}
import { Logger, Module } from '@nestjs/common';

@Module({
  providers: [Logger],
})
export class AppModule {}
```

Then inject the logger simply by type hinting it with the Logger from `@nestjs/common`:

```javascript theme={null}
import { Controller, Logger } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  constructor(private readonly logger: Logger) {}

  meow() {
    this.logger.log({ message: '🐱' });
  }
}
```
