Hello community,

here is the log from the commit of package kured for openSUSE:Factory checked 
in at 2019-03-29 20:33:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kured (Old)
 and      /work/SRC/openSUSE:Factory/.kured.new.25356 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kured"

Fri Mar 29 20:33:40 2019 rev:5 rq:689655 version:1.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kured/kured.changes      2019-03-01 
16:48:49.877767220 +0100
+++ /work/SRC/openSUSE:Factory/.kured.new.25356/kured.changes   2019-03-29 
20:33:41.610628890 +0100
@@ -1,0 +2,11 @@
+Thu Mar 28 17:44:13 UTC 2019 - Jan Engelhardt <[email protected]>
+
+- Combine %setup calls.
+
+-------------------------------------------------------------------
+Thu Mar 28 11:48:25 CET 2019 - [email protected]
+
+- kured-telemetrics.patch: add hooks for telemetrics data
+- Renamed kured-yaml to kured-k8s-yaml to follow new policy
+
+-------------------------------------------------------------------

New:
----
  kured-telemetrics.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kured.spec ++++++
--- /var/tmp/diff_new_pack.AHMk5e/_old  2019-03-29 20:33:42.466628943 +0100
+++ /var/tmp/diff_new_pack.AHMk5e/_new  2019-03-29 20:33:42.470628942 +0100
@@ -32,6 +32,7 @@
 URL:            https://github.com/weaveworks/kured
 Source:         %{name}-%{version}.tar.gz
 Source1:        vendor.tar.gz
+Patch:          kured-telemetrics.patch
 BuildRequires:  fdupes
 BuildRequires:  go >= 1.10
 BuildRequires:  go-go-md2man
@@ -53,18 +54,20 @@
 
 - Cordons & drains worker nodes before reboot, uncordoning them after
 
-%package yaml
-Summary:        yaml file to run kured container
+%package k8s-yaml
+Summary:        Kubernetes yaml file to run kured container
 Group:          System/Management
 BuildArch:      noarch
+Provides:       kured-yaml = 1.1.0
+Obsoletes:      kured-yaml <= 1.1.0
 
-%description yaml
+%description k8s-yaml
 This package contains the yaml file requried to download and run the
 kured container in a kubernetes cluster.
 
 %prep
-%setup -q
-%setup -q -T -D -a 1
+%setup -qa1
+%patch -p0
 
 %build
 
@@ -97,10 +100,10 @@
 rm %{name}.1
 
 # Install provided yaml file to download and run the kured container
-mkdir %{buildroot}%{_datadir}/kured
-cat kured-rbac.yaml kured-ds.yaml > 
%{buildroot}%{_datadir}/kured/kured-%{version}.yaml
-chmod 644  %{buildroot}%{_datadir}/kured/kured-%{version}.yaml
-sed -i -e 's|image: quay.io/weaveworks/kured|image: 
registry.opensuse.org/kubic/kured:%{version}|g' 
%{buildroot}%{_datadir}/kured/kured-%{version}.yaml
+mkdir -p %{buildroot}%{_datadir}/k8s-yaml/kured
+cat kured-rbac.yaml kured-ds.yaml > 
%{buildroot}%{_datadir}/k8s-yaml/kured/kured.yaml
+chmod 644  %{buildroot}%{_datadir}/k8s-yaml/kured/kured.yaml
+sed -i -e 's|image: quay.io/weaveworks/kured|image: 
registry.opensuse.org/kubic/kured:%{version}|g' 
%{buildroot}%{_datadir}/k8s-yaml/kured/kured.yaml
 
 %fdupes %{buildroot}
 
@@ -110,8 +113,9 @@
 %{_bindir}/%{name}
 %{_mandir}/man1/kured.1%{?ext_man}
 
-%files yaml
-%dir %{_datarootdir}/kured
-%{_datarootdir}/kured/kured-%{version}.yaml
+%files k8s-yaml
+%dir %{_datarootdir}/k8s-yaml
+%dir %{_datarootdir}/k8s-yaml/kured
+%{_datarootdir}/k8s-yaml/kured/kured.yaml
 
 %changelog

++++++ kured-telemetrics.patch ++++++
--- cmd/kured/main.go
+++ cmd/kured/main.go   2019/03/13 12:06:12
@@ -8,7 +8,7 @@
        "regexp"
        "time"
 
-       log "github.com/sirupsen/logrus"
+       "github.com/sirupsen/logrus"
        "github.com/spf13/cobra"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/client-go/kubernetes"
@@ -20,6 +20,7 @@
        "github.com/weaveworks/kured/pkg/daemonsetlock"
        "github.com/weaveworks/kured/pkg/delaytick"
        "github.com/weaveworks/kured/pkg/notifications/slack"
+       "github.com/weaveworks/kured/pkg/notifications/telemetrics"
 )
 
 var (
@@ -35,6 +36,8 @@
        rebootSentinel string
        slackHookURL   string
        slackUsername  string
+       telemetricsEnabled bool
+       telemetricsLevel int
 
        // Metrics
        rebootRequiredGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{
@@ -42,6 +45,8 @@
                Name:      "reboot_required",
                Help:      "OS requires reboot due to software updates.",
        }, []string{"node"})
+
+       log = logrus.New()
 )
 
 func init() {
@@ -74,6 +79,11 @@
        rootCmd.PersistentFlags().StringVar(&slackUsername, "slack-username", 
"kured",
                "slack username for reboot notfications")
 
+       rootCmd.PersistentFlags().BoolVarP(&telemetricsEnabled, "telemetrics", 
"", false,
+               "Enable telemetrics messages")
+       rootCmd.PersistentFlags().IntVarP(&telemetricsLevel, 
"telemetrics-level", "", 2,
+               "Only telemetrics messages with this or a higher severity level 
are submitted")
+
        if err := rootCmd.Execute(); err != nil {
                log.Fatal(err)
        }
@@ -83,15 +93,15 @@
 func newCommand(name string, arg ...string) *exec.Cmd {
        cmd := exec.Command(name, arg...)
 
-       cmd.Stdout = log.NewEntry(log.StandardLogger()).
+       cmd.Stdout = logrus.NewEntry(logrus.StandardLogger()).
                WithField("cmd", cmd.Args[0]).
                WithField("std", "out").
-               WriterLevel(log.InfoLevel)
+               WriterLevel(logrus.InfoLevel)
 
-       cmd.Stderr = log.NewEntry(log.StandardLogger()).
+       cmd.Stderr = logrus.NewEntry(logrus.StandardLogger()).
                WithField("cmd", cmd.Args[0]).
                WithField("std", "err").
-               WriterLevel(log.WarnLevel)
+               WriterLevel(logrus.WarnLevel)
 
        return cmd
 }
@@ -186,6 +196,9 @@
                        log.Warnf("Error notifying slack: %v", err)
                }
        }
