# Logger Utility

A comprehensive, theme-aware logging service for the Sixbell Telco SDK with support for multiple log levels, console output, in-memory storage, and persistent IndexedDB logging.

## Features

- 📊 **6 Log Levels**: trace, debug, info, warn, error, fatal
- 🎨 **Theme-Aware**: Automatic dark/light mode color schemes
- 💾 **Persistent Storage**: Optional IndexedDB logging with retention policies
- 🔇 **Silent Mode**: Log without console output
- 📝 **Context Support**: Add component, action, and custom metadata to logs
- 🔍 **Flexible Filtering**: Log level thresholds to control output
- 🏭 **Factory Pattern**: DI-ready provider for easy Angular integration
- 📥 **Log Download**: Export logs as JSON files
- 🧪 **Fully Tested**: 50+ tests covering all functionality

## Installation

The logger is included in the UI kit. Import from:

```typescript
import { LoggerService } from '@sixbell-telco/sdk/utils/logger';
import { provideLogger } from '@sixbell-telco/sdk/utils/logger';
```

## Quick Start

### Basic Usage

```typescript
import { Component, inject } from '@angular/core';
import { LoggerService } from '@sixbell-telco/sdk/utils/logger';

@Component({
  selector: 'app-example',
  template: `<div>Check console for logs</div>`,
})
export class ExampleComponent {
  private logger = inject(LoggerService);

  ngOnInit() {
    this.logger.info('Component initialized');
    this.logger.warn('This is a warning');
    this.logger.error('Something went wrong', new Error('Details here'));
  }
}
```

### Setup in Application

Configure the logger in your application bootstrap:

```typescript
import { bootstrapApplication } from '@angular/platform-browser';
import { provideLogger } from '@sixbell-telco/sdk/utils/logger';
import { AppComponent } from './app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideLogger({
      enableLogging: isDevMode(),
      logLevel: isDevMode() ? 'debug' : 'warn',
      showTimestamp: true,
      showDate: true,
      persistToIndexedDB: true,
      idbRetentionDays: 7,
      idbMaxLogs: 5000,
      silentMode: !isDevMode(),
    }),
  ],
});
```

Showcase reference: `projects/showcase/src/app/app.config.ts`

## Log Levels

Log levels are ordered by severity. The logger will only output messages at or above the configured threshold.

| Level     | Value | Use Case                            | Color        |
| --------- | ----- | ----------------------------------- | ------------ |
| **trace** | 0     | Very detailed debugging information | Gray         |
| **debug** | 1     | General debugging information       | Blue         |
| **info**  | 2     | Informational messages              | Green        |
| **warn**  | 3     | Warning conditions                  | Orange       |
| **error** | 4     | Error conditions                    | Red          |
| **fatal** | 5     | Fatal errors that may crash the app | White on Red |

### Example: Log Level Filtering

```typescript
// With logLevel: 'warn', only warn, error, and fatal will appear
logger.configure({ logLevel: 'warn' });

logger.debug('Not shown'); // ✗ Below threshold
logger.info('Not shown'); // ✗ Below threshold
logger.warn('Will show'); // ✓ At threshold
logger.error('Will show'); // ✓ Above threshold
logger.fatal('Will show'); // ✓ Above threshold
```

## API Reference

### Configuration

```typescript
interface LoggerConfig {
  enableLogging?: boolean; // Enable/disable logging (default: false)
  logLevel?: LogLevel; // Minimum level to log (default: 'error')
  showTimestamp?: boolean; // Show time in logs (default: false)
  showDate?: boolean; // Show date + time (default: false)
  silentMode?: boolean; // Log without console output (default: false)
  persistToIndexedDB?: boolean; // Save logs to IndexedDB (default: false)
  idbRetentionDays?: number; // Keep logs for X days (default: 7)
  idbMaxLogs?: number; // Max logs in IndexedDB (default: 5000)
  isDarkMode?: boolean; // Use dark theme colors (default: false)
  onError?: (error, context) => void; // Error callback
  errorReporter?: { captureException }; // External error reporter
}
```

### Methods

#### Logging Methods

```typescript
logger.trace(message: string, context?: LoggerContext)
logger.debug(message: string, context?: LoggerContext)
logger.info(message: string, context?: LoggerContext)
logger.warn(message: string, context?: LoggerContext)
logger.error(message: string, error?: Error, context?: LoggerContext)
logger.fatal(message: string, error?: Error, context?: LoggerContext)
```

#### Configuration

