serverpod / serverpod

Serverpod is a next-generation app and web server, explicitly built for the Flutter and Dart ecosystem.
BSD 3-Clause "New" or "Revised" License
2.57k stars 237 forks source link

RFC: Serverpod Server Logging Framework #2847

Open christerswahn opened 1 month ago

christerswahn commented 1 month ago

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.

serverpod-logs

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.

[!NOTE] The reader is invited to ask questions and add suggestions - the more specific the better!

Introduction

Needs

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.

RFC_ Logging Framework

(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

  1. 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.

  2. 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

  1. As a user, I want the Serverpod framework logging to produce the typical server logs out of the box (e.g. request logging).

Outputs

  1. 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).

  2. As a user, I want the existing logging database to continue working pretty much the same way, unless I configure differently.

  3. 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.

  4. 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.

  5. As a user, I want stdout, stderr, and the log database to be outputs available out-of-the-box.

Outputs, Future

  1. As a user I want a GCP logging output to be available in the future.

  2. As a user I want a Sentry logging output to be available in the future.

  3. As a user I want an AWS logging output to be available in the future.

Scopes

  1. 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.

  2. 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

  1. As a user, I want to be able to set a level filter per scope (which then applies to all outputs).

  2. As a user, I want to be able to set a level and content filter per output.

Formatting

  1. 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.

  2. As a user, I want to be able to define the formatting of log records differently for each output.

  3. As a user, I want an easy and consistent way to log error messages based on exceptions.

Tracing

  1. As a user, I want the Serverpod framework logging to include tracing information, enabling tracing an operation from the client, via server’s received request, invocation of endpoint, and execution of user code.

Performance & Reliability

  1. Logging should have a negligible effect on the execution time of server requests.

  2. For each output, log messages should appear almost immediately after they were produced (as far as possible with the individual output technology).

  3. For each output, log messages should be included in the same order that they were produced.

Configuration

  1. As a user I want there to be good default logging configurations for production mode and development mode.

  2. 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).

  3. As a user I want to set initial values for specific logging filters/levels via environment variables.

  4. As a user I want to override specific logging filters/levels on the server’s command line.

  5. 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

  1. Compile the feedback on this RFC and identify the concrete stories to aim for in the initial versions
  2. Evaluate existing dart logging packages and determine what to use
  3. Create an initial version of the new logger and ship with Serverpod, ensuring compatibility and functional consistency with earlier versions
christerswahn commented 1 month ago

Suggestion to add test-supporting user stories:

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.

runyaga commented 1 month ago

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