Metadata-Version: 2.4
Name: BohLogger
Version: 0.2.0
Summary: Backoffice Logger Helper
Author: Max Guenes
Author-email: max.santos@e-deploy.com.br
Requires-Python: >=3.12
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: grayloghelper (>=0.7.0)
Requires-Dist: messagebus (>=1.0.0)
Requires-Dist: messageprocessor (>=4)
Description-Content-Type: text/markdown

# BohLogger

Backoffice logger helper. Provides a ready-made
`messageprocessorutil.LoggingProcessorCallback` that enriches the Graylog (GELF)
log context with standard backoffice fields throughout the message-processing
lifecycle, plus small helpers to add and clear arbitrary log fields.

Under the hood it wires `grayloghelper` (the thread-local GELF field store) into
the `MessageProcessor` callback hooks, so every log line emitted while a message
or event is being handled automatically carries the same set of contextual
fields.

## Exports

- `BackofficeLoggingProcessorCallback` — a `LoggingProcessorCallback` subclass
  that stamps invocation metadata, message/event details, and exception info
  onto the Graylog log context and clears them when processing ends.
- `add_log_data(field, value)` — set a single log field for the current thread.
- `add_user_session_fields(user_name, user_id, user_session_uuid=None)` — stamp
  the current user's `user_name` and `user_id` (and the optional
  `user_session_uuid`, when provided) onto the log context. Cleared automatically
  with the other backoffice fields when the invocation ends.
- `clear_log_field(*fields)` — remove one or more log fields from the current
  thread's context.

## Log fields

`BackofficeLoggingProcessorCallback` manages the following keys
(`BackofficeLogKeys`):

| Field | Source | Notes |
|---|---|---|
| `invocation_source` | always | `"message"`, `"httpmessage"`, or `"event"` |
| `invocation_status` | always | lifecycle stage (see below) |
| `invocation_start_at` | always | start time, epoch **milliseconds** |
| `invocation_duration` | always | elapsed time since start, **milliseconds** |
| `api_method` | `HttpRequestMessage` | HTTP method |
| `api_url` | `HttpRequestMessage` | request URL |
| `event_subject` | `Event` | event subject |
| `event_type` | `Event` | event type |
| `user_name` | `add_user_session_fields` | current user's name |
| `user_id` | `add_user_session_fields` | current user's id |
| `user_session_uuid` | `add_user_session_fields` | current user's session uuid (optional) |
| `exception_type` | on exception | exception class name |

`invocation_status` takes one of: `process_begun`, `business_called`,
`process_finished`, `parse_exception`, `exception`.

## How it works

The callback maps each `LoggingProcessorCallback` hook to a Graylog field
update:

1. **`process_begun`** — records `_start_at`, derives `invocation_source` from
   the incoming `message`/`event` (adding `api_method`/`api_url` for
   `HttpRequestMessage`, or `event_subject`/`event_type` for `Event`), and sets
   `invocation_status=process_begun` plus `invocation_start_at`.
2. **`business_called`** — sets `invocation_status=business_called` and updates
   `invocation_duration`.
3. **`process_finished`** — sets `invocation_status=process_finished`, updates
   the duration, then **clears all backoffice fields** for the thread.
4. **`parse_exception`** — sets `invocation_status=parse_exception`, records
   `exception_type`, updates the duration, then clears all fields.
5. **`unhandled_exception`** — sets `invocation_status=exception`, records
   `exception_type`, updates the duration, then clears all fields.

Every hook also delegates to its `super()` implementation, preserving the base
callback's logging and thread-name behavior. Durations and start times are
stored in milliseconds.

## Usage

Pass `BackofficeLoggingProcessorCallback` to your `MessageProcessor` wherever a
`LoggingProcessorCallback` is expected:

```python
import logging

from boh.logger import BackofficeLoggingProcessorCallback

callback = BackofficeLoggingProcessorCallback(
    logger=logging.getLogger("backoffice"),
    ignored_exceptions=[SomeExpectedError],          # optional
    log_level_exceptions={SomeWarning: logging.WARNING},  # optional
)

# hand `callback` to the MessageProcessor that drives your handler
```

Constructor `**kwargs` are forwarded to the base `LoggingProcessorCallback`
(`logger`, `ignored_exceptions`, `log_level_exceptions`).

### Adding your own fields

Within a handler you can attach extra fields to the current log context; they
appear on every subsequent log line until the invocation finishes (or you clear
them):

```python
from boh.logger import add_log_data, clear_log_field

add_log_data("store_id", 42)
add_log_data("operation", "close_register")

# ... later, if you need to drop them early ...
clear_log_field("store_id", "operation")
```

Backoffice fields managed by the callback are cleared automatically when the
invocation ends (`process_finished` or an exception hook).

## Installation

```bash
poetry add BohLogger --source E-Deploy
```

Requires Python >= 3.12. Depends on `grayloghelper`, `messagebus`, and
`messageprocessor`.

