diff --git a/database/main.go b/database/main.go index 8bfd4f3..47a7679 100644 --- a/database/main.go +++ b/database/main.go @@ -10,6 +10,7 @@ import ( const AlertMsg = "alert service from logmania, device did not send new message for a while" type DB struct { + // depraced Format -> transformation to new format by db.update() Hostname map[string]string `json:"hostname,omitempty"` HostTo map[string]map[string]bool `json:"host_to,omitempty"` MaxPrioIn map[string]log.Level `json:"maxLevel,omitempty"` diff --git a/database/read.go b/database/read.go index f4186dc..6629b78 100644 --- a/database/read.go +++ b/database/read.go @@ -9,12 +9,12 @@ func ReadDBFile(path string) *DB { var db DB if err := file.ReadJSON(path, &db); err == nil { - log.Infof("loaded %d hosts", len(db.HostTo)) db.InitNotify() db.InitHost() // import db.update() + log.Infof("loaded %d hosts and %d notifies", len(db.Hosts), len(db.Notifies)) return &db } else { log.Error("failed to open db file: ", path, ":", err) diff --git a/lib/config.go b/lib/config.go index 72a57dd..6e8872c 100644 --- a/lib/config.go +++ b/lib/config.go @@ -19,6 +19,7 @@ type NotifyConfig struct { Address string `toml:"address"` Webroot string `toml:"webroot"` } `toml:"websocket"` + FileDirectory string `toml:"file_directory"` } type ReceiveConfig struct { diff --git a/logmania_example.conf b/logmania_example.conf index b4fab0a..23ee178 100644 --- a/logmania_example.conf +++ b/logmania_example.conf @@ -10,6 +10,8 @@ address = ":10002" state_file = "/tmp/logmania.state.json" debug = true +file_directory = "/tmp/" + [notify.xmpp] jid = "user@example.org" password = "password" diff --git a/notify/all/internal.go b/notify/all/internal.go index 12e0587..0ecc0f3 100644 --- a/notify/all/internal.go +++ b/notify/all/internal.go @@ -50,7 +50,7 @@ func (n *Notifier) sender() { } } if !send { - logger.Warn("notify not send to anybody: [%s] %s", c.Level.String(), c.Message) + logger.Warnf("notify not send to anybody: [%s] %s", c.Level.String(), c.Message) } } } diff --git a/notify/all/main.go b/notify/all/main.go index 95aff78..b66a415 100644 --- a/notify/all/main.go +++ b/notify/all/main.go @@ -1,6 +1,7 @@ package all import ( + _ "dev.sum7.eu/genofire/logmania/notify/file" _ "dev.sum7.eu/genofire/logmania/notify/websocket" _ "dev.sum7.eu/genofire/logmania/notify/xmpp" ) diff --git a/notify/file/main.go b/notify/file/main.go new file mode 100644 index 0000000..20c0c2d --- /dev/null +++ b/notify/file/main.go @@ -0,0 +1,79 @@ +package file + +import ( + "os" + "path" + "regexp" + + log "github.com/sirupsen/logrus" + + "dev.sum7.eu/genofire/logmania/bot" + "dev.sum7.eu/genofire/logmania/database" + "dev.sum7.eu/genofire/logmania/lib" + "dev.sum7.eu/genofire/logmania/notify" +) + +const ( + proto = "file" +) + +var logger = log.WithField("notify", proto) + +type Notifier struct { + notify.Notifier + files map[string]*os.File + formatter log.Formatter + path string +} + +func Init(config *lib.NotifyConfig, db *database.DB, bot *bot.Bot) notify.Notifier { + logger.Info("startup") + if config.FileDirectory == "" { + return nil + } + + return &Notifier{ + files: make(map[string]*os.File), + formatter: &log.JSONFormatter{}, + path: config.FileDirectory, + } +} + +func (n *Notifier) getFile(name string) *os.File { + if file, ok := n.files[name]; ok { + return file + } + if m, err := regexp.MatchString(`^[0-9A-Za-z_-]*$`, name); err != nil || !m { + logger.Errorf("not allowed to use '%s:%s'", proto, name) + return nil + } + filename := path.Join(n.path, name+".json") + file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + logger.Errorf("could not open file: %s", err.Error()) + return nil + } + n.files[name] = file + return file +} + +func (n *Notifier) Send(e *log.Entry, to *database.Notify) bool { + if to.Protocol != proto { + return false + } + byteText, err := n.formatter.Format(e) + if err != nil { + return false + } + text := to.RunReplace(string(byteText)) + file := n.getFile(to.To) + if file == nil { + return false + } + _, err = file.WriteString(text) + return err == nil +} + +func init() { + notify.AddNotifier(Init) +} diff --git a/notify/websocket/main.go b/notify/websocket/main.go index d864d1a..6d917d1 100644 --- a/notify/websocket/main.go +++ b/notify/websocket/main.go @@ -66,9 +66,17 @@ func (n *Notifier) Send(e *log.Entry, to *database.Notify) bool { if to.Protocol != proto { return false } + n.ws.SendAll(&websocket.Message{ Subject: to.Address(), - Body: e, + Body: &log.Entry{ + Buffer: e.Buffer, + Data: e.Data, + Level: e.Level, + Logger: e.Logger, + Message: to.RunReplace(e.Message), + Time: e.Time, + }, }) return true } diff --git a/webroot/js/view/log.js b/webroot/js/view/log.js index 99f79cc..fd66921 100644 --- a/webroot/js/view/log.js +++ b/webroot/js/view/log.js @@ -11,7 +11,7 @@ function levelToColor (lvl) { function addItem (el, msg) { const div = domlib.newAt(el, 'div', { - 'class': levelToColor(msg.Leve) + 'class': levelToColor(msg.Level) }); domlib.newAt(div, 'span', null, msg.Data.hostname); domlib.newAt(div, 'span', null, msg.Message); @@ -24,13 +24,6 @@ class LogView extends View { if (!this.init) { this.init = true; } - - /* - * Domlib.newAt(this.el, 'h2', {'class': 'ui header'}, 'Log'); - * for (const msg in store.channel.ffhb) { - * domlib.newAt(this.el, 'div', null, msg.Data.hostname, msg); - *} - */ }