Open christerswahn opened 1 month ago
As a user, I want it to be easy to test for expected logged content (string / json content and levels) in my tests.
As a user, I want it to be easy to test for expected log statistics (quantity of different kinds of log messages) in my tests.
As a user, I want to easily silence or redirect logging during my tests except for the logs I inspect, to avoid noise.
Add ability to mark variables as private so it gets masked or redacted in production
https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code#3665948
Serverpod would benefit from a framework that makes logging more consistent, robust, capable, configurable, and extensible - while retaining the user friendliness of accessing server logs via Insights.
The purpose of this document is to describe the capabilities of a new logging framework for Serverpod server.
The focus at this stage is on concepts and user stories, not on implementation details.
Introduction
Needs
A capable logging framework enables the developer to only mind the content of a log message when adding logging to their code. While doing so they should not need to consider the various formatting, filtering, and output destinations the system may have, now or in the future.
Obversely, when configuring or overriding the logging settings for a given server launch, the operator should not need to consider various logging sources or areas in the code base - they should all be counted on to behave the same standardized way.
An operator overseeing the logs from a server should be able to effectively search and parse the logs, be able to adjust the content filters, and apply queries on the consistently formatted content.
Situation
The Serverpod server codebase has various “logging” outputs - some print(), some stderr.writeln(), and some session.log(). This has been added over the years. Log message format, errors, and exceptions are not treated consistently.
There is no central mechanism to configure this. Some logging depends on development/server mode, some depends on the Session object, some depends on neither of those.
If launching the server in a hosted environment, with particular requirements on how to channel logs, this is cumbersome to achieve due to the various output forms, and getting consistent formatting is simply not possible today.
This document
This document focuses on concepts and user stories, to align the objectives for the new logging framework in the first step. It is not necessary to include all documented user stories in the first versions. And some stories may be infeasible to implement. But having a more comprehensive set of user stories helps inform the overall shape and approach of the logging framework.
Related open issues
2563
2504
1352
Terminology
User - a developer working with their application’s Serverpod server codebase
Scopes - namespaces for logging, e.g. code packages, features, or areas
Tracing - tracing an individual operation across multiple log records
Concepts
The roles of the different concepts in the user stories can be illustrated like this.
(This diagram makes an assumption on output stream solution in order to highlight what is considered configuration vs code. Actual solution may end up different.)
User Stories
Conventional API
As a user, I want a conventional logging api that works pretty much as expected compared to other dart codebases I may have experience with.
As a user, I want a conventional logging api that works reasonably familiar compared to other languages and frameworks I may have experience with.
Pre-baked Logging
Outputs
As a user, I want the default log output to be to stdout, and only stdout (with the exception of the existing logging database for Insights).
As a user, I want the existing logging database to continue working pretty much the same way, unless I configure differently.
As a user, I want it to be simple to direct the log output to different destinations for different occasions - locally, in production, different test scenarios, etc.
As a user, I want 100% of the outputs from the Serverpod framework code to be via the logging framework, i.e. no “rogue outputs” such as prints or output not adhering to the logging.
As a user, I want stdout, stderr, and the log database to be outputs available out-of-the-box.
Outputs, Future
As a user I want a GCP logging output to be available in the future.
As a user I want a Sentry logging output to be available in the future.
As a user I want an AWS logging output to be available in the future.
Scopes
As a user, I want the logging framework to have an easily understandable, extensible, and hierarchical structure of scopes (namespaces / logger names) that enable me to filter and search logs at both high and low granularities.
As a user, I want the log scopes that are predefined in the Serverpod framework code to be consistently applied, well thought out, and easily distinguishable from user code logging.
Filtering
As a user, I want to be able to set a level filter per scope (which then applies to all outputs).
As a user, I want to be able to set a level and content filter per output.
Formatting
As a user, I want to be able to define the formatting of log records output: Selecting fields to include, produce plain text column formatting, and JSON.
As a user, I want to be able to define the formatting of log records differently for each output.
As a user, I want an easy and consistent way to log error messages based on exceptions.
Tracing
Performance & Reliability
Logging should have a negligible effect on the execution time of server requests.
For each output, log messages should appear almost immediately after they were produced (as far as possible with the individual output technology).
For each output, log messages should be included in the same order that they were produced.
Configuration
As a user I want there to be good default logging configurations for production mode and development mode.
As a user I want to be able to define my logging configuration including filtering, formatting, and outputs via configuration file (i.e. not requiring code changes).
As a user I want to set initial values for specific logging filters/levels via environment variables.
As a user I want to override specific logging filters/levels on the server’s command line.
As a user, I want to be able to override logging configuration live, i.e. on a running server, in a way that’s coherent with current insights API.
Next Steps