peek_talker 2.0.0
peek_talker: ^2.0.0 copied to clipboard
Reports the calls Talker logs to Peek, so they can be read in the app.
peek_talker #
Reports the calls Talker logs to Peek, so they can be read inside the app.
Peek records the call, it does not take part in it — and here it does not
even record: an app that already logs its calls through Talker has them in
talker.stream, so this package listens there and nothing is logged twice.
Install #
dependencies:
peek: ^2.0.0
peek_talker: ^2.0.0
Use #
One line, next to the Talker you already have:
peek.attach(PeekTalkerAdapter(peek, talker: talker));
That is all, as long as Talker sees the calls — with
talker_dio_logger, that
means its interceptor is on the client:
dio.interceptors.add(TalkerDioLogger(talker: talker));
peek.attach hands the adapter's life to the instance: peek.dispose()
releases it. An adapter built without attaching must be disposed by hand.
The compiled version of these lines lives in
example/lib/talker_setup.dart.
The history is replayed #
Talker keeps what it logged before the adapter existed, and the adapter
reports it, oldest first — an app that opens Peek after a failure wants to
see the failure. Pass replayHistory: false to start from now instead.
A call whose beginning was never seen is reported as one finished entry rather than as an answer to nothing.
Peek reads the objects, not the text #
TalkerDioLoggerSettings decides what the console prints. Turning
printRequestData off hides a body from the console and changes nothing
here: the log entry still carries Dio's own objects, and that is what Peek
maps.
What Peek keeps and what it hides is set on the instance, through
PeekOptions — one place for every adapter. Nothing is masked until the
app asks; the default policy covers the usual secret names, and a set can
be extended by spreading the defaults back in:
final peek = Peek(
options: const PeekOptions(
redaction: PeekRedactionPolicy(
headerNames: {...PeekRedactionPolicy.defaultHeaderNames, 'x-api-key'},
),
),
);
Teaching it another logger #
Talker carries whatever its integrations put in it. A mapper claims the
entries it knows and leaves the rest alone, so another integration —
talker_http_logger, talker_chopper_logger, an app's own log class — is
a mapper rather than a change to the adapter:
final class HttpTalkerLogMapper implements PeekTalkerLogMapper {
const HttpTalkerLogMapper();
@override
bool canMap(TalkerData data) => data is HttpRequestLog;
@override
PeekEvent? map(TalkerData data, PeekTalkerContext context) {
final log = data as HttpRequestLog;
return PeekRequestStarted(
id: context.begin(log.request),
timestamp: log.time,
request: PeekRequest(method: log.request.method, uri: log.request.url),
source: context.source,
);
}
}
The three entries of one call — it went out, it came back, it failed —
report under one id: mark the object they share with context.begin and
find it again with context.find. Then pass the mappers in, in the order
they should be tried:
PeekTalkerAdapter(
peek,
talker: talker,
mappers: const [
HttpTalkerLogMapper(),
...PeekTalkerAdapter.defaultMappers,
],
);
Limits #
- Only what Talker logged. A client without a Talker integration is
invisible here; give it one, or use an adapter of its own, such as
peek_dio. - Streamed bodies and file contents are described rather than read;
see
peek_dio. - Do not use both
peek_talkerandPeekDioInterceptoron the same client: the call would be reported twice, once by each.
See the repository README for the full picture.