Processing JSON logs with clef-tool
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:
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:
- Serilog.Formatting.Compact.Reader to parse CLEF files,
- Serilog to enrich events,
- Serilog.Filters.Expressions to apply filters,
- Serilog.Formatting.Compact to format JSON output, and
- the Serilog Console, File and Seq sinks to send events to different output destinations.
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:
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 attachedTags[?] = 'important'
- look inside aTags
array property for any equal to the string importantUser.Id <> 1234
- dot through structured data into sub-propertiesContains(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=
:
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 :-)