Using Serilog with F# Discriminated Unions
This week GitHub user vlaci called us out on awful F# support in Serilog. In their issue report they show how a nice clean discriminated union type like “Option” is represented hideously in structured data:
type Shape =
| Circle of Radius : double
| Rectangle of Width : double * Height : double
| Arc // ...
let shape = Circle 5.
Log.Information("Drawing a {@Shape}", shape)
Prints:
2015-01-14 16:52:06 [Information] Drawing a Circle { Radius: 5, Tag: 0, IsCircle:
True, IsRectangle: False, IsArc: False }
The verbosity gets worse for types with more values.
I took this as a chance to crank up Visual Studio and get reacquainted with F#, using the example from @vlaci as a starting point. Using Serilog.Extras.FSharp you can now enjoy your discriminated unions encoded pleasantly like:
2015-01-14 16:58:31 [Information] Drawing a Circle { Radius: 5 }
Depending on the log storage you use you’ll be able to query on the tag as well as the fields (like Radius
) from the union.
You can enable this by installing the package and adding Destructure.FSharpTypes()
to your logger configuration:
open Serilog
[]
let main argv =
Log.Logger <- LoggerConfiguration()
.Destructure.FSharpTypes()
.WriteTo.ColoredConsole()
.CreateLogger()
Log.Information("Drawing a {@Shape}", Circle 5.)
0
Thanks again to vlaci for kicking this off. I was especially keen to see this in because I’m sure someone with better F# skills than mine can add a lot to the Serilog/F# experience. If you have ideas we’d love to hear from you on the project site!