Metadata-Version: 2.4
Name: lumax
Version: 0.1.0
Summary: Lumax is a lightweight Python logging library designed to bring clarity and visibility to application behavior through structured, developer-friendly logs.
Author-email: Agra Bima Yuda <hub.agrayuda@gmail.com>
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.14
Requires-Dist: pydantic>=2.13.4
Requires-Dist: typal>=0.1.3
Description-Content-Type: text/markdown

# lumax

A lightweight structured logging framework for modern Python.

lumax focuses on composable logging pipelines, immutable events, structured fields, and sink-based extensibility.

---

## Features

* Structured logging
* Immutable event model
* Composable sink pipeline
* Filtering support
* Field transformation system
* Include / exclude / redact support
* JSON serialization
* Console logging
* File logging
* HTTP logging
* Easy integration with Promtail, Loki, and other observability stacks
* Type-safe architecture
* Minimal and extensible design

---

## Installation

```bash
pip install lumax
```

---

## Overview

lumax is built around four core concepts:

| Concept   | Responsibility                 |
| --------- | ------------------------------ |
| Event     | Immutable log payload          |
| Identity  | Metadata describing the source |
| Sink      | Output destination             |
| Transform | Field projection and redaction |

The logging pipeline is intentionally simple:

```text
Logger
  → FilterSink
  → TransformSink
  → Output Sink
```

---

# Quick Start

## Basic Logger

```python
from lumax.core.identity import Identity
from lumax.core.level import Level
from lumax.logger import Logger
from lumax.sinks.console import ConsoleSink

logger = Logger(
    identity=Identity(
        environment="development",
        service="api",
        type="application",
    ),
    sinks=[ConsoleSink()],
)

logger.info(
    "User authenticated",
    user_id=123,
    provider="github",
)
```

---

## Example Output

```json
{
  "timestamp": "2026-05-22T10:00:00+00:00",
  "level": "INFO",
  "identity": {
    "environment": "development",
    "service": "api",
    "type": "application"
  },
  "message": "User authenticated",
  "fields": {
    "user_id": 123,
    "provider": "github"
  }
}
```

---

# Core Concepts

## Identity

Identity describes where a log event originates from.

```python
from lumax.core.identity import Identity

identity = Identity(
    environment="production",
    service="billing",
    type="service",
)
```

### Fields

| Field       | Description                    |
| ----------- | ------------------------------ |
| environment | Runtime environment            |
| service     | Service or application name    |
| type        | Logger category                |
| labels      | Additional structured metadata |

---

## Event

Every emitted log becomes an immutable `Event`.

```python
from lumax.core.event import Event
```

An event contains:

* timestamp
* level
* identity
* message
* fields

---

## Levels

```python
from lumax.core.level import Level
```

Available levels:

* DEBUG
* INFO
* WARNING
* ERROR
* CRITICAL

---

# Sinks

Sinks are responsible for outputting log events.

## ConsoleSink

```python
from lumax.sinks.console import ConsoleSink
```

Outputs logs to stdout.

---

## FileSink

```python
from lumax.sinks.file import FileSink
```

Writes logs to files.

### Example

```python
from lumax.sinks.file import FileSink

sink = FileSink(
    dir="./logs",
)
```

If no filename is provided, lumax automatically generates one using the current UTC timestamp.

Example:

```text
2026-05-22_10-00-00.log
```

---

## HTTPSink

```python
from lumax.sinks.http import HTTPSink
```

Sends logs to HTTP endpoints using `httpx`.

### Example

```python
import httpx

from lumax.sinks.http import HTTPSink

client = httpx.Client(
    base_url="https://example.com",
    headers={
        "Authorization": "Bearer token"
    },
)

sink = HTTPSink(
    client=client,
    url="/logs",
)
```

---

# Filtering

Filtering controls whether an event should be emitted.

```python
from lumax.core.filter import Filter
from lumax.sinks.filtering import FilterSink
from lumax.core.level import Level
```

### Example

```python
sink = FilterSink(
    sink=ConsoleSink(),
    filter=Filter(
        level=Level.INFO,
        types=frozenset({"application"}),
    ),
)
```

---

# Transformations

Transformations reshape event fields before emission.

lumax supports:

* include
* exclude
* redact

The transformation system mirrors Pydantic's include/exclude behavior.

---

## Include

```python
from lumax.core.transform import Transform

transform = Transform(
    include={
        "user": {
            "id",
            "username",
        }
    }
)
```

---

## Exclude

```python
transform = Transform(
    exclude={
        "password": True,
        "token": True,
    }
)
```

---

## Redact

```python
transform = Transform(
    redact={
        "email": True,
        "credit_card": True,
    }
)
```

---

## TransformSink

```python
from lumax.sinks.transform import TransformSink

sink = TransformSink(
    sink=ConsoleSink(),
    transform=transform,
)
```

---

# Structured Fields

Additional fields can be attached to every log event.

```python
logger.info(
    "Payment processed",
    payment_id="pay_123",
    amount=1000,
    currency="USD",
)
```

These fields remain structured and serializable.

---

# JSON Serialization

Events are serializable via:

```python
event.to_json()
```

lumax includes a robust serializer capable of handling:

* dataclasses
* datetime
* UUID
* enums
* mappings
* sequences
* Pydantic models

---

# Integration with Observability Stacks

lumax is designed to integrate cleanly with:

* Grafana Loki
* Promtail
* ELK Stack
* OpenTelemetry pipelines
* Cloud logging systems

Because events are structured JSON objects, lumax works naturally with log aggregation systems.

---

# Design Philosophy

lumax follows several core principles:

## Immutable Events

Events are never mutated after creation.

## Structured First

Logs should be machine-readable by default.

## Composable Pipelines

Behavior is composed through sinks.

## Minimal Core

The framework stays lightweight while remaining extensible.

## Explicit Transformations

Filtering and field shaping are separate concerns.

---

# Example Pipeline

```python
from lumax.core.filter import Filter
from lumax.core.identity import Identity
from lumax.core.level import Level
from lumax.core.transform import Transform
from lumax.logger import Logger
from lumax.sinks.console import ConsoleSink
from lumax.sinks.filtering import FilterSink
from lumax.sinks.transform import TransformSink

sink = TransformSink(
    sink=FilterSink(
        sink=ConsoleSink(),
        filter=Filter(
            level=Level.INFO,
        ),
    ),
    transform=Transform(
        redact={
            "password": True,
            "token": True,
        },
    ),
)

logger = Logger(
    identity=Identity(
        environment="development",
        service="api",
        type="application",
    ),
    sinks=[sink],
)

logger.info(
    "User login",
    username="agra",
    password="secret",
    token="jwt-token",
)
```

---

# License

MIT
