| // Copyright 2014 Canonical Ltd. |
| // Licensed under the LGPLv3, see LICENCE file for details. |
| |
| package loggo |
| |
| import ( |
| "fmt" |
| "runtime" |
| "time" |
| ) |
| |
| // A Logger represents a logging module. It has an associated logging |
| // level which can be changed; messages of lesser severity will |
| // be dropped. Loggers have a hierarchical relationship - see |
| // the package documentation. |
| // |
| // The zero Logger value is usable - any messages logged |
| // to it will be sent to the root Logger. |
| type Logger struct { |
| impl *module |
| } |
| |
| func (logger Logger) getModule() *module { |
| if logger.impl == nil { |
| return defaultContext.root |
| } |
| return logger.impl |
| } |
| |
| // Name returns the logger's module name. |
| func (logger Logger) Name() string { |
| return logger.getModule().Name() |
| } |
| |
| // LogLevel returns the configured min log level of the logger. |
| func (logger Logger) LogLevel() Level { |
| return logger.getModule().level |
| } |
| |
| // EffectiveLogLevel returns the effective min log level of |
| // the receiver - that is, messages with a lesser severity |
| // level will be discarded. |
| // |
| // If the log level of the receiver is unspecified, |
| // it will be taken from the effective log level of its |
| // parent. |
| func (logger Logger) EffectiveLogLevel() Level { |
| return logger.getModule().getEffectiveLogLevel() |
| } |
| |
| // SetLogLevel sets the severity level of the given logger. |
| // The root logger cannot be set to UNSPECIFIED level. |
| // See EffectiveLogLevel for how this affects the |
| // actual messages logged. |
| func (logger Logger) SetLogLevel(level Level) { |
| logger.getModule().setLevel(level) |
| } |
| |
| // Logf logs a printf-formatted message at the given level. |
| // A message will be discarded if level is less than the |
| // the effective log level of the logger. |
| // Note that the writers may also filter out messages that |
| // are less than their registered minimum severity level. |
| func (logger Logger) Logf(level Level, message string, args ...interface{}) { |
| logger.LogCallf(2, level, message, args...) |
| } |
| |
| // LogCallf logs a printf-formatted message at the given level. |
| // The location of the call is indicated by the calldepth argument. |
| // A calldepth of 1 means the function that called this function. |
| // A message will be discarded if level is less than the |
| // the effective log level of the logger. |
| // Note that the writers may also filter out messages that |
| // are less than their registered minimum severity level. |
| func (logger Logger) LogCallf(calldepth int, level Level, message string, args ...interface{}) { |
| module := logger.getModule() |
| if !module.willWrite(level) { |
| return |
| } |
| // Gather time, and filename, line number. |
| now := time.Now() // get this early. |
| // Param to Caller is the call depth. Since this method is called from |
| // the Logger methods, we want the place that those were called from. |
| _, file, line, ok := runtime.Caller(calldepth + 1) |
| if !ok { |
| file = "???" |
| line = 0 |
| } |
| // Trim newline off format string, following usual |
| // Go logging conventions. |
| if len(message) > 0 && message[len(message)-1] == '\n' { |
| message = message[0 : len(message)-1] |
| } |
| |
| // To avoid having a proliferation of Info/Infof methods, |
| // only use Sprintf if there are any args, and rely on the |
| // `go vet` tool for the obvious cases where someone has forgotten |
| // to provide an arg. |
| formattedMessage := message |
| if len(args) > 0 { |
| formattedMessage = fmt.Sprintf(message, args...) |
| } |
| module.write(Entry{ |
| Level: level, |
| Filename: file, |
| Line: line, |
| Timestamp: now, |
| Message: formattedMessage, |
| }) |
| } |
| |
| // Criticalf logs the printf-formatted message at critical level. |
| func (logger Logger) Criticalf(message string, args ...interface{}) { |
| logger.Logf(CRITICAL, message, args...) |
| } |
| |
| // Errorf logs the printf-formatted message at error level. |
| func (logger Logger) Errorf(message string, args ...interface{}) { |
| logger.Logf(ERROR, message, args...) |
| } |
| |
| // Warningf logs the printf-formatted message at warning level. |
| func (logger Logger) Warningf(message string, args ...interface{}) { |
| logger.Logf(WARNING, message, args...) |
| } |
| |
| // Infof logs the printf-formatted message at info level. |
| func (logger Logger) Infof(message string, args ...interface{}) { |
| logger.Logf(INFO, message, args...) |
| } |
| |
| // Debugf logs the printf-formatted message at debug level. |
| func (logger Logger) Debugf(message string, args ...interface{}) { |
| logger.Logf(DEBUG, message, args...) |
| } |
| |
| // Tracef logs the printf-formatted message at trace level. |
| func (logger Logger) Tracef(message string, args ...interface{}) { |
| logger.Logf(TRACE, message, args...) |
| } |
| |
| // IsLevelEnabled returns whether debugging is enabled |
| // for the given log level. |
| func (logger Logger) IsLevelEnabled(level Level) bool { |
| return logger.getModule().willWrite(level) |
| } |
| |
| // IsErrorEnabled returns whether debugging is enabled |
| // at error level. |
| func (logger Logger) IsErrorEnabled() bool { |
| return logger.IsLevelEnabled(ERROR) |
| } |
| |
| // IsWarningEnabled returns whether debugging is enabled |
| // at warning level. |
| func (logger Logger) IsWarningEnabled() bool { |
| return logger.IsLevelEnabled(WARNING) |
| } |
| |
| // IsInfoEnabled returns whether debugging is enabled |
| // at info level. |
| func (logger Logger) IsInfoEnabled() bool { |
| return logger.IsLevelEnabled(INFO) |
| } |
| |
| // IsDebugEnabled returns whether debugging is enabled |
| // at debug level. |
| func (logger Logger) IsDebugEnabled() bool { |
| return logger.IsLevelEnabled(DEBUG) |
| } |
| |
| // IsTraceEnabled returns whether debugging is enabled |
| // at trace level. |
| func (logger Logger) IsTraceEnabled() bool { |
| return logger.IsLevelEnabled(TRACE) |
| } |