diff --git a/cmd/setup-node/commands/root.go b/cmd/setup-node/commands/root.go index 5b2073bd2d..0dbf2ed8df 100644 --- a/cmd/setup-node/commands/root.go +++ b/cmd/setup-node/commands/root.go @@ -60,6 +60,13 @@ var rootCmd = &cobra.Command{ if discordWebhookURL := discord.GetWebhookURLFromEnv(); discordWebhookURL != "" { hook := discord.NewHook(tag, discordWebhookURL) logging.AddHook(hook) + + // Workaround for Discord logger hook. Actually, it's Info. + log.Error(discord.StartLogMessage) + defer log.Error(discord.StopLogMessage) + } else { + log.Info(discord.StartLogMessage) + defer log.Info(discord.StopLogMessage) } var rdr io.Reader diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 68ac9de15b..774839c2dc 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -56,6 +56,15 @@ var rootCmd = &cobra.Command{ Run: func(_ *cobra.Command, args []string) { log := initLogger(tag, syslogAddr) + if discordWebhookURL := discord.GetWebhookURLFromEnv(); discordWebhookURL != "" { + // Workaround for Discord logger hook. Actually, it's Info. + log.Error(discord.StartLogMessage) + defer log.Error(discord.StopLogMessage) + } else { + log.Info(discord.StartLogMessage) + defer log.Info(discord.StopLogMessage) + } + delayDuration, err := time.ParseDuration(delay) if err != nil { log.WithError(err).Error("Failed to parse delay duration.") diff --git a/go.mod b/go.mod index 581c1e8e0b..5a5a2230a0 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/schollz/progressbar/v2 v2.15.0 github.com/shirou/gopsutil v2.20.5+incompatible github.com/sirupsen/logrus v1.6.0 - github.com/skycoin/dmsg v0.0.0-20200922082251-01fafc6408e7 + github.com/skycoin/dmsg v0.0.0-20201008074402-acbe6d76d785 github.com/skycoin/skycoin v0.26.0 github.com/skycoin/yamux v0.0.0-20200803175205-571ceb89da9f github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 diff --git a/go.sum b/go.sum index fb367920d7..5b8fde7660 100644 --- a/go.sum +++ b/go.sum @@ -224,8 +224,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/skycoin/dmsg v0.0.0-20200922082251-01fafc6408e7 h1:8MLQ7JNk54C34lwZns1b60UTlr5kGWe6SLIxT18eBIk= -github.com/skycoin/dmsg v0.0.0-20200922082251-01fafc6408e7/go.mod h1:xkd4GkAkPfwbbBDyp6rJoUWjPaV/Jj4bxAhsMTKO7ck= +github.com/skycoin/dmsg v0.0.0-20201008074402-acbe6d76d785 h1:wO5+dExw3a+eNPQk6cCPZnEP5P1KxBafADeWZEFQCrY= +github.com/skycoin/dmsg v0.0.0-20201008074402-acbe6d76d785/go.mod h1:xkd4GkAkPfwbbBDyp6rJoUWjPaV/Jj4bxAhsMTKO7ck= github.com/skycoin/skycoin v0.26.0 h1:xDxe2r8AclMntZ550Y/vUQgwgLtwrf9Wu5UYiYcN5/o= github.com/skycoin/skycoin v0.26.0/go.mod h1:78nHjQzd8KG0jJJVL/j0xMmrihXi70ti63fh8vXScJw= github.com/skycoin/yamux v0.0.0-20200803175205-571ceb89da9f h1:A5dEM1OE9YhN3LciZU9qPjo7fJ46JeHNi3JCroDkK0Y= diff --git a/vendor/github.com/skycoin/dmsg/cmdutil/service_flags.go b/vendor/github.com/skycoin/dmsg/cmdutil/service_flags.go index a8cdff66f3..678a3d8f82 100644 --- a/vendor/github.com/skycoin/dmsg/cmdutil/service_flags.go +++ b/vendor/github.com/skycoin/dmsg/cmdutil/service_flags.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "strings" + "time" "unicode" "github.com/sirupsen/logrus" @@ -147,7 +148,7 @@ func (sf *ServiceFlags) Logger() *logging.Logger { } if discordWebhookURL := discord.GetWebhookURLFromEnv(); discordWebhookURL != "" { - hook := discord.NewHook(sf.Tag, discordWebhookURL) + hook := discord.NewHook(sf.Tag, discordWebhookURL, discord.WithLimit(10*time.Minute)) logging.AddHook(hook) } diff --git a/vendor/github.com/skycoin/dmsg/discord/discord.go b/vendor/github.com/skycoin/dmsg/discord/discord.go deleted file mode 100644 index 4997c5d842..0000000000 --- a/vendor/github.com/skycoin/dmsg/discord/discord.go +++ /dev/null @@ -1,31 +0,0 @@ -package discord - -import ( - "os" - "time" - - "github.com/kz/discordrus" - "github.com/sirupsen/logrus" -) - -const ( - webhookURLEnvName = "DISCORD_WEBHOOK_URL" -) - -// NewHook creates a new Discord hook. -func NewHook(tag, webHookURL string) logrus.Hook { - return discordrus.NewHook(webHookURL, logrus.ErrorLevel, discordOpts(tag)) -} - -func discordOpts(tag string) *discordrus.Opts { - return &discordrus.Opts{ - Username: tag, - TimestampFormat: time.RFC3339, - TimestampLocale: time.UTC, - } -} - -// GetWebhookURLFromEnv extract Discord webhook URL from env. -func GetWebhookURLFromEnv() string { - return os.Getenv(webhookURLEnvName) -} diff --git a/vendor/github.com/skycoin/dmsg/discord/hook.go b/vendor/github.com/skycoin/dmsg/discord/hook.go new file mode 100644 index 0000000000..61a9f29886 --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/discord/hook.go @@ -0,0 +1,100 @@ +package discord + +import ( + "os" + "time" + + "github.com/kz/discordrus" + "github.com/sirupsen/logrus" +) + +const webhookURLEnvName = "DISCORD_WEBHOOK_URL" + +const ( + loggedLevel = logrus.ErrorLevel + startStopLogLevel = logrus.InfoLevel +) + +const ( + // StartLogMessage defines a message on binary starting. + StartLogMessage = "Starting" + // StopLogMessage defines a message on binary stopping. + StopLogMessage = "Stopping" +) + +// Hook is a Discord logger hook. +type Hook struct { + logrus.Hook + limit time.Duration + timestamps map[string]time.Time +} + +// Option defines an option for Discord logger hook. +type Option func(*Hook) + +// WithLimit enables logger rate limiter with specified limit. +func WithLimit(limit time.Duration) Option { + return func(h *Hook) { + h.limit = limit + h.timestamps = make(map[string]time.Time) + } +} + +// NewHook returns a new Hook. +func NewHook(tag, webHookURL string, opts ...Option) logrus.Hook { + parent := discordrus.NewHook(webHookURL, loggedLevel, discordOpts(tag)) + + hook := &Hook{ + Hook: parent, + } + + for _, opt := range opts { + opt(hook) + } + + return hook +} + +// Fire checks whether rate is fine and fires the underlying hook. +func (h *Hook) Fire(entry *logrus.Entry) error { + switch entry.Message { + case StartLogMessage, StopLogMessage: + // Start and stop messages should be logged by Hook but they should have Info level. + // With Info level, they would not be passed to hook. + // So we can use Error level in the codebase and change level to Info in the hook, + // then it appears as Info in logs. + entry.Level = startStopLogLevel + } + + if h.shouldFire(entry) { + return h.Hook.Fire(entry) + } + + return nil +} + +func (h *Hook) shouldFire(entry *logrus.Entry) bool { + if h.limit != 0 && h.timestamps != nil { + v, ok := h.timestamps[entry.Message] + if ok && entry.Time.Sub(v) < h.limit { + return false + } + + h.timestamps[entry.Message] = entry.Time + } + + return true +} + +func discordOpts(tag string) *discordrus.Opts { + return &discordrus.Opts{ + Username: tag, + TimestampFormat: time.RFC3339, + TimestampLocale: time.UTC, + } +} + +// GetWebhookURLFromEnv extracts webhook URL from an environment variable. +func GetWebhookURLFromEnv() string { + return os.Getenv(webhookURLEnvName) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 136d47f832..f5ba2c045e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -151,7 +151,7 @@ github.com/shirou/gopsutil/process ## explicit github.com/sirupsen/logrus github.com/sirupsen/logrus/hooks/syslog -# github.com/skycoin/dmsg v0.0.0-20200922082251-01fafc6408e7 +# github.com/skycoin/dmsg v0.0.0-20201008074402-acbe6d76d785 ## explicit github.com/skycoin/dmsg github.com/skycoin/dmsg/buildinfo