11 var bufferPool *sync.Pool
14 bufferPool = &sync.Pool{
15 New: func() interface{} {
16 return new(bytes.Buffer)
21 // Defines the key when adding errors using WithError.
22 var ErrorKey = "error"
24 // An entry is the final or intermediate Logrus logging entry. It contains all
25 // the fields passed with WithField{,s}. It's finally logged when Debug, Info,
26 // Warn, Error, Fatal or Panic is called on it. These objects can be reused and
27 // passed around as much as you wish to avoid field duplication.
31 // Contains all the fields set by the user.
34 // Time at which the log entry was created
37 // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
40 // Message passed to Debug, Info, Warn, Error, Fatal or Panic
43 // When formatter is called in entry.log(), an Buffer may be set to entry
47 func NewEntry(logger *Logger) *Entry {
50 // Default is three fields, give a little extra room
51 Data: make(Fields, 5),
55 // Returns the string representation from the reader and ultimately the
57 func (entry *Entry) String() (string, error) {
58 serialized, err := entry.Logger.Formatter.Format(entry)
62 str := string(serialized)
66 // Add an error as single field (using the key defined in ErrorKey) to the Entry.
67 func (entry *Entry) WithError(err error) *Entry {
68 return entry.WithField(ErrorKey, err)
71 // Add a single field to the Entry.
72 func (entry *Entry) WithField(key string, value interface{}) *Entry {
73 return entry.WithFields(Fields{key: value})
76 // Add a map of fields to the Entry.
77 func (entry *Entry) WithFields(fields Fields) *Entry {
78 data := make(Fields, len(entry.Data)+len(fields))
79 for k, v := range entry.Data {
82 for k, v := range fields {
85 return &Entry{Logger: entry.Logger, Data: data}
88 // This function is not declared with a pointer value because otherwise
89 // race conditions will occur when using multiple goroutines
90 func (entry Entry) log(level Level, msg string) {
91 var buffer *bytes.Buffer
92 entry.Time = time.Now()
96 if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
97 entry.Logger.mu.Lock()
98 fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
99 entry.Logger.mu.Unlock()
101 buffer = bufferPool.Get().(*bytes.Buffer)
103 defer bufferPool.Put(buffer)
104 entry.Buffer = buffer
105 serialized, err := entry.Logger.Formatter.Format(&entry)
108 entry.Logger.mu.Lock()
109 fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
110 entry.Logger.mu.Unlock()
112 entry.Logger.mu.Lock()
113 _, err = entry.Logger.Out.Write(serialized)
115 fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
117 entry.Logger.mu.Unlock()
120 // To avoid Entry#log() returning a value that only would make sense for
121 // panic() to use in Entry#Panic(), we avoid the allocation by checking
123 if level <= PanicLevel {
128 func (entry *Entry) Debug(args ...interface{}) {
129 if entry.Logger.level() >= DebugLevel {
130 entry.log(DebugLevel, fmt.Sprint(args...))
134 func (entry *Entry) Print(args ...interface{}) {
138 func (entry *Entry) Info(args ...interface{}) {
139 if entry.Logger.level() >= InfoLevel {
140 entry.log(InfoLevel, fmt.Sprint(args...))
144 func (entry *Entry) Warn(args ...interface{}) {
145 if entry.Logger.level() >= WarnLevel {
146 entry.log(WarnLevel, fmt.Sprint(args...))
150 func (entry *Entry) Warning(args ...interface{}) {
154 func (entry *Entry) Error(args ...interface{}) {
155 if entry.Logger.level() >= ErrorLevel {
156 entry.log(ErrorLevel, fmt.Sprint(args...))
160 func (entry *Entry) Fatal(args ...interface{}) {
161 if entry.Logger.level() >= FatalLevel {
162 entry.log(FatalLevel, fmt.Sprint(args...))
167 func (entry *Entry) Panic(args ...interface{}) {
168 if entry.Logger.level() >= PanicLevel {
169 entry.log(PanicLevel, fmt.Sprint(args...))
171 panic(fmt.Sprint(args...))
174 // Entry Printf family functions
176 func (entry *Entry) Debugf(format string, args ...interface{}) {
177 if entry.Logger.level() >= DebugLevel {
178 entry.Debug(fmt.Sprintf(format, args...))
182 func (entry *Entry) Infof(format string, args ...interface{}) {
183 if entry.Logger.level() >= InfoLevel {
184 entry.Info(fmt.Sprintf(format, args...))
188 func (entry *Entry) Printf(format string, args ...interface{}) {
189 entry.Infof(format, args...)
192 func (entry *Entry) Warnf(format string, args ...interface{}) {
193 if entry.Logger.level() >= WarnLevel {
194 entry.Warn(fmt.Sprintf(format, args...))
198 func (entry *Entry) Warningf(format string, args ...interface{}) {
199 entry.Warnf(format, args...)
202 func (entry *Entry) Errorf(format string, args ...interface{}) {
203 if entry.Logger.level() >= ErrorLevel {
204 entry.Error(fmt.Sprintf(format, args...))
208 func (entry *Entry) Fatalf(format string, args ...interface{}) {
209 if entry.Logger.level() >= FatalLevel {
210 entry.Fatal(fmt.Sprintf(format, args...))
215 func (entry *Entry) Panicf(format string, args ...interface{}) {
216 if entry.Logger.level() >= PanicLevel {
217 entry.Panic(fmt.Sprintf(format, args...))
221 // Entry Println family functions
223 func (entry *Entry) Debugln(args ...interface{}) {
224 if entry.Logger.level() >= DebugLevel {
225 entry.Debug(entry.sprintlnn(args...))
229 func (entry *Entry) Infoln(args ...interface{}) {
230 if entry.Logger.level() >= InfoLevel {
231 entry.Info(entry.sprintlnn(args...))
235 func (entry *Entry) Println(args ...interface{}) {
236 entry.Infoln(args...)
239 func (entry *Entry) Warnln(args ...interface{}) {
240 if entry.Logger.level() >= WarnLevel {
241 entry.Warn(entry.sprintlnn(args...))
245 func (entry *Entry) Warningln(args ...interface{}) {
246 entry.Warnln(args...)
249 func (entry *Entry) Errorln(args ...interface{}) {
250 if entry.Logger.level() >= ErrorLevel {
251 entry.Error(entry.sprintlnn(args...))
255 func (entry *Entry) Fatalln(args ...interface{}) {
256 if entry.Logger.level() >= FatalLevel {
257 entry.Fatal(entry.sprintlnn(args...))
262 func (entry *Entry) Panicln(args ...interface{}) {
263 if entry.Logger.level() >= PanicLevel {
264 entry.Panic(entry.sprintlnn(args...))
268 // Sprintlnn => Sprint no newline. This is to get the behavior of how
269 // fmt.Sprintln where spaces are always added between operands, regardless of
270 // their type. Instead of vendoring the Sprintln implementation to spare a
271 // string allocation, we do the simplest thing.
272 func (entry *Entry) sprintlnn(args ...interface{}) string {
273 msg := fmt.Sprintln(args...)
274 return msg[:len(msg)-1]