github.com/godaddy-x/freego@v1.0.156/job/logger.go (about) 1 package job 2 3 import ( 4 "io/ioutil" 5 "log" 6 "os" 7 "strings" 8 "time" 9 ) 10 11 // DefaultLogger is used by Cron if none is specified. 12 var DefaultLogger Logger = PrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags)) 13 14 // DiscardLogger can be used by callers to discard all zlog messages. 15 var DiscardLogger Logger = PrintfLogger(log.New(ioutil.Discard, "", 0)) 16 17 // Logger is the interface used in this package for logging, so that any backend 18 // can be plugged in. It is a subset of the github.com/go-logr/logr interface. 19 type Logger interface { 20 // Info logs routine messages about cron's operation. 21 Info(msg string, keysAndValues ...interface{}) 22 // Error logs an error condition. 23 Error(err error, msg string, keysAndValues ...interface{}) 24 } 25 26 // PrintfLogger wraps a Printf-based logger (such as the standard library "zlog") 27 // into an implementation of the Logger interface which logs errors only. 28 func PrintfLogger(l interface{ Printf(string, ...interface{}) }) Logger { 29 return printfLogger{l, false} 30 } 31 32 // VerbosePrintfLogger wraps a Printf-based logger (such as the standard library 33 // "zlog") into an implementation of the Logger interface which logs everything. 34 func VerbosePrintfLogger(l interface{ Printf(string, ...interface{}) }) Logger { 35 return printfLogger{l, true} 36 } 37 38 type printfLogger struct { 39 logger interface{ Printf(string, ...interface{}) } 40 logInfo bool 41 } 42 43 func (pl printfLogger) Info(msg string, keysAndValues ...interface{}) { 44 if pl.logInfo { 45 keysAndValues = formatTimes(keysAndValues) 46 pl.logger.Printf( 47 formatString(len(keysAndValues)), 48 append([]interface{}{msg}, keysAndValues...)...) 49 } 50 } 51 52 func (pl printfLogger) Error(err error, msg string, keysAndValues ...interface{}) { 53 keysAndValues = formatTimes(keysAndValues) 54 pl.logger.Printf( 55 formatString(len(keysAndValues)+2), 56 append([]interface{}{msg, "error", err}, keysAndValues...)...) 57 } 58 59 // formatString returns a logfmt-like format string for the number of 60 // key/values. 61 func formatString(numKeysAndValues int) string { 62 var sb strings.Builder 63 sb.WriteString("%s") 64 if numKeysAndValues > 0 { 65 sb.WriteString(", ") 66 } 67 for i := 0; i < numKeysAndValues/2; i++ { 68 if i > 0 { 69 sb.WriteString(", ") 70 } 71 sb.WriteString("%v=%v") 72 } 73 return sb.String() 74 } 75 76 // formatTimes formats any time.Time values as RFC3339. 77 func formatTimes(keysAndValues []interface{}) []interface{} { 78 var formattedArgs []interface{} 79 for _, arg := range keysAndValues { 80 if t, ok := arg.(time.Time); ok { 81 arg = t.Format(time.RFC3339) 82 } 83 formattedArgs = append(formattedArgs, arg) 84 } 85 return formattedArgs 86 }