npm package: @inso_web/els-nest
Description: NestJS module и LoggerService для @inso_web/els-client. Drop-in замена встроенного Logger NestJS, nestjs-pino и pino-nestjs. Поддержка app.useLogger() и DI инжекта.
Author: INSOWEB
Latest version: 0.3.0

# @inso_web/els-nest

[![npm version](https://img.shields.io/npm/v/@inso_web/els-nest.svg)](https://www.npmjs.com/package/@inso_web/els-nest)
[![npm downloads](https://img.shields.io/npm/dm/@inso_web/els-nest.svg)](https://www.npmjs.com/package/@inso_web/els-nest)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)

NestJS module и `LoggerService` поверх [`@inso_web/els-client`](https://www.npmjs.com/package/@inso_web/els-client). Drop-in замена встроенного `Logger` NestJS, `nestjs-pino` и `pino-nestjs`.

## Что внутри

- **`ELSModule.forRoot(config)`** / **`forRootAsync(opts)`** — глобальный DI модуль
- **`ELSLoggerService`** — реализует `@nestjs/common.LoggerService`. Подключается через `app.useLogger(...)` и автоматически перехватывает вызовы встроенного `new Logger(ContextName).log()` со всего приложения
- **`ELS_CLIENT`** — DI токен для прямого инжекта `ELSClient` в свои сервисы
- **Re-export `ELSClient`** + типы

## Quick Start

```bash
npm i @inso_web/els-nest @nestjs/common
```

### `app.module.ts`

```ts
import { Module } from "@nestjs/common";
import { ELSModule } from "@inso_web/els-nest";

@Module({
  imports: [
    ELSModule.forRoot({
      endpoint: "https://api.insoweb.ru/els",
      apiKey: process.env.ELS_API_KEY!,
      appSlug: "my-nest-app",
      serviceName: "api",
      deploymentEnv: "PRODUCTION",
      minLevel: "info",
    }),
  ],
})
export class AppModule {}
```

### `main.ts`

```ts
import { NestFactory } from "@nestjs/core";
import { ELSLoggerService } from "@inso_web/els-nest";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { bufferLogs: true });
  app.useLogger(app.get(ELSLoggerService));
  await app.listen(3000);
}
bootstrap();
```

### Любой сервис

```ts
import { Injectable, Logger } from "@nestjs/common";

@Injectable()
export class UserService {
  // Используем встроенный Nest Logger как обычно — он теперь шлёт в ELS
  private readonly logger = new Logger(UserService.name);

  findOne(id: string) {
    this.logger.log(`Finding user ${id}`);  // → ELS info
    try {
      // ...
    } catch (e) {
      this.logger.error(e);  // → ELS error
    }
  }
}
```

## Migration from встроенного Nest Logger

**В коде сервисов вообще ничего менять не нужно.** Достаточно одной строки в `main.ts`:

```diff
  const app = await NestFactory.create(AppModule, { bufferLogs: true });
+ app.useLogger(app.get(ELSLoggerService));
  await app.listen(3000);
```

Все существующие `new Logger(SomeContext).log()` / `.error()` / `.warn()` теперь автоматически летят в ELS, сохраняя `context` (имя класса). API не меняется.

## Migration from nestjs-pino

```diff
- import { LoggerModule } from 'nestjs-pino';
- @Module({ imports: [LoggerModule.forRoot()] })
+ import { ELSModule } from '@inso_web/els-nest';
+ @Module({ imports: [ELSModule.forRoot({ endpoint, apiKey, appSlug })] })

  // main.ts
- import { Logger } from 'nestjs-pino';
- app.useLogger(app.get(Logger));
+ import { ELSLoggerService } from '@inso_web/els-nest';
+ app.useLogger(app.get(ELSLoggerService));
```

В сервисах ничего менять не нужно — `new Logger().log()` продолжает работать.

## Migration from winston-nestjs

```diff
- import { WinstonModule } from 'nest-winston';
- @Module({ imports: [WinstonModule.forRoot({ ... transports: [...] })] })
+ import { ELSModule } from '@inso_web/els-nest';
+ @Module({ imports: [ELSModule.forRoot({ endpoint, apiKey, appSlug })] })
```

## forRootAsync (для конфига из ConfigService)

```ts
ELSModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    endpoint: config.get("ELS_URL"),
    apiKey: config.get("ELS_API_KEY"),
    appSlug: config.get("APP_SLUG"),
  }),
});
```

## Прямой инжект ELSClient

Если хочешь использовать `ELSClient` напрямую в сервисе (например, `child` логгер с request-scoped биндингами):

```ts
import { Injectable, Inject } from "@nestjs/common";
import { ELS_CLIENT, ELSClient } from "@inso_web/els-nest";

@Injectable()
export class MyService {
  constructor(@Inject(ELS_CLIENT) private readonly els: ELSClient) {}

  process(reqId: string) {
    const log = this.els.child({ requestId: reqId });
    log.info("processing");
  }
}
```

## License

MIT