86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
package cron
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// DefaultLogger is used by Cron if none is specified.
|
|
var DefaultLogger Logger = PrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags))
|
|
|
|
// DiscardLogger can be used by callers to discard all log messages.
|
|
var DiscardLogger Logger = PrintfLogger(log.New(ioutil.Discard, "", 0))
|
|
|
|
// Logger is the interface used in this package for logging, so that any backend
|
|
// can be plugged in. It is a subset of the github.com/go-logr/logr interface.
|
|
type Logger interface {
|
|
// Info logs routine messages about cron's operation.
|
|
Info(msg string, keysAndValues ...interface{})
|
|
// Error logs an error condition.
|
|
Error(err error, msg string, keysAndValues ...interface{})
|
|
}
|
|
|
|
// PrintfLogger wraps a Printf-based logger (such as the standard library "log")
|
|
// into an implementation of the Logger interface which logs errors only.
|
|
func PrintfLogger(l interface{ Printf(string, ...interface{}) }) Logger {
|
|
return printfLogger{l, false}
|
|
}
|
|
|
|
// VerbosePrintfLogger wraps a Printf-based logger (such as the standard library
|
|
// "log") into an implementation of the Logger interface which logs everything.
|
|
func VerbosePrintfLogger(l interface{ Printf(string, ...interface{}) }) Logger {
|
|
return printfLogger{l, true}
|
|
}
|
|
|
|
type printfLogger struct {
|
|
logger interface{ Printf(string, ...interface{}) }
|
|
logInfo bool
|
|
}
|
|
|
|
func (pl printfLogger) Info(msg string, keysAndValues ...interface{}) {
|
|
if pl.logInfo {
|
|
keysAndValues = formatTimes(keysAndValues)
|
|
pl.logger.Printf(
|
|
formatString(len(keysAndValues)),
|
|
append([]interface{}{msg}, keysAndValues...)...)
|
|
}
|
|
}
|
|
|
|
func (pl printfLogger) Error(err error, msg string, keysAndValues ...interface{}) {
|
|
keysAndValues = formatTimes(keysAndValues)
|
|
pl.logger.Printf(
|
|
formatString(len(keysAndValues)+2),
|
|
append([]interface{}{msg, "error", err}, keysAndValues...)...)
|
|
}
|
|
|
|
// formatString returns a logfmt-like format string for the number of
|
|
// key/values.
|
|
func formatString(numKeysAndValues int) string {
|
|
var sb strings.Builder
|
|
sb.WriteString("%s")
|
|
if numKeysAndValues > 0 {
|
|
sb.WriteString(", ")
|
|
}
|
|
for i := 0; i < numKeysAndValues/2; i++ {
|
|
if i > 0 {
|
|
sb.WriteString(", ")
|
|
}
|
|
sb.WriteString("%v=%v")
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
// formatTimes formats any time.Time values as RFC3339.
|
|
func formatTimes(keysAndValues []interface{}) []interface{} {
|
|
var formattedArgs []interface{}
|
|
for _, arg := range keysAndValues {
|
|
if t, ok := arg.(time.Time); ok {
|
|
arg = t.Format(time.RFC3339)
|
|
}
|
|
formattedArgs = append(formattedArgs, arg)
|
|
}
|
|
return formattedArgs
|
|
}
|