blob: fbdfd9e4500c0c5c3be89c84c49d9fc521307278 [file] [log] [blame]
David K. Bainbridge528b3182017-01-23 08:51:59 -08001// Copyright 2014 Canonical Ltd.
2// Licensed under the LGPLv3, see LICENCE file for details.
3
4package loggo
5
6import (
7 "fmt"
8 "runtime"
9 "time"
10)
11
12// A Logger represents a logging module. It has an associated logging
13// level which can be changed; messages of lesser severity will
14// be dropped. Loggers have a hierarchical relationship - see
15// the package documentation.
16//
17// The zero Logger value is usable - any messages logged
18// to it will be sent to the root Logger.
19type Logger struct {
20 impl *module
21}
22
23func (logger Logger) getModule() *module {
24 if logger.impl == nil {
25 return defaultContext.root
26 }
27 return logger.impl
28}
29
30// Name returns the logger's module name.
31func (logger Logger) Name() string {
32 return logger.getModule().Name()
33}
34
35// LogLevel returns the configured min log level of the logger.
36func (logger Logger) LogLevel() Level {
37 return logger.getModule().level
38}
39
40// EffectiveLogLevel returns the effective min log level of
41// the receiver - that is, messages with a lesser severity
42// level will be discarded.
43//
44// If the log level of the receiver is unspecified,
45// it will be taken from the effective log level of its
46// parent.
47func (logger Logger) EffectiveLogLevel() Level {
48 return logger.getModule().getEffectiveLogLevel()
49}
50
51// SetLogLevel sets the severity level of the given logger.
52// The root logger cannot be set to UNSPECIFIED level.
53// See EffectiveLogLevel for how this affects the
54// actual messages logged.
55func (logger Logger) SetLogLevel(level Level) {
56 logger.getModule().setLevel(level)
57}
58
59// Logf logs a printf-formatted message at the given level.
60// A message will be discarded if level is less than the
61// the effective log level of the logger.
62// Note that the writers may also filter out messages that
63// are less than their registered minimum severity level.
64func (logger Logger) Logf(level Level, message string, args ...interface{}) {
65 logger.LogCallf(2, level, message, args...)
66}
67
68// LogCallf logs a printf-formatted message at the given level.
69// The location of the call is indicated by the calldepth argument.
70// A calldepth of 1 means the function that called this function.
71// A message will be discarded if level is less than the
72// the effective log level of the logger.
73// Note that the writers may also filter out messages that
74// are less than their registered minimum severity level.
75func (logger Logger) LogCallf(calldepth int, level Level, message string, args ...interface{}) {
76 module := logger.getModule()
77 if !module.willWrite(level) {
78 return
79 }
80 // Gather time, and filename, line number.
81 now := time.Now() // get this early.
82 // Param to Caller is the call depth. Since this method is called from
83 // the Logger methods, we want the place that those were called from.
84 _, file, line, ok := runtime.Caller(calldepth + 1)
85 if !ok {
86 file = "???"
87 line = 0
88 }
89 // Trim newline off format string, following usual
90 // Go logging conventions.
91 if len(message) > 0 && message[len(message)-1] == '\n' {
92 message = message[0 : len(message)-1]
93 }
94
95 // To avoid having a proliferation of Info/Infof methods,
96 // only use Sprintf if there are any args, and rely on the
97 // `go vet` tool for the obvious cases where someone has forgotten
98 // to provide an arg.
99 formattedMessage := message
100 if len(args) > 0 {
101 formattedMessage = fmt.Sprintf(message, args...)
102 }
103 module.write(Entry{
104 Level: level,
105 Filename: file,
106 Line: line,
107 Timestamp: now,
108 Message: formattedMessage,
109 })
110}
111
112// Criticalf logs the printf-formatted message at critical level.
113func (logger Logger) Criticalf(message string, args ...interface{}) {
114 logger.Logf(CRITICAL, message, args...)
115}
116
117// Errorf logs the printf-formatted message at error level.
118func (logger Logger) Errorf(message string, args ...interface{}) {
119 logger.Logf(ERROR, message, args...)
120}
121
122// Warningf logs the printf-formatted message at warning level.
123func (logger Logger) Warningf(message string, args ...interface{}) {
124 logger.Logf(WARNING, message, args...)
125}
126
127// Infof logs the printf-formatted message at info level.
128func (logger Logger) Infof(message string, args ...interface{}) {
129 logger.Logf(INFO, message, args...)
130}
131
132// Debugf logs the printf-formatted message at debug level.
133func (logger Logger) Debugf(message string, args ...interface{}) {
134 logger.Logf(DEBUG, message, args...)
135}
136
137// Tracef logs the printf-formatted message at trace level.
138func (logger Logger) Tracef(message string, args ...interface{}) {
139 logger.Logf(TRACE, message, args...)
140}
141
142// IsLevelEnabled returns whether debugging is enabled
143// for the given log level.
144func (logger Logger) IsLevelEnabled(level Level) bool {
145 return logger.getModule().willWrite(level)
146}
147
148// IsErrorEnabled returns whether debugging is enabled
149// at error level.
150func (logger Logger) IsErrorEnabled() bool {
151 return logger.IsLevelEnabled(ERROR)
152}
153
154// IsWarningEnabled returns whether debugging is enabled
155// at warning level.
156func (logger Logger) IsWarningEnabled() bool {
157 return logger.IsLevelEnabled(WARNING)
158}
159
160// IsInfoEnabled returns whether debugging is enabled
161// at info level.
162func (logger Logger) IsInfoEnabled() bool {
163 return logger.IsLevelEnabled(INFO)
164}
165
166// IsDebugEnabled returns whether debugging is enabled
167// at debug level.
168func (logger Logger) IsDebugEnabled() bool {
169 return logger.IsLevelEnabled(DEBUG)
170}
171
172// IsTraceEnabled returns whether debugging is enabled
173// at trace level.
174func (logger Logger) IsTraceEnabled() bool {
175 return logger.IsLevelEnabled(TRACE)
176}