Skip to main content

spring_boot_starter_logging 0.1.3 copy "spring_boot_starter_logging: ^0.1.3" to clipboard
spring_boot_starter_logging: ^0.1.3 copied to clipboard

Logging starter for spring_boot_dart: console patterns, log files with rollover, logging.* properties and an in-memory log buffer for in-app log viewers.

spring_boot_starter_logging #

Logging for spring_boot_dart applications, like spring-boot-starter-logging. Add the dependency; the generator discovers the auto-configuration and a LoggingSystem is installed behind the SpringLog facade. No code needed.

dependencies:
  spring_boot_dart: ^0.1.0
  spring_boot_starter_logging: ^0.1.0
const log = SpringLog('neon.checkout');

log.info('paid 12.5', fields: {'order': 1});
23:08:01.580  INFO [neon.checkout] paid 12.5 {order=1}

Properties #

logging.level.root=info                  # Boot's default with this starter
logging.level.neon.checkout=debug        # a logger and its descendants
logging.group.payments=neon.card,neon.cash
logging.level.payments=trace
logging.pattern.console=%d{HH:mm:ss.SSS} %5p [%logger] %m%X%ex
logging.threshold.console=warn           # console: warnings and errors only
logging.console.enabled=true
logging.buffer.enabled=true
logging.buffer.capacity=1000
logging.threshold.buffer=debug
logging.file.name=logs/shop.log          # a log file (or logging.file.path=logs → logs/spring.log)
logging.pattern.file=%d %5p [%logger] %m%X%ex
logging.threshold.file=info
logging.file.max-size=10MB               # roll over into shop.log.1, .2, ...
logging.file.max-history=7               # rolled-over files kept
logging.file.clean-history-on-start=false
logging.enabled=false                    # turn the starter off

Pattern tokens: %d{yyyy-MM-dd HH:mm:ss.SSS}, %p/%level, %c/%logger, %m/%msg, %X{key} (one field), %X (all fields), %ex (error and stack trace), %seq, %n, %%; widths pad (%5p, %-20logger). An unknown token fails the start.

Log files #

logging.file.name (a file) or logging.file.path (a directory with spring.log) turns on a FileAppender. Lines logged in one synchronous burst are written together at the end of the microtask; the rest is written when the context closes. When the file would grow past max-size it becomes shop.log.1 (older ones shift to .2, .3, ...) and only max-history of them are kept. Differences from Logback: the history counts files, not days, and archives are not compressed.

Relative locations are resolved against LoggingSystem.instance.fileDirectory when it is set, else against the working directory. In Flutter the writable directory is only known at runtime, so set it before starting (the coming Flutter starter will do it for you):

LoggingSystem.instance.fileDirectory =
    (await getApplicationDocumentsDirectory()).path; // path_provider
await runApplicationAsync(args);

On the web there is no file system: logging.file.* is ignored with a warning and FileAppender.isSupported is false.

A log screen (Flutter) #

LogBuffer keeps the last records in memory. It is a bean (inject it) and also LoggingSystem.instance.buffer. Its API is made for a log viewer:

class LogScreen extends StatefulWidget { ... }

class _LogScreenState extends State<LogScreen> {
  final buffer = LoggingSystem.instance.buffer;
  var query = const LogQuery(minLevel: SpringLogLevel.info);

  @override
  Widget build(BuildContext context) => Column(children: [
    TextField(onChanged: (text) => setState(() => query = query.copyWith(text: text))),
    Expanded(
      child: StreamBuilder<List<SpringLogRecord>>(
        stream: buffer.watch(query), // current list, then one per burst
        builder: (context, snapshot) {
          final records = snapshot.data ?? const [];
          return ListView.builder(
            itemCount: records.length,
            itemBuilder: (context, i) => ListTile(
              key: ValueKey(records[i].sequence),
              title: Text(records[i].message),
              subtitle: Text('${records[i].loggerName} · ${records[i].fields}'),
            ),
          );
        },
      ),
    ),
  ]);
}
Need API
Live filtered list buffer.watch(query) → Stream<List<SpringLogRecord>>
Snapshot buffer.records, buffer.query(query)
Every new record buffer.onRecord
Badges buffer.counts[SpringLogLevel.error], buffer.dropped
Logger filter menu buffer.loggerNames
Share / copy buffer.export(query) (or with a LogPattern)
Clear buffer.clear()
Filters LogQuery(minLevel, levels, logger, text, fields, since), immutable, copyWith (null removes a criterion)
Change levels at runtime loggingSystem.setLevel('neon', SpringLogLevel.debug), rootLevel

Records are immutable and carry time, sequence (a stable list key), level, loggerName, message, fields, error, stackTrace.

In Flutter, send the console to debugPrint before starting: LoggingSystem.instance.console.out = debugPrint;

Own appenders #

class CrashReportAppender extends LogAppender {
  CrashReportAppender() : super(threshold: SpringLogLevel.error);

  @override
  void write(SpringLogRecord record) =>
      crashlytics.recordError(record.error ?? record.message, record.stackTrace);
}

LoggingSystem.instance.addAppender(CrashReportAppender());

A failing appender does not stop the others.

Without Spring Boot #

LoggingSystem.instance
  ..configure(environment) // the logging.* properties
  ..install();
0
likes
0
points
728
downloads

Publisher

verified publisherfarum-azula.org

Weekly Downloads

Logging starter for spring_boot_dart: console patterns, log files with rollover, logging.* properties and an in-memory log buffer for in-app log viewers.

Repository (GitHub)
View/report issues

Topics

#logging #configuration #spring

License

unknown (license)

Dependencies

spring_boot_dart

More

Packages that depend on spring_boot_starter_logging