Logging
import 'package:gisila/gisila.dart';Logger
Section titled “Logger”Pluggable sink for structured log events. The framework logs startup, shutdown, unhandled exceptions, authenticator failures and (with logRequests) one access-log line per request through AppConfig.logger.
abstract class Logger { Logger(); LogLevel get level; void log(LogEvent event);
void trace(String message, {Map<String, Object?>? fields}); void debug(String message, {Map<String, Object?>? fields}); void info(String message, {Map<String, Object?>? fields}); void warning(String message, {Map<String, Object?>? fields, Object? error, StackTrace? stackTrace}); void error(String message, {Map<String, Object?>? fields, Object? error, StackTrace? stackTrace}); void fatal(String message, {Map<String, Object?>? fields, Object? error, StackTrace? stackTrace});}When to use: log through app.config.logger from your own code so everything shares one format. Implement Logger to send logs somewhere other than the console (a file, OpenTelemetry, a vendor SDK) or to wrap another logger (redaction, fan-out).
| Member | Description |
|---|---|
level |
Minimum level emitted. The convenience methods drop anything below it before building an event. |
log(event) |
Emit one event. Implementations should also respect level. |
trace … fatal |
Build a LogEvent with the current UTC time and call log. warning, error and fatal also take an error and stack trace. |
Example
class RedactingLogger extends Logger { RedactingLogger(this.inner); final Logger inner; static const _secret = {'password', 'token', 'authorization'};
@override LogLevel get level => inner.level;
@override void log(LogEvent e) => inner.log(LogEvent( level: e.level, message: e.message, timestamp: e.timestamp, requestId: e.requestId, principalId: e.principalId, error: e.error, stackTrace: e.stackTrace, fields: { for (final f in e.fields.entries) f.key: _secret.contains(f.key.toLowerCase()) ? '[redacted]' : f.value, }, ));}
final app = GisilaApp( config: AppConfig(logger: RedactingLogger(ConsoleLogger(format: LogFormat.json))),);ConsoleLogger
Section titled “ConsoleLogger”The default logger: writes to stdout, and to stderr for warning and above.
class ConsoleLogger extends Logger { ConsoleLogger({ LogLevel level = LogLevel.info, LogFormat format = LogFormat.text, void Function(String line)? stdoutSink, void Function(String line)? stderrSink, }); final LogLevel level; final LogFormat format;}When to use: almost always, in text format for development and json in production where a collector (Loki, CloudWatch, the gisila panel’s log view) reads stdout. Pass stdoutSink/stderrSink to capture lines in tests.
Text format:
2026-10-31T09:12:44.120Z [INFO ] req=Xb3k9QpLm2Ty7vRa user=42 GET /orders -> 200 (12ms) method=GET path=/orders query= status=200 duration_ms=12 remote=127.0.0.1:50122JSON format: the event’s fields, then ts, level, msg, and requestId, principalId, error, stack when present. The event’s own keys win over fields with the same name.
{"method":"GET","path":"/orders","query":"","status":200,"duration_ms":12,"remote":"127.0.0.1:50122","ts":"2026-10-31T09:12:44.120Z","level":"info","msg":"GET /orders -> 200 (12ms)","requestId":"Xb3k9QpLm2Ty7vRa","principalId":"42"}LogEvent
Section titled “LogEvent”One structured log record.
class LogEvent { LogEvent({ required LogLevel level, required String message, required DateTime timestamp, String? requestId, String? principalId, Object? error, StackTrace? stackTrace, Map<String, Object?>? fields, });}| Field | Description |
|---|---|
level, message, timestamp |
Severity, text, time (the framework uses UTC). |
requestId, principalId |
Set by the access log; set them yourself when building events in a request. |
error, stackTrace |
The failure, if any. |
fields |
Arbitrary key/value pairs. The access log uses method, path, query, status, duration_ms, remote, and requestBody/responseBody when enabled. |
app.config.logger.log(LogEvent( level: LogLevel.info, message: 'order placed', timestamp: DateTime.now().toUtc(), requestId: ctx.requestId, principalId: ctx.principal?.id, fields: {'orderId': order.id, 'total': order.total},));LogLevel
Section titled “LogLevel”enum LogLevel { trace(0), debug(1), info(2), warning(3), error(4), fatal(5), off(6); final int priority; bool operator >=(LogLevel other);}Severities from most to least verbose. off silences everything. >= compares priorities.
LogFormat
Section titled “LogFormat”enum LogFormat { text, json }Output format of ConsoleLogger.
See also: Structured logging guide, AppConfig logging fields.