+       if telemetricsEnabled {
+               telemetrics.NotifyDrain(nodeID)
+       }
 
        drainCmd := newCommand("/usr/bin/kubectl", "drain",
                "--ignore-daemonsets", "--delete-local-data", "--force", nodeID)
@@ -211,6 +224,9 @@
                        log.Warnf("Error notifying slack: %v", err)
                }
        }
+       if telemetricsEnabled {
+               telemetrics.NotifyReboot(nodeID)
+       }
 
        // Relies on hostPID:true and privileged:true to enter host mount space
        rebootCmd := newCommand("/usr/bin/nsenter", "-m/proc/1/ns/mnt", 
"/bin/systemctl", "reboot")
@@ -292,6 +308,13 @@
        log.Infof("Lock Annotation: %s/%s:%s", dsNamespace, dsName, 
lockAnnotation)
        log.Infof("Reboot Sentinel: %s every %v", rebootSentinel, period)
 
+       if telemetricsEnabled {
+               hook, err := telemetrics.NewTelemetricsHook(telemetricsEnabled, 
telemetricsLevel)
+               if err == nil {
+                       log.Hooks.Add(hook)
+               }
+       }
+
        go rebootAsRequired(nodeID)
        go maintainRebootRequiredMetric(nodeID)
 
--- kured-ds.yaml
+++ kured-ds.yaml       2019/03/13 11:45:31
@@ -54,3 +54,5 @@
 #            - --reboot-sentinel=/var/run/reboot-required
 #            - --slack-hook-url=https://hooks.slack.com/...
 #            - --slack-username=prod
+#            - --telemetrics
+#            - --telemetrics-level=2
--- pkg/notifications/telemetrics/telemetrics.go
+++ pkg/notifications/telemetrics/telemetrics.go        2019/03/13 12:17:41
@@ -0,0 +1,70 @@
+package telemetrics
+
+import (
+        "os"
+        "os/exec"
+       "fmt"
+       "github.com/sirupsen/logrus"
+       "strconv"
+)
+
+func notify(severity int, message string) error {
+        // Relies on hostPID:true and privileged:true to enter host mount space
+        telemCmd := exec.Command("/usr/bin/nsenter", "-m/proc/1/ns/mnt",
+        "--", "/usr/bin/telem-record-gen", "-s", strconv.Itoa(severity), "-c",
+        "works.weave/kured/reboot", "--payload", message)
+        if err := telemCmd.Run(); err != nil {
+               fmt.Fprintf(os.Stderr, "Error invoking telm-record-gen command: 
%v", err)
+               return err
+        }
+       return nil
+}
+
+func NotifyDrain(nodeID string) error {
+       return notify(1, fmt.Sprintf("Draining node %s", nodeID))
+}
+
+func NotifyReboot(nodeID string) error {
+       return notify(1, fmt.Sprintf("Rebooting node %s", nodeID))
+}
+
+type TelemetricsHook struct {
+        enabled bool
+       min_level int
+}
+
+func NewTelemetricsHook(enabled bool, min_level int) (*TelemetricsHook, error) 
{
+       return &TelemetricsHook{enabled, min_level}, nil
+}
+
+func (hook *TelemetricsHook) Fire(entry *logrus.Entry) error {
+       switch entry.Level {
+       case logrus.PanicLevel, logrus.FatalLevel:
+               if hook.min_level <= 4 {
+                       return notify (4, entry.Message)
+               }
+       case logrus.ErrorLevel:
+               if hook.min_level <= 3 {
+                       return notify (3, entry.Message)
+               }
+       case logrus.WarnLevel:
+               if hook.min_level <= 2 {
+                       return notify (2, entry.Message)
+               }
+       case logrus.InfoLevel:
+               if hook.min_level <= 1 {
+                       return notify (1, entry.Message)
+               }
+       case logrus.DebugLevel, logrus.TraceLevel:
+               if hook.min_level == 0 {
+                       return notify (1, entry.Message)
+               }
+       default:
+               return nil
+       }
+       return nil
+}
+
+func (hook *TelemetricsHook) Levels() []logrus.Level {
+       return logrus.AllLevels
+}
++++++ vendor.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/alt_exit.go 
new/vendor/github.com/sirupsen/logrus/alt_exit.go
--- old/vendor/github.com/sirupsen/logrus/alt_exit.go   2018-11-15 
20:22:56.986337192 +0100
+++ new/vendor/github.com/sirupsen/logrus/alt_exit.go   2019-03-12 
13:15:34.130444171 +0100
@@ -51,9 +51,9 @@
        os.Exit(code)
 }
 
-// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
-// all handlers. The handlers will also be invoked when any Fatal log entry is
-// made.
+// RegisterExitHandler appends a Logrus Exit handler to the list of handlers,
+// call logrus.Exit to invoke all handlers. The handlers will also be invoked 
when
+// any Fatal log entry is made.
 //
 // This method is useful when a caller wishes to use logrus to log a fatal
 // message but also needs to gracefully shutdown. An example usecase could be
@@ -62,3 +62,15 @@
 func RegisterExitHandler(handler func()) {
        handlers = append(handlers, handler)
 }
