Sooner or later
printfn style of logging becomes too cumbersome and you start to search for a logging library.
For F# developers the most obvious choice is Logary, but very soon you
find out that your Logary logging code is even less readable. In this article you will find F# tricks,
which helped me to create a neat abstraction for logging in Semagle Framework.
Logary is perfect for libraries because it does not require you to reference Logary library. You only need to add Facade.fs dependency to your paket dependencies file:
and add a replacement target to your FAKE build script:
Thus, it was easy to configure and add logger to my code:
However, I needed synchronous and low overhead logging, i.e., evaluation of the logged message
only if the message level is above the minimal configured level. With Logary my simple
printfn "iteration = %d, objective = %f" k (objective n) became:
Some developers may disagree with me, but I think that logging should not pollute the code and should be simple and readable. So, I started to search for ways to simplify the logging code.
First, I found that I can create a builder with custom operations:
So, I was able to write a much more readable code:
Second, I found the “magic” annotation
So, now I can write:
Therefore, now my logging code is as simple as
printfn, but also it is lazily evaluated
and easily distinguished from other code.
If you find this DSL useful, you can download LoggerBulder code here and adapt it to your needs.