# Unified Logging System

MotoVaultPro uses a unified logging system with centralized log aggregation.

## Overview

- **Single Control**: One `LOG_LEVEL` environment variable controls all containers
- **Correlation IDs**: `requestId` field traces requests across services
- **Centralized Aggregation**: Grafana + Loki for log querying and visualization

## LOG_LEVEL Values

| Level | Frontend | Backend | PostgreSQL | Redis | Traefik |
|-------|----------|---------|------------|-------|---------|
| DEBUG | debug | debug | all queries, 0ms | debug | DEBUG |
| INFO | info | info | DDL only, 500ms | verbose | INFO |
| WARN | warn | warn | errors, 1000ms | notice | WARN |
| ERROR | error | error | errors only | warning | ERROR |

## Environment Defaults

| Environment | LOG_LEVEL | Purpose |
|-------------|-----------|---------|
| Development | DEBUG | Full debugging locally |
| Staging | DEBUG | Full debugging in staging |
| Production | INFO | Standard production logging |

## Correlation IDs

All logs include a `requestId` field (UUID v4) for tracing requests:

- **Traefik**: Forwards X-Request-Id if present
- **Backend**: Generates UUID if X-Request-Id missing, includes in all logs
- **Frontend**: Includes requestId in API call logs

### Example Log Entry
```json
{
  "level": "info",
  "time": "2024-01-15T10:30:00.000Z",
  "requestId": "550e8400-e29b-41d4-a716-446655440000",
  "msg": "Request processed",
  "method": "GET",
  "path": "/api/vehicles",
  "status": 200,
  "duration": 45
}
```

## Grafana Access

- URL: https://logs.motovaultpro.com
- Default credentials: admin/admin (change on first login)

### Example LogQL Queries

Query by requestId:
```
{container="mvp-backend"} |= "550e8400-e29b-41d4"
```

Query all errors:
```
{container=~"mvp-.*"} | json | level="error"
```

Query slow requests (>500ms):
```
{container="mvp-backend"} | json | duration > 500
```

## Configuration

Logging configuration is generated by `scripts/ci/generate-log-config.sh`:

```bash
# Generate DEBUG level config
./scripts/ci/generate-log-config.sh DEBUG

# Generate INFO level config
./scripts/ci/generate-log-config.sh INFO
```

This creates `.env.logging` which is sourced by docker-compose.

## Architecture

```
+-----------------------------------------------------------------------+
|                         CI/CD PIPELINE                                |
|  LOG_LEVEL --> generate-log-config.sh --> .env.logging                |
+-----------------------------------------------------------------------+
                                |
                                v
+-----------------------------------------------------------------------+
|                       APPLICATION LAYER                               |
|  Frontend   Backend    OCR      Postgres   Redis    Traefik           |
|      |         |         |         |         |         |              |
|      +---------+---------+---------+---------+---------+              |
|                          |                                            |
|                Docker Log Driver (json-file, 10m x 3)                 |
+-----------------------------------------------------------------------+
                           |
                           v
              Alloy --> Loki (30-day retention) --> Grafana
```

## Troubleshooting

### Logs not appearing in Grafana

1. Check Alloy is running: `docker logs mvp-alloy`
2. Check Loki is healthy: `curl http://localhost:3100/ready`
3. Verify log rotation is not too aggressive

### Invalid LOG_LEVEL

Both frontend and backend will warn and fall back to 'info' if an invalid LOG_LEVEL is provided.
