PotatoBeans standard logging library for all PotatoBeans services. Now published as open source for all users and PotatoBeans former clients to use and import.
logutil library provides a Logger interface and some additional default implementations for logging. Although not
designed for speed, the library can be further extended to acknowledge other common logging methods, including some
quick ones. The library is not restricted to not use cgo too and so C languages can be used when needed to create
some more quick loggers.
Compared to the rest of logging libraries out there, logutil does not provide much more features. It provides a basic
interface to log into a few outputs, with 5 log levels: TRACE, DEBUG, INFO, WARN, and ERROR. The new logutil.ContextLogger
interface adds context support, which is useful for OpenTelemetry logging, which is also supported.
The example below creates a function that reads from config (can be parsed with potatobeansco/go-config). The MultiLogger
provides a basic way to send to multiple logger all at once. The MultiLogger sends logs to all the logutil.ContextLogger outputs,
allowing you to log into multiple outputs. The standard example below logs to stdoutput, a file, and OpenTelemetry LoggerProvider in case it is given.
type Config struct {
LoggingToStd bool `config:"LOGGING_TO_STD"`
LoggingStdColor bool `config:"LOGGING_STD_COLOR"`
LoggingToFile bool `config:"LOGGING_TO_FILE"`
LoggingFilePath string `config:"LOGGING_FILE_PATH"`
}
func createLogger(loggingConfig *Config, prefix string, logProvider *sdklog.LoggerProvider) logutil.ContextLogger {
var loggers []logutil.ContextLogger
if loggingConfig.LoggingToStd {
logger := logutil.NewStdLogger(loggingConfig.LoggingStdColor, prefix)
logger.OutputMode = logutil.StdLoggerOutputModeOnlyStdOut
loggers = append(loggers, logger)
}
if loggingConfig.LoggingToFile {
loggers = append(loggers, logutil.NewFileLogger(loggingConfig.LoggingFilePath, prefix))
}
if logProvider != nil {
loggers = append(loggers, logutil.NewOpenTelemetryLogger(logProvider, prefix, version))
}
return logutil.NewMultiLogger(loggers...)
}The result is a ContextLogger which can be used everywhere in your code. You can create different logger with different
prefixes for different use cases. Prefixes show up in standard output and file, such as (myservice):
2025/03/10 13:58:16 [ERROR ] myservice: cannot ping database: failed to connect to 127.0.0.1:5432
Prefix is also sent as attribute (prefix) for OpenTelemetry log, in addition to the custom kind attribute which can
be log or access.
Currently, the supported Logger in this repository are:
- FileLogger (to file)
- StdLogger (to stdout/stderr)
- FluentdLogger (to fluentd in_udp or in_tcp inputs)
- OpenTelemetryLogger (to OpenTelemetry log provider)
All of these loggers support context parameters. However, it is only the OpenTelemetryLogger that so far uses it. OpenTelemetryLogger can capture trace parent data from its context, to provide Trace to Log or Log to Trace functionalities, such as the ones provided by Grafana and other services.