# Logging Framework

## Purpose

VCollab applications need consistent logging across all scripts and
services — same log levels, same format, same behavior. The
`vcti-logging` package provides configurable logging with custom log
levels (TRACE, VERBOSE), color output, and flexible handler
configuration for console and file targets.

**Dependencies:** `colorlog` (for colored console output)

---

## Installation

```bash
# Latest main branch
pip install vcti-logging



### In `requirements.txt`

```
vcti-logging>=1.0.5
```

### In `pyproject.toml` dependencies

```toml
dependencies = [
    "vcti-logging>=1.0.5",
]
```

---

## Quick Start

```python
from pathlib import Path
from vcti.logging import logger, setup_logging
from vcti.logging.config import ConsoleLogConfig, FileLogConfig

# Setup console logging with color
setup_logging([
    ConsoleLogConfig(log_level="debug", enable_color_log=True),
])

# Log at standard levels
logger.info("Application started")
logger.warning("Low disk space")
logger.error("Connection failed")

# Log at custom levels
logger.trace("Entering function X with args: %s", args)
logger.verbose("Processing item %d of %d", i, total)

# Setup console + file logging
setup_logging([
    ConsoleLogConfig(log_level="info", enable_color_log=True),
    FileLogConfig(log_level="debug", file_path=Path("app.log")),
])
```

---

## Log Levels

| Level | Value | Purpose |
|-------|-------|---------|
| `TRACE` | 5 | Very detailed diagnostic output |
| `DEBUG` | 10 | Debug information |
| `VERBOSE` | 15 | Detailed but less noisy than DEBUG |
| `INFO` | 20 | General information |
| `WARNING` | 30 | Warning conditions |
| `ERROR` | 40 | Error conditions |
| `FATAL` | 50 | Critical/fatal errors |

All levels are available as strings for configuration: `"trace"`,
`"debug"`, `"verbose"`, `"info"`, `"warning"`, `"error"`, `"fatal"`.

---

## Configuration

### Message Format Presets

Instead of writing raw format strings, use named presets:

| Preset | What it shows | Use case |
|--------|--------------|----------|
| `"minimal"` | message only | CLI tools, clean output |
| `"standard"` | level + message | general development (default) |
| `"detailed"` | level + file + line + message | debugging |

Each preset has a plain and color variant — the correct one is selected
automatically based on `enable_color_log`.

You can also pass a raw format string (e.g.,
`"%(asctime)s - %(levelname)s - %(message)s"`) if presets don't fit your
needs.

### Console logging

```python
from vcti.logging.config import ConsoleLogConfig

# Using a preset (recommended)
config = ConsoleLogConfig(
    log_level="debug",
    enable_color_log=True,
    message_format="detailed",
)

# Using a raw format string
config = ConsoleLogConfig(
    log_level="debug",
    message_format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
```

### File logging

```python
from pathlib import Path
from vcti.logging.config import FileLogConfig

config = FileLogConfig(
    file_path=Path("logs/application.log"),
    log_level="info",
    message_format="standard",
)
```

By default, the file handler opens in append mode (`"a"`). To overwrite
the file on each run, set `mode="w"`:

```python
config = FileLogConfig(
    file_path=Path("logs/application.log"),
    log_level="info",
    mode="w",
)
```

### Combined with different presets

Console and file handlers can use different presets independently:

```python
from pathlib import Path
from vcti.logging import setup_logging
from vcti.logging.config import ConsoleLogConfig, FileLogConfig

setup_logging([
    ConsoleLogConfig(log_level="info", enable_color_log=True, message_format="standard"),
    FileLogConfig(log_level="debug", file_path=Path("app.log"), message_format="detailed"),
])
```

---

## Public API

| Symbol | Purpose |
|--------|---------|
| `setup_logging(configs)` | Configure logging handlers |
| `logger` | Pre-configured logger instance (name: "vcti") |
| `MESSAGE_FORMAT_PRESETS` | Available format presets (minimal, standard, detailed) |
| `resolve_message_format(fmt)` | Resolve a preset name or raw format string |
| `LogLevel` | IntEnum of all log levels |
| `LogLevelStr` | Literal type for valid level strings |
| `decode_log_level(name)` | String to LogLevel enum |
| `encode_log_level(level)` | LogLevel enum to string |
| `LogLevelCoder` | Convenience class for Pydantic models |
| `CustomLevelLogger` | Logger class with trace()/verbose() methods |

---

## Child Loggers

The package logger is named `"vcti"`. Application code should create
child loggers to keep log output identifiable:

```python
import logging

app_logger = logging.getLogger("vcti.myapp")
app_logger.info("Application-specific message")
```

Child loggers inherit handlers and levels from the parent — no extra
`setup_logging()` call is needed.

---

## LogLevelCoder for Pydantic Models

```python
from pydantic import BaseModel, Field
from vcti.logging import LogLevelCoder

class AppConfig(BaseModel):
    log_level: LogLevelCoder.Literal = Field(
        default=LogLevelCoder.default,
        description=f"Supported: {'/'.join(LogLevelCoder.list)}",
    )
```

---

## Benchmarks

```bash
pip install -e ".[bench]"
python benchmarks/benchmark_logging.py
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for details.

---

## Documentation

- [Design](docs/design.md) — Architecture decisions and custom level design
- [Source Guide](docs/source-guide.md) — File descriptions and execution flows
- [API Reference](docs/api.md) — Autodoc for all modules
