switch architectur
This commit is contained in:
parent
a0b30e6a9c
commit
992c0eaf02
|
@ -1,92 +0,0 @@
|
||||||
// receiver of log entry over network (websocket)
|
|
||||||
package receive
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
|
|
||||||
"github.com/genofire/logmania/database"
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
"github.com/genofire/logmania/notify"
|
|
||||||
|
|
||||||
logOutput "github.com/genofire/logmania/log/hook/output"
|
|
||||||
)
|
|
||||||
|
|
||||||
// http.Handler for init network
|
|
||||||
type Handler struct {
|
|
||||||
http.Handler
|
|
||||||
upgrader websocket.Upgrader
|
|
||||||
Notify notify.Notifier
|
|
||||||
}
|
|
||||||
|
|
||||||
// init new Handler
|
|
||||||
func NewHandler(notifyHandler notify.Notifier) *Handler {
|
|
||||||
return &Handler{
|
|
||||||
upgrader: websocket.Upgrader{},
|
|
||||||
Notify: notifyHandler,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// server response of handler
|
|
||||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
logEntry := log.HTTP(r)
|
|
||||||
c, err := h.upgrader.Upgrade(w, r, nil)
|
|
||||||
if err != nil {
|
|
||||||
logEntry.Warn("no webservice upgrade:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
token := ""
|
|
||||||
defer c.Close()
|
|
||||||
for {
|
|
||||||
if token == "" {
|
|
||||||
var maybeToken string
|
|
||||||
msgType, msg, err := c.ReadMessage()
|
|
||||||
if err != nil {
|
|
||||||
logEntry.Error("receiving token", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if msgType != websocket.TextMessage {
|
|
||||||
logEntry.Warn("receive no token")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
maybeToken = string(msg)
|
|
||||||
logEntry.AddField("token", maybeToken)
|
|
||||||
if !database.IsTokenValid(maybeToken) {
|
|
||||||
logEntry.Warn("receive wrong token")
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
token = maybeToken
|
|
||||||
logEntry.Info("receive valid token")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var entry log.Entry
|
|
||||||
msgType, msg, err := c.ReadMessage()
|
|
||||||
if msgType == -1 {
|
|
||||||
c.Close()
|
|
||||||
logEntry.Info("connecting closed")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
logEntry.Error("receiving log entry:", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(msg, &entry)
|
|
||||||
if err != nil {
|
|
||||||
logEntry.Error("umarshal log entry:", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
dbEntry := database.InsertEntry(token, &entry)
|
|
||||||
if dbEntry != nil && h.Notify != nil {
|
|
||||||
h.Notify.Send(dbEntry)
|
|
||||||
} else {
|
|
||||||
l := logOutput.NewLogger()
|
|
||||||
e := log.New()
|
|
||||||
e.Text = "No notifier found"
|
|
||||||
e.Level = log.WarnLevel
|
|
||||||
l.Hook(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package receive
|
|
|
@ -15,34 +15,25 @@ import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/genofire/logmania/api/receive"
|
|
||||||
"github.com/genofire/logmania/database"
|
|
||||||
"github.com/genofire/logmania/lib"
|
"github.com/genofire/logmania/lib"
|
||||||
"github.com/genofire/logmania/log"
|
log "github.com/genofire/logmania/log"
|
||||||
logOutput "github.com/genofire/logmania/log/hook/output"
|
|
||||||
"github.com/genofire/logmania/notify"
|
"github.com/genofire/logmania/notify"
|
||||||
"github.com/genofire/logmania/notify/all"
|
allNotify "github.com/genofire/logmania/notify/all"
|
||||||
|
"github.com/genofire/logmania/receive"
|
||||||
|
allReceiver "github.com/genofire/logmania/receive/all"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configPath string
|
configPath string
|
||||||
config *lib.Config
|
config *lib.Config
|
||||||
api *lib.HTTPServer
|
|
||||||
apiNoPanic *bool
|
|
||||||
notifier notify.Notifier
|
notifier notify.Notifier
|
||||||
debug bool
|
receiver receive.Receiver
|
||||||
|
logChannel chan *log.Entry
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.StringVar(&configPath, "config", "logmania.conf", "config file")
|
flag.StringVar(&configPath, "config", "logmania.conf", "config file")
|
||||||
flag.BoolVar(&debug, "debug", false, "enable debuging")
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
logger := NewSelfLogger()
|
|
||||||
|
|
||||||
if debug {
|
|
||||||
logger.AboveLevel = log.DebugLevel
|
|
||||||
logOutput.AboveLevel = log.DebugLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("starting logmania")
|
log.Info("starting logmania")
|
||||||
|
|
||||||
|
@ -51,16 +42,17 @@ func main() {
|
||||||
log.Panicf("Could not load '%s' for configuration.", configPath)
|
log.Panicf("Could not load '%s' for configuration.", configPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
database.Connect(config.Database.Type, config.Database.Connect)
|
notifier = allNotify.Init(&config.Notify)
|
||||||
log.AddLogger("selflogger", logger)
|
log.Save = notifier.Send
|
||||||
|
go func() {
|
||||||
|
for a := range logChannel {
|
||||||
|
notifier.Send(a)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
notifier = all.NotifyInit(&config.Notify)
|
receiver = allReceiver.Init(&config.Receive, logChannel)
|
||||||
|
|
||||||
api = &lib.HTTPServer{
|
go receiver.Listen()
|
||||||
Addr: config.API.Bind,
|
|
||||||
Handler: receive.NewHandler(notifier),
|
|
||||||
}
|
|
||||||
api.Start()
|
|
||||||
|
|
||||||
// Wait for system signal
|
// Wait for system signal
|
||||||
sigchan := make(chan os.Signal, 1)
|
sigchan := make(chan os.Signal, 1)
|
||||||
|
@ -68,7 +60,7 @@ func main() {
|
||||||
for sig := range sigchan {
|
for sig := range sigchan {
|
||||||
switch sig {
|
switch sig {
|
||||||
case syscall.SIGTERM:
|
case syscall.SIGTERM:
|
||||||
log.Warn("terminated of logmania")
|
log.Panic("terminated of logmania")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
case syscall.SIGQUIT:
|
case syscall.SIGQUIT:
|
||||||
quit()
|
quit()
|
||||||
|
@ -81,6 +73,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func quit() {
|
func quit() {
|
||||||
|
receiver.Close()
|
||||||
notifier.Close()
|
notifier.Close()
|
||||||
log.Info("quit of logmania")
|
log.Info("quit of logmania")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
@ -93,10 +86,10 @@ func reload() {
|
||||||
log.Errorf("reload: could not load '%s' for new configuration. Skip reload.", configPath)
|
log.Errorf("reload: could not load '%s' for new configuration. Skip reload.", configPath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if api.Rebind(config.API.Bind) {
|
receiver.Close()
|
||||||
log.Info("reload: new api bind")
|
receiver = allReceiver.Init(&config.Receive, logChannel)
|
||||||
}
|
go receiver.Listen()
|
||||||
if database.ReplaceConnect(config.Database.Type, config.Database.Connect) {
|
|
||||||
log.Info("reload: new database connection establish")
|
notifier.Close()
|
||||||
}
|
notifier = allNotify.Init(&config.Notify)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/genofire/logmania/database"
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
|
|
||||||
logOutput "github.com/genofire/logmania/log/hook/output"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SelfLogger struct {
|
|
||||||
log.Logger
|
|
||||||
AboveLevel log.LogLevel
|
|
||||||
lastMsg string
|
|
||||||
lastTime int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSelfLogger() *SelfLogger {
|
|
||||||
return &SelfLogger{
|
|
||||||
AboveLevel: log.InfoLevel,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *SelfLogger) Hook(e *log.Entry) {
|
|
||||||
if e.Level >= l.AboveLevel {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO strange logger
|
|
||||||
if l.lastTime > 15 {
|
|
||||||
panic("selflogger same log to oftern")
|
|
||||||
}
|
|
||||||
if l.lastMsg == e.Text {
|
|
||||||
l.lastTime += 1
|
|
||||||
} else {
|
|
||||||
l.lastMsg = e.Text
|
|
||||||
l.lastTime = 1
|
|
||||||
}
|
|
||||||
dbEntry := database.InsertEntry("", e)
|
|
||||||
if dbEntry != nil && notifier != nil {
|
|
||||||
notifier.Send(dbEntry)
|
|
||||||
} else {
|
|
||||||
l := logOutput.NewLogger()
|
|
||||||
e := log.New()
|
|
||||||
e.Text = "No notifier found"
|
|
||||||
e.Level = log.WarnLevel
|
|
||||||
l.Hook(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *SelfLogger) Close() {
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
type Application struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
//Entries []*Entry `json:"entries" gorm:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsTokenValid(token string) bool {
|
|
||||||
result := db.Where("token = ?", token).First(&Application{})
|
|
||||||
return !result.RecordNotFound()
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/jinzhu/gorm"
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
dbType, connect string
|
|
||||||
db *gorm.DB
|
|
||||||
)
|
|
||||||
|
|
||||||
func Connect(initDBType, initConnect string) {
|
|
||||||
var err error
|
|
||||||
db, err = gorm.Open(initDBType, initConnect)
|
|
||||||
if err != nil {
|
|
||||||
log.Panic("failed to connect to database", err)
|
|
||||||
}
|
|
||||||
bootstrap()
|
|
||||||
dbType = initDBType
|
|
||||||
connect = initConnect
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReplaceConnect(initDBType, initConnect string) bool {
|
|
||||||
if dbType == initDBType && connect == initConnect {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
dbTemp, err := gorm.Open(initDBType, initConnect)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to setup new database connection", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
err = db.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to close old database connection", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
db = dbTemp
|
|
||||||
bootstrap()
|
|
||||||
dbType = initDBType
|
|
||||||
connect = initConnect
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func bootstrap() {
|
|
||||||
|
|
||||||
var user User
|
|
||||||
var app Application
|
|
||||||
db.AutoMigrate(&user)
|
|
||||||
db.AutoMigrate(&app)
|
|
||||||
db.AutoMigrate(&Entry{})
|
|
||||||
if resultUser := db.First(&user); resultUser.RecordNotFound() {
|
|
||||||
user.Name = "root"
|
|
||||||
if resultApp := db.First(app); resultApp.RecordNotFound() {
|
|
||||||
app.Name = "TestSoftware"
|
|
||||||
app.Token = "example"
|
|
||||||
db.Create(&app)
|
|
||||||
user.Permissions = []Application{app}
|
|
||||||
}
|
|
||||||
db.Create(&user)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package database
|
|
|
@ -1,42 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Entry struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Time time.Time
|
|
||||||
ApplicationID int
|
|
||||||
Fields string `sql:"type:json"`
|
|
||||||
Text string
|
|
||||||
Level int
|
|
||||||
}
|
|
||||||
|
|
||||||
func transformToDB(dbEntry *log.Entry) *Entry {
|
|
||||||
jsonData, err := json.Marshal(dbEntry.Fields)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &Entry{
|
|
||||||
Level: int(dbEntry.Level),
|
|
||||||
Text: dbEntry.Text,
|
|
||||||
Fields: string(jsonData),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InsertEntry(token string, entryLog *log.Entry) *Entry {
|
|
||||||
app := Application{}
|
|
||||||
db.Where("token = ?", token).First(&app)
|
|
||||||
entry := transformToDB(entryLog)
|
|
||||||
entry.Time = time.Now()
|
|
||||||
entry.ApplicationID = app.ID
|
|
||||||
result := db.Create(&entry)
|
|
||||||
if result.Error != nil {
|
|
||||||
log.Error("saving log entry to database", result.Error)
|
|
||||||
}
|
|
||||||
return entry
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import "github.com/genofire/logmania/log"
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string
|
|
||||||
Mail string
|
|
||||||
XMPP string
|
|
||||||
NotifyMail bool
|
|
||||||
NotifyXMPP bool
|
|
||||||
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
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
logClient "github.com/genofire/logmania/log/hook/client"
|
|
||||||
logOutput "github.com/genofire/logmania/log/hook/output"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
logClient.Init("ws://localhost:8081", "example", log.DebugLevel)
|
|
||||||
log.Info("startup")
|
|
||||||
log.New().AddField("answer", 42).AddFields(map[string]interface{}{"answer": 3, "foo": "bar"}).Warn("Some spezial")
|
|
||||||
log.Debug("Never shown up")
|
|
||||||
logOutput.ShowTime = false
|
|
||||||
logOutput.AboveLevel = log.DebugLevel
|
|
||||||
log.Debugf("Startup %v", time.Now())
|
|
||||||
logOutput.ShowTime = true
|
|
||||||
log.Panic("let it crash")
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
logOutput "github.com/genofire/logmania/log/hook/output"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.Info("startup")
|
|
||||||
log.New().AddField("answer", 42).AddFields(map[string]interface{}{"answer": 3, "foo": "bar"}).Warn("Some spezial")
|
|
||||||
log.Debug("Never shown up")
|
|
||||||
logOutput.ShowTime = false
|
|
||||||
logOutput.AboveLevel = log.DebugLevel
|
|
||||||
log.Debugf("Startup %v", time.Now())
|
|
||||||
logOutput.ShowTime = true
|
|
||||||
log.Panic("let it crash")
|
|
||||||
}
|
|
|
@ -4,25 +4,15 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
"github.com/genofire/logmania/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Struct of the configuration
|
// Struct of the configuration
|
||||||
// e.g. under github.com/genofire/logmania/logmania_example.conf
|
// e.g. under github.com/genofire/logmania/logmania_example.conf
|
||||||
type Config struct {
|
type Config struct {
|
||||||
API struct {
|
Notify NotifyConfig `toml:"notify"`
|
||||||
Bind string `toml:"bind"`
|
Receive ReceiveConfig `toml:"receive"`
|
||||||
Interactive bool `toml:"interactive"`
|
|
||||||
} `toml:"api"`
|
|
||||||
Notify NotifyConfig `toml:"notify"`
|
|
||||||
Database struct {
|
|
||||||
Type string `toml:"type"`
|
|
||||||
Connect string `toml:"connect"`
|
|
||||||
} `toml:"database"`
|
|
||||||
Webserver struct {
|
|
||||||
Enable bool `toml:"enable"`
|
|
||||||
Bind string `toml:"bind"`
|
|
||||||
} `toml:"webserver"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotifyConfig struct {
|
type NotifyConfig struct {
|
||||||
|
@ -37,11 +27,19 @@ type NotifyConfig struct {
|
||||||
StatusMessage string `toml:"status_message"`
|
StatusMessage string `toml:"status_message"`
|
||||||
StartupNotify string `toml:"startup_notify"`
|
StartupNotify string `toml:"startup_notify"`
|
||||||
} `toml:"xmpp"`
|
} `toml:"xmpp"`
|
||||||
|
IRC struct {
|
||||||
|
} `toml:"irc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReceiveConfig struct {
|
||||||
|
Syslog struct {
|
||||||
|
Bind string `toml:"bind"`
|
||||||
|
} `toml:"syslog"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// read configuration from a file (use toml as file-format)
|
// read configuration from a file (use toml as file-format)
|
||||||
func ReadConfig(path string) (*Config, error) {
|
func ReadConfig(path string) (*Config, error) {
|
||||||
log.Debugf("load of configfile: %s", path)
|
log.Infof("load of configfile: %s", path)
|
||||||
var config Config
|
var config Config
|
||||||
file, _ := ioutil.ReadFile(path)
|
file, _ := ioutil.ReadFile(path)
|
||||||
err := toml.Unmarshal(file, &config)
|
err := toml.Unmarshal(file, &config)
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// some little goodies for logmania
|
|
||||||
package lib
|
|
56
lib/http.go
56
lib/http.go
|
@ -1,56 +0,0 @@
|
||||||
package lib
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// little httpserver to handle reconnect and http.Handlers
|
|
||||||
type HTTPServer struct {
|
|
||||||
srv *http.Server
|
|
||||||
Addr string
|
|
||||||
Handler http.Handler
|
|
||||||
errorNoPanic bool
|
|
||||||
errorNoPanicAsync sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// start httpserver
|
|
||||||
func (hs *HTTPServer) Start() {
|
|
||||||
hs.srv = &http.Server{
|
|
||||||
Addr: hs.Addr,
|
|
||||||
Handler: hs.Handler,
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
log.Debug("startup of http listener")
|
|
||||||
if err := hs.srv.ListenAndServe(); err != nil {
|
|
||||||
if hs.errorNoPanic {
|
|
||||||
log.Debug("httpserver shutdown without panic")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// rebind httpserver to a new address (e.g. new configuration)
|
|
||||||
func (hs *HTTPServer) Rebind(addr string) bool {
|
|
||||||
if addr == hs.Addr {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
hs.errorNoPanicAsync.Lock()
|
|
||||||
hs.errorNoPanic = true
|
|
||||||
hs.Close()
|
|
||||||
hs.Addr = addr
|
|
||||||
hs.Start()
|
|
||||||
hs.errorNoPanic = false
|
|
||||||
hs.errorNoPanicAsync.Unlock()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// close/stop current httpserver
|
|
||||||
func (hs *HTTPServer) Close() {
|
|
||||||
log.Debug("startup of http listener")
|
|
||||||
hs.srv.Close()
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
package log
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestString(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
results := map[LogLevel]string{
|
|
||||||
DebugLevel: "Debug",
|
|
||||||
InfoLevel: "Info",
|
|
||||||
WarnLevel: "Warn",
|
|
||||||
ErrorLevel: "ERROR",
|
|
||||||
PanicLevel: "PANIC",
|
|
||||||
LogLevel(-2): "NOT VALID",
|
|
||||||
}
|
|
||||||
|
|
||||||
for value, expected := range results {
|
|
||||||
assert.Equal(expected, value.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLogLevelFunc(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
results := map[LogLevel]func(...interface{}){
|
|
||||||
DebugLevel: entry.Debug,
|
|
||||||
InfoLevel: entry.Info,
|
|
||||||
WarnLevel: entry.Warn,
|
|
||||||
ErrorLevel: entry.Error,
|
|
||||||
}
|
|
||||||
|
|
||||||
for value, function := range results {
|
|
||||||
function()
|
|
||||||
assert.Equal(value, entry.Level)
|
|
||||||
}
|
|
||||||
assert.Panics(func() {
|
|
||||||
entry.Panic()
|
|
||||||
assert.Equal(PanicLevel, entry.Level)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func TestLogLevelFormatFunc(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
results := map[LogLevel]func(string, ...interface{}){
|
|
||||||
DebugLevel: entry.Debugf,
|
|
||||||
InfoLevel: entry.Infof,
|
|
||||||
WarnLevel: entry.Warnf,
|
|
||||||
ErrorLevel: entry.Errorf,
|
|
||||||
}
|
|
||||||
|
|
||||||
for value, function := range results {
|
|
||||||
function("%.1f", 31.121)
|
|
||||||
assert.Equal(value, entry.Level)
|
|
||||||
assert.Equal("31.1", entry.Text)
|
|
||||||
}
|
|
||||||
assert.Panics(func() {
|
|
||||||
entry.Panicf("")
|
|
||||||
assert.Equal(PanicLevel, entry.Level)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLogLevelInit(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
results := map[LogLevel]func(...interface{}){
|
|
||||||
DebugLevel: Debug,
|
|
||||||
InfoLevel: Info,
|
|
||||||
WarnLevel: Warn,
|
|
||||||
ErrorLevel: Error,
|
|
||||||
}
|
|
||||||
|
|
||||||
for value, function := range results {
|
|
||||||
function()
|
|
||||||
assert.Equal(value, entry.Level)
|
|
||||||
}
|
|
||||||
assert.Panics(func() {
|
|
||||||
Panic()
|
|
||||||
assert.Equal(PanicLevel, entry.Level)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLogLevelInitFormatFunc(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
results := map[LogLevel]func(string, ...interface{}){
|
|
||||||
DebugLevel: Debugf,
|
|
||||||
InfoLevel: Infof,
|
|
||||||
WarnLevel: Warnf,
|
|
||||||
ErrorLevel: Errorf,
|
|
||||||
}
|
|
||||||
|
|
||||||
for value, function := range results {
|
|
||||||
function("%.1f", 31.121)
|
|
||||||
assert.Equal(value, entry.Level)
|
|
||||||
assert.Equal("31.1", entry.Text)
|
|
||||||
}
|
|
||||||
assert.Panics(func() {
|
|
||||||
Panicf("")
|
|
||||||
assert.Equal(PanicLevel, entry.Level)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,32 +1,9 @@
|
||||||
package log
|
package log
|
||||||
|
|
||||||
// interface of a logger
|
type loggerFunc func(*Entry)
|
||||||
type Logger interface {
|
|
||||||
Hook(*Entry)
|
|
||||||
Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
var loggers = make(map[string]Logger)
|
var Save loggerFunc
|
||||||
|
|
||||||
// bind logger to handle saving/output of a Log entry
|
func init() {
|
||||||
func AddLogger(name string, logger Logger) {
|
Save = func(*Entry) {}
|
||||||
if logger != nil {
|
|
||||||
loggers[name] = logger
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func RemoveLogger(name string) {
|
|
||||||
loggers[name].Close()
|
|
||||||
delete(loggers, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func save(e *Entry) {
|
|
||||||
for _, logger := range loggers {
|
|
||||||
logger.Hook(e)
|
|
||||||
}
|
|
||||||
if e.Level == PanicLevel {
|
|
||||||
for _, logger := range loggers {
|
|
||||||
logger.Close()
|
|
||||||
}
|
|
||||||
panic("panic see last log in logmania")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package log
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
var entry *Entry
|
|
||||||
|
|
||||||
type SaveLogger struct {
|
|
||||||
Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*SaveLogger) Hook(e *Entry) {
|
|
||||||
entry = e
|
|
||||||
}
|
|
||||||
func (*SaveLogger) Close() {}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
entry = &Entry{}
|
|
||||||
AddLogger("name", &SaveLogger{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLogger(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
assert.Len(loggers, 1)
|
|
||||||
|
|
||||||
AddLogger("blub", &SaveLogger{})
|
|
||||||
assert.Len(loggers, 2)
|
|
||||||
RemoveLogger("blub")
|
|
||||||
assert.Len(loggers, 1)
|
|
||||||
|
|
||||||
assert.PanicsWithValue("panic see last log in logmania", func() {
|
|
||||||
save(&Entry{Level: PanicLevel})
|
|
||||||
})
|
|
||||||
}
|
|
16
log/main.go
16
log/main.go
|
@ -5,23 +5,25 @@ import "fmt"
|
||||||
|
|
||||||
// a struct with all information of a log entry
|
// a struct with all information of a log entry
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
Level LogLevel `json:"level"`
|
Level LogLevel `json:"level"`
|
||||||
Fields map[string]interface{} `json:"fields"`
|
Hostname string `json:"hostname"`
|
||||||
Text string `json:"text"`
|
Service string `json:"service"`
|
||||||
|
Fields map[string]interface{} `json:"fields"`
|
||||||
|
Text string `json:"text"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// save/out current state of log entry
|
// Save/out current state of log entry
|
||||||
func (e *Entry) Log(level LogLevel, v ...interface{}) {
|
func (e *Entry) Log(level LogLevel, v ...interface{}) {
|
||||||
e.Text = fmt.Sprint(v...)
|
e.Text = fmt.Sprint(v...)
|
||||||
e.Level = level
|
e.Level = level
|
||||||
save(e)
|
Save(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// save/out current state of log entry with formation
|
// Save/out current state of log entry with formation
|
||||||
func (e *Entry) Logf(level LogLevel, format string, v ...interface{}) {
|
func (e *Entry) Logf(level LogLevel, format string, v ...interface{}) {
|
||||||
e.Text = fmt.Sprintf(format, v...)
|
e.Text = fmt.Sprintf(format, v...)
|
||||||
e.Level = level
|
e.Level = level
|
||||||
save(e)
|
Save(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// init new log entry
|
// init new log entry
|
||||||
|
|
|
@ -1,9 +1,2 @@
|
||||||
[api]
|
[receive.syslog]
|
||||||
bind = ":8081"
|
bind = ":10001"
|
||||||
|
|
||||||
[database]
|
|
||||||
type = "sqlite3"
|
|
||||||
connect = "test.db"
|
|
||||||
|
|
||||||
[webserver]
|
|
||||||
enable = true
|
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
package all
|
package all
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/genofire/logmania/database"
|
|
||||||
"github.com/genofire/logmania/lib"
|
"github.com/genofire/logmania/lib"
|
||||||
|
"github.com/genofire/logmania/log"
|
||||||
"github.com/genofire/logmania/notify"
|
"github.com/genofire/logmania/notify"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Notifier struct {
|
type Notifier struct {
|
||||||
notify.Notifier
|
notify.Notifier
|
||||||
list []notify.Notifier
|
list []notify.Notifier
|
||||||
|
channelNotify chan *log.Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
func NotifyInit(config *lib.NotifyConfig) notify.Notifier {
|
func Init(config *lib.NotifyConfig) notify.Notifier {
|
||||||
var list []notify.Notifier
|
var list []notify.Notifier
|
||||||
for _, init := range notify.NotifyRegister {
|
for _, init := range notify.NotifyRegister {
|
||||||
notify := init(config)
|
notify := init(config)
|
||||||
|
@ -21,15 +22,25 @@ func NotifyInit(config *lib.NotifyConfig) notify.Notifier {
|
||||||
}
|
}
|
||||||
list = append(list, notify)
|
list = append(list, notify)
|
||||||
}
|
}
|
||||||
return &Notifier{
|
|
||||||
list: list,
|
n := &Notifier{
|
||||||
|
list: list,
|
||||||
|
channelNotify: make(chan *log.Entry),
|
||||||
|
}
|
||||||
|
go n.sender()
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Notifier) sender() {
|
||||||
|
for c := range n.channelNotify {
|
||||||
|
for _, item := range n.list {
|
||||||
|
item.Send(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notifier) Send(entry *database.Entry) {
|
func (n *Notifier) Send(e *log.Entry) {
|
||||||
for _, item := range n.list {
|
n.channelNotify <- e
|
||||||
go item.Send(entry)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notifier) Close() {
|
func (n *Notifier) Close() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package all
|
package all
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "github.com/genofire/logmania/notify/console"
|
||||||
_ "github.com/genofire/logmania/notify/xmpp"
|
_ "github.com/genofire/logmania/notify/xmpp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// logger to print log entry (with color)
|
package console
|
||||||
// this logger would be bind by importing
|
|
||||||
package output
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -10,48 +8,38 @@ import (
|
||||||
|
|
||||||
"github.com/bclicn/color"
|
"github.com/bclicn/color"
|
||||||
|
|
||||||
|
"github.com/genofire/logmania/lib"
|
||||||
"github.com/genofire/logmania/log"
|
"github.com/genofire/logmania/log"
|
||||||
|
"github.com/genofire/logmania/notify"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TimeFormat = "2006-01-02 15:04:05"
|
errOutput io.Writer = os.Stderr
|
||||||
ShowTime = true
|
output io.Writer = os.Stdout
|
||||||
AboveLevel = log.InfoLevel
|
|
||||||
errOutput io.Writer = os.Stderr
|
|
||||||
output io.Writer = os.Stdout
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// logger for output
|
// logger for output
|
||||||
type Logger struct {
|
type Notifier struct {
|
||||||
log.Logger
|
notify.Notifier
|
||||||
TimeFormat string
|
TimeFormat string
|
||||||
ShowTime bool
|
ShowTime bool
|
||||||
AboveLevel log.LogLevel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentLogger (for override settings e.g. AboveLevel,ShowTime or TimeFormat)
|
func Init(config *lib.NotifyConfig) notify.Notifier {
|
||||||
var CurrentLogger *Logger
|
return &Notifier{
|
||||||
|
|
||||||
// create a new output logger
|
|
||||||
func NewLogger() *Logger {
|
|
||||||
return &Logger{
|
|
||||||
TimeFormat: "2006-01-02 15:04:05",
|
TimeFormat: "2006-01-02 15:04:05",
|
||||||
ShowTime: true,
|
ShowTime: true,
|
||||||
AboveLevel: log.InfoLevel,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle a log entry (print it on the terminal with color)
|
// handle a log entry (print it on the terminal with color)
|
||||||
func (l *Logger) Hook(e *log.Entry) {
|
func (n *Notifier) Send(e *log.Entry) {
|
||||||
if e.Level < AboveLevel {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
v := []interface{}{}
|
v := []interface{}{}
|
||||||
format := "[%s] %s"
|
format := "[%s] %s"
|
||||||
|
|
||||||
if ShowTime {
|
if n.ShowTime {
|
||||||
format = "%s [%s] %s"
|
format = "%s [%s] %s"
|
||||||
v = append(v, color.LightBlue(time.Now().Format(TimeFormat)))
|
v = append(v, color.LightBlue(time.Now().Format(n.TimeFormat)))
|
||||||
}
|
}
|
||||||
lvl := e.Level.String()
|
lvl := e.Level.String()
|
||||||
switch e.Level {
|
switch e.Level {
|
||||||
|
@ -85,11 +73,8 @@ func (l *Logger) Hook(e *log.Entry) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do nothing - terminal did not need something to close
|
func (n *Notifier) Close() {}
|
||||||
func (l *Logger) Close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
CurrentLogger = NewLogger()
|
notify.AddNotifier(Init)
|
||||||
log.AddLogger("output", CurrentLogger)
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package output
|
package console
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -27,14 +27,11 @@ func TestOutput(t *testing.T) {
|
||||||
out, err := captureOutput(func() {
|
out, err := captureOutput(func() {
|
||||||
log.Info("test")
|
log.Info("test")
|
||||||
})
|
})
|
||||||
assert.Regexp("-.*\\[.{5}Info.{4}\\] test", out)
|
|
||||||
assert.Equal("", err)
|
assert.Equal("", err)
|
||||||
|
|
||||||
ShowTime = false
|
|
||||||
out, err = captureOutput(func() {
|
out, err = captureOutput(func() {
|
||||||
log.Warn("test")
|
log.Warn("test")
|
||||||
})
|
})
|
||||||
assert.Regexp("\\[.{5}Warn.{4}\\] test", out)
|
|
||||||
assert.NotRegexp("-.*\\[.{5}Warn.{4}\\] test", out)
|
assert.NotRegexp("-.*\\[.{5}Warn.{4}\\] test", out)
|
||||||
assert.Equal("", err)
|
assert.Equal("", err)
|
||||||
|
|
||||||
|
@ -42,7 +39,6 @@ func TestOutput(t *testing.T) {
|
||||||
log.Error("test")
|
log.Error("test")
|
||||||
})
|
})
|
||||||
assert.Equal("", out)
|
assert.Equal("", out)
|
||||||
assert.Regexp("\\[.{5}ERROR.{4}\\] test", err)
|
|
||||||
|
|
||||||
out, err = captureOutput(func() {
|
out, err = captureOutput(func() {
|
||||||
log.Debug("test")
|
log.Debug("test")
|
||||||
|
@ -50,16 +46,6 @@ func TestOutput(t *testing.T) {
|
||||||
assert.Equal("", out)
|
assert.Equal("", out)
|
||||||
assert.Equal("", err)
|
assert.Equal("", err)
|
||||||
|
|
||||||
AboveLevel = log.DebugLevel
|
|
||||||
|
|
||||||
out, err = captureOutput(func() {
|
|
||||||
log.New().AddField("a", 3).Debug("test")
|
|
||||||
})
|
|
||||||
assert.Regexp("\\[.{5}Debug.{4}\\] test .{8}(a=3)", out)
|
|
||||||
assert.Equal("", err)
|
|
||||||
|
|
||||||
log.RemoveLogger("output")
|
|
||||||
|
|
||||||
out, err = captureOutput(func() {
|
out, err = captureOutput(func() {
|
||||||
log.Info("test")
|
log.Info("test")
|
||||||
})
|
})
|
|
@ -1,14 +1,14 @@
|
||||||
package notify
|
package notify
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/genofire/logmania/database"
|
|
||||||
"github.com/genofire/logmania/lib"
|
"github.com/genofire/logmania/lib"
|
||||||
|
"github.com/genofire/logmania/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var NotifyRegister []NotifyInit
|
var NotifyRegister []NotifyInit
|
||||||
|
|
||||||
type Notifier interface {
|
type Notifier interface {
|
||||||
Send(entry *database.Entry)
|
Send(entry *log.Entry)
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package xmpp
|
package xmpp
|
||||||
|
|
||||||
import "github.com/genofire/logmania/database"
|
import "github.com/genofire/logmania/log"
|
||||||
|
|
||||||
func formatEntry(e *database.Entry) string {
|
func formatEntry(e *log.Entry) string {
|
||||||
return e.Text
|
return e.Text
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package xmpp
|
package xmpp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/genofire/logmania/database"
|
|
||||||
"github.com/genofire/logmania/lib"
|
"github.com/genofire/logmania/lib"
|
||||||
"github.com/genofire/logmania/log"
|
"github.com/genofire/logmania/log"
|
||||||
"github.com/genofire/logmania/notify"
|
"github.com/genofire/logmania/notify"
|
||||||
|
@ -13,7 +12,7 @@ type Notifier struct {
|
||||||
client *xmpp.Client
|
client *xmpp.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NotifyInit(config *lib.NotifyConfig) notify.Notifier {
|
func Init(config *lib.NotifyConfig) notify.Notifier {
|
||||||
options := xmpp.Options{
|
options := xmpp.Options{
|
||||||
Host: config.XMPP.Host,
|
Host: config.XMPP.Host,
|
||||||
User: config.XMPP.Username,
|
User: config.XMPP.Username,
|
||||||
|
@ -31,15 +30,17 @@ func NotifyInit(config *lib.NotifyConfig) notify.Notifier {
|
||||||
return &Notifier{client: client}
|
return &Notifier{client: client}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notifier) Send(e *database.Entry) {
|
func (n *Notifier) Send(e *log.Entry) {
|
||||||
users := database.UserByApplication(e.ApplicationID)
|
/*users :=
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
if user.NotifyXMPP && log.LogLevel(e.Level) >= user.NotifyAfterLoglevel {
|
if user.NotifyXMPP && log.LogLevel(e.Level) >= user.NotifyAfterLoglevel {
|
||||||
n.client.SendHtml(xmpp.Chat{Remote: user.XMPP, Type: "chat", Text: formatEntry(e)})
|
n.client.SendHtml(xmpp.Chat{Remote: user.XMPP, Type: "chat", Text: formatEntry(e)})
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Notifier) Close() {}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
notify.AddNotifier(NotifyInit)
|
notify.AddNotifier(Init)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package all
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/genofire/logmania/lib"
|
||||||
|
"github.com/genofire/logmania/log"
|
||||||
|
"github.com/genofire/logmania/receive"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Receiver struct {
|
||||||
|
receive.Receiver
|
||||||
|
list []receive.Receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init(config *lib.ReceiveConfig, exportChannel chan *log.Entry) receive.Receiver {
|
||||||
|
var list []receive.Receiver
|
||||||
|
for _, init := range receive.Register {
|
||||||
|
receiver := init(config, exportChannel)
|
||||||
|
|
||||||
|
if receiver == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, receiver)
|
||||||
|
}
|
||||||
|
return &Receiver{
|
||||||
|
list: list,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Receiver) Listen() {
|
||||||
|
for _, item := range r.list {
|
||||||
|
go item.Listen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Receiver) Close() {
|
||||||
|
for _, item := range r.list {
|
||||||
|
item.Close()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package all
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/genofire/logmania/receive/syslog"
|
||||||
|
)
|
|
@ -0,0 +1,19 @@
|
||||||
|
package receive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/genofire/logmania/lib"
|
||||||
|
"github.com/genofire/logmania/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Register = make(map[string]ReceiverInit)
|
||||||
|
|
||||||
|
type Receiver interface {
|
||||||
|
Listen()
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReceiverInit func(*lib.ReceiveConfig, chan *log.Entry) Receiver
|
||||||
|
|
||||||
|
func AddReceiver(name string, n ReceiverInit) {
|
||||||
|
Register[name] = n
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package syslog
|
||||||
|
|
||||||
|
import "github.com/genofire/logmania/log"
|
||||||
|
|
||||||
|
var SyslogPriorityMap = map[uint]log.LogLevel{
|
||||||
|
0: log.PanicLevel,
|
||||||
|
1: log.PanicLevel,
|
||||||
|
2: log.PanicLevel,
|
||||||
|
3: log.ErrorLevel,
|
||||||
|
4: log.WarnLevel,
|
||||||
|
5: log.InfoLevel,
|
||||||
|
6: log.InfoLevel,
|
||||||
|
7: log.DebugLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
func toLogEntry(logParts map[string]interface{}) *log.Entry {
|
||||||
|
severityID := uint(logParts["severity"].(int))
|
||||||
|
level := SyslogPriorityMap[severityID]
|
||||||
|
|
||||||
|
if _, ok := logParts["content"]; ok {
|
||||||
|
return &log.Entry{
|
||||||
|
Level: level,
|
||||||
|
Hostname: logParts["hostname"].(string),
|
||||||
|
Service: logParts["tag"].(string),
|
||||||
|
Text: logParts["content"].(string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &log.Entry{
|
||||||
|
Level: level,
|
||||||
|
Hostname: logParts["hostname"].(string),
|
||||||
|
Service: logParts["app_name"].(string),
|
||||||
|
Text: logParts["message"].(string),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package syslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/mcuadros/go-syslog.v2"
|
||||||
|
|
||||||
|
"github.com/genofire/logmania/lib"
|
||||||
|
"github.com/genofire/logmania/log"
|
||||||
|
"github.com/genofire/logmania/receive"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Receiver struct {
|
||||||
|
channel syslog.LogPartsChannel
|
||||||
|
exportChannel chan *log.Entry
|
||||||
|
server *syslog.Server
|
||||||
|
receive.Receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init(config *lib.ReceiveConfig, exportChannel chan *log.Entry) receive.Receiver {
|
||||||
|
channel := make(syslog.LogPartsChannel)
|
||||||
|
handler := syslog.NewChannelHandler(channel)
|
||||||
|
|
||||||
|
server := syslog.NewServer()
|
||||||
|
server.SetFormat(syslog.RFC5424)
|
||||||
|
server.SetHandler(handler)
|
||||||
|
server.ListenUDP(config.Syslog.Bind)
|
||||||
|
|
||||||
|
log.Info("syslog binded to: ", config.Syslog.Bind)
|
||||||
|
|
||||||
|
return &Receiver{
|
||||||
|
channel: channel,
|
||||||
|
server: server,
|
||||||
|
exportChannel: exportChannel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *Receiver) Listen() {
|
||||||
|
rc.server.Boot()
|
||||||
|
log.Info("boot syslog")
|
||||||
|
go func(channel syslog.LogPartsChannel) {
|
||||||
|
for logParts := range channel {
|
||||||
|
rc.exportChannel <- toLogEntry(logParts)
|
||||||
|
}
|
||||||
|
}(rc.channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *Receiver) Close() {
|
||||||
|
rc.server.Kill()
|
||||||
|
rc.server.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
receive.AddReceiver("syslog", Init)
|
||||||
|
}
|
Loading…
Reference in New Issue