Logs: Prevent feedback loops by omitting repeated messages

This also prevents debug and trace messages to be sent to the frontend.
This commit is contained in:
Michael Mayer 2022-05-20 11:31:39 +02:00
parent 41e7cc0513
commit 2de1e338bd
5 changed files with 89 additions and 16 deletions

View file

@ -93,7 +93,11 @@ func wsReader(ws *websocket.Conn, writeMutex *sync.Mutex, connId string, conf *c
func wsWriter(ws *websocket.Conn, writeMutex *sync.Mutex, connId string) {
pingTicker := time.NewTicker(15 * time.Second)
s := event.Subscribe(
"log.*",
"log.fatal",
"log.error",
"log.warning",
"log.warn",
"log.info",
"notify.*",
"index.*",
"upload.*",

28
internal/event/buffer.go Normal file
View file

@ -0,0 +1,28 @@
package event
import (
"bytes"
"sync"
)
// Buffer is a goroutine safe buffer.
type Buffer struct {
buffer bytes.Buffer
mutex sync.RWMutex
}
// Set updates the buffer content.
func (b *Buffer) Set(s string) (err error) {
b.mutex.Lock()
defer b.mutex.Unlock()
b.buffer.Reset()
_, err = b.buffer.WriteString(s)
return err
}
// Get returns the buffer content.
func (b *Buffer) Get() string {
b.mutex.RLock()
defer b.mutex.RUnlock()
return b.buffer.String()
}

View file

@ -0,0 +1,19 @@
package event
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestBuffer(t *testing.T) {
b := Buffer{}
assert.Equal(t, "", b.Get())
assert.Equal(t, nil, b.Set("foo123 !!!"))
assert.Equal(t, "foo123 !!!", b.Get())
assert.Equal(t, nil, b.Set("BAR"))
assert.Equal(t, "BAR", b.Get())
assert.Equal(t, nil, b.Set(""))
assert.Equal(t, "", b.Get())
}

21
internal/event/init.go Normal file
View file

@ -0,0 +1,21 @@
package event
import (
"os"
"github.com/sirupsen/logrus"
)
func init() {
hooks := logrus.LevelHooks{}
hooks.Add(NewHook(SharedHub()))
Log = &logrus.Logger{
Out: os.Stderr,
Formatter: &logrus.TextFormatter{},
Hooks: hooks,
Level: logrus.DebugLevel,
ExitFunc: os.Exit,
ReportCaller: false,
}
}

View file

@ -1,23 +1,37 @@
package event
import (
"os"
"fmt"
"github.com/leandro-lugaresi/hub"
"github.com/sirupsen/logrus"
)
var Log *logrus.Logger
var LastLog Buffer
// Hook represents a log event hook.
type Hook struct {
hub *hub.Hub
}
// NewHook creates a new log event hook.
func NewHook(hub *hub.Hub) *Hook {
return &Hook{hub: hub}
}
// Fire publishes a new log event,
func (h *Hook) Fire(entry *logrus.Entry) error {
if entry == nil {
return fmt.Errorf("log entry is empty")
} else if entry.Message == "" {
return fmt.Errorf("log message is empty")
} else if LastLog.Get() == entry.Message {
return nil
} else if err := LastLog.Set(entry.Message); err != nil {
return err
}
h.hub.Publish(Message{
Name: "log." + entry.Level.String(),
Fields: Data{
@ -30,20 +44,7 @@ func (h *Hook) Fire(entry *logrus.Entry) error {
return nil
}
// Levels returns a slice containing all supported log levels.
func (h *Hook) Levels() []logrus.Level {
return logrus.AllLevels
}
func init() {
hooks := logrus.LevelHooks{}
hooks.Add(NewHook(SharedHub()))
Log = &logrus.Logger{
Out: os.Stderr,
Formatter: &logrus.TextFormatter{},
Hooks: hooks,
Level: logrus.DebugLevel,
ExitFunc: os.Exit,
ReportCaller: false,
}
}