npm package: @krnpg/logging-client
Description: NestJS HTTP request logging interceptor for the Monitoring API with batched delivery and sensitive data redaction.
Latest version: 1.0.2

# @krnpg/logging-client

NestJS HTTP request logging interceptor for the [Monitoring API](https://github.com/your-org/monitoring). Automatically captures all HTTP requests and responses with batched delivery, sensitive data redaction, and configurable options.

## Features

- Automatic HTTP request/response logging via NestJS interceptor
- Batched log delivery (configurable batch size and flush interval)
- Sensitive data redaction (passwords, tokens, secrets, etc.)
- Response body truncation (configurable max size)
- Path exclusion (e.g. `/health`, `/metrics`)
- Client credentials authentication (clientId/clientSecret)
- Async module registration (for ConfigService integration)

## Installation

```bash
npm install @krnpg/logging-client
# or
pnpm add @krnpg/logging-client
# or
yarn add @krnpg/logging-client
```

### Peer Dependencies

Make sure you have these installed in your NestJS project:

```bash
npm install @nestjs/common @nestjs/core rxjs
```

## Setup

### 1. Get Credentials

Create an environment in the Monitoring dashboard (Settings tab) or via the API:

```bash
curl -X POST http://your-monitoring-api/api/applications/{appId}/environments \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-admin-key" \
  -d '{"name": "production"}'
```

This returns a `clientId` and `clientSecret`. Save the secret — it is only shown once.

### 2. Register the Module

#### Static registration

```typescript
import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { LoggingClientModule, LoggingInterceptor } from '@krnpg/logging-client';

@Module({
  imports: [
    LoggingClientModule.register({
      apiUrl: 'http://localhost:4000',
      clientId: 'your-client-id',
      clientSecret: 'your-client-secret',
      excludePaths: ['/health', '/metrics'],
    }),
  ],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

#### Async registration (recommended for production)

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { LoggingClientModule, LoggingInterceptor } from '@krnpg/logging-client';

@Module({
  imports: [
    ConfigModule.forRoot(),
    LoggingClientModule.registerAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        apiUrl: config.get('MONITORING_API_URL'),
        clientId: config.get('MONITORING_CLIENT_ID'),
        clientSecret: config.get('MONITORING_CLIENT_SECRET'),
        excludePaths: ['/health', '/metrics'],
      }),
    }),
  ],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

### 3. Environment Variables

Add these to your `.env` file:

```env
MONITORING_API_URL=http://localhost:4000
MONITORING_CLIENT_ID=your-client-id
MONITORING_CLIENT_SECRET=your-client-secret
```

## Configuration Options

| Option | Type | Default | Description |
|---|---|---|---|
| `apiUrl` | `string` | **required** | Monitoring API base URL |
| `clientId` | `string` | **required** | Client ID from environment credentials |
| `clientSecret` | `string` | **required** | Client Secret from environment credentials |
| `excludePaths` | `string[]` | `[]` | Paths to exclude from logging |
| `logBodies` | `boolean` | `true` | Whether to log request/response bodies |
| `logHeaders` | `boolean` | `true` | Whether to log request headers |
| `maxBodySize` | `number` | `10240` | Max body size to capture in bytes (10KB) |
| `batchSize` | `number` | `10` | Number of logs to buffer before flushing |
| `flushInterval` | `number` | `5000` | Auto-flush interval in milliseconds |

## What Gets Logged

Each HTTP request captures:

- **Method** — GET, POST, PUT, DELETE, PATCH
- **Path** — Request URL
- **Query** — Query parameters
- **Status Code** — HTTP response status
- **Duration** — Response time in milliseconds
- **Request Headers** — Content-Type, User-Agent, Origin (sanitized)
- **Request Body** — Sanitized and truncated
- **Response Body** — Sanitized and truncated
- **Error** — Error message and stack trace (if any)
- **IP** — Client IP address (supports X-Forwarded-For)
- **User Agent** — Browser/client identifier
- **User ID** — From `request.user.id` or `request.user.sub` (if authenticated)

## Sensitive Data Redaction

The following fields are automatically redacted from request/response bodies and headers:

`password`, `token`, `accessToken`, `refreshToken`, `authorization`, `secret`, `creditCard`, `cardNumber`, `cvv`, `ssn`

## Exports

```typescript
import {
  LoggingClientModule,    // NestJS dynamic module
  LoggingClientService,   // Service for manual log pushing
  LoggingInterceptor,     // HTTP interceptor (use as APP_INTERCEPTOR)
  LoggingClientConfig,    // Configuration interface
  RequestLogPayload,      // Log payload type
} from '@krnpg/logging-client';
```

## Publishing to npm

### First-time setup

1. Create an npm account at [npmjs.com](https://www.npmjs.com/signup) if you don't have one
2. Create the `@monitoring` organization at [npmjs.com/org/create](https://www.npmjs.com/org/create) (free for public packages)
3. Login from your terminal:

```bash
npm login
```

### Publish

```bash
cd packages/logging-client
pnpm build
npm publish
```

The package is configured with `publishConfig.access: "public"` so scoped publishing works automatically.

### Version updates

```bash
# Patch release (1.0.0 → 1.0.1) — bug fixes
npm version patch

# Minor release (1.0.0 → 1.1.0) — new features
npm version minor

# Major release (1.0.0 → 2.0.0) — breaking changes
npm version major

# Then publish
npm publish
```

### Verify

After publishing, confirm the package is live:

```bash
npm info @krnpg/logging-client
```

## License

MIT