Skip to content

v0.4.0 — Monolog processor

Choose a tag to compare

@mrDlef mrDlef released this 16 Aug 23:27
· 115 commits to main since this release
86c0309

If your application already logs its OpenSearch request bodies, you no longer
have to touch every call site. Push one processor and the raw request is
replaced by its digest wherever it appears.

use MrDlef\OsQueryDigest\Monolog\DigestProcessor;

$logger->pushProcessor(new DigestProcessor());

$logger->info('opensearch.search', [
    'query' => $request,               // → {"idx": …, "q": …, "sig": …, "hash": …}
    'index' => 'logs-2026.08.16',
    'took'  => $response['took'],      // untouched, like the rest of the context
]);

The keys it reads are configurable — new DigestProcessor($formatter, 'search_body', 'target') — and anything that is not a search request is left
exactly as it was found. A processor that guessed would corrupt your log lines.

Both Monolog versions, one class

  • Monolog 2 hands a processor an array; Monolog 3 hands a LogRecord.
    Implementing ProcessorInterface would pin the class to one of them, so it
    stays a plain callable — which both versions accept wherever a processor
    is expected.
  • Monolog 3 makes context readonly, so it cannot be assigned. The update
    goes through with(context: …). Named arguments are PHP 8 syntax and this
    file has to parse on 7.4, so the same call is written as an unpack of a
    string-keyed array, which PHP 8.1 turns into named arguments — and 8.1 is
    Monolog 3's own floor.
  • instanceof against a class that does not exist is false rather than an
    error, and does not autoload, so the Monolog 3 branch never runs under 2.

This matters because a PHP 7.4 user can only have Monolog 2, and that is exactly
who the 7.4 support exists for. Verified on both sides: 7.4 → Monolog 2.11, 8.0
→ Monolog 2, 8.1+ → Monolog 3, with the same 107 tests.

Lazy, and safe

The digest stays lazy, so a record buffered by a FingersCrossedHandler that
never triggers costs nothing.

That laziness moves any parse failure into Monolog's formatting, where an
exception would cost the whole record. So a request the library cannot read
yields {"error": "…"} in place of the digest. You lose the digest, never the
log line.

It deliberately does not fall back to the raw request: that would restore the
wall of nested braces this library exists to keep out, at the size that made it
unloggable in the first place. The error message says what went wrong, which is
the part you can act on.

Dependency

Monolog is a suggested dependency, never a required one. The library itself
still has no runtime dependencies beyond ext-json.

"suggest": {
    "monolog/monolog": "^2.0 || ^3.0"
}

No hash moves

Nothing under src/Fingerprint, src/Render, src/Parser, src/Normalizer or
src/Tree changed, and no fixture moved. The q2: prefix stays and every
fingerprint published under it remains valid.

Full changelog: v0.3.0...v0.4.0