# VedaTrace (Python SDK)

VedaTrace is a production-grade Python logging SDK for structured application logs.
It provides a safe, synchronous-first API with built-in transports, batching, retry controls, and contextual child loggers.

---

## Table of Contents

- [Installation](#installation)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Transports](#transports)
- [Batching (Opt-In)](#batching-opt-in)
- [Retry Policy (HTTP Only)](#retry-policy-http-only)
- [Child Loggers](#child-loggers)
- [Safety Guarantees](#safety-guarantees)
- [License](#license)

---

## Installation

```bash
pip install vedatrace
```

## Quickstart

```python
from vedatrace import VedaTrace, VedaTraceConfig

config = VedaTraceConfig(
    api_key="YOUR_API_KEY",
    service="your-service",
    console_enabled=False,
)

logger = VedaTrace("YOUR_API_KEY", service="your-service", config=config)
logger.info("Service started", {"env": "production"})
```

## Configuration

Use `VedaTraceConfig` to control runtime behavior.

```python
from vedatrace import BatchingConfig, RetryConfig, VedaTrace, VedaTraceConfig


def on_error(exc: Exception) -> None:
    # Route SDK failures to your telemetry.
    pass


config = VedaTraceConfig(
    api_key="YOUR_API_KEY",
    service="your-service",
    console_enabled=False,
    batching=BatchingConfig(enabled=True, batch_size=10, flush_interval_seconds=5.0),
    retry=RetryConfig(max_retries=3, retry_delay_seconds=1.0),
    on_error=on_error,
)

logger = VedaTrace("YOUR_API_KEY", service="your-service", config=config)
```

## Transports

Default behavior:
- HTTP transport is enabled by default.
- Console transport is enabled when `console_enabled=True`.

Custom transports:
- If `config.transports` is set, only those transports are used.

```python
from vedatrace import LogRecord, VedaTrace, VedaTraceConfig


class MemoryTransport:
    def __init__(self) -> None:
        self.batches: list[list[LogRecord]] = []

    def emit(self, records: list[LogRecord]) -> None:
        self.batches.append(list(records))

    def close(self) -> None:
        return None


transport = MemoryTransport()
config = VedaTraceConfig(
    api_key="YOUR_API_KEY",
    service="your-service",
    console_enabled=False,
    transports=[transport],
)

logger = VedaTrace("YOUR_API_KEY", service="your-service", config=config)
logger.info("Stored in custom transport")
```

## Batching (Opt-In)

Batching is disabled by default. Enable it to queue logs and flush in groups by threshold or interval.

```python
from vedatrace import BatchingConfig, VedaTrace, VedaTraceConfig

config = VedaTraceConfig(
    api_key="YOUR_API_KEY",
    service="your-service",
    console_enabled=False,
    batching=BatchingConfig(enabled=True, batch_size=10, flush_interval_seconds=5.0),
)

logger = VedaTrace("YOUR_API_KEY", service="your-service", config=config)
logger.info("Queued log")
logger.flush()  # Force-send pending records
```

## Retry Policy (HTTP Only)

`RetryConfig` applies only to HTTP sends. Retries use a fixed delay and stop after the configured maximum attempts.
If all retries fail, the final error is routed to `on_error` when provided.

```python
from vedatrace import RetryConfig, VedaTrace, VedaTraceConfig

config = VedaTraceConfig(
    api_key="YOUR_API_KEY",
    service="your-service",
    console_enabled=False,
    retry=RetryConfig(max_retries=3, retry_delay_seconds=1.0),
)

logger = VedaTrace("YOUR_API_KEY", service="your-service", config=config)
logger.info("Event")
```

## Child Loggers

```python
from vedatrace import VedaTrace

parent = VedaTrace("YOUR_API_KEY", service="your-service")
api_logger = parent.child({"module": "api"})
api_logger.info("Request handled", {"request_id": "123"})
```

Metadata precedence is: `parent defaults < child defaults < per-call metadata`.
Child loggers share engine resources; `child.close()` does not tear down the parent-owned engine.

## Safety Guarantees

- Public logging methods never raise (`debug`, `info`, `warning`, `error`, `fatal`, `flush`, `close`).
- Internal failures are swallowed and routed to `on_error(Exception)` when configured.

## License

MIT

