telegraf/logger/default_logger.go

197 lines
4.5 KiB
Go

package logger
import (
"errors"
"io"
"log"
"os"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/rotate"
"github.com/influxdata/wlog"
)
const (
LogTargetFile = "file"
LogTargetStderr = "stderr"
)
type defaultLogger struct {
Category string
Name string
Alias string
LogLevel telegraf.LogLevel
prefix string
onError []func()
writer io.Writer
internalWriter io.Writer
timezone *time.Location
}
func (t *defaultLogger) Write(b []byte) (n int, err error) {
var line []byte
timeToPrint := time.Now().In(t.timezone)
if !prefixRegex.Match(b) {
line = append([]byte(timeToPrint.Format(time.RFC3339)+" I! "), b...)
} else {
line = append([]byte(timeToPrint.Format(time.RFC3339)+" "), b...)
}
return t.writer.Write(line)
}
// NewLogger creates a new logger instance
func (t *defaultLogger) New(category, name, alias string) telegraf.Logger {
var prefix string
if category != "" {
prefix = "[" + category
if name != "" {
prefix += "." + name
}
if alias != "" {
prefix += "::" + alias
}
prefix += "] "
}
return &defaultLogger{
Category: category,
Name: name,
Alias: alias,
LogLevel: t.LogLevel,
prefix: prefix,
writer: t.writer,
internalWriter: t.internalWriter,
timezone: t.timezone,
}
}
func (t *defaultLogger) Close() error {
// avoid closing stderr
if t.internalWriter == os.Stderr {
return nil
}
closer, isCloser := t.internalWriter.(io.Closer)
if !isCloser {
return errors.New("the underlying writer cannot be closed")
}
return closer.Close()
}
// OnErr defines a callback that triggers only when errors are about to be written to the log
func (t *defaultLogger) RegisterErrorCallback(f func()) {
t.onError = append(t.onError, f)
}
func (t *defaultLogger) Level() telegraf.LogLevel {
return t.LogLevel
}
// Errorf logs an error message, patterned after log.Printf.
func (t *defaultLogger) Errorf(format string, args ...interface{}) {
log.Printf("E! "+t.prefix+format, args...)
for _, f := range t.onError {
f()
}
}
// Error logs an error message, patterned after log.Print.
func (t *defaultLogger) Error(args ...interface{}) {
for _, f := range t.onError {
f()
}
log.Print(append([]interface{}{"E! " + t.prefix}, args...)...)
}
// Debugf logs a debug message, patterned after log.Printf.
func (t *defaultLogger) Debugf(format string, args ...interface{}) {
log.Printf("D! "+t.prefix+" "+format, args...)
}
// Debug logs a debug message, patterned after log.Print.
func (t *defaultLogger) Debug(args ...interface{}) {
log.Print(append([]interface{}{"D! " + t.prefix}, args...)...)
}
// Warnf logs a warning message, patterned after log.Printf.
func (t *defaultLogger) Warnf(format string, args ...interface{}) {
log.Printf("W! "+t.prefix+format, args...)
}
// Warn logs a warning message, patterned after log.Print.
func (t *defaultLogger) Warn(args ...interface{}) {
log.Print(append([]interface{}{"W! " + t.prefix}, args...)...)
}
// Infof logs an information message, patterned after log.Printf.
func (t *defaultLogger) Infof(format string, args ...interface{}) {
log.Printf("I! "+t.prefix+format, args...)
}
// Info logs an information message, patterned after log.Print.
func (t *defaultLogger) Info(args ...interface{}) {
log.Print(append([]interface{}{"I! " + t.prefix}, args...)...)
}
func createDefaultLogger(cfg *Config) (logger, error) {
log.SetFlags(0)
// Set the log-level
switch cfg.logLevel {
case telegraf.Error:
wlog.SetLevel(wlog.ERROR)
case telegraf.Warn:
wlog.SetLevel(wlog.WARN)
case telegraf.Info:
wlog.SetLevel(wlog.INFO)
case telegraf.Debug:
wlog.SetLevel(wlog.DEBUG)
}
// Setup the writer target
var writer io.Writer = os.Stderr
if cfg.LogTarget == "file" && cfg.Logfile != "" {
w, err := rotate.NewFileWriter(
cfg.Logfile,
cfg.RotationInterval,
cfg.RotationMaxSize,
cfg.RotationMaxArchives,
)
if err != nil {
return nil, err
}
writer = w
}
// Get configured timezone
timezoneName := cfg.LogWithTimezone
if strings.EqualFold(timezoneName, "local") {
timezoneName = "Local"
}
tz, err := time.LoadLocation(timezoneName)
if err != nil {
return nil, errors.New("error while setting logging timezone: " + err.Error())
}
// Setup the logger
l := &defaultLogger{
writer: wlog.NewWriter(writer),
internalWriter: writer,
timezone: tz,
}
log.SetOutput(l)
return l, nil
}
func init() {
add("stderr", createDefaultLogger)
add("file", createDefaultLogger)
}