Documentation ¶
Overview ¶
Package multilogger is a thin wrapper around logrus https://github.com/sirupsen/logrus that writes logs simultaneously to many outputs at the same time. Each output (implemented as Hook) have their own logging level. It exposes the same API as a regular logrus logger.
How to use it ¶
So, you can use multilogger to write logs to standard error with a minimal logging level (i.e. WarningLevel) and have the full debug log (i.e. DebugLevel or TraceLevel) written to a file.
import "github.com/coveooss/multilogger" import "github.com/sirupsen/logrus" func main() { log := New("test") // By default, logs are sent to stderr and the logging level is set to WarningLevel log.AddHooks(NewFileHook("debug.log", logrus.DebugLevel)) // It is possible to add a file as a target for the logs log.AddHooks(NewFileHook("verbose.log", "trace")) // The logging level could be expressed as string, logrus.Level or int log.Warning("This is a warning") log.Infof("This is an information %s", message) }
Differences with logrus
- The multilogger object is based on a logrus.Entry instead of a logrus.Logger.
- The methods Print, Println and Printf are used to print information directly to stdout without log decoration. Within logrus, these methods are aliases to Info, Infoln and Infof.
- It is not possible to set the global logging level with multilogger, the logging level is determined by hooks that are added to the logging object and the resulting logging level is the highest logging level defined for individual hooks.
- Hooks are fired according to their own logging level while they were fired according to the global logging level with logrus.
- The default formatter used by console and file hook is highly customizable.
Where is it used ¶
This project is used in other Coveo projects to reduce visual clutter in CI systems while keeping debug logs available when errors arise:
gotemplate https://github.com/coveooss/gotemplate terragrunt https://github.com/coveooss/terragrunt tgf https://github.com/coveooss/tgf
Index ¶
- Constants
- func AcceptedLevels() []string
- func AcceptedLevelsString() string
- func GetGlobalFileFormat() string
- func GetGlobalFormat() string
- func ParseBool(value string) bool
- func ParseLogLevel(level interface{}) logrus.Level
- func SetDurationFormat(style DurationFormat, rounded, longUnit, override bool) bool
- func SetDurationPrecision(precision time.Duration, override bool) (time.Duration, bool)
- func SetGlobalFileFormat(format string, override bool) (string, bool)
- func SetGlobalFormat(format string, override bool) (string, bool)
- func TryParseLogLevel(level interface{}) (logrus.Level, error)
- type DurationFormat
- type DurationFunc
- type Formatter
- type Hook
- func (hook *Hook) Fire(entry *logrus.Entry) error
- func (hook *Hook) Formatter() *Formatter
- func (hook *Hook) GetFormatter() logrus.Formatter
- func (hook *Hook) GetInnerHook() logrus.Hook
- func (hook *Hook) Levels() []logrus.Level
- func (hook *Hook) SetColor(color bool) *Hook
- func (hook *Hook) SetFormat(formats ...interface{}) *Hook
- func (hook *Hook) SetFormatter(formatter logrus.Formatter) *Hook
- func (hook *Hook) SetOut(out io.Writer) *Hook
- func (hook *Hook) SetStdout(out io.Writer) *Hook
- type Logger
- func (logger *Logger) AddConsole(name string, level interface{}, format ...interface{}) *Logger
- func (logger *Logger) AddError(err error)
- func (logger *Logger) AddFile(filename string, isDir bool, level interface{}, format ...interface{}) *Logger
- func (logger *Logger) AddHook(name string, level interface{}, hook logrus.Hook) *Logger
- func (logger *Logger) AddHooks(hooks ...*Hook) *Logger
- func (logger *Logger) AddTime(duration time.Duration) *Logger
- func (logger *Logger) Child(child string) *Logger
- func (logger *Logger) ClearError() error
- func (logger *Logger) Close() error
- func (logger *Logger) Copy(module ...string) *Logger
- func (logger *Logger) Formatter() (result *Formatter)
- func (logger *Logger) GetDefaultConsoleHook() *Hook
- func (logger *Logger) GetDefaultConsoleHookLevel() logrus.Level
- func (logger *Logger) GetDefaultInnerHook() (result logrus.Hook)
- func (logger *Logger) GetError() error
- func (logger *Logger) GetFormatter() (result logrus.Formatter)
- func (logger *Logger) GetHookLevel(name string) logrus.Level
- func (logger *Logger) GetLevel() logrus.Level
- func (logger *Logger) GetModule() string
- func (logger *Logger) Hook(name string) *Hook
- func (logger *Logger) IsLevelEnabled(level logrus.Level) bool
- func (logger *Logger) ListHooks() []string
- func (logger *Logger) Print(args ...interface{})
- func (logger *Logger) Printf(format string, args ...interface{})
- func (logger *Logger) Println(args ...interface{})
- func (logger *Logger) RemoveHook(name string) *Logger
- func (logger *Logger) SetAllOutputs(out io.Writer) *Logger
- func (logger *Logger) SetColor(color bool) *Logger
- func (logger *Logger) SetDefaultConsoleHookLevel(level interface{}) error
- func (logger *Logger) SetExitFunc(exitFunc func(int))
- func (logger *Logger) SetFormat(formats ...interface{}) *Logger
- func (logger *Logger) SetFormatter(formatter logrus.Formatter) *Logger
- func (logger *Logger) SetHookLevel(name string, level interface{}) error
- func (logger *Logger) SetModule(module string) *Logger
- func (logger *Logger) SetOut(out io.Writer) *Logger
- func (logger *Logger) SetReportCaller(reportCaller bool) *Logger
- func (logger *Logger) SetStdout(out io.Writer) *Logger
- func (logger *Logger) TryAddHook(name string, level interface{}, hook logrus.Hook) (*Logger, error)
- func (logger *Logger) WithContext(ctx context.Context) *Logger
- func (logger *Logger) WithField(key string, value interface{}) *Logger
- func (logger *Logger) WithFields(fields logrus.Fields) *Logger
- func (logger *Logger) WithTime(time time.Time) *Logger
- func (logger *Logger) Write(writeBuffer []byte) (int, error)
Examples ¶
- GetDurationFunc
- Logger.AddConsole
- Logger.AddConsole (Overwrite)
- Logger.AddFile
- Logger.AddFile (Folder)
- Logger.AddFile (FolderWithInvalidModuleName)
- Logger.AddTime
- Logger.Child
- Logger.Copy
- Logger.Formatter (RoundDuration)
- Logger.WithField
- Logger.WithFields
- Logger.WithTime
- New (Default)
- New (Log_catcher)
- New (Log_catcher_disabled)
- New (Output_sent_to_info)
- New (SettingLoggingLevel)
- SetDurationPrecision
Constants ¶
const ( // CallerEnvVar is an environment variable that enable the caller stack by default. CallerEnvVar = "MULTILOGGER_CALLER" // FormatEnvVar is an environment variable that allows users to set the default format used for log entry. FormatEnvVar = "MULTILOGGER_FORMAT" // FormatFileEnvVar is an environment variable that allows users to set the default format used for log entry using a file logger. FormatFileEnvVar = "MULTILOGGER_FILE_FORMAT" // DefaultFileFormat is the format used by NewFileHook if neither MULTILOGGER_FORMAT or MULTILOGGER_FILE_FORMAT are set. DefaultFileFormat = "%module:SquareBrackets,IgnoreEmpty,Space%%time% %-8level:upper% %message%" )
const (
// DefaultConsoleFormat is the format used by NewConsoleHook if MULTILOGGER_FORMAT is not set.
DefaultConsoleFormat = "%module:Italic,Green,SquareBrackets,IgnoreEmpty,Space%%time% %-8level:upper,color% %message:color%"
)
const ( // DisabledLevel can be set when one of the logging hooks should be disabled. DisabledLevel logrus.Level = math.MaxUint32 )
Variables ¶
This section is empty.
Functions ¶
func AcceptedLevels ¶
func AcceptedLevels() []string
AcceptedLevels returns all accepted logrus levels.
func AcceptedLevelsString ¶
func AcceptedLevelsString() string
AcceptedLevelsString returns all accepted logrus levels as a comma-separated string.
func GetGlobalFileFormat ¶ added in v0.5.0
func GetGlobalFileFormat() string
GetGlobalFileFormat returns the currently globally set file log format.
func GetGlobalFormat ¶ added in v0.5.0
func GetGlobalFormat() string
GetGlobalFormat returns the currently globally set console log format.
func ParseBool ¶ added in v0.2.0
ParseBool returns true for any value that is set and is not clearly a false. It never returns an error.
True values are: 1, t, true, yes, y, on (of any non false value) False values are: 0, f, false, no, n, off
func ParseLogLevel ¶
ParseLogLevel converts a string or number into a logging level. It panics if the supplied valid cannot be converted into a valid logrus Level.
func SetDurationFormat ¶ added in v0.5.2
func SetDurationFormat(style DurationFormat, rounded, longUnit, override bool) bool
SetDurationFormat globally set the duration format preferences (across executables).
func SetDurationPrecision ¶ added in v0.5.0
SetDurationPrecision allows duration to be rounded up to the desired precision (globally set across executables).
Example ¶
const format = "%module:square% %time% %globaldelay:round% %message%" log := getTestLogger("", logrus.InfoLevel).SetModule("Rounded").SetFormat(format) defaultLog := getTestLogger("", logrus.TraceLevel).SetModule("Default").SetFormat(format) defaultLog.Formatter().FormatDuration = GetDurationFunc(NativeFormat, false, false) // We set the format of the log to include fields SetDurationPrecision(time.Nanosecond, true) for i := time.Duration(1); i < 365*24*time.Hour; { i *= 25 + time.Nanosecond t := baseTime.Add(i) log.WithTime(t).Infof("%v later", i) defaultLog.WithTime(t).Tracef("%v later", i) }
Output:
func SetGlobalFileFormat ¶ added in v0.5.0
SetGlobalFileFormat configure the default format used for file logging and ensure that it is available for all applications by setting an environment variable.
func SetGlobalFormat ¶ added in v0.5.0
SetGlobalFormat configure the default format used for console logging and ensure that it is available for all applications by setting an environment variable.
func TryParseLogLevel ¶ added in v0.2.0
TryParseLogLevel converts a string or number into a logging level.
Types ¶
type DurationFormat ¶ added in v0.5.2
type DurationFormat int
DurationFormat represents the representation of a duration rendering format
const ( // NativeFormat formats durations using the native golang duration format. NativeFormat DurationFormat = iota // PreciseFormat formats durations with precise unit for each segment 1d2h3m4s5ms6µs. PreciseFormat // ClassicFormat formats durations with higher units such as days, months, years, // but use floating value bellow minutes as native golang format does. ClassicFormat )
type DurationFunc ¶ added in v0.5.2
DurationFunc is the prototype used to represent a duration format function.
func GetDurationFunc ¶ added in v0.5.2
func GetDurationFunc(format DurationFormat, rounded, longUnit bool) DurationFunc
GetDurationFunc returns a function that can be used to format a duration.
Example ¶
durations := []time.Duration{ 0, time.Nanosecond, time.Microsecond, time.Millisecond, time.Second, time.Minute, time.Hour, day, week, month, year, 9*year + 8*month + 7*day + 6*time.Hour + 5*time.Minute + 4*time.Second + 3*time.Millisecond + 2*time.Microsecond + 1*time.Nanosecond, } w := tabwriter.NewWriter(os.Stdout, 20, 0, 1, ' ', tabwriter.TabIndent) fmt.Fprintln(w, "Native\tClassic\tClassic Rounded\tPrecise\tPrecise Rounded\tNative long\tRounded long\t.") fmt.Fprintln(w, "------\t-------\t---------------\t-------\t---------------\t-----------\t------------\t.") print := func(duration time.Duration) { fmt.Fprintf(w, "%v\t", duration) fmt.Fprintf(w, "%s\t", GetDurationFunc(ClassicFormat, false, false)(duration)) fmt.Fprintf(w, "%s\t", GetDurationFunc(ClassicFormat, true, false)(duration)) fmt.Fprintf(w, "%s\t", GetDurationFunc(PreciseFormat, false, false)(duration)) fmt.Fprintf(w, "%s\t", GetDurationFunc(PreciseFormat, true, false)(duration)) fmt.Fprintf(w, "%s\t", GetDurationFunc(NativeFormat, false, true)(duration)) fmt.Fprintf(w, "%s\t", GetDurationFunc(PreciseFormat, true, true)(duration)) fmt.Fprintln(w, ".") } var total time.Duration for _, duration := range durations { total += 5 * duration print(duration) if duration != 0 { print(10 * duration) if total != duration { print(total) } } } w.Flush()
Output: Native Classic Classic Rounded Precise Precise Rounded Native long Rounded long . ------ ------- --------------- ------- --------------- ----------- ------------ . 0s 0s 0s 0s 0s 0 second 0 second . 1ns 1ns 1ns 1ns 1ns 1 nanosecond 1 nanosecond . 10ns 10ns 10ns 10ns 10ns 10 nanoseconds 10 nanoseconds . 5ns 5ns 5ns 5ns 5ns 5 nanoseconds 5 nanoseconds . 1µs 1µs 1µs 1µs 1µs 1 microsecond 1 microsecond . 10µs 10µs 10µs 10µs 10µs 10 microseconds 10 microseconds . 5.005µs 5.005µs 5.01µs 5µs5ns 5µs10ns 5.005 microseconds 5 microseconds 10 nanoseconds . 1ms 1ms 1ms 1ms 1ms 1 millisecond 1 millisecond . 10ms 10ms 10ms 10ms 10ms 10 milliseconds 10 milliseconds . 5.005005ms 5.005005ms 5.01ms 5ms5µs5ns 5ms10µs 5.005005 milliseconds 5 milliseconds 10 microseconds . 1s 1s 1s 1s 1s 1 second 1 second . 10s 10s 10s 10s 10s 10 seconds 10 seconds . 5.005005005s 5.005005005s 5.01s 5s5ms5µs5ns 5s10ms 5.005005005 seconds 5 seconds 10 milliseconds . 1m0s 1m 1m 1m 1m 1 minute 1 minute . 10m0s 10m 10m 10m 10m 10 minutes 10 minutes . 5m5.005005005s 5m5.005005005s 5m5s 5m5s5ms5µs5ns 5m5s 5 minutes 5.005005005 seconds 5 minutes 5 seconds . 1h0m0s 1h 1h 1h 1h 1 hour 1 hour . 10h0m0s 10h 10h 10h 10h 10 hours 10 hours . 5h5m5.005005005s 5h5m5.005005005s 5h5m 5h5m5s5ms5µs5ns 5h5m 5 hours 5 minutes 5.005005005 seconds 5 hours 5 minutes . 24h0m0s 1d 1d 1d 1d 24 hours 1 day . 240h0m0s 1w3d 1w3d 1w3d 1w3d 240 hours 1 week 3 days . 125h5m5.005005005s 5d5h5m5.005005005s 5d5h5m 5d5h5m5s5ms5µs5ns 5d5h5m 125 hours 5 minutes 5.005005005 seconds 5 days 5 hours 5 minutes . 168h0m0s 7d 7d 7d 7d 168 hours 7 days . 1680h0m0s 2mo1w3d 2mo1w3d 2mo1w3d 2mo1w3d 1680 hours 2 months 1 week 3 days . 965h5m5.005005005s 5w5d5h5m5.005005005s 5w5d 5w5d5h5m5s5ms5µs5ns 5w5d 965 hours 5 minutes 5.005005005 seconds 5 weeks 5 days . 720h0m0s 4w2d 4w2d 4w2d 4w2d 720 hours 4 weeks 2 days . 7200h0m0s 10mo 10mo 10mo 10mo 7200 hours 10 months . 4565h5m5.005005005s 6mo1w3d5h5m5.005005005s 6mo1w3d 6mo1w3d5h5m5s5ms5µs5ns 6mo1w3d 4565 hours 5 minutes 5.005005005 seconds 6 months 1 week 3 days . 8640h0m0s 1y 1y 1y 1y 8640 hours 1 year . 86400h0m0s 10y 10y 10y 10y 86400 hours 10 years . 47765h5m5.005005005s 5y6mo1w3d5h5m5.005005005s 5y6mo1w3d 5y6mo1w3d5h5m5s5ms5µs5ns 5y6mo1w3d 47765 hours 5 minutes 5.005005005 seconds 5 years 6 months 1 week 3 days . 83694h5m4.003002001s 9y8mo7d6h5m4.003002001s 9y8mo7d 9y8mo7d6h5m4s3ms2µs1ns 9y8mo7d 83694 hours 5 minutes 4.003002001 seconds 9 years 8 months 7 days . 836940h50m40.03002001s 96y10mo1w5d12h50m40.03002001s 96y10mo1w6d 96y10mo1w5d12h50m40s30ms20µs10ns 96y10mo1w6d 836940 hours 50 minutes 40.03002001 seconds 96 years 10 months 1 week 6 days . 466235h30m25.02001501s 53y11mo2w2d11h30m25.02001501s 53y11mo2w2d 53y11mo2w2d11h30m25s20ms15µs10ns 53y11mo2w2d 466235 hours 30 minutes 25.02001501 seconds 53 years 11 months 2 weeks 2 days .
func TryGetDurationFunc ¶ added in v0.5.2
func TryGetDurationFunc(format DurationFormat, rounded, longUnit bool) (DurationFunc, error)
TryGetDurationFunc returns a function that can be used to format a duration.
type Formatter ¶ added in v0.1.1
type Formatter struct { // Available standard keys: time, delay, globaldelay, delta, message, level, module, file, line, func. // Also can include custom fields but limited to strings. // All of fields need to be wrapped inside %% i.e %time% %message% TimestampFormat string FormatDuration func(time.Duration) string FormatCaller func(*runtime.Frame) string // RoundDuration allows user to define the granularity of durations RoundDuration time.Duration // ColorMap allows user to define the color attributes associated with the error level. // Attribute names are defined by http://github.com/fatih/color ColorMap map[logrus.Level][]multicolor.Attribute // LevelName allows user to rename default level name. LevelName map[logrus.Level]string // contains filtered or unexported fields }
Formatter implements logrus.Formatter interface.
func NewFormatter ¶ added in v0.2.0
NewFormatter creates a new formatter with color setting and takes the first defined format string as the log format.
func (*Formatter) SetLogFormat ¶ added in v0.2.0
SetLogFormat initialize the log format with the first defined format in the list.
type Hook ¶ added in v0.2.0
type Hook struct {
// contains filtered or unexported fields
}
Hook represents a hook that logs at a given level. This struct must be extended to implement the Fire func.
func NewConsoleHook ¶
NewConsoleHook creates a new hook to log information to console (default to stderr).
level: Accept any kind of object, but must be resolvable into a valid logrus level name.
func NewFileHook ¶
NewFileHook creates a new hook to log information into a file.
level: Accept any kind of object, but must be resolvable into a valid logrus level name.
func NewHook ¶ added in v0.2.0
NewHook generates a named hook wrapper that is able the handle its own logging level.
level: Accept any kind of object, but must be resolvable into a valid logrus level name.
func (*Hook) Formatter ¶ added in v0.2.0
Formatter returns the Formatter associated to the hook. The function will panic if called upon a hook that do not support formatter.
func (*Hook) GetFormatter ¶ added in v0.2.0
GetFormatter returns the formater associated to the hook. The function will panic if called upon a hook that do not support formatter.
func (*Hook) GetInnerHook ¶ added in v0.3.0
GetInnerHook returns the inner hook actually used by the leveled hook.
func (*Hook) SetColor ¶ added in v0.2.0
SetColor allows setting color mode on hook that support it. The function will panic if called upon a hook that do not support formatter.
func (*Hook) SetFormat ¶ added in v0.2.0
SetFormat allows setting a format string on hook that support it. The function will panic if called upon a hook that do not support formatter.
func (*Hook) SetFormatter ¶ added in v0.2.0
SetFormatter allows setting a formatter on hook that support it. The function will panic if called upon a hook that do not support formatter.
type Logger ¶ added in v0.2.0
type Logger struct { *logrus.Entry PrintLevel logrus.Level Catcher bool // contains filtered or unexported fields }
Logger represents a logger that logs to both a file and the console at different (configurable) levels.
func New ¶
New creates a new Multilogger instance. If no hook is provided, it defaults to standard console logger at warning log level.
Example (Default) ¶
log := getTestLogger("default") log.Warning("This is a warning") log.Println("The logging level is set to", log.GetLevel()) log.Printf("Module = %s\n", log.GetModule())
Output: [default] 2018/06/24 12:34:56.789 WARNING This is a warning The logging level is set to warning Module = default
Example (Log_catcher) ¶
log := getTestLogger("catcher", logrus.TraceLevel) cmd := exec.Command("cat") stdin, _ := cmd.StdinPipe() cmd.Stdout, cmd.Stderr = log, log cmd.Start() lines := []string{ "Hello,", "", "This is a text that contains:", "[Error] Oops! there is an error", "This should be considered as a [warning] message", "This should go directly to output", "Format tags like %hello in output aren't considered", } for _, line := range lines { io.WriteString(stdin, line+"\n") } stdin.Close() cmd.Wait()
Output: Hello, This is a text that contains: [catcher] 2018/06/24 12:34:56.789 ERROR Oops! there is an error [catcher] 2018/06/24 12:34:56.789 WARNING This should be considered as a warning message This should go directly to output Format tags like %hello in output aren't considered
Example (Log_catcher_disabled) ¶
log := getTestLogger("catcher", logrus.TraceLevel) // We disable the log catcher. log.Catcher = false fmt.Fprintln(log, "Hello,") fmt.Fprintln(log) fmt.Fprintln(log, "This is a text that contains:") fmt.Fprintln(log, "[Error] Oops! there is an error") fmt.Fprintln(log, "This should be considered as a [warning] message") fmt.Fprintln(log, "This should go directly to output")
Output: Hello, This is a text that contains: [Error] Oops! there is an error This should be considered as a [warning] message This should go directly to output
Example (Output_sent_to_info) ¶
log := getTestLogger("catcher", logrus.TraceLevel) // We send all regular text to the InfoLevel. log.PrintLevel = logrus.InfoLevel fmt.Fprintln(log, "This is a text that contains:") fmt.Fprintln(log, "[Error] Oops! there is an error") fmt.Fprintln(log, "This should be considered as a [warning] message") fmt.Fprintln(log, "This should go directly to output")
Output: [catcher] 2018/06/24 12:34:56.789 INFO This is a text that contains: [catcher] 2018/06/24 12:34:56.789 ERROR Oops! there is an error [catcher] 2018/06/24 12:34:56.789 WARNING This should be considered as a warning message [catcher] 2018/06/24 12:34:56.789 INFO This should go directly to output
Example (SettingLoggingLevel) ¶
// Logging level could be set by explicitely declaring the hook log := New("console", NewConsoleHook("", logrus.InfoLevel)) log.Println("The logging level is set to", log.GetLevel()) // Or it can also be set after initializing the logger // It is possible to use either a logrus.Level or a string to specify the level log = New("console") log.SetHookLevel("", "trace") log.Println("The logging level is set to", log.GetLevel())
Output: The logging level is set to info The logging level is set to trace
func (*Logger) AddConsole ¶ added in v0.2.0
AddConsole adds a console hook to the current logger.
Example ¶
log := getTestLogger("json") // We add an additional console hook. log.AddConsole("json", logrus.WarnLevel, new(logrus.JSONFormatter)) log.Warning("New JSON log")
Output: [json] 2018/06/24 12:34:56.789 WARNING New JSON log {"level":"warning","module-field":"json","msg":"New JSON log","time":"2018-06-24T12:34:56Z"}
Example (Overwrite) ¶
log := getTestLogger("json") // We overwrite the default console hook by not specifying a name to our new console. // We also set the JSON formatter to pretty format the JSON code. log.AddConsole("", logrus.WarnLevel, &logrus.JSONFormatter{PrettyPrint: true}) log.Warning("New JSON log")
Output: { "level": "warning", "module-field": "json", "msg": "New JSON log", "time": "2018-06-24T12:34:56Z" }
func (*Logger) AddError ¶ added in v0.2.0
AddError let functions to add error to the current logger indicating that something went wrong in the logging process.
func (*Logger) AddFile ¶ added in v0.2.0
func (logger *Logger) AddFile(filename string, isDir bool, level interface{}, format ...interface{}) *Logger
AddFile adds a file hook to the current logger.
Example ¶
log := getTestLogger("file") var logfile string if temp, err := ioutil.TempFile("", "example"); err != nil { log.Fatal(err) } else { logfile = temp.Name() defer os.Remove(logfile) } log.AddFile(logfile, false, logrus.TraceLevel) log.Info("This is information") log.Warning("This is a warning") content, _ := ioutil.ReadFile(logfile) fmt.Println("Content of the log file is:") fmt.Println(string(content))
Output: [file] 2018/06/24 12:34:56.789 WARNING This is a warning Content of the log file is: # 2018/06/24 12:34:56.789 [file] 2018/06/24 12:34:56.789 INFO This is information [file] 2018/06/24 12:34:56.789 WARNING This is a warning
Example (Folder) ¶
log := getTestLogger("file") logDir, err := ioutil.TempDir("", "example") if err != nil { log.Fatal(err) } defer os.RemoveAll(logDir) // Adding a log folder and creating a child logger log.AddFile(logDir, true, logrus.TraceLevel) childLogger := log.Child("folder/module") // Logging into the main logger and the child logger log.Info("This is information") childLogger.Warning("This is a warning") childLogger.Info("This is information") // Reading the main logger logs firstFile := filepath.Join(logDir, "file.log") firstContent, _ := ioutil.ReadFile(firstFile) fmt.Println("Content of the first log file is:") fmt.Println(string(firstContent)) // Reading the child logger logs secondFile := filepath.Join(logDir, "file.folder", "module.log") secondContent, _ := ioutil.ReadFile(secondFile) fmt.Println("Content of the second log file is:") fmt.Println(string(secondContent))
Output: [file:folder/module] 2018/06/24 12:34:56.789 WARNING This is a warning Content of the first log file is: # 2018/06/24 12:34:56.789 [file] 2018/06/24 12:34:56.789 INFO This is information Content of the second log file is: # 2018/06/24 12:34:56.789 [file:folder/module] 2018/06/24 12:34:56.789 WARNING This is a warning [file:folder/module] 2018/06/24 12:34:56.789 INFO This is information
Example (FolderWithInvalidModuleName) ¶
// Create a test logger with lots of special chars in its name loggerName := "/abc:def!/g$%?&*().,;`^<>/" log := getTestLogger(loggerName) logDir, err := ioutil.TempDir("", "example") if err != nil { log.Fatal(err) } defer os.RemoveAll(logDir) // Adding a log folder log.AddFile(logDir, true, logrus.TraceLevel) // Logging into the main logger and the child logger log.Info("This is information") // Reading the logs (all the special chars except OS separators and module separators (:) will be removed from the file name) firstFile := filepath.Join(logDir, "abc.def", "g.log") firstContent, _ := ioutil.ReadFile(firstFile) fmt.Println(string(firstContent))
Output: # 2018/06/24 12:34:56.789 [/abc:def!/g$%?&*().,;`^<>/] 2018/06/24 12:34:56.789 INFO This is information
func (*Logger) AddHook ¶ added in v0.2.0
AddHook adds a hook to the hook collection and associated it with a name and a level. Can also be used to replace an existing hook.
func (*Logger) AddHooks ¶ added in v0.2.0
AddHooks adds a collection of hook wrapper as hook to the current logger.
func (*Logger) AddTime ¶ added in v0.2.0
AddTime add the specified duration to the current logger if its time has been freezed. Useful for testing.
Example ¶
log := getTestLogger("time", "Trace") // We can create a logger with a fix moment in time. t, _ := time.Parse(time.RFC3339, "2020-12-25T00:00:00Z") log = log.WithTime(t) log.Info("Log from fixed time") log.AddTime(5 * time.Second).Trace("Log 5 seconds later") log.AddTime(8 * time.Millisecond).Warning("Log 8 more milliseconds later")
Output: [time] 2020/12/25 00:00:00.000 INFO Log from fixed time [time] 2020/12/25 00:00:05.000 TRACE Log 5 seconds later [time] 2020/12/25 00:00:05.008 WARNING Log 8 more milliseconds later
func (*Logger) Child ¶ added in v0.2.0
Child clones the logger, appending the child's name to the parent's module name.
Example ¶
log := getTestLogger("original", logrus.TraceLevel) log.Info("Log from original") log.Child("1").Trace("Log from first child") log.Child("2").Trace("Log from second child")
Output: [original] 2018/06/24 12:34:56.789 INFO Log from original [original:1] 2018/06/24 12:34:56.789 TRACE Log from first child [original:2] 2018/06/24 12:34:56.789 TRACE Log from second child
func (*Logger) ClearError ¶ added in v0.2.0
ClearError cleans up the current error state of the logging process. It also returns the current error state.
func (*Logger) Copy ¶ added in v0.2.0
Copy returns a new logger with the same hooks but a different module name. module is optional, if not supplied, the original module name will copied. If many name are supplied, they are joined with a - separator.
Example ¶
log := getTestLogger("original", logrus.TraceLevel) log.Info("Log from original") log.Copy("copy").Trace("Log from copy") log.Copy("").Debug("I have no module") log.Copy().Debug("I have the same module as the original")
Output: [original] 2018/06/24 12:34:56.789 INFO Log from original [copy] 2018/06/24 12:34:56.789 TRACE Log from copy 2018/06/24 12:34:56.789 DEBUG I have no module [original] 2018/06/24 12:34:56.789 DEBUG I have the same module as the original
func (*Logger) Formatter ¶ added in v0.3.0
Formatter returns the Formatter associated to the default console hook.
Example (RoundDuration) ¶
log := getTestLogger("RoundDuration", logrus.InfoLevel) // We set the format of the log to include fields log.SetFormat("%time% %globaldelay:round% %level:upper% %message%") log.Formatter().RoundDuration = 5 * time.Millisecond log.Info("Starting") for i := time.Duration(1); i < 24*time.Hour; { i *= 10 log.WithTime(baseTime.Add(i)).Infof("%v later", i) }
Output: 2018/06/24 12:34:56.789 (<5ms) INFO Starting 2018/06/24 12:34:56.789 (<5ms) INFO 10ns later 2018/06/24 12:34:56.789 (<5ms) INFO 100ns later 2018/06/24 12:34:56.789 (<5ms) INFO 1µs later 2018/06/24 12:34:56.789 (<5ms) INFO 10µs later 2018/06/24 12:34:56.789 (<5ms) INFO 100µs later 2018/06/24 12:34:56.790 (<5ms) INFO 1ms later 2018/06/24 12:34:56.799 (10ms) INFO 10ms later 2018/06/24 12:34:56.889 (100ms) INFO 100ms later 2018/06/24 12:34:57.789 (1s) INFO 1s later 2018/06/24 12:35:06.789 (10s) INFO 10s later 2018/06/24 12:36:36.789 (1m40s) INFO 1m40s later 2018/06/24 12:51:36.789 (16m40s) INFO 16m40s later 2018/06/24 15:21:36.789 (2h47m) INFO 2h46m40s later 2018/06/25 16:21:36.789 (1d3h47m) INFO 27h46m40s later
func (*Logger) GetDefaultConsoleHook ¶ added in v0.3.0
GetDefaultConsoleHook returns the default console hook.
func (*Logger) GetDefaultConsoleHookLevel ¶ added in v0.3.0
GetDefaultConsoleHookLevel returns the logging level associated to the default console hook.
func (*Logger) GetDefaultInnerHook ¶ added in v0.3.0
GetDefaultInnerHook returns the inner hook actually used by the default console hook.
func (*Logger) GetError ¶ added in v0.2.0
GetError returns the current error state of the logging process.
func (*Logger) GetFormatter ¶ added in v0.3.0
GetFormatter returns the formater associated to the default console hook.
func (*Logger) GetHookLevel ¶ added in v0.2.0
GetHookLevel returns the logging level associated with a specific logger.
func (*Logger) GetLevel ¶ added in v0.2.0
GetLevel returns the highest logger level registered by the hooks.
func (*Logger) GetModule ¶ added in v0.2.0
GetModule returns the module name associated to the current logger.
func (*Logger) IsLevelEnabled ¶ added in v0.2.0
IsLevelEnabled checks if the log level of the logger is greater than the level param
func (*Logger) Print ¶ added in v0.2.0
func (logger *Logger) Print(args ...interface{})
Print acts as fmt.Print but sends the output to a special logging level that allows multiple output support through Hooks.
ATTENTION, default behaviour for logrus.Print is to log at Info level.
func (*Logger) Printf ¶ added in v0.2.0
Printf acts as fmt.Printf but sends the output to a special logging level that allows multiple output support through Hooks.
ATTENTION, default behaviour for logrus.Printf is to log at Info level.
func (*Logger) Println ¶ added in v0.2.0
func (logger *Logger) Println(args ...interface{})
Println acts as fmt.Println but sends the output to a special logging level that allows multiple output support through Hooks.
ATTENTION, default behaviour for logrus.Println is to log at Info level.
func (*Logger) RemoveHook ¶ added in v0.2.0
RemoveHook deletes a hook from the hook collection.
func (*Logger) SetAllOutputs ¶ added in v0.3.0
SetAllOutputs allows configuring the output and the logging stream on the default console hook if there is.
func (*Logger) SetColor ¶ added in v0.3.0
SetColor allows setting color mode on the default console hook if there is.
func (*Logger) SetDefaultConsoleHookLevel ¶ added in v0.3.0
SetDefaultConsoleHookLevel set a new log level for the default console hook.
func (*Logger) SetExitFunc ¶ added in v0.2.0
SetExitFunc let user define what should be executed when a logging call exit (default is call to os.Exit(int)).
func (*Logger) SetFormat ¶ added in v0.3.0
SetFormat allows setting a format string on the default console hook if there is.
func (*Logger) SetFormatter ¶ added in v0.3.0
SetFormatter allows setting a formatter to the default console hook if there is.
func (*Logger) SetHookLevel ¶ added in v0.2.0
SetHookLevel set a new log level for a registered hook.
func (*Logger) SetModule ¶ added in v0.3.0
SetModule sets the module name associated to the current logger.
func (*Logger) SetOut ¶ added in v0.3.0
SetOut allows configuring the logging stream on the default console hook if there is.
func (*Logger) SetReportCaller ¶ added in v0.2.0
SetReportCaller enables caller reporting to be added to each log entry.
func (*Logger) SetStdout ¶ added in v0.3.0
SetStdout allows configuring the output stream on the default console hook if there is.
func (*Logger) TryAddHook ¶ added in v0.2.0
TryAddHook adds a hook to the hook collection and associated it with a name and a level. Can also be used to replace an existing hook.
func (*Logger) WithContext ¶ added in v0.2.0
WithContext return a new logger with a new context.
func (*Logger) WithField ¶ added in v0.2.0
WithField return a new logger with a single additional entry.
Example ¶
log := getTestLogger("field", "Trace") // We set the format of the log to include fields log.SetFormat("%module:square% %time% %level:upper% %message% %fields%.") // We create a new logger with additional context log2 := log.WithField("hello", "world!").WithField("pi", math.Pi) log.Info("No additional field") log2.Info("With additional fields")
Output: [field] 2018/06/24 12:34:56.789 INFO No additional field . [field] 2018/06/24 12:34:56.789 INFO With additional fields hello=world! pi=3.141592653589793.
func (*Logger) WithFields ¶ added in v0.2.0
WithFields return a new logger with a new fields value.
Example ¶
log := getTestLogger("field", "Trace") // We set the format of the log to include fields log.SetFormat("%module:square% %time% %level:upper% %message% %fields%.") // We create a new logger with additional context log2 := log.WithFields(logrus.Fields{ "hello": "world!", "pi": math.Pi, }) log.Info("No additional field") log2.Info("With additional fields")
Output: [field] 2018/06/24 12:34:56.789 INFO No additional field . [field] 2018/06/24 12:34:56.789 INFO With additional fields hello=world! pi=3.141592653589793.
func (*Logger) WithTime ¶ added in v0.2.0
WithTime return a new logger with a fixed time for log entry (useful for testing).
Example ¶
log := getTestLogger("time", logrus.InfoLevel) // We can create a logger with a fix moment in time. t, _ := time.Parse(time.RFC3339, "2020-12-25T00:00:00Z") log = log.WithTime(t) log.Info("Log from fixed time")
Output: [time] 2020/12/25 00:00:00.000 INFO Log from fixed time