Metadata-Version: 2.4
Name: oak-logging
Version: 1.0.0
Summary: A tiny, dependency-free logging framework with PII scrubbing, JSON output, and colored CLI logs
Author: Kavya Goyal
License: MIT
Project-URL: Homepage, https://kavya-24.github.io/oak-logging
Project-URL: Repository, https://github.com/Kavya-24/oak-logging
Project-URL: Documentation, https://github.com/Kavya-24/oak-logging#readme
Keywords: logging,log,pii,redaction,scrubbing,json,structured-logging
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
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: Topic :: System :: Logging
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# oak

<img width="822" height="357" alt="Screenshot 2026-08-01 at 4 23 37 PM" src="https://github.com/user-attachments/assets/78bf74cd-a8df-4cf2-b586-b1703275d1fa" />


PyPi: https://pypi.org/project/oak-logging/1.0.0/
Try it out!
https://kavya-24.github.io/oak-logging/

A tiny, dependency-free logging framework for Python, built on top of the
standard library's `logging`. It gives you:

- **Levels** — `debug`, `info`, `warning`, `error`, `exception`
- **Structured errors** — a dedicated formatter prints exception type, message
  and traceback in a readable block
- **PII scrubbing** — redacts emails, phone numbers, SSNs, credit cards, IPs,
  and sensitive field names (passwords, tokens, API keys, ...) from messages
  and `extra` fields
- **JSON output** — structured, machine-friendly lines for shipping to log
  aggregators
- **Colored CLI logs** — automatic ANSI colors on TTYs
- **Simple initialization** — one `init()` call to configure everything

Zero dependencies. Python 3.9+.

## Install

```bash
pip install oak-logging   # import stays `import oak`
```

Or from source:

```bash
pip install -e .
```

## Quick start

```python
import oak

log = oak.init("DEBUG")

log.debug("entering parse loop")
log.info("user signed up", extra={"user_id": 42})
log.warning("disk at 90%", extra={"usage_pct": 90.1})
log.error("payment failed")
```

Output (colors shown when writing to a terminal):

```
2026-08-01 15:30:00 DEBUG app: entering parse loop
2026-08-01 15:30:00 INFO  app: user signed up
2026-08-01 15:30:00 WARNING app: disk at 90%
2026-08-01 15:30:00 ERROR app: payment failed
```

## Initialization options

```python
log = oak.init(
    level="DEBUG",          # str or int; default "INFO"
    output="console",       # "console", "json", or a file path
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    error_format=True,      # structured block for ERROR+ logs
    pii_scrubbing=True,     # redact PII from messages and extra fields
    color=None,             # None=auto (TTY), True=force, False=off
    name="app",             # underlying stdlib logger name
)
```

You can also configure the root logger imperatively with `oak.configure(...)`,
and grab additional loggers with `oak.get_logger("worker")` — they share the
same configuration.

## PII scrubbing

PII is redacted from the log message itself and from any `extra` values:

1. **Pattern-based** — known PII shapes are redacted anywhere in the message:

   ```python
   log.info("contact jane@example.com or 555-123-4567")
   # contact [REDACTED] or [REDACTED]
   ```

2. **Key-based** — `extra` fields whose names look sensitive are redacted
   (including nested dicts and lists):

   ```python
   log.info("signup", extra={
       "email": "jane@example.com",   # redacted
       "password": "hunter2",         # redacted
       "user_id": 7,                  # kept
   })
   ```

   `extra` is not printed by default — it behaves exactly like stdlib logging:
   reference a key in your format string to see it, and the scrubbed value is
   what gets logged:

   ```python
   log = oak.init(format="%(asctime)s %(levelname)s %(email)s")
   # 2026-08-01 15:30:00 INFO [REDACTED]
   ```

Covered patterns: email, phone numbers, SSNs, credit card numbers, IPv4 and
MAC addresses. Sensitive key names include `email`, `password`, `token`,
`api_key`, `ssn`, `credit_card`, and more. Disable scrubbing with
`pii_scrubbing=False` if you ever need to (not recommended).

Scrubbing helpers are public too: `oak.scrub_message`, `oak.scrub_extra`,
`oak.scrub_value`, and `oak.REDACTED`.

## Structured errors

With the default `error_format=True`, `ERROR`/`exception` logs get a readable,
structured error block:

```python
try:
    json.loads(bad_payload)
except ValueError:
    log.exception("could not parse payload")
```

```
2026-08-01 15:30:00 ERROR app: could not parse payload
  ERROR TYPE: JSONDecodeError
  ERROR MSG : Expecting value: line 1 column 1 (char 0)
  TRACEBACK:
  Traceback (most recent call last):
    ...
```

## JSON output

```python
log = oak.init("INFO", json=True)
log.info("order placed")
log.error("payment failed for jane@example.com")
```

```json
{"ts": "2026-08-01T15:30:00", "level": "INFO", "logger": "app", "message": "order placed"}
{"ts": "2026-08-01T15:30:00", "level": "ERROR", "logger": "app", "message": "payment failed for [REDACTED]"}
```

## File output

```python
log = oak.init(level="INFO", output="app.log")
```

## Demo

```bash
oak-demo
```

## Development

```bash
python -m venv .venv
.venv/bin/pip install -e . pytest
.venv/bin/python -m pytest
```

## License

MIT
