package models import ( "log" "reflect" "github.com/fatih/color" "github.com/influxdata/telegraf" ) // Logger defines a logging structure for plugins. type Logger struct { OnErrs []func() Name string // Name is the plugin name, will be printed in the `[]`. } // NewLogger creates a new logger instance func NewLogger(pluginType, name, alias string) *Logger { return &Logger{ Name: logName(pluginType, name, alias), } } // OnErr defines a callback that triggers only when errors are about to be written to the log func (l *Logger) OnErr(f func()) { l.OnErrs = append(l.OnErrs, f) } // Errorf logs an error message, patterned after log.Printf. func (l *Logger) Errorf(format string, args ...interface{}) { for _, f := range l.OnErrs { f() } log.Printf("E! ["+l.Name+"] "+format, args...) } // Error logs an error message, patterned after log.Print. func (l *Logger) Error(args ...interface{}) { for _, f := range l.OnErrs { f() } log.Print(append([]interface{}{"E! [" + l.Name + "] "}, args...)...) } // Debugf logs a debug message, patterned after log.Printf. func (l *Logger) Debugf(format string, args ...interface{}) { log.Printf("D! ["+l.Name+"] "+format, args...) } // Debug logs a debug message, patterned after log.Print. func (l *Logger) Debug(args ...interface{}) { log.Print(append([]interface{}{"D! [" + l.Name + "] "}, args...)...) } // Warnf logs a warning message, patterned after log.Printf. func (l *Logger) Warnf(format string, args ...interface{}) { log.Printf("W! ["+l.Name+"] "+format, args...) } // Warn logs a warning message, patterned after log.Print. func (l *Logger) Warn(args ...interface{}) { log.Print(append([]interface{}{"W! [" + l.Name + "] "}, args...)...) } // Infof logs an information message, patterned after log.Printf. func (l *Logger) Infof(format string, args ...interface{}) { log.Printf("I! ["+l.Name+"] "+format, args...) } // Info logs an information message, patterned after log.Print. func (l *Logger) Info(args ...interface{}) { log.Print(append([]interface{}{"I! [" + l.Name + "] "}, args...)...) } // logName returns the log-friendly name/type. func logName(pluginType, name, alias string) string { if alias == "" { return pluginType + "." + name } return pluginType + "." + name + "::" + alias } func SetLoggerOnPlugin(i interface{}, logger telegraf.Logger) { valI := reflect.ValueOf(i) if valI.Type().Kind() != reflect.Ptr { valI = reflect.New(reflect.TypeOf(i)) } field := valI.Elem().FieldByName("Log") if !field.IsValid() { return } switch field.Type().String() { case "telegraf.Logger": if field.CanSet() { field.Set(reflect.ValueOf(logger)) } default: logger.Debugf("Plugin %q defines a 'Log' field on its struct of an unexpected type %q. Expected telegraf.Logger", valI.Type().Name(), field.Type().String()) } } func deprecationPrefix(level telegraf.Escalation) string { switch level { case telegraf.Warn: return "W! " + color.YellowString("DeprecationWarning") case telegraf.Error: return "E! " + color.RedString("DeprecationError") } return "" } func PrintPluginDeprecationNotice(level telegraf.Escalation, name string, info telegraf.DeprecationInfo) { switch level { case telegraf.Warn, telegraf.Error: prefix := deprecationPrefix(level) log.Printf( "%s: Plugin %q deprecated since version %s and will be removed in %s: %s", prefix, name, info.Since, info.RemovalIn, info.Notice, ) } } func PrintOptionDeprecationNotice(level telegraf.Escalation, plugin, option string, info telegraf.DeprecationInfo) { switch level { case telegraf.Warn, telegraf.Error: prefix := deprecationPrefix(level) log.Printf( "%s: Option %q of plugin %q deprecated since version %s and will be removed in %s: %s", prefix, option, plugin, info.Since, info.RemovalIn, info.Notice, ) } } func PrintOptionValueDeprecationNotice(level telegraf.Escalation, plugin, option string, value interface{}, info telegraf.DeprecationInfo) { switch level { case telegraf.Warn, telegraf.Error: prefix := deprecationPrefix(level) log.Printf( `%s: Value "%+v" for option %q of plugin %q deprecated since version %s and will be removed in %s: %s`, prefix, value, option, plugin, info.Since, info.RemovalIn, info.Notice, ) } }