Serilog 2.0 introduced a nice compact JSON output format that can be used with the console, file, and several other text-based sinks. The format is very simple, just newline-separated JSON streams with some well-known properties defined (like @t for “timestamp”). We often refer to it as CLEF - compact log event format.

There are still situations where it makes more sense to write to STDOUT or a log file, rather than ship events directly to a log server via HTTP or UDP. CLEF is a nice machine-readable alternative to text in these scenarios.

{"@t":"2017-07-07T03:44:57.8532799Z","@mt":"Hello, {User}!","User":"nblumhardt"}

Machine readable != human readable, of course, so there’s a trade-off to make. Since I deal with files in CLEF format practically every day, I whipped up clef-tool to make reading and filtering CLEF more pleasant. I wrote previously about how clef.exe is built and packaged, but didn’t mention much about what the tool is for, hence this quick and belated introduction.

Given CLEF as input, clef.exe echos each event to its output, formatted as text:

CLEF tool echo

This is how I use it the most; I find I can scan through text by eye much faster than I can scan through the JSON.

The output looks a lot like the Serilog console sink’s output. That’s because under the hood, clef.exe is just chaining together components of Serilog, including:

I think it’s interesting that all of these components, most of them not intended for “interactive” use, can be put together to make something quite friendly.

Filtering is especially pleasant:

CLEF tool filtering

The filtering syntax is pretty flexible. Along with references to structured log event properties like Counter in the example, and standard properties like @Level, @Message and so-on, a full range of logical, numeric, and text-based operations are supported:

  • @Message like 'Hello%' - find events where the rendered message starts with the string Hello
  • @Exception is not null - events with an exception attached
  • Tags[?] = 'important' - look inside a Tags array property for any equal to the string important
  • User.Id <> 1234 - dot through structured data into sub-properties
  • Contains(RawUrl, /p-\d{3}\//) - regular expression search

clef.exe accepts input on STDIN or from a file (specify -i filename), and can write to the console (default), a file (-o filename), or Seq (--out-seq="https://...").

File and console output can themselves be formatted as JSON with --format-clef, or written in an alternative text format by specifying a Serilog output template with --format-template=:

CLEF tool formatting

Finally, you can tack extra properties onto a batch of events using -p NAME=VALUE, for example -p Hostname=abcd1234 - handy especially when you need to import logs from multiple sources into Seq.

Downloads are via GitHub releases. It’d be great to hear from you if you find clef-tool useful :-)