```typescript
// Configure globally
logger.configure({ enableLogging: true, logLevel: 'debug' });

// Create temporary logger with different config
const debugLogger = logger.withConfig({ logLevel: 'trace' });
debugLogger.debug('Detailed debug info');
logger.debug('Respects original config');
```

#### Storage & Retrieval

```typescript
// Get in-memory logs
const logs = logger.getStoredLogs();

// Clear in-memory logs
logger.clearStoredLogs();

// Get persisted logs from IndexedDB
const persistedLogs = await logger.getPersistedLogs();

// Clear IndexedDB logs
await logger.clearPersistedLogs();

// Download all logs as JSON
await logger.downloadLogs('my-logs.json');
```

#### Theme Management

```typescript
// Set dark mode explicitly
logger.setDarkMode(true);

// Get current theme
const isDark = logger.isDarkMode();

// Restore system preference detection
logger.setDarkMode(undefined);
```

## Usage Examples

### Example 1: Basic Logging with Context

```typescript
import { Component, inject } from '@angular/core';
import { LoggerService } from '@sixbell-telco/sdk/utils/logger';

@Component({
  selector: 'app-user-list',
  template: `<div>Users</div>`,
})
export class UserListComponent {
  private logger = inject(LoggerService);

  loadUsers() {
    const context = {
      component: 'UserListComponent',
      action: 'loadUsers',
    };

    this.logger.info('Loading users', context);

    try {
      // Load users...
      this.logger.info('Users loaded successfully', context);
    } catch (error) {
      this.logger.error('Failed to load users', error as Error, context);
    }
  }
}
```

### Example 2: Environment-Specific Configuration

```typescript
// environment.ts
export const environment = {
  production: false,
  logger: {
    enableLogging: true,
    logLevel: 'debug',
    showTimestamp: true,
    persistToIndexedDB: false,
  },
};

// environment.prod.ts
export const environment = {
  production: true,
  logger: {
    enableLogging: true,
    logLevel: 'warn',
    showTimestamp: true,
    persistToIndexedDB: true,
    idbRetentionDays: 30,
  },
};

// main.ts
import { environment } from './environments/environment';
import { provideLogger } from '@sixbell-telco/sdk/utils/logger';

bootstrapApplication(AppComponent, {
  providers: [provideLogger(environment.logger)],
});
```

### Example 3: Error Reporting Integration

```typescript
import { provideLogger } from '@sixbell-telco/sdk/utils/logger';

// With external error reporter (e.g., Sentry)
bootstrapApplication(AppComponent, {
  providers: [
    provideLogger({
      enableLogging: true,
      errorReporter: {
        captureException: (error, context) => {
          // Send to Sentry, LogRocket, etc.
          console.log('Reporting error:', error, context);
        },
      },
      onError: (error, context) => {
        console.log('Error callback:', error, context);
      },
    }),
  ],
});
```

### Example 4: Silent Mode for Testing

```typescript
describe('MyService', () => {
  let service: MyService;
  let logger: LoggerService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        MyService,
        provideLogger({
          enableLogging: true,
          silentMode: true, // No console output during tests
          logLevel: 'trace',
        }),
      ],
    });
    logger = TestBed.inject(LoggerService);
    service = TestBed.inject(MyService);
  });

  it('should log without console output', () => {
    service.doSomething();
    const logs = logger.getStoredLogs();
    expect(logs.length).toBeGreaterThan(0);
  });
});
```

### Example 5: Temporary Debug Logger

```typescript
// In your service
private logger = inject(LoggerService);

debugComplexOperation() {
  // Use debug-level logger just for this operation
  const debugLogger = this.logger.withConfig({
    logLevel: 'trace'
  });

  debugLogger.trace('Step 1: Starting complex operation');
  debugLogger.trace('Step 2: Processing data');
  debugLogger.trace('Step 3: Finalizing');

  // Regular logger respects original config
  this.logger.info('Complex operation completed');
}
```

### Example 6: Download Logs for Debugging

```typescript
// In a settings or debug component
downloadApplicationLogs() {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const filename = `app-logs-${timestamp}.json`;

  this.logger.downloadLogs(filename);
}
```

## Logging Best Practices

### ✅ Do

- **Use appropriate log levels**: Use `info` for normal flow, `warn` for recoverable issues, `error` for failures
- **Add context**: Include component name and action to help debugging
- **Log at boundaries**: Log when entering/exiting major functions or components
- **Use descriptive messages**: Make it clear what happened
- **Include errors properly**: Pass Error objects to error/fatal methods

