Skip to main content

Logger CLI - Experimental

Since this library was built to compose my personal stack, I extended the original Logger into the LoggerCLI, that is intended to be used by my CLI tools. You can find this at the loggerCLI package, inside the root package.

caution

This is just an experimental feature, so it can be removed in future versions. Use at your own risk

LoggerCLI logs can be nested, creating a tree-like structure, easing visualization. You can create an instance of the LoggerCLI using the New function, inside the loggerCLI package.

Inside the loggerCLI package there's another package: beautify. You can use this package to pretty-print a set of logs. When using some CLI tool that uses the LoggerCLI, you can just pipe the output to the beautify package:

some-tool --json --some-flag some-file | go run PATH/TO/go-log/loggerCLI/beautify
note

The beautify package expects to receive one log per line, parsed as a JSON object. If you're using some CLI tool, you can create and set a --json CLI flag, and forward it to the New function that creates the LoggerCLI instance (as a bool value)

note

If the nesting is too deep, or if there's some log with a long message, the terminal can break the visualization (by putting unexpected break lines). To fix it, you can just print the beautify output to some file (maybe using the > terminal operator?) and open it using another GUI (maybe some text editor?)

caution

This package is far from optimized, and expects that the output knows how to print ANSI codes (virtually any modern terminal knows how to do it).

For details, see the source code

Creating a new LoggerCLI instance#

Using the New function, at the package loggerCLI, you can get a new LoggerCLI instance. This constructor receives two arguments:

  1. json: Controls the output. If true, it will print one log per line, parsed as json object
  2. lvlsEnabled: An uint64 value, that represents the Log Levels (see ParseLogLevel)
tip

If you're creating some CLI tool and want to provide Log Level customization via its flags, you can use the ParseLogLevel function, exported at the loggerCLI package, to parse a human-readable description of the log levels into the uint64.

For details, see the source code

Nesting logs#

Logs created by the LoggerCLI are intended to be nested, so, the API is built in a way that makes it possible. Every log level method will return another instance of LoggerCLI, that will nest its own logs inside the LoggerCLI that created it. Example:

flags := parseCliFlags()lvl0 := loggerCLI.New(flags.json, flags.debug, flags.trace)lvl1 := lvl0.Info("Lvl 0")lvl2 := lvl1.Warn("Lvl 1")lvl0.Info("Lvl 1 - again")lvl2.Error("Lvl 2")lvl1.Warn("Lvl 1 - again")
// Will output://    [ INFO ] Lvl 0//    [ WARN ] Lvl 1//    [ INFO ] Lvl 0 - again//    [ ERROR ] Lvl 2//    [ WARN ] Lvl 1 - again
// If forwarded to "beautify" (with "json" = true)://    [ INFO ] Lvl 0//    |--[ WARN ] Lvl 1//    |  '--[ ERROR ] Lvl 2//    '--[ WARN ] Lvl 1 - again//    [ INFO ] Lvl 0 - again
tip

Don't forget that it's recommended to create, at least, one CLI Flag: --json. The value of this flag should be forwarded to the New function, easing the pipe of the output to the beautify package

Helpers#

When dealing with theLoggerCLI in a CLI tool, for example, you will find that it's very boring to parse/read string values that the user have passed via CLI flags, to configure the LoggerCLI instance. To help you with this boilerplate code, there's some helper functions/constants that you can use.

ParseLogLevel#

func ParseLogLevel(str string) uint64 { ... }

This function will take some string and return the equivalent Log Levels that should be enabled. The structure of the string is very simple: the log level names separated by "|", without spaces. Example:

your-CLI-tool --some-flag=1 --log-levels="DEBUG|WARN|FATAL" --other-flag="some string"

The value of the --log-levels flag, when given to the ParseLogLevel function, will return the uint64 that enables the DEBUG, WARN and FATAL log levels.

tip

You can pass the ParseLogLevel returned value directly to the loggerCLI.New function

note

The ParseLogLevel function accepts the value "ALL", that enables all log levels. This way, you don't need to set the --log-levels flag value to "TRACE|DEBUG|INFO|WARN|ERROR|FATAL", just set to "ALL" (considering the example above)

ValidateLogLevels#

func ValidateLogLevels(s string) bool { ... }

This function will return a boolean indicating whether the given string is a valid log levels string or not. If true, the string can be safely used. Otherwise, its behaviour is undefined.

caution

Always test any string that represents log levels before using it, because since ParseLogLevel don't return errors, it will silently misbehave

LogLevelsValues#

const LogLevelsValues = `"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "ALL"`

This const is intended to be used in --help messages in CLI tools. You can safely display the content of this string when telling to the user which values he can use inside the log level string.

caution

Always use this const string instead of hard-coding the message all by yourself. If the API changes and you're using this string, the changes will be automatically reflect in your code