Metadata-Version: 2.4
Name: T-autolog
Version: 2.3.0
Summary: Zero-config auto-instrumentation logging for Python
Author-email: Hamza Ennaffati <hamzaennaffati98@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/YOUR_USERNAME/autolog
Project-URL: Repository, https://github.com/YOUR_USERNAME/autolog
Project-URL: Issues, https://github.com/YOUR_USERNAME/autolog/issues
Keywords: logging,instrumentation,tracing,debugging,autolog
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Logging
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: tomli>=2.0; python_version < "3.11"
Provides-Extra: fastapi
Requires-Dist: starlette>=0.20; extra == "fastapi"
Provides-Extra: flask
Requires-Dist: flask>=2.0; extra == "flask"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: httpx; extra == "dev"
Requires-Dist: fastapi; extra == "dev"
Requires-Dist: flask; extra == "dev"

# autolog

> Zero-config, structured, async-safe logging for Python. Drop one line into your entrypoint and every function call gets instrumented — inputs, outputs, duration, errors, traces. No changes to your business logic required.

---

## Features

- **Zero-touch** — `autolog.start()` patches your packages at import time
- **Structured output** — `pretty` for dev, `json` for production (Datadog/Loki/ELK)
- **Async-native** — sync, `async def`, generators, async generators all handled
- **Sensitive data redaction** — passwords, tokens, API keys auto-masked
- **Trace IDs + bound context** — `bind(user_id=42)` adds fields to every downstream log
- **Sampling** — `sample=0.01` to log 1% of calls in hot paths
- **Exclude patterns** — skip noisy modules without touching their code
- **Per-package levels** — DEBUG one package, WARN another
- **Production-safe** — rotating files, traceback capture, body-size guards, upstream trace propagation
- **Single CLI** — `autolog run myapp.main`, no entrypoint changes needed

---

## Installation

```bash
pip install autolog
pip install "autolog[fastapi]"   # FastAPI middleware
pip install "autolog[flask]"     # Flask middleware
```

---

## Quick start

```python
import autolog
autolog.start()

# everything you import from here on is auto-logged
from myapp.services import process_order
process_order(123)
```

**Output:**

```
[2026-05-07 14:23:01.042] [INFO ] [myapp.services.process_order]
  ▸ trace    : 3f4a1b2c-...
  ▸ inputs   : {"order_id": 123}
  ▸ result   : {"status": "ok"}
  ▸ duration : 0.0031 s
```

---

## The `start()` API

`start()` is the single entry point. All options are optional.

```python
autolog.start(
    packages=["myapp", "utils"],         # None → auto-discover
    exclude=["myapp.hot_path.*"],        # glob patterns to skip
    service="my-api",                    # label in logs
    level={"myapp": "DEBUG", "default": "INFO"},
    format="json",                       # or "pretty" (default)
    log_file="app.log",                  # rotating, 10MB × 5 backups
    sample=0.1,                          # log 10% of calls
    config="pyproject.toml",             # explicit config path
)
```

### Resolution order
**kwargs > env vars > `[tool.autolog]` in `pyproject.toml` > defaults**

---

## Three ways to use it

### 1. Code

```python
import autolog
autolog.start(packages=["myapp"])
```

### 2. Config in `pyproject.toml`

```toml
[tool.autolog]
packages = ["myapp", "utils"]
exclude  = ["myapp.cache.*"]
service  = "my-api"
level    = { myapp = "DEBUG", default = "INFO" }
format   = "json"
log_file = "app.log"
sample   = 0.5
```

```python
import autolog
autolog.start()   # reads pyproject.toml automatically
```

### 3. CLI runner — zero entrypoint changes

```bash
autolog run myapp.main
autolog run myapp.main --format json --level DEBUG
autolog run myapp.main --exclude "myapp.hot.*" --sample 0.1
autolog show                              # show resolved config
```

---

## Bound context fields (structlog-style)

Attach fields once, get them on every log inside the same async context:

```python
from autolog import bind, unbind

async def request_middleware(request, call_next):
    bind(user_id=request.user.id, org_id=request.org.id)
    try:
        return await call_next(request)
    finally:
        unbind()
```

Now every log inside this request includes `user_id` and `org_id` automatically — no need to pass them around.

---

## Decorator mode (opt-in)

```python
from autolog import log, no_log

@log
def calculate(x, y): ...

@log
class OrderService:
    def create(self, data): ...

@log(sample=0.01)         # log 1% of calls
def hot_path(): ...

@no_log                    # never log this one, even if package is auto-instrumented
def secret_op(): ...
```

`@log` works on both functions and classes — handles `@staticmethod`, `@classmethod`, `@property`, sync/async/generators automatically.

---

## Trace IDs

Async-safe per-request correlation:

```python
from autolog import new_trace_id, get_trace_id, set_trace_id

new_trace_id()                        # generate UUID4 for this context
set_trace_id("custom-id")             # use an externally-supplied one
get_trace_id()                        # read current
```

---

## Framework middleware

### FastAPI

```python
from fastapi import FastAPI
from autolog.middleware.fastapi import AutoLogMiddleware

app = FastAPI()
app.add_middleware(AutoLogMiddleware, service="my-api")
```

- Honors upstream `X-Request-ID`, `X-Trace-ID`, `traceparent` headers
- Skips body capture for `multipart/`, `octet-stream`, `text/event-stream`, `image/*`, `video/*`
- Truncates large bodies at `max_body_bytes` (default 64KB) — won't OOM on uploads
- Async-safe: logging runs in `BackgroundTask`, never blocks the response

### Flask

```python
from flask import Flask
from autolog.middleware.flask import init_autolog

app = Flask(__name__)
init_autolog(app, service="my-api")
```

---

## Configuration via environment variables

| Var | Effect |
|---|---|
| `AUTOLOG_LEVEL` | Override level |
| `AUTOLOG_FILE` | Mirror logs to file |
| `AUTOLOG_FORMAT` | `pretty` or `json` |
| `AUTOLOG_SERVICE` | Service name |
| `AUTOLOG_DISABLE=1` | Disable all instrumentation |
| `AUTOLOG_FILE_MAX_BYTES` | Rotation size, default 10MB |
| `AUTOLOG_FILE_BACKUPS` | Rotated backups, default 5 |
| `NO_COLOR=1` | Disable ANSI colors |

---

## Sensitive data redaction

These keys (and tokens within them) are auto-redacted:

`password`, `passwd`, `token`, `secret`, `auth`, `credential`, `apikey`, `jwt`, `bearer`, `api_key`, `access_token`, `refresh_token`, `private_key`

Token-aware: `apiKey`, `API_KEY`, `client.secret` all match. `keyword`, `monkey`, `author` do **not** match (no false positives).

---

## License

MIT