+
+// DeferExitHandler prepends a Logrus Exit handler to the list of handlers,
+// call logrus.Exit to invoke all handlers. The handlers will also be invoked 
when
+// any Fatal log entry is made.
+//
+// This method is useful when a caller wishes to use logrus to log a fatal
+// message but also needs to gracefully shutdown. An example usecase could be
+// closing database connections, or sending a alert that the application is
+// closing.
+func DeferExitHandler(handler func()) {
+       handlers = append([]func(){handler}, handlers...)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/entry.go 
new/vendor/github.com/sirupsen/logrus/entry.go
--- old/vendor/github.com/sirupsen/logrus/entry.go      2018-11-15 
20:22:56.986337192 +0100
+++ new/vendor/github.com/sirupsen/logrus/entry.go      2019-03-12 
13:15:34.130444171 +0100
@@ -2,14 +2,33 @@
 
 import (
        "bytes"
+       "context"
        "fmt"
        "os"
        "reflect"
+       "runtime"
+       "strings"
        "sync"
        "time"
 )
 
-var bufferPool *sync.Pool
+var (
+       bufferPool *sync.Pool
+
+       // qualified package name, cached at first use
+       logrusPackage string
+
+       // Positions in the call stack when tracing to report the calling method
+       minimumCallerDepth int
+
+       // Used for caller information initialisation
+       callerInitOnce sync.Once
+)
+
+const (
+       maximumCallerDepth int = 25
+       knownLogrusFrames  int = 4
+)
 
 func init() {
        bufferPool = &sync.Pool{
@@ -17,15 +36,18 @@
                        return new(bytes.Buffer)
                },
        }
+
+       // start at the bottom of the stack before the package-name cache is 
primed
+       minimumCallerDepth = 1
 }
 
 // Defines the key when adding errors using WithError.
 var ErrorKey = "error"
 
 // An entry is the final or intermediate Logrus logging entry. It contains all
-// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
-// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
-// passed around as much as you wish to avoid field duplication.
+// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
+// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
+// reused and passed around as much as you wish to avoid field duplication.
 type Entry struct {
        Logger *Logger
 
@@ -35,16 +57,22 @@
        // Time at which the log entry was created
        Time time.Time
 
-       // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal 
or Panic
+       // Level the log entry was logged at: Trace, Debug, Info, Warn, Error, 
Fatal or Panic
        // This field will be set on entry firing and the value will be equal 
to the one in Logger struct field.
        Level Level
 
-       // Message passed to Debug, Info, Warn, Error, Fatal or Panic
+       // Calling method, with package name
+       Caller *runtime.Frame
+
+       // Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
        Message string
 
        // When formatter is called in entry.log(), a Buffer may be set to entry
        Buffer *bytes.Buffer
 
+       // Contains the context set by the user. Useful for hook processing etc.
+       Context context.Context
+
        // err may contain a field formatting error
        err string
 }
@@ -52,8 +80,8 @@
 func NewEntry(logger *Logger) *Entry {
        return &Entry{
                Logger: logger,
-               // Default is five fields, give a little extra room
-               Data: make(Fields, 5),
+               // Default is three fields, plus one optional.  Give a little 
extra room.
+               Data: make(Fields, 6),
        }
 }
 
@@ -73,6 +101,12 @@
        return entry.WithField(ErrorKey, err)
 }
 
+// Add a context to the Entry.
+func (entry *Entry) WithContext(ctx context.Context) *Entry {
+       entry.Context = ctx
+       return entry
+}
+
 // Add a single field to the Entry.
 func (entry *Entry) WithField(key string, value interface{}) *Entry {
        return entry.WithFields(Fields{key: value})
@@ -84,23 +118,88 @@
        for k, v := range entry.Data {
                data[k] = v
        }
-       var field_err string
+       fieldErr := entry.err
        for k, v := range fields {
-               if t := reflect.TypeOf(v); t != nil && t.Kind() == reflect.Func 
{
-                       field_err = fmt.Sprintf("can not add field %q", k)
-                       if entry.err != "" {
-                               field_err = entry.err + ", " + field_err
+               isErrField := false
+               if t := reflect.TypeOf(v); t != nil {
+                       switch t.Kind() {
+                       case reflect.Func:
+                               isErrField = true
+                       case reflect.Ptr:
+                               isErrField = t.Elem().Kind() == reflect.Func
+                       }
+               }
+               if isErrField {
+                       tmp := fmt.Sprintf("can not add field %q", k)
+                       if fieldErr != "" {
+                               fieldErr = entry.err + ", " + tmp
+                       } else {
+                               fieldErr = tmp
                        }
                } else {
                        data[k] = v
                }
        }
-       return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: 
field_err}
+       return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: 
fieldErr, Context: entry.Context}
 }
 
 // Overrides the time of the Entry.
 func (entry *Entry) WithTime(t time.Time) *Entry {
-       return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t}
+       return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: 
entry.err, Context: entry.Context}
+}
+
+// getPackageName reduces a fully qualified function name to the package name
+// There really ought to be to be a better way...
+func getPackageName(f string) string {
+       for {
+               lastPeriod := strings.LastIndex(f, ".")
+               lastSlash := strings.LastIndex(f, "/")
+               if lastPeriod > lastSlash {
+                       f = f[:lastPeriod]
+               } else {
+                       break
+               }
+       }
+
+       return f
+}
+
+// getCaller retrieves the name of the first non-logrus calling function
+func getCaller() *runtime.Frame {
+
+       // cache this package's fully-qualified name
+       callerInitOnce.Do(func() {
+               pcs := make([]uintptr, 2)
+               _ = runtime.Callers(0, pcs)
+               logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name())
+
+               // now that we have the cache, we can skip a minimum count of 
known-logrus functions
+               // XXX this is dubious, the number of frames may vary
+               minimumCallerDepth = knownLogrusFrames
+       })
+
+       // Restrict the lookback frames to avoid runaway lookups
+       pcs := make([]uintptr, maximumCallerDepth)
+       depth := runtime.Callers(minimumCallerDepth, pcs)
+       frames := runtime.CallersFrames(pcs[:depth])
+
+       for f, again := frames.Next(); again; f, again = frames.Next() {
+               pkg := getPackageName(f.Function)
+
+               // If the caller isn't part of this package, we're done
+               if pkg != logrusPackage {
+                       return &f
+               }
+       }
+
+       // if we got here, we failed to find the caller's context
+       return nil
+}
+
+func (entry Entry) HasCaller() (has bool) {
+       return entry.Logger != nil &&
+               entry.Logger.ReportCaller &&
+               entry.Caller != nil
 }
 
 // This function is not declared with a pointer value because otherwise
@@ -119,6 +218,9 @@
 
        entry.Level = level
        entry.Message = msg
+       if entry.Logger.ReportCaller {
+               entry.Caller = getCaller()
+       }
 
        entry.fireHooks()
 
@@ -162,26 +264,30 @@
        }
 }
 
