mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-04-18 21:08:05 -04:00
117 lines
4.0 KiB
Markdown
117 lines
4.0 KiB
Markdown
# Logger
|
|
|
|
**Source:** `src/lib/server/utils/logger/` (`$logger/*`)
|
|
|
|
## Table of Contents
|
|
|
|
- [Log Levels](#log-levels)
|
|
- [Configuration](#configuration)
|
|
- [Output Formats](#output-formats)
|
|
- [Usage](#usage)
|
|
|
|
The logger is a singleton class that writes to two outputs simultaneously:
|
|
colored console lines for development and JSON files for persistence. Settings
|
|
are stored in SQLite and can be changed at runtime without a restart. Log files
|
|
rotate daily (`YYYY-MM-DD.log`) and are cleaned up by the `logsCleanup` job
|
|
based on a configurable retention window.
|
|
|
|
## Log Levels
|
|
|
|
Four levels, ordered from least to most severe:
|
|
|
|
| Level | Color | Purpose |
|
|
| ------- | ------ | ----------------------------------------- |
|
|
| `DEBUG` | Cyan | Internal diagnostics, step-by-step detail |
|
|
| `INFO` | Green | Normal operational events worth recording |
|
|
| `WARN` | Yellow | Unexpected but handled situations |
|
|
| `ERROR` | Red | Failures that need attention |
|
|
|
|
The `min_level` setting acts as a threshold filter. Setting it to `WARN` drops
|
|
all `DEBUG` and `INFO` entries. The default is `DEBUG` (log everything).
|
|
|
|
## Configuration
|
|
|
|
Settings live in the `log_settings` table (singleton row, `id = 1`):
|
|
|
|
| Column | Type | Default | Purpose |
|
|
| ----------------- | ------- | ------- | ----------------------------- |
|
|
| `retention_days` | integer | 30 | Days before cleanup deletes |
|
|
| `min_level` | text | DEBUG | Minimum severity to record |
|
|
| `enabled` | integer | 1 | Master toggle for all logging |
|
|
| `file_logging` | integer | 1 | Write to daily JSON files |
|
|
| `console_logging` | integer | 1 | Write to stdout with colors |
|
|
|
|
`LogSettingsManager` (`settings.ts`) caches these values in memory and exposes a
|
|
`reload()` method that the settings UI calls after saving. If the database is
|
|
unavailable (e.g. during early startup), the manager falls back to hardcoded
|
|
defaults: INFO level, both outputs enabled, 30-day retention.
|
|
|
|
## Output Formats
|
|
|
|
**Console** -- human-readable, ANSI-colored:
|
|
|
|
```
|
|
2026-04-14T12:00:00.000Z | INFO | Sync processing complete | [SyncProcessor] | {"totalSynced":4}
|
|
```
|
|
|
|
Each segment is pipe-delimited. Timestamps and metadata are grey; the level
|
|
token is colored per the table above.
|
|
|
|
**File** -- one JSON object per line, appended to `{logsDir}/YYYY-MM-DD.log`:
|
|
|
|
```json
|
|
{
|
|
"timestamp": "2026-04-14T12:00:00.000Z",
|
|
"level": "INFO",
|
|
"message": "Sync processing complete",
|
|
"source": "SyncProcessor",
|
|
"meta": { "totalSynced": 4 }
|
|
}
|
|
```
|
|
|
|
File writes are async and non-blocking. If a write fails the entry is lost but
|
|
the application continues normally.
|
|
|
|
## Usage
|
|
|
|
Import the singleton and call a level method:
|
|
|
|
```ts
|
|
import { logger } from '$logger/logger.ts';
|
|
|
|
await logger.info('Sync processing complete', {
|
|
source: 'SyncProcessor',
|
|
meta: { totalSynced: 4, instanceCount: 2 }
|
|
});
|
|
```
|
|
|
|
All four level methods (`debug`, `info`, `warn`, `error`) share the same
|
|
signature: `(message: string, options?: { source?: string; meta?: unknown })`.
|
|
They are async -- use `await` so file writes complete before the caller
|
|
continues.
|
|
|
|
`errorWithTrace` is a variant that also prints the stack trace to console (in
|
|
grey) and writes it to the file log's `meta.stack` field:
|
|
|
|
```ts
|
|
await logger.errorWithTrace('Failed to compile cache', error, {
|
|
source: 'PCDManager',
|
|
meta: { databaseId: id }
|
|
});
|
|
```
|
|
|
|
**Conventions:**
|
|
|
|
- `source` is the module or subsystem name (`PCDManager`, `SyncProcessor`,
|
|
`ArrSyncJob`, `NotificationManager`). Some modules use sub-tags like
|
|
`EntitySync:Cooldown`.
|
|
- `meta` carries structured context: IDs, counts, timing, error messages.
|
|
Keep it serializable -- no class instances or circular references.
|
|
- For testing, instantiate the `Logger` class directly with a custom config
|
|
instead of importing the singleton:
|
|
|
|
```ts
|
|
import { Logger } from '$logger/logger.ts';
|
|
const testLogger = new Logger({ logsDir: '/tmp/test-logs', minLevel: 'DEBUG' });
|
|
```
|