@logispark/nest-js-logger
v1.0.3
Published
A reusable NestJS logger module that sends structured logs to a hosted logger API
Maintainers
Readme
@logispark/nest-js-logger
A lightweight NestJS logger middleware that forwards structured logs (errors, warnings, activity) to a hosted Grafana logging service. It does not connect to any database — all log delivery is handled by the Grafana backend.
Features
- Structured Logging — Consistent log format with levels (
debug,info,warn,error,fatal), metadata, and contextual fields - Automatic HTTP Logging — Intercepts all HTTP requests/responses and logs them with timing, user info, and tenant context
- Grafana Integration — Posts logs directly to your hosted Grafana logging endpoint via HTTP
- Multi-Tenant Aware — Automatically extracts tenant ID from user object,
x-tenant-idheader, or subdomain - Sensitive Data Redaction — Automatically redacts passwords, tokens, secrets, credit cards, CVVs, and SSNs from request/response bodies
- Route Exclusion — Skip logging for specific routes (e.g., health checks)
- Global Module — Register once, inject anywhere in your NestJS application
Installation
npm install @logispark/nest-js-loggerPeer Dependencies
npm install @nestjs/common @nestjs/core @nestjs/axios rxjsQuick Start
1. Register the module
import { Module } from '@nestjs/common';
import { NestJsLoggerModule } from '@logispark/nest-js-logger';
@Module({
imports: [
NestJsLoggerModule.forRoot({
loggerApiUrl: 'http://3.140.127.147:3001/your-log-endpoint',
appId: 'my-app',
environment: 'dev',
apiKey: 'your-api-key', // optional
timeout: 5000, // optional, default: 5000ms
excludeRoutes: ['/health'], // optional
}),
],
})
export class AppModule {}2. Use the logging service manually
import { Injectable } from '@nestjs/common';
import { NestJsLoggerService } from '@logispark/nest-js-logger';
@Injectable()
export class OrdersService {
constructor(private readonly logger: NestJsLoggerService) {}
async createOrder(order: any) {
await this.logger.info('Order created', {
user_id: order.userId,
new_values: order,
metadata: { orderId: order.id },
});
}
async handleError(err: Error) {
await this.logger.error('Order failed', {
message: err.message,
metadata: { stack: err.stack },
});
}
}3. Enable automatic HTTP logging (recommended)
Apply the interceptor globally so every request/response is logged automatically:
import { NestJsLoggingInterceptor } from '@logispark/nest-js-logger';
import { APP_INTERCEPTOR } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_INTERCEPTOR,
useClass: NestJsLoggingInterceptor,
},
],
})
export class AppModule {}How It Works
This package is a pure middleware — it receives log data from your NestJS app and POSTs it as JSON to your configured Grafana endpoint. There is no local database, no ClickHouse client, and no direct storage. All persistence and querying is handled by the Grafana service.
Your NestJS App
│
│ (HTTP request comes in)
▼
NestJsLoggingInterceptor
│
│ builds structured log payload
▼
NestJsLoggerService.log()
│
│ POST /your-log-endpoint (JSON)
▼
Grafana Logging Service ──► ClickHouse (managed by Grafana)API Reference
NestJsLoggerOptions
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| loggerApiUrl | string | Yes | — | Full URL of your Grafana log ingestion endpoint |
| appId | string | Yes | — | Application identifier |
| environment | 'dev' \| 'prod' \| 'stage' | No | 'dev' | Environment name |
| apiKey | string | No | — | Bearer token for API auth |
| timeout | number | No | 5000 | HTTP request timeout in milliseconds |
| excludeRoutes | string[] | No | [] | Route prefixes to skip in the interceptor |
NestJsLoggerService methods
| Method | Description |
|--------|-------------|
| log(payload) | Send a log with full control over all fields |
| debug(message, extras?) | Log at debug level |
| info(message, extras?) | Log at info level |
| warn(message, extras?) | Log at warn level |
| error(message, extras?) | Log at error level |
NestJsLogPayload fields
| Field | Type | Description |
|-------|------|-------------|
| app_id | string | Application identifier |
| app_type | 'web' \| 'mobile' \| 'backend' | Application type |
| environment | 'dev' \| 'prod' \| 'stage' | Environment |
| level | 'debug' \| 'info' \| 'warn' \| 'error' \| 'fatal' | Log level |
| message | string | Log message |
| log_type | 'error' \| 'activity' | Log category |
| tenant_id | string | Tenant identifier |
| user_id | string | User identifier |
| user_name | string | Username |
| url | string | Request URL |
| request_type | 'GET' \| 'POST' \| 'PUT' \| 'PATCH' \| 'DELETE' | HTTP method |
| source | string | Client IP or forwarded address |
| metadata | Record<string, any> | Additional key-value data |
| old_values | Record<string, any> | Previous values (for update operations) |
| new_values | Record<string, any> | New values (for create/update operations) |
How the Interceptor Works
The NestJsLoggingInterceptor automatically captures:
- HTTP method, URL, and response status code
- Request duration in milliseconds
- User info from
request.user(compatible with Passport or any auth guard) - Tenant ID from the user object,
x-tenant-idheader, or subdomain - Request and response bodies (with sensitive fields redacted automatically)
- Error details including stack traces for failed requests
Log levels are assigned based on HTTP status code:
info— 2xx / 3xxwarn— 4xxerror— 5xx or thrown exceptions
License
MIT License — see LICENSE for details.
