npm package: @samofprog/nestjs-logstack
Description: Configurable Winston logger for NestJS with daily file rotation and console output.
Author: samuel assemien
Latest version: 2.0.6

# @samofprog/nestjs-logstack

[![npm version](https://img.shields.io/npm/v/@samofprog/nestjs-logstack.svg)](https://www.npmjs.com/package/@samofprog/nestjs-logstack)
[![npm downloads](https://img.shields.io/npm/dm/@samofprog/nestjs-logstack.svg)](https://www.npmjs.com/package/@samofprog/nestjs-logstack)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.8+-blue.svg)](https://www.typescriptlang.org/)
[![NestJS](https://img.shields.io/badge/NestJS-11.0+-red.svg)](https://nestjs.com/)

A modern, flexible, and production-ready Winston-based logging solution for NestJS applications with daily file rotation, level-based organization, and environment-aware configuration.

## ✨ Features

- 🚀 **Easy NestJS Integration** - Drop-in replacement for default NestJS logger
- 📅 **Daily Log Rotation** - Automatic file rotation with configurable retention
- 📁 **Level-based Organization** - Separate log files for info, warn, and error
- 🗜️ **Auto Compression** - Old logs automatically compressed to save storage
- 🎨 **Developer Friendly** - Colorized console output with context and timestamps
- 📊 **Structured JSON Logs** - Production-ready JSON format for parsing and analysis
- ⚙️ **Environment Aware** - Automatic config based on NODE_ENV
- 🔧 **Highly Configurable** - Full control over retention, size, format, and output
- 📦 **Zero Extra Dependencies** - Winston, nest-winston included
- ✅ **Full TypeScript Support** - Complete type definitions
- 🎯 **Flexible Environment Detection** - Partial matching support (prod, test, etc.)

## 📦 Installation

```bash
# npm
npm install @samofprog/nestjs-logstack

# yarn
yarn add @samofprog/nestjs-logstack

# pnpm
pnpm add @samofprog/nestjs-logstack
```

## 🚀 Quick Start

### Basic Setup

```typescript
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { LoggerUtils } from '@samofprog/nestjs-logstack';

async function bootstrap() {
  const loggerUtils = new LoggerUtils();
  const app = await NestFactory.create(AppModule, {
    logger: loggerUtils.buildLogger(),
  });

  await app.listen(3000);
}

bootstrap();
```

### Auto Configuration by Environment

```typescript
// Automatically configures based on NODE_ENV
import { LoggerUtils } from '@samofprog/nestjs-logstack';

const app = await NestFactory.create(AppModule, {
  logger: new LoggerUtils().buildLogger(
    LoggerUtils.createConfigFromEnv()
  ),
});
```

## 📖 Usage Guide

### Basic Configuration

```typescript
import { LoggerUtils } from '@samofprog/nestjs-logstack';

const loggerUtils = new LoggerUtils();

// Use defaults (20MB file size, 14 days retention)
const logger = loggerUtils.buildLogger();

// Custom configuration
const logger = loggerUtils.buildLogger({
  maxSize: '50m',
  maxFiles: '30d',
  enableConsole: true,
  enableFileLogging: true,
});
```

### Environment-Specific Presets

```typescript
import { LoggerUtils } from '@samofprog/nestjs-logstack';

// Development preset
// - 20MB max size, 7 days retention
// - Debug level, colorized console, no JSON
const devLogger = new LoggerUtils().buildLogger(
  LoggerUtils.createDevConfig()
);

// Production preset (text console)
// - 50MB max size, 30 days retention
// - Info level, text console output, files in JSON
const prodLogger = new LoggerUtils().buildLogger(
  LoggerUtils.createProdConfig()
);

// Production preset (JSON console for log aggregators)
// - 50MB max size, 30 days retention
// - Info level, JSON console, full stack traces, no file logging
const prodJsonLogger = new LoggerUtils().buildLogger(
  LoggerUtils.createProdJsonConfig()
);

// Testing preset
// - 10MB max size, 1 day retention
// - Error level only, console disabled, no file logging
const testLogger = new LoggerUtils().buildLogger(
  LoggerUtils.createTestConfig()
);

// Auto-select based on NODE_ENV
const autoLogger = new LoggerUtils().buildLogger(
  LoggerUtils.createConfigFromEnv()
);
```

### Advanced Configuration

```typescript
import { LoggerUtils, LoggerConfig } from '@samofprog/nestjs-logstack';

const config: LoggerConfig = {
  // Path where logs will be stored
  logDir: './custom-logs',

  // Maximum file size before rotation
  maxSize: '100m',

  // How long to keep logs (days or size-based)
  maxFiles: '60d',

  // Console output level
  consoleLevel: 'debug',

  // Enable/disable outputs
  enableConsole: true,
  enableFileLogging: true,

  // JSON output for production
  jsonConsole: false,

  // Custom date pattern for files
  datePattern: 'YYYY-MM-DD HH:mm',

  // Custom directories per log level
  levelDirs: {
    info: './logs/info',
    warn: './logs/warnings',
    error: './logs/errors',
  },
};

const logger = new LoggerUtils().buildLogger(config);
```

## 🔌 API Reference

### `LoggerUtils` Class

#### Constructor

```typescript
const loggerUtils = new LoggerUtils();
```

Detects production environment automatically via `NODE_ENV?.includes("prod")`.

#### `buildLogger(config?: LoggerConfig)`

Creates and caches a NestJS-compatible Winston logger instance.

```typescript
buildLogger(config?: LoggerConfig): LoggerService
```

**Parameters:**
- `config` (optional) - `LoggerConfig` object with customization options

**Returns:** NestJS `LoggerService` instance

**Example:**
```typescript
const logger = loggerUtils.buildLogger({
  maxSize: '50m',
  maxFiles: '30d',
});
```

#### `getLogger(config?: LoggerConfig)`

Alias for `buildLogger()`. Returns cached instance if already created.

```typescript
const logger = loggerUtils.getLogger();
```

#### `resetLogger()`

Clears the cached logger instance. Useful for testing.

```typescript
loggerUtils.resetLogger();
```

### Static Configuration Methods

#### `createDevConfig()`

Returns development-optimized configuration.

```typescript
static createDevConfig(): LoggerConfig
```

**Settings:**
- Max size: 20MB
- Retention: 7 days
- Console level: debug
- Output: Colorized text

#### `createProdConfig()`

Returns production-optimized configuration.

```typescript
static createProdConfig(): LoggerConfig
```

**Settings:**
- Max size: 50MB
- Retention: 30 days
- Console level: info
- Output: JSON format

#### `createTestConfig()`

Returns test-optimized configuration.

```typescript
static createTestConfig(): LoggerConfig
```

**Settings:**
- Max size: 10MB
- Retention: 1 day
- Console: disabled
- File logging: disabled

#### `createConfigFromEnv()`

Auto-selects configuration based on `NODE_ENV`.

```typescript
static createConfigFromEnv(): LoggerConfig
```

Supports partial matching:
- Contains "prod" → production config
- Contains "test" → test config
- Default → development config

**Example:**
```typescript
// NODE_ENV=production-docker → uses createProdConfig()
// NODE_ENV=test → uses createTestConfig()
// NODE_ENV=development → uses createDevConfig()
const config = LoggerUtils.createConfigFromEnv();
```

### `LoggerConfig` Interface

```typescript
interface LoggerConfig {
  // Directory where logs are stored
  logDir?: string;

  // Maximum file size before rotation (e.g., "20m", "100k")
  maxSize?: string;

  // Retention period for logs (e.g., "14d", "30d")
  maxFiles?: string;

  // Console output log level
  consoleLevel?: string;

  // Enable console output
  enableConsole?: boolean;

  // Enable file logging
  enableFileLogging?: boolean;

  // Date format for log file names
  datePattern?: string;

  // Use JSON format for console logs
  jsonConsole?: boolean;

  // Include stack traces in JSON console output
  jsonIncludeStack?: boolean;

  // Custom directories per log level
  levelDirs?: Record<string, string>;
}
```

## 📁 Log Directory Structure

Logs are organized in a `logs/` directory at your project root:

```
logs/
├── info-2024-10-29.log          # Info level logs
├── warn-2024-10-29.log          # Warning level logs
├── error-2024-10-29.log         # Error level logs
└── archived/                    # Old compressed logs
    ├── info-2024-10-28.log.gz
    ├── warn-2024-10-28.log.gz
    └── error-2024-10-28.log.gz
```

### Console Output Format (Development)

```
2024-10-29 14:30:45 info: [AppController] Server is running on port 3000
2024-10-29 14:30:46 info: [App] Database connection established
```

**Note:** If no context is provided, defaults to `[App]`

### File Output Format (JSON)

```json
{
  "timestamp": "2024-10-29 14:30:45",
  "level": "info",
  "message": "Server is running on port 3000",
  "context": "AppController"
}
```

**Context Handling:**
- **String**: Displayed as-is in logs
- **Object**: Automatically JSON stringified for readability
- **Undefined/Null**: Defaults to "App"

## ⚙️ Configuration Examples

### Minimal Configuration

```typescript
new LoggerUtils().buildLogger();
// Uses all defaults
```

### Development Environment

```typescript
new LoggerUtils().buildLogger({
  logDir: './logs/dev',
  maxSize: '20m',
  maxFiles: '7d',
  consoleLevel: 'debug',
  enableFileLogging: true,
  jsonConsole: false,
});
```

### Production Environment

```typescript
new LoggerUtils().buildLogger({
  logDir: '/var/log/app',
  maxSize: '100m',
  maxFiles: '90d',
  consoleLevel: 'info',
  enableFileLogging: true,
  jsonConsole: true,
});
```

### Testing Environment

```typescript
new LoggerUtils().buildLogger({
  enableConsole: false,
  enableFileLogging: false,
});
```

## 🌍 Environment Detection

The logger automatically detects the environment using `NODE_ENV`:

```bash
# Production
NODE_ENV=production npm start
NODE_ENV=prod npm start
NODE_ENV=production-docker npm start  # ← Also detected as production

# Testing
NODE_ENV=test npm test
NODE_ENV=testing npm test

# Development (default)
NODE_ENV=development npm run dev
npm run dev  # ← Defaults to development
```

## 📊 Log Levels

Supported Winston log levels:

- `error` - Error messages
- `warn` - Warning messages
- `info` - Informational messages
- `http` - HTTP request logs
- `debug` - Debug messages
- `verbose` - Verbose messages
- `silly` - Silly messages

## 🔄 Logger Caching

The logger instance is cached after creation. Subsequent calls return the cached instance:

```typescript
const utils = new LoggerUtils();

const logger1 = utils.buildLogger();
const logger2 = utils.buildLogger();  // Returns cached logger1

// Force reset
utils.resetLogger();
const logger3 = utils.buildLogger();  // Creates new instance
```

## 🧪 Testing

When using in tests, disable file logging for better performance:

```typescript
// test.setup.ts
import { LoggerUtils } from '@samofprog/nestjs-logstack';

beforeAll(() => {
  const logger = new LoggerUtils().buildLogger(
    LoggerUtils.createTestConfig()
  );
  app.useLogger(logger);
});
```

## 🔒 Security Notes

- Logs are stored with default file permissions (readable by owner)
- Set appropriate directory permissions in production
- Ensure log directories are not publicly accessible
- Consider rotating logs regularly (handled automatically)
- JSON logs may contain sensitive information - review before rotation

## 📝 Troubleshooting

### Logs Not Being Created

1. Check write permissions on the `logs` directory
2. Verify `enableFileLogging` is `true`
3. Check `consoleLevel` is appropriate for your messages
4. Ensure `NODE_ENV` is set correctly for auto-config

### High Disk Usage

1. Reduce `maxFiles` retention period
2. Reduce `maxSize` per file
3. Monitor log volume and adjust accordingly
4. Check for error loops creating excessive logs

### TypeScript Import Errors

```
TS7016: Could not find a declaration file for module '@samofprog/nestjs-logstack'
```

Update your `tsconfig.json`:
```json
{
  "compilerOptions": {
    "skipLibCheck": true
  }
}
```

## 🤝 Contributing

We welcome contributions! Please see our [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.

## 📄 License

MIT © 2024 Samuel Assemien

See [LICENSE](./LICENSE) file for details.

## 📚 Resources

- [NestJS Documentation](https://docs.nestjs.com/)
- [Winston Logger](https://github.com/winstonjs/winston)
- [nest-winston Integration](https://github.com/gremo/nest-winston)

## 🐛 Issues & Support

- **Bug Reports**: [GitHub Issues](https://github.com/samofprog/nestjs-logstack/issues)
- **Feature Requests**: [GitHub Discussions](https://github.com/samofprog/nestjs-logstack/discussions)
- **Questions**: Create an issue with label `question`

## 🎯 Roadmap

- [ ] Support for additional transports (Slack, email)
- [ ] Log filtering and sampling
- [ ] Performance metrics integration
- [ ] Cloud storage support (S3, GCS)

---

Made with ❤️ by [Samuel Assemien](https://github.com/samofprog)