talker_grpc_logger
Lightweight and customizable grpc client logger on talker base.
Talker - Advanced exception handling and logging for dart/flutter applications 🚀
Preview
This is how the logs of your grpc requests will look in the console

Features
- Logs unary and streaming RPCs (client-, server-, and bidi-streaming).
- Captures method path, payload, metadata, duration, status code and error message.
- Obfuscates sensitive headers (
Authorization,Cookie,x-api-key, …) via a case-insensitivehiddenHeadersset. - Per-flag control over what is rendered and whether a log entry is emitted at all.
- Customizable colors via
AnsiPen, JSON formatting viaTalkerJsonFormatter. - Pluggable
Talkerinstance — works standalone or withtalker_flutter's UI.
Getting started
Follow these steps to use this package
Add dependency
dependencies:
talker_grpc_logger: ^5.1.20
Usage
Create an interceptor and instrument your RPC client:
import 'package:grpc/grpc.dart';
import 'package:talker_grpc_logger/talker_grpc_logger.dart';
void main() {
late final channel = GrpcOrGrpcWebClientChannel.toSingleEndpoint(
host: 'localhost',
port: 50051,
);
// Generate your RPC client as usual, and use the interceptor to log the
// requests and responses.
late final rpcClient = YourRPCClient(
channel,
interceptors: [
TalkerGrpcLogger(),
],
);
}
Usage with Talker
Very similar to the section above — just pass a Talker instance to the interceptor so logs land in the same stream you already render:
import 'package:grpc/grpc.dart';
import 'package:talker_flutter/talker_flutter.dart';
import 'package:talker_grpc_logger/talker_grpc_logger.dart';
void main() {
// Not mandatory, but useful to see the grpc logs in the Talker screen.
final talker = TalkerFlutter.init();
// Define port and host as you see fit.
const host = 'localhost';
const port = 50051;
// transportSecure needs to be true when talking to a server through TLS.
// This can be disabled for local development.
// GrpcOrGrpcWebClientChannel is a channel type compatible with web and
// native. There are other channel types available for each platform.
late final channel = GrpcOrGrpcWebClientChannel.toSingleEndpoint(
host: host,
port: port,
transportSecure: host != 'localhost',
);
final interceptors = <ClientInterceptor>[
TalkerGrpcLogger(talker: talker),
];
late final rpcClient = YourRPCClient(channel, interceptors: interceptors);
}
Streaming
Streaming RPCs are logged in three stages:
- Init — a single
Stream startedentry when the call starts. - Chunks — one entry per outgoing request and one per incoming response.
- Completion — a
Stream completed (<n> responses / <m> requests)entry on clean finish, or a single error entry if the stream fails.
Each stage can be toggled independently:
TalkerGrpcLogger(
settings: const TalkerGrpcLoggerSettings(
printStreamInit: true, // "Stream started"
printStreamChunks: true, // per-chunk entries
printStreamComplete: true, // "Stream completed (N responses / M requests)"
),
);
printStreamChunks controls whether the per-chunk entry is emitted at all.
To keep the entry but drop the payload, use printRequestData /
printResponseData instead — those flags render the entry without its
Data: block.
The completion entry always reports both counters, regardless of
printStreamChunks. Turning per-chunk logging off hides the individual
Data: entries but does not affect the Stream completed (N responses / M requests) summary — request and response counts are tracked anyway.
For long-lived or high-frequency streams, turn per-chunk logging off and keep only the lifecycle entries:
TalkerGrpcLogger(
settings: const TalkerGrpcLoggerSettings(
printStreamChunks: false,
),
);
Obfuscation
Sensitive header values are replaced with ***** in the log output. The
matching is case-insensitive and the original CallOptions.metadata is
never mutated — obfuscation happens on a copy used only for formatting.
TalkerGrpcLogger(
settings: const TalkerGrpcLoggerSettings(
hiddenHeaders: {'authorization', 'cookie', 'x-api-key'},
),
);
With this configuration:
Authorization: Bearer abc.def→Authorization: *****Cookie: session=...→Cookie: *****x-api-key: ...→x-api-key: *****x-trace-id: 123→ unchanged (not inhiddenHeaders)
By default hiddenHeaders is empty, so nothing is masked. Enabling it is
strongly recommended for anything beyond local development.
Deprecated: the
obfuscateTokenflag onTalkerGrpcLoggerandGrpcErrorLogstill works for backward compatibility, but it only hides a single hard-codedauthorizationheader. PreferhiddenHeaders— it supports arbitrary keys and is case-insensitive.
Configuration
All behavior is driven by TalkerGrpcLoggerSettings. It is immutable and
Equatable, so instances are safe to share and cheap to derive with
copyWith:
const base = TalkerGrpcLoggerSettings();
final debug = base.copyWith(
logLevel: LogLevel.debug,
printStreamChunks: true,
);
| Field | Default | Purpose |
|---|---|---|
enabled |
true |
Master switch. When false the interceptor passes calls through untouched. |
logLevel |
LogLevel.debug |
Level attached to request and response logs. Error logs always use LogLevel.error. |
printRequestData |
true |
Render the request payload (Data: {...}) in request logs. |
printRequestHeaders |
true |
Render request metadata. Subject to hiddenHeaders. |
printResponseData |
true |
Render the response payload in response logs. |
printResponseHeaders |
true |
Render response metadata. |
printResponseDuration |
true |
Render elapsed milliseconds for completed requests. |
printErrorCode |
true |
Render Code: <GRPC_STATUS>, e.g. UNAVAILABLE. |
printErrorHeaders |
true |
Render request metadata in error logs. Subject to hiddenHeaders. |
printErrorMessage |
true |
Render Message: <text> in error logs. |
printStreamInit |
true |
Emit the Stream started lifecycle entry. |
printStreamChunks |
true |
Emit one entry per stream chunk. |
printStreamComplete |
true |
Emit the Stream completed (<n> responses / <m> requests) lifecycle entry. |
hiddenHeaders |
{} |
Case-insensitive set of header names to mask with *****. |
jsonFormatter |
TalkerJsonFormatter() |
Formatter for payloads and headers. |
requestPen |
null (violet xterm(219)) |
Console color for request logs. |
responsePen |
null (green xterm(46)) |
Console color for response logs. |
errorPen |
null (red) |
Console color for error logs. |
Examples
Minimal, no stream chunk spam:
TalkerGrpcLogger(
settings: const TalkerGrpcLoggerSettings(
printStreamChunks: false,
hiddenHeaders: {'authorization'},
),
);
Pretty JSON with quotes stripped, custom colors:
TalkerGrpcLogger(
settings: TalkerGrpcLoggerSettings(
jsonFormatter: const TalkerJsonFormatter(stripQuotes: true),
requestPen: AnsiPen()..blue(),
errorPen: AnsiPen()..magenta(),
),
);
Disable entirely (useful in release builds):
TalkerGrpcLogger(
settings: const TalkerGrpcLoggerSettings(enabled: false),
);