feat: structured logging helpers + get_issue instrumentation (#14) #24

Merged
Latte merged 2 commits from feat/get-issue-debug-logging into dev 2026-06-22 15:09:59 +00:00
Owner

Closes #14.

Adds reusable, secret-safe structured-logging helpers and instruments get_issue so nullable-field parsing (the class of failure behind #13) is diagnosable.

Helpers (logging_utils)

  • log_event(logger, level, event, **context) — emit a named event with a context mapping; keys in SENSITIVE_CONTEXT_KEYS (token, authorization, password, …) are masked as ***.
  • log_nullable_field(logger, event, field, value) — record whether a parsed field is None plus its runtime type, without dumping contents.
  • sanitize_context(...) — shared masking primitive.
  • The JSON formatter now serializes a record's context into the payload.

Instrumentation

  • get_issue_tool emits get_issue.start, get_issue.payload_shape, and get_issue.field_check (labels/assignees/user) at DEBUG. Silent unless LOG_LEVEL=DEBUG.

Scope note

log_exception from the issue's suggestion was intentionally omitted: logging an exception message conflicts with the project's "no exception-detail leakage" posture, so only the exception type is ever logged (unchanged behaviour).

Tests & docs

  • New tests/test_logging_utils.py: helpers, masking, formatter context, and the get_issue instrumentation.
  • docs/observability.md documents the pattern and its reuse for other parsing-heavy endpoints.
Closes #14. Adds reusable, secret-safe structured-logging helpers and instruments `get_issue` so nullable-field parsing (the class of failure behind #13) is diagnosable. ## Helpers (`logging_utils`) - `log_event(logger, level, event, **context)` — emit a named event with a `context` mapping; keys in `SENSITIVE_CONTEXT_KEYS` (`token`, `authorization`, `password`, …) are masked as `***`. - `log_nullable_field(logger, event, field, value)` — record whether a parsed field is `None` plus its runtime type, without dumping contents. - `sanitize_context(...)` — shared masking primitive. - The JSON formatter now serializes a record's `context` into the payload. ## Instrumentation - `get_issue_tool` emits `get_issue.start`, `get_issue.payload_shape`, and `get_issue.field_check` (labels/assignees/user) at `DEBUG`. Silent unless `LOG_LEVEL=DEBUG`. ## Scope note `log_exception` from the issue's suggestion was intentionally omitted: logging an exception *message* conflicts with the project's "no exception-detail leakage" posture, so only the exception *type* is ever logged (unchanged behaviour). ## Tests & docs - New `tests/test_logging_utils.py`: helpers, masking, formatter context, and the `get_issue` instrumentation. - `docs/observability.md` documents the pattern and its reuse for other parsing-heavy endpoints.
Latte added 1 commit 2026-06-22 13:41:09 +00:00
feat: add structured logging helpers and instrument get_issue (#14)
docker / test (pull_request) Successful in 29s
test / test (push) Successful in 38s
lint / lint (push) Successful in 39s
docker / lint (pull_request) Successful in 39s
docker / docker-test (pull_request) Successful in 12s
docker / docker-publish (pull_request) Has been skipped
lint / lint (pull_request) Successful in 28s
test / test (pull_request) Successful in 22s
f53e1a3a5a
Adds reusable, secret-safe logging helpers to `logging_utils`:
- `log_event(logger, level, event, **context)` emits a named event with a
  sanitized `context` mapping (sensitive keys masked as `***`).
- `log_nullable_field(...)` records whether a parsed field is None plus its
  runtime type, without dumping its contents.
- `sanitize_context(...)` is the shared masking primitive.

The JSON formatter now serializes a record's `context` into the payload.

`get_issue_tool` is instrumented at DEBUG (`get_issue.start`,
`get_issue.payload_shape`, `get_issue.field_check` for labels/assignees/user)
so the nullable-field parsing that caused #13 is diagnosable going forward.

Adds tests for the helpers, the formatter, and the get_issue instrumentation,
and documents the pattern in docs/observability.md.
Latte force-pushed feat/get-issue-debug-logging from baacd9e9b5 to f53e1a3a5a 2026-06-22 13:41:09 +00:00 Compare
Latte added 1 commit 2026-06-22 13:59:22 +00:00
test: cover write-tool auth and backend error branches
lint / lint (push) Successful in 36s
docker / test (pull_request) Successful in 32s
test / test (push) Successful in 38s
docker / lint (pull_request) Successful in 38s
docker / docker-test (pull_request) Successful in 12s
docker / docker-publish (pull_request) Has been skipped
test / test (pull_request) Successful in 25s
lint / lint (pull_request) Successful in 27s
538d6d964a
Every write tool's `except (Auth...)` re-raise and `except GiteaError ->
RuntimeError` wrapping was previously untested, leaving write_tools at 60%
coverage and the repo below the 80% gate. Adds parametrized error-path tests
for all 15 write tools (backend error wrapping + auth propagation), raising
write_tools coverage to 99% and total coverage above the gate.
Latte merged commit 10a307ac02 into dev 2026-06-22 15:09:59 +00:00
Latte deleted branch feat/get-issue-debug-logging 2026-06-22 15:09:59 +00:00
Sign in to join this conversation.