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 instanceUsing the New
function, at the package loggerCLI
, you can get a new LoggerCLI
instance. This constructor receives
two arguments:
json
: Controls the output. If true, it will print one log per line, parsed asjson
objectlvlsEnabled
: Anuint64
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 logsLogs 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
#
HelpersWhen 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.
#
ParseLogLevelfunc 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)
#
ValidateLogLevelsfunc 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
#
LogLevelsValuesconst 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