NAME
Langertha::Knarr::RequestLog - Local disk logging of proxy requests
VERSION
version 1.102
SYNOPSIS
use Langertha::Knarr::RequestLog;
my $rlog = Langertha::Knarr::RequestLog->new(config => $config);
my $handle = $rlog->start_request(
model => 'gpt-5.6-terra',
format => 'openai',
engine => 'Langertha::Engine::OpenAI',
path => '/v1/chat/completions',
stream => 1,
messages => \@messages,
params => \%params,
);
# ... handle request ...
$rlog->end_request($handle,
output => $response_text,
usage => { input => 100, output => 50, total => 150 },
);
DESCRIPTION
Records every proxy request as a JSON log entry on local disk. Supports two modes: JSONL (one line per request, append to a single file) and per-request JSON files in a directory.
When both log_file and log_dir are set, both are written. When neither is set, all methods are no-ops.
Log file/directory are read from the config file's logging: section or from the KNARR_LOG_FILE and KNARR_LOG_DIR environment variables. The module strips surrounding quotes from environment variable values.
config
The Langertha::Knarr::Config object. Required. Provides log_file and log_dir settings.
log_file
Path to the JSONL log file. One JSON object per line, suitable for tail -f knarr.jsonl | jq. Resolved from logging.file in config or KNARR_LOG_FILE environment variable. Several workers (knarr start -w) append to the same file: each line goes out as one write under an exclusive lock, so lines never interleave.
log_dir
Path to a directory for per-request JSON files. Each request produces a pretty-printed {timestamp}_{pid}-{seq}_{format}_{model}.json file, e.g. 20260929_201530_123_4711-1_openai_gpt-4o.json: the process id and a sequence number counted per process keep requests that finish in the same millisecond -- in one process or in several workers -- in separate files. Resolved from logging.dir in config or KNARR_LOG_DIR environment variable.
start_request
my $handle = $rlog->start_request(
model => $model_name,
format => 'openai',
engine => $engine_class,
path => '/v1/chat/completions',
stream => 1,
messages => \@messages,
params => \%params,
);
Begins collecting data for a request. Returns a handle (hashref) that must be passed to "end_request". Returns undef when logging is disabled.
end_request
$rlog->end_request($handle,
output => $response_text,
usage => { input => 100, output => 50, total => 150 },
);
# On error:
$rlog->end_request($handle, error => "Something went wrong");
Completes the log entry with output, usage, duration and writes it to disk. Does nothing when $handle is undef (logging was disabled at start).
usage takes a Langertha::Usage (the shape every routed response carries) or a plain hashref. Objects are flattened with to_hash to input_tokens / output_tokens / total_tokens, plus cached_tokens (prompt-cache reads) and cache_write_tokens (prompt-cache writes) when the request had any; those are informational, the three canonical counts are unchanged. An object that counts no token is logged as null. Hashrefs are logged verbatim.
tool_calls takes the response's Langertha::ToolCall list and is logged trimmed: each call keeps its name and id plus an arguments preview capped at 200 characters (truncated flags whether it was cut). The full arguments are recorded in the Langfuse trace instead (see "end_trace" in Langertha::Knarr::Tracing), because the JSONL log is the running operational record and tool arguments can be large or carry user data.
SEE ALSO
Langertha::Knarr — Request logging is wired in for all routes
Langertha::Knarr::Config — Provides
log_fileandlog_dirLangertha::Knarr::Tracing — Langfuse tracing (complementary)
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha-knarr/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.