Metadata-Version: 2.4
Name: fastapi-logplus
Version: 0.1.0
Summary: A FastAPI logging toolkit with structured logging, middleware, and observability utilities
Author: Amogha Hegde
License: MIT
Project-URL: Homepage, https://github.com/Amogha-Hegde/fastapi-logplus
Project-URL: Repository, https://github.com/Amogha-Hegde/fastapi-logplus
Project-URL: Issues, https://github.com/Amogha-Hegde/fastapi-logplus/issues
Keywords: fastapi,logging,observability,json-logging,middleware,request-id
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Framework :: AsyncIO
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi
Provides-Extra: color
Requires-Dist: colorlog>=6.8.0; extra == "color"
Provides-Extra: json
Requires-Dist: orjson>=3.10.0; extra == "json"
Provides-Extra: test
Requires-Dist: httpx2>=2.0.0; python_version >= "3.10" and extra == "test"
Requires-Dist: pytest>=8.0.0; extra == "test"
Requires-Dist: pytest-cov>=5.0.0; extra == "test"
Dynamic: license-file

# fastapi-logplus

[![Tests](https://github.com/Amogha-Hegde/fastapi-logplus/actions/workflows/ci.yml/badge.svg)](https://github.com/Amogha-Hegde/fastapi-logplus/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/Amogha-Hegde/fastapi-logplus/branch/main/graph/badge.svg)](https://codecov.io/gh/Amogha-Hegde/fastapi-logplus)
[![PyPI version](https://img.shields.io/pypi/v/fastapi-logplus.svg)](https://pypi.org/project/fastapi-logplus/)
[![Python versions](https://img.shields.io/pypi/pyversions/fastapi-logplus.svg)](https://pypi.org/project/fastapi-logplus/)
[![PyPI downloads](https://static.pepy.tech/badge/fastapi-logplus)](https://pepy.tech/project/fastapi-logplus)

`fastapi-logplus` is a reusable logging toolkit for FastAPI services. It gives you one place to standardize logging config, request-scoped context, structured output, and uvicorn logger behavior across services.

## Features

- plain, color, or JSON log output
- optional timed rotating file logging
- request-scoped context via `ContextVar`
- request ID generation and propagation
- trace, span, project, org, tenant, and user context extraction
- request and response summary/header/body logging
- per-logger level overrides for `uvicorn`, `fastapi`, `starlette`, and app loggers

## Installation

Base install:

```bash
pip install fastapi-logplus
```

With colored console logging:

```bash
pip install "fastapi-logplus[color]"
```

With JSON logging support:

```bash
pip install "fastapi-logplus[json]"
```

For development and tests:

```bash
pip install "fastapi-logplus[test]"
```

## Quick Start

```python
import logging.config

from fastapi import FastAPI

from fastapi_logplus import RequestContextMiddleware, get_logger_config

app = FastAPI()
app.add_middleware(RequestContextMiddleware)

logging.config.dictConfig(
    get_logger_config(
        log_level="INFO",
        console_style="color",
        include_request_id=True,
    )
)


@app.get("/health")
async def health():
    return {"ok": True}
```

Runnable example:

```bash
python -m examples.basic_app
```

## JSON Logging Example

```python
import logging.config

from fastapi_logplus import get_logger_config

logging.config.dictConfig(
    get_logger_config(
        log_level="INFO",
        console_style="json",
        include_request_id=True,
        logger_levels={
            "uvicorn.access": "WARNING",
        },
    )
)
```

## File Logging Example

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

from fastapi_logplus import get_logger_config

logging.config.dictConfig(
    get_logger_config(
        log_level="INFO",
        base_dir=Path("."),
        log_file_name="app.log",
        enable_file_logging=True,
        console_style="plain",
        file_style="json",
        include_request_id=True,
    )
)
```

This creates `./logs/app.log` with timed rotation via `TimedRotatingFileHandler`.

## Middleware

Available middleware exports:

- `RequestContextMiddleware`
- `RequestLogMiddleware`
- `RequestIdMiddleware`

`RequestContextMiddleware` is the main one to use. It:

- reads incoming context headers like `x-request-id` and `x-trace-id`
- generates a request ID when one is missing
- binds request context into log records
- propagates `x-request-id` back on the response
- can emit request and response logs when enabled through env vars

## Public API

Config:

- `get_logger_config`
- `get_logger_config_from_file`
- `get_logger_config_with_file`
- `get_logger_config_without_file`

Context helpers:

- `bind_log_context`
- `bind_request_context`
- `bind_request_id`
- `bind_trace_context`
- `get_log_context`
- `get_request_id`
- `wrap_with_log_context`
- `wrap_with_request_context`
- `wrap_with_request_id`
- `wrap_with_trace_context`

Filters and formatters:

- `RequestIdFilter`
- `LogContextFilter`
- `SafePlainFormatter`
- `SafeColoredFormatter`
- `JsonFormatter`

## INI Config

`get_logger_config_from_file()` reads a `[fastapi-logplus]` section. See:

- `fastapi-logplus.plain.sample.ini`
- `fastapi-logplus.json.sample.ini`

Minimal example:

```ini
[fastapi-logplus]
log_level = INFO
console_style = color
include_request_id = true
include_uvicorn_logs = true
```

Full plain-text sample:

```ini
[fastapi-logplus]
log_level = INFO
console_style = plain
include_request_id = true
include_uvicorn_logs = true
enable_file_logging = true
base_dir = .
log_file_name = app.log
file_style = plain
log_when = W0
log_backup = 100
log_timezone = UTC
app_loggers =
    main

[logger_levels]
uvicorn.access = WARNING
uvicorn.error = INFO
fastapi = INFO
main = DEBUG

[text_field_defaults]
tenant = -
user_id = null
```

Full JSON sample:

```ini
[fastapi-logplus]
log_level = INFO
console_style = json
include_request_id = true
include_uvicorn_logs = true
enable_file_logging = true
base_dir = .
log_file_name = app.json.log
file_style = json
log_when = W0
log_backup = 100
log_timezone = UTC
app_loggers =
    main

[logger_levels]
uvicorn.access = WARNING
uvicorn.error = INFO
main = DEBUG

[json_fields]
timestamp = timestamp
level = levelname
logger = name
message = message
event = event
method = method
path = path
status_code = status_code
request_id = request_id
trace_id = trace_id
tenant = tenant
user_id = user_id
duration_ms = duration_ms

[json_field_defaults]
tenant = -
user_id = null

[text_field_defaults]
tenant = -
user_id = null
```

### `[fastapi-logplus]`

- `log_level`: required default log level for configured app loggers. Values are normalized to uppercase, for example `INFO`, `DEBUG`, `WARNING`, `ERROR`.
- `console_style`: console formatter style. Accepted values: `plain`, `color`, `json`.
- `include_request_id`: boolean flag that adds `RequestIdFilter` to handlers and appends request context fields to text logs.
- `include_uvicorn_logs`: boolean flag that includes or excludes `uvicorn`, `uvicorn.access`, and `uvicorn.error` from configured named loggers.
- `enable_file_logging`: boolean flag that enables timed rotating file logging. If omitted, file logging turns on automatically when `log_file_name` is set.
- `base_dir`: base path used for file logging. Log files are written under `<base_dir>/logs/`.
- `log_file_name`: file name for rotating file logs, such as `app.log` or `app.json.log`. It must be a file name, not a path.
- `file_style`: file formatter style. Accepted values: `plain`, `color`, `json`.
- `log_when`: `TimedRotatingFileHandler` rotation interval. Accepted values: `S`, `M`, `H`, `D`, `MIDNIGHT`, or `W0` through `W6`.
- `log_backup`: number of rotated files to retain. Must be an integer greater than or equal to `0`.
- `log_timezone`: timezone used by text and JSON formatters. Use `UTC`, `local`, or any valid IANA timezone such as `Asia/Kolkata`.
- `app_loggers`: comma-separated or multiline list of additional named loggers to configure.

Boolean INI values accept `1`, `true`, `yes`, `on`, `0`, `false`, `no`, and `off`.

### `[logger_levels]`

Use this section for per-logger level overrides:

```ini
[logger_levels]
uvicorn.access = WARNING
uvicorn.error = INFO
fastapi = INFO
main = DEBUG
```

Each key is a logger name and each value is a log level. Logger names listed here are also added to the configured logger set.

### `[json_fields]`

Use this section only with JSON output. Each key is the output JSON key and each value is the source `LogRecord` field:

```ini
[json_fields]
timestamp = timestamp
level = levelname
logger = name
message = message
event = event
method = method
path = path
status_code = status_code
request_id = request_id
trace_id = trace_id
tenant = tenant
user_id = user_id
duration_ms = duration_ms
```

Special source fields include `timestamp`, `asctime`, `message`, and `hostname`. Other values are read directly from the log record, including request context fields populated by middleware and filters.

### `[json_field_defaults]`

Use this section to provide fallback JSON values when a mapped field is missing:

```ini
[json_field_defaults]
tenant = -
user_id = null
```

The literal INI value `null` becomes Python `None`; fields with `None` values are omitted from JSON output.

### `[text_field_defaults]`

Use this section to provide fallback values for text formatter fields:

```ini
[text_field_defaults]
tenant = -
user_id = null
```

These defaults prevent text format strings from failing when optional request context fields are absent.

### `[log_colors]`

Optional color formatter overrides can be supplied as level-to-color mappings:

```ini
[log_colors]
DEBUG = blue
INFO = bold_white
WARNING = yellow
ERROR = red
CRITICAL = bold_red
```

This section is used by `console_style = color` or `file_style = color` and requires the `color` extra for colored output.

## Environment Variables

See `.env.example` for copyable example values.

Request logging configuration:

- `FASTAPI_LOGPLUS_LOG_REQUESTS`
- `FASTAPI_LOGPLUS_LOG_REQUEST_HEADERS`
- `FASTAPI_LOGPLUS_LOG_RESPONSE_HEADERS`
- `FASTAPI_LOGPLUS_LOG_REQUEST_BODY`
- `FASTAPI_LOGPLUS_LOG_RESPONSE_BODY`
- `FASTAPI_LOGPLUS_REQUEST_LOGGER`
- `FASTAPI_LOGPLUS_BODY_MAX_LENGTH`
- `FASTAPI_LOGPLUS_REDACT_HEADERS`

Header overrides:

- `FASTAPI_LOGPLUS_REQUEST_ID_HEADER`
- `FASTAPI_LOGPLUS_TRACE_ID_HEADER`
- `FASTAPI_LOGPLUS_SPAN_ID_HEADER`
- `FASTAPI_LOGPLUS_PROJECT_ID_HEADER`
- `FASTAPI_LOGPLUS_ORG_ID_HEADER`
- `FASTAPI_LOGPLUS_TENANT_HEADER`
- `FASTAPI_LOGPLUS_USER_ID_HEADER`

Response propagation flags:

- `FASTAPI_LOGPLUS_PROPAGATE_TRACE_ID`
- `FASTAPI_LOGPLUS_PROPAGATE_SPAN_ID`
- `FASTAPI_LOGPLUS_PROPAGATE_PROJECT_ID`
- `FASTAPI_LOGPLUS_PROPAGATE_ORG_ID`
- `FASTAPI_LOGPLUS_PROPAGATE_TENANT`
- `FASTAPI_LOGPLUS_PROPAGATE_USER_ID`

Structured output metadata:

- `FASTAPI_LOGPLUS_SERVICE_NAME`
- `FASTAPI_LOGPLUS_ENVIRONMENT`

## Scope

This package focuses on application logging and request context for FastAPI services. It does not try to replace full observability tooling.
