Nowadays most backend-software is written as a microservice that needs to interact with other internal and possibly external services. Although the benefits are quite obvious (independently deployable and managed, etc) there are some associated challenges.
With this setup it becomes very hard to diagnose what went wrong in the case of failure. We might have isolated logs but how can we tell a call to a database and an external service are associated to a single http request? This is a very common problem with a only a few solutions and not so many standards.
Distributed tracing is still an area of research but some standards have already emerged in the past years, most of them based on the Google Dapper specification:
The solution proposed by these specifications are very broad and their intent is to become a standard no matter what programming language you’re using. But it comes with a price. Setting this up is not a trivial task and the most important feature is to trace distributed calls which, in my opinion, can be simplified quite a lot with a minimalistic solution.
The RIO Monad
The most common approach to carry “context” (this can be a “Trace-Id”) in functional programming is by using the
ReaderT monad transformer or more commonly called
There are a few blog posts out there recommending the use of the
RIO monad, which is basically
IO defined as a
newtype, in production applications. The most remarkable ones and where I’ve got the inspiration to write this library are:
- [Jul 2017] - The RIO Monad by Michael Snoyman
- [Mar 2018] - Haskell modules for masses by Eric Torreborre
The implementation presented by this library follows the same idea but in a minimalistic way: just carrying a
TraceId around instead of a whole application context. And it is mainly adapted to work nicely with
Http4s while abstracting over the effect type using
Cats Effect which are two amazing libraries of the Typelevel ecosystem.
The main type defined as
type Trace[F[_], A] = Kleisli[F, TraceId, A], a bit simpler than how
RIO is defined because it’s also doing less.