fblog makes JSON logs readable without leaving the terminal
Small command-line JSON Log viewer
At a glance
- What is it?
- fblog is a small Rust command line tool that pretty prints JSON log files, with a Lua filter language, template based formatting and support for piped streams from kubectl. It suits developers who read structured logs all day and want colour and filtering without opening an editor.
- Who is it for?
- Adopt fblog if you read JSON logs from a terminal and want colour, field selection and a filter language without running a web viewer or a full log platform. Do not adopt it for unstructured text logs, for logs it cannot parse as JSON, or when you need server side search and retention, since it reads a file or a stream and formats it.
- Can I use it commercially?
- Yes. WTFPL is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 21 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A log viewer for one file format, not a log platform
fblog is described as a small tool to view json log files, and that is the whole scope. It is a Rust binary that reads JSON log entries and renders them in a terminal with sensible defaults, including the message, the severity and the timestamp. The project is distributed under the WTFPL, which is about as permissive as a licence gets, and the Cargo manifest classifies it under command line utilities. The audience is developers and operators who look at structured logs constantly and are tired of running jq, or of opening a file in an editor and scrolling past the noise. The important framing is that fblog does not index, store, ship or search. It reads a file, or whatever is piped into it, and formats it. That makes it a comfortable fit in a shell pipeline and a poor fit as a replacement for a server side log index. The repository is a single Rust crate with a src/ directory, a Cargo.toml, a Dockerfile, a default_config.toml and a set of sample log files used in the documentation examples, including sample_elastic.log, sample_nested.json.log, sample_context.log and sample_numbered.json.log.
Selecting fields is a pair of flags, not a pipeline
The simplest use of fblog is to ask it for particular fields from each log entry, and the documented example is short:
``` shell-script fblog -a message -a "status > a" sample_nested.json.log ```
The -a flag is repeatable, so you can name several fields and get a table of them, which is the thing you want when a log line has thirty keys and you care about three. The second form in that example uses the greater than sign to reach a nested field, pulling the a value inside the status object of each entry. This is the part where fblog earns its keep over a raw dump, because a filtered view is the difference between reading a log and searching a log. The tool also tries to detect the message, the severity and the timestamp of a log entry on its own, and that behaviour can be customised, with the documentation pointing at the --help output for the details. The result is that fblog handles the common case with no configuration at all, and gives you the knobs for the case where your application names its fields differently from the convention.
Lua is the filter language, and the fields become variables
Filtering is done with Lua, and the documentation is unusually clear about how the log fields are exposed. Simple equality works as you would expect, with a not equal operator written as a tilde equals sign, so a filter like the level not being info is written in the documented example as:
fblog -f 'level ~= "info"' # will print all message where the level is not infoYou can also compare against a string function, which is how the example filters on a field starting with bow. If you are unsure which variables are available, the --print-lua option shows the code that fblog generates for the log you are looking at, which is a small but genuinely useful affordance for a filter language. The field naming has one rule worth knowing. Identifiers that are not valid Lua identifiers, such as a dotted log level, are converted with the dot becoming the character that separates words in a name such as log_level. That is a design choice with a consequence, since two different source fields could collapse to the same Lua name. Nested fields are converted to Lua records, so a nested value is reached with a dot, and array fields become Lua tables with the index starting at 1, which is the documented convention and differs from the zero based indexing you would expect elsewhere.
Templates format the output, and colour is a template function
Output formatting is template based, using handlebars, and the documentation gives a compact example of a custom main line format:
``` shell-script fblog -p --main-line-format "{{#if short_message}}{{ red short_message }}{{/if}}" sample.json.log ```
The -p flag appears here and in the prefix section, and the documentation lists the sanitized variables that fblog provides: fblog_timestamp, fblog_level, fblog_message and fblog_prefix. Nested values are registered as objects, so nested.value reaches a nested value. The colour helpers are listed as a set of handlebar helpers: bold, yellow, red, blue, purple, cyan, green, color_rgb with three components, uppercase, level_style, fixed_size with a width, and min_size with a width. That is a small vocabulary, but it covers the usual case of colouring by severity and truncating a field to a fixed column width. The tool also honours the NO_COLOR convention, disabling colour output when the NO_COLOR environment variable is present, which is the right behaviour for logs that will end up in a file or a ticket. The default formatting is described as available through --help, so the defaults are discoverable rather than hidden in the source.
Pod prefixes and placeholder substitution handle real log shapes
Two features address the awkward realities of production logs rather than a tidy file. The first is prefix handling. If you query docker or kubectl across multiple pods, the log lines arrive prefixed with the pod name, in the shape PODNAME followed by the JSON object. fblog parses that and adds it to the message, using the -p flag. The second is placeholder substitution. Placeholders in the message, in the fblog_message variable, can be substituted with values from a context object or an array, and you enable it either with the -s flag or by setting a context key with -c context or a placeholder format with -F. The placeholder format is written like PREFIX key SUFFIX, and the documented example uses a hash on each side of the key with a JSON log line carrying a count:
``` bash fblog -c extra_data -F '#{key}' example.log ```
The log line in the example is a JSON object with a message containing a count placeholder, an extra_data object holding the count, and a level. The point of the feature is that a message like Found some new items with the number embedded becomes a message with the real number in it, taken from the structured field rather than parsed out of the text. That is the difference between a log viewer and a log formatter, and it is what makes fblog useful on applications that use structured logging properly.
Configuration, completions, and where the tool stops
The rest of the surface is ordinary command line hygiene. fblog reads its configuration from a file called fblog.toml, looked for in the platform config directory, which is $XDG_CONFIG_HOME or $HOME/.config on Linux, {FOLDERID_RoamingAppData} on Windows and $HOME/Library/Application Support on macOS. If the file does not exist or is empty, a default_config.toml in the repository is used, and the documentation links to it. Numeric severities can be mapped to names in a level_map table, with a worked example using values of the kind the bunyan package uses, and the named levels fblog colourises are trace, debug, info, warn, error and fatal. Shell completions are generated with a --generate-completions flag that takes the shell name. There is also a Kubernetes integration, with k9s plugin definitions in the documentation for pod and container log views. The limitation to be clear about is the scope. fblog does not support native log tailing, though the documentation says that is easily achievable, since any endless stream can be piped into it, with tail -f on a file or kubectl logs -f for a cluster. And the tool assumes your input is JSON. A mixed or partially structured log file will not parse, and while the tool tries to detect message, severity and timestamp, that detection is a heuristic rather than a schema, so a format it has not seen before will be rendered less usefully than a purpose built parser for your application would.
Editorial conclusion
Adopt fblog if you read JSON logs from a terminal and want colour, field selection and a filter language without running a web viewer or a full log platform. Do not adopt it for unstructured text logs, for logs it cannot parse as JSON, or when you need server side search and retention, since it reads a file or a stream and formats it. Before you start, run fblog --print-lua to see the variables your filter can use, and check the level_map configuration if your application emits numeric severities rather than names.
Frequently asked questions
How do I install fblog?
Install it with `cargo install fblog`. It is also available through package managers, with an AUR package for Arch Linux and a Homebrew formula listed in the project documentation.
How do I filter fblog output?
Filtering uses Lua expressions passed with the -f flag, for example `fblog -f 'level ~= "info"'` to print messages where the level is not info. Field names that are not valid Lua identifiers are converted with dots becoming a word separator, nested fields become Lua records and array fields become Lua tables indexed from 1. You can use --print-lua to see the generated code for the log you are looking at.
Can fblog follow a live log stream?
It does not support native log tailing, but the documentation shows that any endless stream can be piped into it, for example `tail -f file | fblog` or `kubectl logs -f ... | fblog`.
How do I customise fblog output formatting?
Use the --main-line-format option with a handlebars template, as in the documented example, and use the sanitized variables fblog_timestamp, fblog_level, fblog_message and fblog_prefix. Colour and layout helpers are provided, including bold, the colour names, uppercase, level_style, fixed_size and min_size. Colour output is disabled when the NO_COLOR environment variable is present.
Where does fblog read its configuration from?
From a file called fblog.toml in the platform config directory, which is $XDG_CONFIG_HOME or $HOME/.config on Linux, {FOLDERID_RoamingAppData} on Windows and $HOME/Library/Application Support on macOS. If the file is missing or empty, the default config in the repository is used, and a level_map table can map numeric severities to names.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/brocode-fblog)Was this useful?