summaryrefslogtreecommitdiffstats
path: root/modules/log/logger.go
blob: 925ab02b719eb65e8816d137babb9da5af1b3ded (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package log

import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"
)

// Logger is default logger in the Gitea application.
// it can contain several providers and log message into all providers.
type Logger struct {
	*MultiChannelledLog
	bufferLength int64
}

// newLogger initializes and returns a new logger.
func newLogger(name string, buffer int64) *Logger {
	l := &Logger{
		MultiChannelledLog: NewMultiChannelledLog(name, buffer),
		bufferLength:       buffer,
	}
	return l
}

// SetLogger sets new logger instance with given logger provider and config.
func (l *Logger) SetLogger(name, provider, config string) error {
	eventLogger, err := NewChannelledLog(name, provider, config, l.bufferLength)
	if err != nil {
		return fmt.Errorf("Failed to create sublogger (%s): %v", name, err)
	}

	l.MultiChannelledLog.DelLogger(name)

	err = l.MultiChannelledLog.AddLogger(eventLogger)
	if err != nil {
		if IsErrDuplicateName(err) {
			return fmt.Errorf("Duplicate named sublogger %s %v", name, l.MultiChannelledLog.GetEventLoggerNames())
		}
		return fmt.Errorf("Failed to add sublogger (%s): %v", name, err)
	}

	return nil
}

// DelLogger deletes a sublogger from this logger.
func (l *Logger) DelLogger(name string) (bool, error) {
	return l.MultiChannelledLog.DelLogger(name), nil
}

// Log msg at the provided level with the provided caller defined by skip (0 being the function that calls this function)
func (l *Logger) Log(skip int, level Level, format string, v ...interface{}) error {
	if l.GetLevel() > level {
		return nil
	}
	caller := "?()"
	pc, filename, line, ok := runtime.Caller(skip + 1)
	if ok {
		// Get caller function name.
		fn := runtime.FuncForPC(pc)
		if fn != nil {
			caller = fn.Name() + "()"
		}
	}
	msg := format
	if len(v) > 0 {
		args := make([]interface{}, len(v))
		for i := 0; i < len(args); i++ {
			args[i] = NewColoredValuePointer(&v[i])
		}
		msg = fmt.Sprintf(format, args...)
	}
	stack := ""
	if l.GetStacktraceLevel() <= level {
		stack = Stack(skip + 1)
	}
	return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, stack)
}

// SendLog sends a log event at the provided level with the information given
func (l *Logger) SendLog(level Level, caller, filename string, line int, msg string, stack string) error {
	if l.GetLevel() > level {
		return nil
	}
	event := &Event{
		level:      level,
		caller:     caller,
		filename:   filename,
		line:       line,
		msg:        msg,
		time:       time.Now(),
		stacktrace: stack,
	}
	l.LogEvent(event)
	return nil
}

// Trace records trace log
func (l *Logger) Trace(format string, v ...interface{}) {
	l.Log(1, TRACE, format, v...)
}

// Debug records debug log
func (l *Logger) Debug(format string, v ...interface{}) {
	l.Log(1, DEBUG, format, v...)

}

// Info records information log
func (l *Logger) Info(format string, v ...interface{}) {
	l.Log(1, INFO, format, v...)
}

// Warn records warning log
func (l *Logger) Warn(format string, v ...interface{}) {
	l.Log(1, WARN, format, v...)
}

// Error records error log
func (l *Logger) Error(format string, v ...interface{}) {
	l.Log(1, ERROR, format, v...)
}

// ErrorWithSkip records error log from "skip" calls back from this function
func (l *Logger) ErrorWithSkip(skip int, format string, v ...interface{}) {
	l.Log(skip+1, ERROR, format, v...)
}

// Critical records critical log
func (l *Logger) Critical(format string, v ...interface{}) {
	l.Log(1, CRITICAL, format, v...)
}

// CriticalWithSkip records critical log from "skip" calls back from this function
func (l *Logger) CriticalWithSkip(skip int, format string, v ...interface{}) {
	l.Log(skip+1, CRITICAL, format, v...)
}

// Fatal records fatal log and exit the process
func (l *Logger) Fatal(format string, v ...interface{}) {
	l.Log(1, FATAL, format, v...)
	l.Close()
	os.Exit(1)
}

// FatalWithSkip records fatal log from "skip" calls back from this function and exits the process
func (l *Logger) FatalWithSkip(skip int, format string, v ...interface{}) {
	l.Log(skip+1, FATAL, format, v...)
	l.Close()
	os.Exit(1)
}