```typescript
// Good
this.logger.info('User authenticated', {
  component: 'AuthService',
  action: 'login',
  userId: user.id,
});

try {
  await this.api.fetch();
} catch (error) {
  this.logger.error('API request failed', error as Error, {
    component: 'DataService',
    action: 'fetch',
  });
}
```

### ❌ Don't

- **Avoid logging sensitive data**: Don't log passwords, tokens, or personal information
- **Don't use error level for everything**: Use appropriate levels
- **Don't log in tight loops**: Can impact performance
- **Don't leave debug logs in production**: Use log level filtering instead

```typescript
// Bad
this.logger.error('Password received: ' + password); // Security issue!
this.logger.error('Button clicked'); // Should be 'info'

for (let i = 0; i < 1000000; i++) {
  this.logger.trace('Processing item ' + i); // Performance issue
}
```

## Color Scheme

The logger automatically applies theme-aware colors to console output.

### Light Mode (Default)

- Trace: Dark Gray
- Debug: Dark Blue
- Info: Dark Green
- Warn: Dark Orange
- Error: Dark Red
- Fatal: White on Red

### Dark Mode

- Trace: Light Gray
- Debug: Light Blue
- Info: Light Green
- Warn: Light Orange
- Error: Light Red
- Fatal: White on Light Red

## Storage

### In-Memory Storage

Logs are stored in memory by default (up to 1000 logs). Use `getStoredLogs()` to retrieve them.

### IndexedDB Persistence

Enable persistent storage for logs that survive page refreshes:

```typescript
provideLogger({
  enableLogging: true,
  persistToIndexedDB: true,
  idbRetentionDays: 7, // Keep for 7 days
  idbMaxLogs: 5000, // Store max 5000 logs
});
```

**Note**: IndexedDB is asynchronous. Use `await logger.getPersistedLogs()` to retrieve stored logs.

## Testing

The logger includes 50+ tests covering all functionality. Tests use Jest and ng-mocks patterns:

```typescript
import { TestBed } from '@angular/core/testing';
import { LoggerService } from '@sixbell-telco/sdk/utils/logger';
import { provideLogger } from '@sixbell-telco/sdk/utils/logger';

describe('LoggerService', () => {
  let service: LoggerService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [provideLogger({ enableLogging: true, logLevel: 'trace' })],
    });
    service = TestBed.inject(LoggerService);
  });

  it('should log messages', () => {
    service.info('Test message');
    const logs = service.getStoredLogs();
    expect(logs[0].message).toBe('Test message');
  });
});
```

## Common Issues

### Logs Not Appearing

**Problem**: No logs in console

- Check `enableLogging` is `true`
- Check `logLevel` is set to capture your message level
- Check `silentMode` is `false`

### IndexedDB Not Persisting

**Problem**: Logs not saved to IndexedDB

- Check `persistToIndexedDB` is `true`
- Check browser supports IndexedDB (not disabled in settings)
- Verify logs using browser DevTools → Application → IndexedDB → sixbell_ui_kit

### Performance Issues

**Problem**: Console output is slow

- Reduce `logLevel` to only log important messages
- Use `silentMode: true` for high-frequency operations
- Avoid logging large objects

## API Types

```typescript
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';

export interface LoggerContext {
  component?: string;
  action?: string;
  timestamp?: number;
  [key: string]: unknown; // Custom properties
}

export interface LoggerConfig {
  enableLogging?: boolean;
  logLevel?: LogLevel;
  showTimestamp?: boolean;
  showDate?: boolean;
  silentMode?: boolean;
  persistToIndexedDB?: boolean;
  idbRetentionDays?: number;
  idbMaxLogs?: number;
  isDarkMode?: boolean;
  onError?: (error: Error, context: LoggerContext) => void;
  errorReporter?: {
    captureException: (error: Error, context?: LoggerContext) => void;
  };
}
```

IndexedDB requires modern browser support (IE not supported).

## Performance Considerations

- **In-Memory Storage**: Max 1000 logs to prevent memory bloat
- **IndexedDB**: Asynchronous, doesn't block main thread
- **Console Output**: Can be disabled with `silentMode`
- **Theme Detection**: Only initialized when logging is enabled

## Contributing

When adding features to the logger:

1. Update types in `models/logger.ts`
2. Add constants in `constants.ts`
3. Update `LoggerService` implementation
4. Add tests in `logger.service.spec.ts`
5. Update provider tests in `logger.provider.spec.ts`
6. Update this README with examples

## Related Documentation

- [UI Kit Overview](../../README.md)
- [Theme Utility](../theme/README.md)
- [Translation Utility](../translation/README.md)
