From f94f35c657e861b2e059bc869c102c89ea2fcdc4 Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Fri, 16 Jun 2017 10:33:35 +0200 Subject: [PATCH] [TASK] add notify to xmpp --- api/receive/main.go | 13 +++++++++--- api/recieve/main_test.go | 1 - cmd/logmania/main.go | 8 ++++++- database/entry.go | 3 ++- database/user.go | 6 ++++++ lib/config.go | 28 +++++++++++++------------ log/logger.go | 4 +++- notify/all/internal.go | 39 ++++++++++++++++++++++++++++++++++ notify/all/main.go | 5 +++++ notify/main.go | 22 ++++++++++++++++++++ notify/xmpp/internal.go | 7 +++++++ notify/xmpp/main.go | 45 ++++++++++++++++++++++++++++++++++++++++ 12 files changed, 161 insertions(+), 20 deletions(-) delete mode 100644 api/recieve/main_test.go create mode 100644 notify/all/internal.go create mode 100644 notify/all/main.go create mode 100644 notify/main.go create mode 100644 notify/xmpp/internal.go create mode 100644 notify/xmpp/main.go diff --git a/api/receive/main.go b/api/receive/main.go index 5327310..c8ec475 100644 --- a/api/receive/main.go +++ b/api/receive/main.go @@ -5,21 +5,25 @@ import ( "encoding/json" "net/http" + "github.com/gorilla/websocket" + "github.com/genofire/logmania/database" "github.com/genofire/logmania/log" - "github.com/gorilla/websocket" + "github.com/genofire/logmania/notify" ) // http.Handler for init network type Handler struct { http.Handler upgrader websocket.Upgrader + Notify notify.Notifier } // init new Handler -func NewHandler() *Handler { +func NewHandler(notifyHandler notify.Notifier) *Handler { return &Handler{ upgrader: websocket.Upgrader{}, + Notify: notifyHandler, } } @@ -72,6 +76,9 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { logEntry.Error("umarshal log entry:", err) break } - database.InsertEntry(token, &entry) + dbEntry := database.InsertEntry(token, &entry) + if dbEntry != nil && h.Notify != nil { + h.Notify.Send(dbEntry) + } } } diff --git a/api/recieve/main_test.go b/api/recieve/main_test.go deleted file mode 100644 index 3ccae50..0000000 --- a/api/recieve/main_test.go +++ /dev/null @@ -1 +0,0 @@ -package receive diff --git a/cmd/logmania/main.go b/cmd/logmania/main.go index 074f0a4..1b90cca 100644 --- a/cmd/logmania/main.go +++ b/cmd/logmania/main.go @@ -20,6 +20,8 @@ import ( "github.com/genofire/logmania/lib" "github.com/genofire/logmania/log" logOutput "github.com/genofire/logmania/log/hook/output" + "github.com/genofire/logmania/notify" + "github.com/genofire/logmania/notify/all" ) var ( @@ -27,6 +29,7 @@ var ( config *lib.Config api *lib.HTTPServer apiNoPanic *bool + notifier notify.Notifier debug bool ) @@ -51,9 +54,11 @@ func main() { database.Connect(config.Database.Type, config.Database.Connect) log.AddLogger("selflogger", logger) + notifier = all.NotifyInit(&config.Notify) + api = &lib.HTTPServer{ Addr: config.API.Bind, - Handler: receive.NewHandler(), + Handler: receive.NewHandler(notifier), } api.Start() @@ -76,6 +81,7 @@ func main() { } func quit() { + notifier.Close() log.Info("quit of logmania") os.Exit(0) } diff --git a/database/entry.go b/database/entry.go index 889cdb4..a8ba6fc 100644 --- a/database/entry.go +++ b/database/entry.go @@ -28,7 +28,7 @@ func transformToDB(dbEntry *log.Entry) *Entry { } } -func InsertEntry(token string, entryLog *log.Entry) { +func InsertEntry(token string, entryLog *log.Entry) *Entry { app := Application{} db.Where("token = ?", token).First(&app) entry := transformToDB(entryLog) @@ -38,4 +38,5 @@ func InsertEntry(token string, entryLog *log.Entry) { if result.Error != nil { log.Error("saving log entry to database", result.Error) } + return entry } diff --git a/database/user.go b/database/user.go index aeabb8e..7712d1b 100644 --- a/database/user.go +++ b/database/user.go @@ -12,3 +12,9 @@ type User struct { NotifyAfterLoglevel log.LogLevel Permissions []Application `gorm:"many2many:user_permissions;"` } + +func UserByApplication(id int) []*User { + var users []*User + db.Model(&Application{ID: id}).Related(&users) + return users +} diff --git a/lib/config.go b/lib/config.go index c7e8961..efbdbaa 100644 --- a/lib/config.go +++ b/lib/config.go @@ -14,19 +14,7 @@ type Config struct { Bind string `toml:"bind"` Interactive bool `toml:"interactive"` } `toml:"api"` - Notify struct { - XMPP struct { - Host string `toml:"host"` - Username string `toml:"username"` - Password string `toml:"password"` - Debug bool `toml:"debug"` - NoTLS bool `toml:"no_tls"` - Session bool `toml:"session"` - Status string `toml:"status"` - StatusMessage string `toml:"status_message"` - StartupNotify string `toml:"startup_notify"` - } `toml:"xmpp"` - } `toml:"notify"` + Notify NotifyConfig `toml:"notify"` Database struct { Type string `toml:"type"` Connect string `toml:"connect"` @@ -37,6 +25,20 @@ type Config struct { } `toml:"webserver"` } +type NotifyConfig struct { + XMPP struct { + Host string `toml:"host"` + Username string `toml:"username"` + Password string `toml:"password"` + Debug bool `toml:"debug"` + NoTLS bool `toml:"no_tls"` + Session bool `toml:"session"` + Status string `toml:"status"` + StatusMessage string `toml:"status_message"` + StartupNotify string `toml:"startup_notify"` + } `toml:"xmpp"` +} + // read configuration from a file (use toml as file-format) func ReadConfig(path string) (*Config, error) { log.Debugf("load of configfile: %s", path) diff --git a/log/logger.go b/log/logger.go index 7094676..006a525 100644 --- a/log/logger.go +++ b/log/logger.go @@ -10,7 +10,9 @@ var loggers = make(map[string]Logger) // bind logger to handle saving/output of a Log entry func AddLogger(name string, logger Logger) { - loggers[name] = logger + if logger != nil { + loggers[name] = logger + } } func RemoveLogger(name string) { loggers[name].Close() diff --git a/notify/all/internal.go b/notify/all/internal.go new file mode 100644 index 0000000..8b7c994 --- /dev/null +++ b/notify/all/internal.go @@ -0,0 +1,39 @@ +package all + +import ( + "github.com/genofire/logmania/database" + "github.com/genofire/logmania/lib" + "github.com/genofire/logmania/notify" +) + +type Notifier struct { + notify.Notifier + list []notify.Notifier +} + +func NotifyInit(config *lib.NotifyConfig) notify.Notifier { + var list []notify.Notifier + for _, init := range notify.NotifyRegister { + notify := init(config) + + if notify == nil { + continue + } + list = append(list, notify) + } + return &Notifier{ + list: list, + } +} + +func (n *Notifier) Send(entry *database.Entry) { + for _, item := range n.list { + item.Send(entry) + } +} + +func (n *Notifier) Close() { + for _, item := range n.list { + item.Close() + } +} diff --git a/notify/all/main.go b/notify/all/main.go new file mode 100644 index 0000000..0c3dec8 --- /dev/null +++ b/notify/all/main.go @@ -0,0 +1,5 @@ +package all + +import ( + _ "github.com/genofire/logmania/notify/xmpp" +) diff --git a/notify/main.go b/notify/main.go new file mode 100644 index 0000000..10af8b0 --- /dev/null +++ b/notify/main.go @@ -0,0 +1,22 @@ +package notify + +import ( + "github.com/genofire/logmania/database" + "github.com/genofire/logmania/lib" +) + +var NotifyRegister []NotifyInit + +type Notifier interface { + Send(entry *database.Entry) + Close() +} + +type NotifyInit func(*lib.NotifyConfig) Notifier + +func AddNotifier(n NotifyInit) { + NotifyRegister = append(NotifyRegister, n) +} + +func Start(config *lib.NotifyConfig) { +} diff --git a/notify/xmpp/internal.go b/notify/xmpp/internal.go new file mode 100644 index 0000000..d17321e --- /dev/null +++ b/notify/xmpp/internal.go @@ -0,0 +1,7 @@ +package xmpp + +import "github.com/genofire/logmania/database" + +func FormatEntry(e *database.Entry) string { + return e.Text +} diff --git a/notify/xmpp/main.go b/notify/xmpp/main.go new file mode 100644 index 0000000..be90700 --- /dev/null +++ b/notify/xmpp/main.go @@ -0,0 +1,45 @@ +package xmpp + +import ( + "github.com/genofire/logmania/database" + "github.com/genofire/logmania/lib" + "github.com/genofire/logmania/log" + "github.com/genofire/logmania/notify" + xmpp "github.com/mattn/go-xmpp" +) + +type Notifier struct { + notify.Notifier + client *xmpp.Client +} + +func NotifyInit(config *lib.NotifyConfig) notify.Notifier { + options := xmpp.Options{ + Host: config.XMPP.Host, + User: config.XMPP.Username, + Password: config.XMPP.Password, + NoTLS: config.XMPP.NoTLS, + Debug: config.XMPP.Debug, + Session: config.XMPP.Session, + Status: config.XMPP.Status, + StatusMessage: config.XMPP.StatusMessage, + } + client, err := options.NewClient() + if err != nil { + return nil + } + return &Notifier{client: client} +} + +func (n *Notifier) Send(e *database.Entry) { + users := database.UserByApplication(e.ApplicationID) + for _, user := range users { + if user.NotifyXMPP && user.NotifyAfterLoglevel <= log.LogLevel(e.Level) { + n.client.SendHtml(xmpp.Chat{Remote: user.XMPP, Type: "chat", Text: FormatEntry(e)}) + } + } +} + +func init() { + notify.AddNotifier(NotifyInit) +}