-func (entry *Entry) Debug(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(DebugLevel) {
-               entry.log(DebugLevel, fmt.Sprint(args...))
+func (entry *Entry) Log(level Level, args ...interface{}) {
+       if entry.Logger.IsLevelEnabled(level) {
+               entry.log(level, fmt.Sprint(args...))
        }
 }
 
+func (entry *Entry) Trace(args ...interface{}) {
+       entry.Log(TraceLevel, args...)
+}
+
+func (entry *Entry) Debug(args ...interface{}) {
+       entry.Log(DebugLevel, args...)
+}
+
 func (entry *Entry) Print(args ...interface{}) {
        entry.Info(args...)
 }
 
 func (entry *Entry) Info(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(InfoLevel) {
-               entry.log(InfoLevel, fmt.Sprint(args...))
-       }
+       entry.Log(InfoLevel, args...)
 }
 
 func (entry *Entry) Warn(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(WarnLevel) {
-               entry.log(WarnLevel, fmt.Sprint(args...))
-       }
+       entry.Log(WarnLevel, args...)
 }
 
 func (entry *Entry) Warning(args ...interface{}) {
@@ -189,37 +295,37 @@
 }
 
 func (entry *Entry) Error(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(ErrorLevel) {
-               entry.log(ErrorLevel, fmt.Sprint(args...))
-       }
+       entry.Log(ErrorLevel, args...)
 }
 
 func (entry *Entry) Fatal(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(FatalLevel) {
-               entry.log(FatalLevel, fmt.Sprint(args...))
-       }
-       Exit(1)
+       entry.Log(FatalLevel, args...)
+       entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panic(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(PanicLevel) {
-               entry.log(PanicLevel, fmt.Sprint(args...))
-       }
+       entry.Log(PanicLevel, args...)
        panic(fmt.Sprint(args...))
 }
 
 // Entry Printf family functions
 
-func (entry *Entry) Debugf(format string, args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(DebugLevel) {
-               entry.Debug(fmt.Sprintf(format, args...))
+func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
+       if entry.Logger.IsLevelEnabled(level) {
+               entry.Log(level, fmt.Sprintf(format, args...))
        }
 }
 
+func (entry *Entry) Tracef(format string, args ...interface{}) {
+       entry.Logf(TraceLevel, format, args...)
+}
+
+func (entry *Entry) Debugf(format string, args ...interface{}) {
+       entry.Logf(DebugLevel, format, args...)
+}
+
 func (entry *Entry) Infof(format string, args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(InfoLevel) {
-               entry.Info(fmt.Sprintf(format, args...))
-       }
+       entry.Logf(InfoLevel, format, args...)
 }
 
 func (entry *Entry) Printf(format string, args ...interface{}) {
@@ -227,9 +333,7 @@
 }
 
 func (entry *Entry) Warnf(format string, args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(WarnLevel) {
-               entry.Warn(fmt.Sprintf(format, args...))
-       }
+       entry.Logf(WarnLevel, format, args...)
 }
 
 func (entry *Entry) Warningf(format string, args ...interface{}) {
@@ -237,36 +341,36 @@
 }
 
 func (entry *Entry) Errorf(format string, args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(ErrorLevel) {
-               entry.Error(fmt.Sprintf(format, args...))
-       }
+       entry.Logf(ErrorLevel, format, args...)
 }
 
 func (entry *Entry) Fatalf(format string, args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(FatalLevel) {
-               entry.Fatal(fmt.Sprintf(format, args...))
-       }
-       Exit(1)
+       entry.Logf(FatalLevel, format, args...)
+       entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panicf(format string, args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(PanicLevel) {
-               entry.Panic(fmt.Sprintf(format, args...))
-       }
+       entry.Logf(PanicLevel, format, args...)
 }
 
 // Entry Println family functions
 
-func (entry *Entry) Debugln(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(DebugLevel) {
-               entry.Debug(entry.sprintlnn(args...))
+func (entry *Entry) Logln(level Level, args ...interface{}) {
+       if entry.Logger.IsLevelEnabled(level) {
+               entry.Log(level, entry.sprintlnn(args...))
        }
 }
 
+func (entry *Entry) Traceln(args ...interface{}) {
+       entry.Logln(TraceLevel, args...)
+}
+
+func (entry *Entry) Debugln(args ...interface{}) {
+       entry.Logln(DebugLevel, args...)
+}
+
 func (entry *Entry) Infoln(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(InfoLevel) {
-               entry.Info(entry.sprintlnn(args...))
-       }
+       entry.Logln(InfoLevel, args...)
 }
 
 func (entry *Entry) Println(args ...interface{}) {
@@ -274,9 +378,7 @@
 }
 
 func (entry *Entry) Warnln(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(WarnLevel) {
-               entry.Warn(entry.sprintlnn(args...))
-       }
+       entry.Logln(WarnLevel, args...)
 }
 
 func (entry *Entry) Warningln(args ...interface{}) {
@@ -284,22 +386,16 @@
 }
 
 func (entry *Entry) Errorln(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(ErrorLevel) {
-               entry.Error(entry.sprintlnn(args...))
-       }
+       entry.Logln(ErrorLevel, args...)
 }
 
 func (entry *Entry) Fatalln(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(FatalLevel) {
-               entry.Fatal(entry.sprintlnn(args...))
-       }
-       Exit(1)
+       entry.Logln(FatalLevel, args...)
+       entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panicln(args ...interface{}) {
-       if entry.Logger.IsLevelEnabled(PanicLevel) {
-               entry.Panic(entry.sprintlnn(args...))
-       }
+       entry.Logln(PanicLevel, args...)
 }
 
 // Sprintlnn => Sprint no newline. This is to get the behavior of how
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/exported.go 
new/vendor/github.com/sirupsen/logrus/exported.go
--- old/vendor/github.com/sirupsen/logrus/exported.go   2018-11-15 
20:22:56.986337192 +0100
+++ new/vendor/github.com/sirupsen/logrus/exported.go   2019-03-12 
13:15:34.130444171 +0100
@@ -1,6 +1,7 @@
 package logrus
 
 import (
+       "context"
        "io"
        "time"
 )
@@ -24,6 +25,12 @@
        std.SetFormatter(formatter)
 }
 
+// SetReportCaller sets whether the standard logger will include the calling
+// method as a field.
+func SetReportCaller(include bool) {
+       std.SetReportCaller(include)
+}
+
 // SetLevel sets the standard logger level.
 func SetLevel(level Level) {
        std.SetLevel(level)
@@ -49,6 +56,11 @@
        return std.WithField(ErrorKey, err)
 }
 
+// WithContext creates an entry from the standard logger and adds a context to 
it.
+func WithContext(ctx context.Context) *Entry {
+       return std.WithContext(ctx)
+}
+
 // WithField creates an entry from the standard logger and adds a field to
 // it. If you want multiple fields, use `WithFields`.
 //
@@ -77,6 +89,11 @@
        return std.WithTime(t)
 }
 
+// Trace logs a message at level Trace on the standard logger.
+func Trace(args ...interface{}) {
+       std.Trace(args...)
+}
+
 // Debug logs a message at level Debug on the standard logger.
 func Debug(args ...interface{}) {
        std.Debug(args...)
@@ -117,6 +134,11 @@
        std.Fatal(args...)
 }
 
+// Tracef logs a message at level Trace on the standard logger.
+func Tracef(format string, args ...interface{}) {
+       std.Tracef(format, args...)
+}
+
 // Debugf logs a message at level Debug on the standard logger.
 func Debugf(format string, args ...interface{}) {
        std.Debugf(format, args...)
@@ -157,6 +179,11 @@
        std.Fatalf(format, args...)
 }
 
+// Traceln logs a message at level Trace on the standard logger.
+func Traceln(args ...interface{}) {
+       std.Traceln(args...)
+}
+
 // Debugln logs a message at level Debug on the standard logger.
 func Debugln(args ...interface{}) {
        std.Debugln(args...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/formatter.go 
new/vendor/github.com/sirupsen/logrus/formatter.go
--- old/vendor/github.com/sirupsen/logrus/formatter.go  2018-11-15 
20:22:56.986337192 +0100
+++ new/vendor/github.com/sirupsen/logrus/formatter.go  2019-03-12 
13:15:34.130444171 +0100
@@ -9,6 +9,8 @@
        FieldKeyLevel          = "level"
        FieldKeyTime           = "time"
        FieldKeyLogrusError    = "logrus_error"
+       FieldKeyFunc           = "func"
+       FieldKeyFile           = "file"
 )
 
 // The Formatter interface is used to implement a custom Formatter. It takes an
@@ -25,7 +27,7 @@
        Format(*Entry) ([]byte, error)
 }
 
-// This is to not silently overwrite `time`, `msg` and `level` fields when
+// This is to not silently overwrite `time`, `msg`, `func` and `level` fields 
when
 // dumping it. If this code wasn't there doing:
 //
 //  logrus.WithField("level", 1).Info("hello")
@@ -37,7 +39,7 @@
 //
 // It's not exported because it's still using Data in an opinionated way. It's 
to
 // avoid code duplication between the two default formatters.
-func prefixFieldClashes(data Fields, fieldMap FieldMap) {
+func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
        timeKey := fieldMap.resolve(FieldKeyTime)
        if t, ok := data[timeKey]; ok {
                data["fields."+timeKey] = t
@@ -61,4 +63,16 @@
                data["fields."+logrusErrKey] = l
                delete(data, logrusErrKey)
        }
+
+       // If reportCaller is not set, 'func' will not conflict.
+       if reportCaller {
+               funcKey := fieldMap.resolve(FieldKeyFunc)
+               if l, ok := data[funcKey]; ok {
+                       data["fields."+funcKey] = l
+               }
+               fileKey := fieldMap.resolve(FieldKeyFile)
+               if l, ok := data[fileKey]; ok {
+                       data["fields."+fileKey] = l
+               }
+       }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/json_formatter.go 
new/vendor/github.com/sirupsen/logrus/json_formatter.go
--- old/vendor/github.com/sirupsen/logrus/json_formatter.go     2018-11-15 
20:22:56.990337177 +0100
+++ new/vendor/github.com/sirupsen/logrus/json_formatter.go     2019-03-12 
13:15:34.130444171 +0100
@@ -4,6 +4,7 @@
        "bytes"
        "encoding/json"
        "fmt"
+       "runtime"
 )
 
 type fieldKey string
@@ -34,20 +35,27 @@
        // As an example:
        // formatter := &JSONFormatter{
        //      FieldMap: FieldMap{
-       //               FieldKeyTime: "@timestamp",
+       //               FieldKeyTime:  "@timestamp",
        //               FieldKeyLevel: "@level",
-       //               FieldKeyMsg: "@message",
+       //               FieldKeyMsg:   "@message",
+       //               FieldKeyFunc:  "@caller",
        //    },
        // }
        FieldMap FieldMap
 
+       // CallerPrettyfier can be set by the user to modify the content
+       // of the function and file keys in the json data when ReportCaller is
+       // activated. If any of the returned value is the empty string the
+       // corresponding key will be removed from json fields.
+       CallerPrettyfier func(*runtime.Frame) (function string, file string)
+
        // PrettyPrint will indent all json logs
        PrettyPrint bool
 }
 
 // Format renders a single log entry
 func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
-       data := make(Fields, len(entry.Data)+3)
+       data := make(Fields, len(entry.Data)+4)
        for k, v := range entry.Data {
                switch v := v.(type) {
                case error:
@@ -65,7 +73,7 @@
                data = newData
        }
 
-       prefixFieldClashes(data, f.FieldMap)
+       prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
 
        timestampFormat := f.TimestampFormat
        if timestampFormat == "" {
@@ -80,6 +88,19 @@
        }
        data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
        data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
+       if entry.HasCaller() {
+               funcVal := entry.Caller.Function
+               fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, 
entry.Caller.Line)
+               if f.CallerPrettyfier != nil {
+                       funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
+               }
+               if funcVal != "" {
+                       data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
+               }
+               if fileVal != "" {
+                       data[f.FieldMap.resolve(FieldKeyFile)] = fileVal
+               }
+       }
 
        var b *bytes.Buffer
        if entry.Buffer != nil {
@@ -93,7 +114,7 @@
                encoder.SetIndent("", "  ")
        }
        if err := encoder.Encode(data); err != nil {
-               return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", 
err)
+               return nil, fmt.Errorf("failed to marshal fields to JSON, %v", 
err)
        }
 
        return b.Bytes(), nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/logger.go 
new/vendor/github.com/sirupsen/logrus/logger.go
--- old/vendor/github.com/sirupsen/logrus/logger.go     2018-11-15 
20:22:56.990337177 +0100
+++ new/vendor/github.com/sirupsen/logrus/logger.go     2019-03-12 
13:15:34.130444171 +0100
@@ -1,6 +1,7 @@
 package logrus
 
 import (
+       "context"
        "io"
        "os"
        "sync"
@@ -24,6 +25,10 @@
        // own that implements the `Formatter` interface, see the `README` or 
included
        // formatters for examples.
        Formatter Formatter
+
+       // Flag for whether to log caller info (off by default)
+       ReportCaller bool
+
        // The logging level the logger should log at. This is typically (and 
defaults
        // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() 
to be
        // logged.
@@ -32,8 +37,12 @@
        mu MutexWrap
        // Reusable empty entry
        entryPool sync.Pool
+       // Function to exit the application, defaults to `os.Exit()`
+       ExitFunc exitFunc
 }
 
+type exitFunc func(int)
+
 type MutexWrap struct {
        lock     sync.Mutex
        disabled bool
@@ -69,10 +78,12 @@
 // It's recommended to make this a global instance called `log`.
 func New() *Logger {
        return &Logger{
-               Out:       os.Stderr,
-               Formatter: new(TextFormatter),
-               Hooks:     make(LevelHooks),
-               Level:     InfoLevel,
+               Out:          os.Stderr,
+               Formatter:    new(TextFormatter),
+               Hooks:        make(LevelHooks),
+               Level:        InfoLevel,
+               ExitFunc:     os.Exit,
+               ReportCaller: false,
        }
 }
 
@@ -114,6 +125,13 @@
        return entry.WithError(err)
 }
 
+// Add a context to the log entry.
+func (logger *Logger) WithContext(ctx context.Context) *Entry {
+       entry := logger.newEntry()
+       defer logger.releaseEntry(entry)
+       return entry.WithContext(ctx)
+}
+
 // Overrides the time of the log entry.
 func (logger *Logger) WithTime(t time.Time) *Entry {
        entry := logger.newEntry()
@@ -121,20 +139,24 @@
        return entry.WithTime(t)
 }
 
-func (logger *Logger) Debugf(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(DebugLevel) {
+func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
+       if logger.IsLevelEnabled(level) {
                entry := logger.newEntry()
-               entry.Debugf(format, args...)
+               entry.Logf(level, format, args...)
                logger.releaseEntry(entry)
        }
 }
 
+func (logger *Logger) Tracef(format string, args ...interface{}) {
+       logger.Logf(TraceLevel, format, args...)
+}
+
+func (logger *Logger) Debugf(format string, args ...interface{}) {
+       logger.Logf(DebugLevel, format, args...)
+}
+
 func (logger *Logger) Infof(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(InfoLevel) {
-               entry := logger.newEntry()
-               entry.Infof(format, args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logf(InfoLevel, format, args...)
 }
 
 func (logger *Logger) Printf(format string, args ...interface{}) {
@@ -144,123 +166,91 @@
 }
 
 func (logger *Logger) Warnf(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(WarnLevel) {
-               entry := logger.newEntry()
-               entry.Warnf(format, args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logf(WarnLevel, format, args...)
 }
 
 func (logger *Logger) Warningf(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(WarnLevel) {
-               entry := logger.newEntry()
-               entry.Warnf(format, args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Warnf(format, args...)
 }
 
 func (logger *Logger) Errorf(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(ErrorLevel) {
-               entry := logger.newEntry()
-               entry.Errorf(format, args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logf(ErrorLevel, format, args...)
 }
 
 func (logger *Logger) Fatalf(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(FatalLevel) {
-               entry := logger.newEntry()
-               entry.Fatalf(format, args...)
-               logger.releaseEntry(entry)
-       }
-       Exit(1)
+       logger.Logf(FatalLevel, format, args...)
+       logger.Exit(1)
 }
 
 func (logger *Logger) Panicf(format string, args ...interface{}) {
-       if logger.IsLevelEnabled(PanicLevel) {
+       logger.Logf(PanicLevel, format, args...)
+}
+
+func (logger *Logger) Log(level Level, args ...interface{}) {
+       if logger.IsLevelEnabled(level) {
                entry := logger.newEntry()
-               entry.Panicf(format, args...)
+               entry.Log(level, args...)
                logger.releaseEntry(entry)
        }
 }
 
+func (logger *Logger) Trace(args ...interface{}) {
+       logger.Log(TraceLevel, args...)
+}
+
 func (logger *Logger) Debug(args ...interface{}) {
-       if logger.IsLevelEnabled(DebugLevel) {
-               entry := logger.newEntry()
-               entry.Debug(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Log(DebugLevel, args...)
 }
 
 func (logger *Logger) Info(args ...interface{}) {
-       if logger.IsLevelEnabled(InfoLevel) {
-               entry := logger.newEntry()
-               entry.Info(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Log(InfoLevel, args...)
 }
 
 func (logger *Logger) Print(args ...interface{}) {
        entry := logger.newEntry()
-       entry.Info(args...)
+       entry.Print(args...)
        logger.releaseEntry(entry)
 }
 
 func (logger *Logger) Warn(args ...interface{}) {
-       if logger.IsLevelEnabled(WarnLevel) {
-               entry := logger.newEntry()
-               entry.Warn(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Log(WarnLevel, args...)
 }
 
 func (logger *Logger) Warning(args ...interface{}) {
-       if logger.IsLevelEnabled(WarnLevel) {
-               entry := logger.newEntry()
-               entry.Warn(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Warn(args...)
 }
 
 func (logger *Logger) Error(args ...interface{}) {
-       if logger.IsLevelEnabled(ErrorLevel) {
-               entry := logger.newEntry()
-               entry.Error(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Log(ErrorLevel, args...)
 }
 
 func (logger *Logger) Fatal(args ...interface{}) {
-       if logger.IsLevelEnabled(FatalLevel) {
-               entry := logger.newEntry()
-               entry.Fatal(args...)
-               logger.releaseEntry(entry)
-       }
-       Exit(1)
+       logger.Log(FatalLevel, args...)
+       logger.Exit(1)
 }
 
 func (logger *Logger) Panic(args ...interface{}) {
-       if logger.IsLevelEnabled(PanicLevel) {
+       logger.Log(PanicLevel, args...)
+}
+
+func (logger *Logger) Logln(level Level, args ...interface{}) {
+       if logger.IsLevelEnabled(level) {
                entry := logger.newEntry()
-               entry.Panic(args...)
+               entry.Logln(level, args...)
                logger.releaseEntry(entry)
        }
 }
 
+func (logger *Logger) Traceln(args ...interface{}) {
+       logger.Logln(TraceLevel, args...)
+}
+
 func (logger *Logger) Debugln(args ...interface{}) {
-       if logger.IsLevelEnabled(DebugLevel) {
-               entry := logger.newEntry()
-               entry.Debugln(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logln(DebugLevel, args...)
 }
 
 func (logger *Logger) Infoln(args ...interface{}) {
-       if logger.IsLevelEnabled(InfoLevel) {
-               entry := logger.newEntry()
-               entry.Infoln(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logln(InfoLevel, args...)
 }
 
 func (logger *Logger) Println(args ...interface{}) {
@@ -270,44 +260,32 @@
 }
 
 func (logger *Logger) Warnln(args ...interface{}) {
-       if logger.IsLevelEnabled(WarnLevel) {
-               entry := logger.newEntry()
-               entry.Warnln(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logln(WarnLevel, args...)
 }
 
 func (logger *Logger) Warningln(args ...interface{}) {
-       if logger.IsLevelEnabled(WarnLevel) {
-               entry := logger.newEntry()
-               entry.Warnln(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Warnln(args...)
 }
 
 func (logger *Logger) Errorln(args ...interface{}) {
-       if logger.IsLevelEnabled(ErrorLevel) {
-               entry := logger.newEntry()
-               entry.Errorln(args...)
-               logger.releaseEntry(entry)
-       }
+       logger.Logln(ErrorLevel, args...)
 }
 
 func (logger *Logger) Fatalln(args ...interface{}) {
-       if logger.IsLevelEnabled(FatalLevel) {
-               entry := logger.newEntry()
-               entry.Fatalln(args...)
-               logger.releaseEntry(entry)
-       }
-       Exit(1)
+       logger.Logln(FatalLevel, args...)
+       logger.Exit(1)
 }
 
 func (logger *Logger) Panicln(args ...interface{}) {
-       if logger.IsLevelEnabled(PanicLevel) {
-               entry := logger.newEntry()
-               entry.Panicln(args...)
-               logger.releaseEntry(entry)
+       logger.Logln(PanicLevel, args...)
+}
+
+func (logger *Logger) Exit(code int) {
+       runHandlers()
+       if logger.ExitFunc == nil {
+               logger.ExitFunc = os.Exit
        }
+       logger.ExitFunc(code)
 }
 
 //When file is opened with appending mode, it's safe to
@@ -357,6 +335,12 @@
        logger.Out = output
 }
 
+func (logger *Logger) SetReportCaller(reportCaller bool) {
+       logger.mu.Lock()
+       defer logger.mu.Unlock()
+       logger.ReportCaller = reportCaller
+}
+
 // ReplaceHooks replaces the logger hooks and returns the old ones
 func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
        logger.mu.Lock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/logrus.go 
new/vendor/github.com/sirupsen/logrus/logrus.go
--- old/vendor/github.com/sirupsen/logrus/logrus.go     2018-11-15 
20:22:56.990337177 +0100
+++ new/vendor/github.com/sirupsen/logrus/logrus.go     2019-03-12 
13:15:34.130444171 +0100
@@ -14,22 +14,11 @@
 
 // Convert the Level to a string. E.g. PanicLevel becomes "panic".
 func (level Level) String() string {
-       switch level {
-       case DebugLevel:
-               return "debug"
-       case InfoLevel:
-               return "info"
-       case WarnLevel:
-               return "warning"
-       case ErrorLevel:
-               return "error"
-       case FatalLevel:
-               return "fatal"
-       case PanicLevel:
-               return "panic"
+       if b, err := level.MarshalText(); err == nil {
+               return string(b)
+       } else {
+               return "unknown"
        }
-
-       return "unknown"
 }
 
 // ParseLevel takes a string level and returns the Logrus log level constant.
@@ -47,12 +36,47 @@
                return InfoLevel, nil
        case "debug":
                return DebugLevel, nil
+       case "trace":
+               return TraceLevel, nil
        }
 
        var l Level
        return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
 }
 
+// UnmarshalText implements encoding.TextUnmarshaler.
+func (level *Level) UnmarshalText(text []byte) error {
+       l, err := ParseLevel(string(text))
+       if err != nil {
+               return err
+       }
+
+       *level = Level(l)
+
+       return nil
+}
+
+func (level Level) MarshalText() ([]byte, error) {
+       switch level {
+       case TraceLevel:
+               return []byte("trace"), nil
+       case DebugLevel:
+               return []byte("debug"), nil
+       case InfoLevel:
+               return []byte("info"), nil
+       case WarnLevel:
+               return []byte("warning"), nil
+       case ErrorLevel:
+               return []byte("error"), nil
+       case FatalLevel:
+               return []byte("fatal"), nil
+       case PanicLevel:
+               return []byte("panic"), nil
+       }
+
+       return nil, fmt.Errorf("not a valid logrus level %d", level)
+}
+
 // A constant exposing all logging levels
 var AllLevels = []Level{
        PanicLevel,
@@ -61,6 +85,7 @@
        WarnLevel,
        InfoLevel,
        DebugLevel,
+       TraceLevel,
 }
 
 // These are the different logging levels. You can set the logging level to log
@@ -69,7 +94,7 @@
        // PanicLevel level, highest level of severity. Logs and then calls 
panic with the
        // message passed to Debug, Info, ...
        PanicLevel Level = iota
-       // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit 
even if the
+       // FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit 
even if the
        // logging level is set to Panic.
        FatalLevel
        // ErrorLevel level. Logs. Used for errors that should definitely be 
noted.
@@ -82,6 +107,8 @@
        InfoLevel
        // DebugLevel level. Usually only enabled when debugging. Very verbose 
logging.
        DebugLevel
+       // TraceLevel level. Designates finer-grained informational events than 
the Debug.
+       TraceLevel
 )
 
 // Won't compile if StdLogger can't be realized by a log.Logger
@@ -148,3 +175,12 @@
        // IsFatalEnabled() bool
        // IsPanicEnabled() bool
 }
+
+// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
+// here for consistancy. Do not use. Use Logger or Entry instead.
+type Ext1FieldLogger interface {
+       FieldLogger
+       Tracef(format string, args ...interface{})
+       Trace(args ...interface{})
+       Traceln(args ...interface{})
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go 
new/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
--- old/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go        
2018-11-15 20:22:56.990337177 +0100
+++ new/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go        
2019-03-12 13:15:34.130444171 +0100
@@ -1,4 +1,4 @@
-// +build !appengine,!js,!windows
+// +build !appengine,!js,!windows,!aix
 
 package logrus
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/text_formatter.go 
new/vendor/github.com/sirupsen/logrus/text_formatter.go
--- old/vendor/github.com/sirupsen/logrus/text_formatter.go     2018-11-15 
20:22:56.990337177 +0100
+++ new/vendor/github.com/sirupsen/logrus/text_formatter.go     2019-03-12 
13:15:34.130444171 +0100
@@ -4,6 +4,7 @@
        "bytes"
        "fmt"
        "os"
+       "runtime"
        "sort"
        "strings"
        "sync"
@@ -11,18 +12,13 @@
 )
 
 const (
-       nocolor = 0
-       red     = 31
-       green   = 32
-       yellow  = 33
-       blue    = 36
-       gray    = 37
+       red    = 31
+       yellow = 33
+       blue   = 36
+       gray   = 37
 )
 
-var (
-       baseTimestamp time.Time
-       emptyFieldMap FieldMap
-)
+var baseTimestamp time.Time
 
 func init() {
        baseTimestamp = time.Now()
@@ -76,6 +72,12 @@
        //         FieldKeyMsg:   "@message"}}
        FieldMap FieldMap
 
+       // CallerPrettyfier can be set by the user to modify the content
+       // of the function and file keys in the json data when ReportCaller is
+       // activated. If any of the returned value is the empty string the
+       // corresponding key will be removed from json fields.
+       CallerPrettyfier func(*runtime.Frame) (function string, file string)
+
        terminalInitOnce sync.Once
 }
 
@@ -90,7 +92,7 @@
 }
 
 func (f *TextFormatter) isColored() bool {
-       isColored := f.ForceColors || f.isTerminal
+       isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != 
"windows"))
 
        if f.EnvironmentOverrideColors {
                if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != 
"0" {
@@ -107,14 +109,19 @@
 
 // Format renders a single log entry
 func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
-       prefixFieldClashes(entry.Data, f.FieldMap)
-
-       keys := make([]string, 0, len(entry.Data))
-       for k := range entry.Data {
+       data := make(Fields)
+       for k, v := range entry.Data {
+               data[k] = v
+       }
+       prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
+       keys := make([]string, 0, len(data))
+       for k := range data {
                keys = append(keys, k)
        }
 
-       fixedKeys := make([]string, 0, 4+len(entry.Data))
+       var funcVal, fileVal string
+
+       fixedKeys := make([]string, 0, 4+len(data))
        if !f.DisableTimestamp {
                fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
        }
@@ -125,6 +132,16 @@
        if entry.err != "" {
                fixedKeys = append(fixedKeys, 
f.FieldMap.resolve(FieldKeyLogrusError))
        }
+       if entry.HasCaller() {
+               fixedKeys = append(fixedKeys,
+                       f.FieldMap.resolve(FieldKeyFunc), 
f.FieldMap.resolve(FieldKeyFile))
+               if f.CallerPrettyfier != nil {
+                       funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
+               } else {
+                       funcVal = entry.Caller.Function
+                       fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, 
entry.Caller.Line)
+               }
+       }
 
        if !f.DisableSorting {
                if f.SortingFunc == nil {
@@ -156,21 +173,26 @@
                timestampFormat = defaultTimestampFormat
        }
        if f.isColored() {
-               f.printColored(b, entry, keys, timestampFormat)
+               f.printColored(b, entry, keys, data, timestampFormat)
        } else {
+
                for _, key := range fixedKeys {
                        var value interface{}
-                       switch key {
-                       case f.FieldMap.resolve(FieldKeyTime):
+                       switch {
+                       case key == f.FieldMap.resolve(FieldKeyTime):
                                value = entry.Time.Format(timestampFormat)
-                       case f.FieldMap.resolve(FieldKeyLevel):
+                       case key == f.FieldMap.resolve(FieldKeyLevel):
                                value = entry.Level.String()
-                       case f.FieldMap.resolve(FieldKeyMsg):
+                       case key == f.FieldMap.resolve(FieldKeyMsg):
                                value = entry.Message
-                       case f.FieldMap.resolve(FieldKeyLogrusError):
+                       case key == f.FieldMap.resolve(FieldKeyLogrusError):
                                value = entry.err
+                       case key == f.FieldMap.resolve(FieldKeyFunc) && 
entry.HasCaller():
+                               value = funcVal
+                       case key == f.FieldMap.resolve(FieldKeyFile) && 
entry.HasCaller():
+                               value = fileVal
                        default:
-                               value = entry.Data[key]
+                               value = data[key]
                        }
                        f.appendKeyValue(b, key, value)
                }
@@ -180,10 +202,10 @@
        return b.Bytes(), nil
 }
 
-func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys 
[]string, timestampFormat string) {
+func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys 
[]string, data Fields, timestampFormat string) {
        var levelColor int
        switch entry.Level {
-       case DebugLevel:
+       case DebugLevel, TraceLevel:
                levelColor = gray
        case WarnLevel:
                levelColor = yellow
@@ -202,15 +224,27 @@
        // the behavior of logrus text_formatter the same as the stdlib log 
package
        entry.Message = strings.TrimSuffix(entry.Message, "\n")
 
+       caller := ""
+
+       if entry.HasCaller() {
+               funcVal := fmt.Sprintf("%s()", entry.Caller.Function)
+               fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, 
entry.Caller.Line)
+
+               if f.CallerPrettyfier != nil {
+                       funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
+               }
+               caller = fileVal + " " + funcVal
+       }
+
        if f.DisableTimestamp {
-               fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, 
levelText, entry.Message)
+               fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, 
levelText, caller, entry.Message)
        } else if !f.FullTimestamp {
-               fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, 
levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
+               fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, 
levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, 
entry.Message)
        } else {
-               fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, 
levelText, entry.Time.Format(timestampFormat), entry.Message)
+               fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, 
levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
        }
        for _, k := range keys {
-               v := entry.Data[k]
+               v := data[k]
                fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
                f.appendValue(b, v)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/sirupsen/logrus/writer.go 
new/vendor/github.com/sirupsen/logrus/writer.go
--- old/vendor/github.com/sirupsen/logrus/writer.go     2018-11-15 
20:22:56.990337177 +0100
+++ new/vendor/github.com/sirupsen/logrus/writer.go     2019-03-12 
13:15:34.130444171 +0100
@@ -24,6 +24,8 @@
        var printFunc func(args ...interface{})
 
        switch level {
+       case TraceLevel:
+               printFunc = entry.Trace
        case DebugLevel:
                printFunc = entry.Debug
        case InfoLevel:


Reply via email to