Logs are a critical thing in production systems and I would like to start a discussion about bringing low-level support for efficient logging into GHC
Context (in Haskell)
Something I see quite often in Haskell applications is the interleaved outputs of two or more logging functions, from the main application that needs to log something, to libraries in dev
mode that trace their execution (like printing SQL queries on the terminal as they appear).
Michael Snoyman wrote a blog post in 2016 about a couple of concurrency problems in Haskell, including that putStrLn
is not thread-safe: Haskell's Missing Concurrency Basics
And for some years I have been using @hackage/log-base for structured logging with multiple backends, which has been a delightful experience, since shipping logs to an aggregator or just on the terminal is very easily done. A delight both at home and at work.
Context (in Erlang)
Before programming in Haskell I was using Elixir and Erlang, who have logging primitives included in the standard application framework shipped with the language (OTP): Logger — Logger v1.16.2
If you want a short read about it, see this article: Erlang/OTP 21's new logger
Fundamentally the idea is that one unified process (green thread) receives all these logging messages from the other processes, and so the distribution of the messages enforces the order in which they are printed on screen (or shipped off to ElasticSearch). Which rids us from interleaved outputs.
Let’s talk about it
Unified primitives for structured logging would in my opinion be a great way to progressively start unifying the ecosystem. Logging is systematically one of the first things one has to figure out when integrating Haskell into a tech stack.
While it is normal to have differences of opinions about the interfaces, one could easily pick a package like @hackage/katip or @hackage/log-base, and retain the guarantees of interoperability that GHC provides: Common log levels, structured logging, thread-safety, common backend interfaces.
I think that unifying the logging infrastructure of Haskell programs will ease its adoption in pre-existing tech stacks, since backends would be written not against specific libraries but against the APIs of GHC. So there would be an obvious gain in industrial adoption.
Edit: I initially proposed that it would live in the RTS (because C code fast), but having this live in user-land would be a perfectly valid solution.
Here is a diagram that captures the high-level flow of things: