Metadata-Version: 2.4
Name: logthisx
Version: 0.2.0
Summary: A modern, friendly Python logging library with colors, rotation, JSON output, context binding and decorators.
Author-email: Kevin Gregoire <kevin.gregoire1004@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/laxyny/logthis
Project-URL: Repository, https://github.com/laxyny/logthis
Project-URL: Issues, https://github.com/laxyny/logthis/issues
Project-URL: Changelog, https://github.com/laxyny/logthis/blob/main/CHANGELOG.md
Keywords: logging,logger,colored,json-logging,rotation,structured-logging
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Topic :: System :: Logging
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: rich
Requires-Dist: rich>=13.0; extra == "rich"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Dynamic: license-file

# logthisx

A modern, friendly Python logging library with sensible defaults, colored
console output, rotating files, structured JSON, context binding, and
decorators. Built on top of the standard `logging` module so it composes
naturally with the rest of the Python ecosystem.

[![PyPI](https://img.shields.io/pypi/v/logthisx.svg)](https://pypi.org/project/logthisx/)
[![Python versions](https://img.shields.io/pypi/pyversions/logthisx.svg)](https://pypi.org/project/logthisx/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![CI](https://github.com/laxyny/logthis/actions/workflows/ci.yml/badge.svg)](https://github.com/laxyny/logthis/actions/workflows/ci.yml)

---

## Table of contents

- [Why logthisx](#why-logthisx)
- [Installation](#installation)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Console logging](#console-logging)
- [File logging](#file-logging)
- [JSON logging](#json-logging)
- [Context binding](#context-binding)
- [Decorators](#decorators)
- [Custom levels](#custom-levels)
- [Exceptions](#exceptions)
- [Redaction](#redaction)
- [CLI](#cli)
- [Migration from 0.1.x](#migration-from-01x)
- [Development](#development)
- [License](#license)

## Why logthisx

- Looks good in your terminal out of the box, without forcing you to know
  the `logging.config` DSL.
- Plays nicely with the standard library: every `logthisx` logger *is* a
  `logging.Logger`, so third-party libraries that already use `logging`
  inherit your configuration.
- No mandatory third-party dependency. `rich` support is available as an
  optional extra.
- Structured logging built in: JSON formatter with a stable schema for
  Docker, CI, log aggregators and observability tools.
- Practical features that are tedious to wire up by hand: rotation, context
  binding, decorators, redaction.

## Installation

```bash
pip install logthisx
```

With the optional `rich` extra for fancier console output:

```bash
pip install "logthisx[rich]"
```

`logthisx` supports Python 3.9 to 3.13.

## Quickstart

```python
from logthisx import configure, logger

configure(level="INFO", console=True, file="logs/app.log")

logger.info("Application started")
logger.success("Operation completed")
logger.warning("Something looks wrong")
logger.error("Something failed")
logger.debug("Debug value", extra={"value": 42})
```

You can also retrieve named loggers:

```python
from logthisx import configure, get_logger

configure(level="DEBUG", console=True)

log = get_logger("my.app")
log.info("Ready")
```

The package is **side-effect free on import**: it does not touch the root
logger unless you ask for it explicitly (`logger_name="root"`).

## Configuration

`configure()` is the single entry point that wires handlers and formatters
together. It is idempotent: calling it again replaces the handlers it
previously installed, so duplicated log lines are not a concern.

```python
from logthisx import configure

configure(
    level="INFO",
    console=True,
    console_json=False,
    detailed=False,
    show_time=True,
    time_format="%Y-%m-%d %H:%M:%S",
    use_color=None,
    file="logs/app.log",
    file_json=False,
    max_bytes=5 * 1024 * 1024,
    backup_count=5,
    redact=True,
    custom_levels=False,
    logger_name="logthisx",
    propagate=False,
)
```

Alternatively, build a `Config` and pass it in:

```python
from logthisx import Config, configure

cfg = Config(level="DEBUG", file="logs/app.log", file_json=True)
configure(config=cfg)
```

Or read it from the environment:

```python
from logthisx import Config, configure

configure(config=Config.from_env())
```

Recognized environment variables (default prefix `LOGTHISX_`):

| Variable | Description |
|----------|-------------|
| `LOGTHISX_LEVEL` | Log level (`DEBUG`, `INFO`, `WARNING`, ...) |
| `LOGTHISX_CONSOLE` | Enable console handler (`1`/`0`) |
| `LOGTHISX_JSON` | Use JSON console output (`1`/`0`) |
| `LOGTHISX_DETAILED` | Include module/function/line in console (`1`/`0`) |
| `LOGTHISX_FILE` | Path to the log file |
| `LOGTHISX_MAX_BYTES` | Rotation threshold in bytes |
| `LOGTHISX_BACKUP_COUNT` | Number of rotated files to keep |
| `LOGTHISX_REDACT` | Enable redaction of sensitive keys (`1`/`0`) |

## Console logging

The default console formatter is a colorized, compact one-liner. Colors are
auto-detected based on whether `stderr` is a TTY; set `use_color=True/False`
to force the behavior, or set `NO_COLOR=1` / `FORCE_COLOR=1` in the
environment.

Enable the `detailed` mode to include `module.function:line`:

```python
configure(level="DEBUG", console=True, detailed=True)
```

## File logging

`configure(file="logs/app.log")` installs a `RotatingFileHandler` that:

- Creates the parent directory if it does not exist.
- Uses UTF-8 encoding by default.
- Rotates the file once it reaches `max_bytes` (default 5 MiB).
- Keeps `backup_count` historical files (default 5).
- Returns a no-op handler and prints a warning if the file cannot be opened,
  so logging never crashes the host application.

## JSON logging

Set `console_json=True` or `file_json=True` to switch to the JSON formatter.
The schema is stable across releases and looks like:

```json
{
  "timestamp": "2026-01-02T15:04:05.123456+00:00",
  "level": "INFO",
  "logger": "my.app",
  "module": "api",
  "function": "handle_request",
  "line": 42,
  "message": "Request received",
  "extra": {"request_id": "abc"},
  "exception": {
    "type": "ValueError",
    "message": "boom",
    "traceback": "..."
  }
}
```

`extra` is always present (possibly empty). `exception` is only present when
the record carries exception information. Timestamps are ISO 8601 with
explicit UTC offset.

## Context binding

Attach structured context to every record without repeating yourself:

```python
from logthisx import get_logger

log = get_logger("api").bind(request_id="abc123", user_id=42)
log.info("Request received")
log.info("Cache hit", extra={"cache_key": "users:42"})
```

`bind()` returns a new logger; the parent is not mutated. Chain calls to
extend the context, and use `unbind("user_id")` to drop a key.

The context shows up in console output, in files and in JSON payloads.

## Decorators

```python
from logthisx.decorators import log_call, log_errors, log_time

@log_call(level="DEBUG", include_args=True)
def add(a, b):
    return a + b

@log_time(threshold_ms=50.0)
def slow_path():
    ...

@log_errors()
def risky():
    raise RuntimeError("boom")
```

All three decorators support both `def` and `async def` functions. They are
cheap when the relevant level is disabled (a single `isEnabledFor` check).

## Custom levels

`logthisx` ships with three extra levels:

| Constant   | Value | Default name |
|------------|-------|--------------|
| `SUCCESS`  | 25    | `SUCCESS`    |
| `ALERT`    | 35    | `ALERT`      |
| `SPECIAL`  | 45    | `SPECIAL`    |

They are registered automatically when `configure(custom_levels=True)` is
called, and exposed as methods (`logger.success`, `logger.alert`,
`logger.special`).

Optional short aliases (`II`, `DD`, `SS`, `WW`, `AA`, `EE`, `AZ`, `CC`) can
be turned on with `custom_level_aliases=True`. They are off by default to
avoid polluting the global namespace for users who prefer standard names.

## Exceptions

Use `logger.exception("message")` from inside an `except:` block. The
traceback is rendered cleanly in the console and stored verbatim in files
and inside the `exception.traceback` field of JSON records.

```python
try:
    risky()
except Exception:
    logger.exception("risky failed")
```

## Redaction

`extra` dictionaries are scanned for sensitive keys (`password`, `token`,
`api_key`, `secret`, `authorization`, ...) and their values are replaced by
`***` before being written. Set `configure(redact=False)` to disable, or
pass a custom set of keys to the formatters directly if you need a tighter
or looser policy.

The redaction **does not inspect the free-form message text**. Replacing
arbitrary substrings in messages is unreliable and gives a false sense of
security. Pass secrets through `extra` so the redaction can do its job.

## CLI

```bash
logthisx --version
logthisx demo            # Emit one record per level so you can preview output
logthisx demo --json     # Same, but in JSON
logthisx doctor          # End-to-end self-check (console, file, rotation, JSON)
```

`logthisx demo` is also handy for verifying that your terminal renders the
colors correctly.

## Migration from 0.1.x

`logthisx` 0.1 exposed four module-level functions:

```python
from logthis import log_info, log_warn, log_error, enable_file_logging

enable_file_logging("logs/app.log")
log_info("hello")
```

These keep working in 0.2.0 but emit `DeprecationWarning`. The recommended
new API is:

```python
from logthisx import configure, logger

configure(level="INFO", console=True, file="logs/app.log")
logger.info("hello")
logger.warning("careful")
logger.error("broken")
```

See [`MIGRATION.md`](MIGRATION.md) for the full guide.

## Development

```bash
git clone https://github.com/laxyny/logthis.git
cd logthis
python -m pip install -e ".[dev]"
python -m ruff check src tests
python -m ruff format --check src tests
python -m pytest
python -m build
```

Contributions are welcome; see [`CONTRIBUTING.md`](CONTRIBUTING.md).

## License

Released under the [MIT License](LICENSE).
