diff --git a/bot/priority.go b/bot/priority.go index 6cdff58..91473af 100644 --- a/bot/priority.go +++ b/bot/priority.go @@ -41,7 +41,7 @@ func NewPriority(db *database.DB) *Command { n.MaxPrioIn = max - return fmt.Sprintf("set filter for %s to %d", to, max) + return fmt.Sprintf("set filter for %s to %s", to, log.LevelString(max)) }, }, { @@ -50,7 +50,7 @@ func NewPriority(db *database.DB) *Command { Action: func(from string, params []string) string { msg := "priority: \n" for _, n := range db.Notifies { - msg = fmt.Sprintf("%s%s - %d\n", msg, n.Address(), n.MaxPrioIn) + msg = fmt.Sprintf("%s%s - %s\n", msg, n.Address(), log.LevelString(n.MaxPrioIn)) } return msg }, @@ -65,7 +65,7 @@ func NewPriority(db *database.DB) *Command { of := params[0] msg := "priority: \n" if notify, ok := db.NotifiesByAddress[of]; ok { - msg = fmt.Sprintf("%s %s is %d", msg, of, notify.MaxPrioIn) + msg = fmt.Sprintf("%s %s is %s", msg, of, log.LevelString(notify.MaxPrioIn)) } return msg }, @@ -74,7 +74,7 @@ func NewPriority(db *database.DB) *Command { Action: func(from string, params []string) string { msg := "priority: \n" if notify, ok := db.NotifiesByAddress[from]; ok { - msg = fmt.Sprintf("%s %s is %d", msg, from, notify.MaxPrioIn) + msg = fmt.Sprintf("%s %s is %s", msg, from, log.LevelString(notify.MaxPrioIn)) } return msg }, diff --git a/output/xmpp/format.go b/output/xmpp/format.go new file mode 100644 index 0000000..5cf81af --- /dev/null +++ b/output/xmpp/format.go @@ -0,0 +1,126 @@ +package xmpp + +import ( + "bytes" + "fmt" + "text/template" + + "github.com/bdlm/log" +) + +var tempLog = template.Must(template.New("log").Parse( + "{{$color := .Color}}" + + // Hostname + "{{ if .Hostname }}{{ .Hostname}}{{ end }}" + + // Level + "{{printf \" %5s\" .Level}}" + + // Message + "{{printf \" %s\" .Message}}" + + // Data + "{{if .Data}}{{range $k, $v := .Data}}" + + "{{printf \" %s\" $k}}" + + "=" + + "{{$v}}" + + "{{end}}{{end}}" + + "", +)) + +var ( + // DEFAULTColor is the default html 'level' color. + DEFAULTColor = "#00ff00" + // ERRORColor is the html 'level' color for error messages. + ERRORColor = "#ff8700" + // FATALColor is the html 'level' color for fatal messages. + FATALColor = "#af0000" + // PANICColor is the html 'level' color for panic messages. + PANICColor = "#ff0000" + // WARNColor is the html 'level' color for warning messages. + WARNColor = "#ffff00" + // DEBUGColor is the html 'level' color for debug messages. + DEBUGColor = "#8a8a8a" + + // DataLabelColor is the html data label color. + DataLabelColor = "#87afff" + // DataValueColor is the html data value color. + DataValueColor = "#d7af87" + // HostnameColor is the html hostname color. + HostnameColor = "#00afff" + // TimestampColor is the html timestamp color. + TimestampColor = "#5faf87" +) + +type logData struct { + Color colors `json:"-"` + Data map[string]interface{} `json:"data,omitempty"` + Hostname string `json:"host,omitempty"` + Level string `json:"level,omitempty"` + Message string `json:"msg,omitempty"` + Timestamp string `json:"time,omitempty"` +} + +type colors struct { + DataLabel string + DataValue string + Hostname string + Level string + Reset string + Timestamp string +} + +func formatLog(entry *log.Entry) (string, string) { + var levelColor string + + var logLine *bytes.Buffer + if entry.Buffer != nil { + logLine = entry.Buffer + } else { + logLine = &bytes.Buffer{} + } + + data := &logData{ + Data: make(map[string]interface{}), + Level: log.LevelString(entry.Level), + Message: entry.Message, + Timestamp: entry.Time.Format(log.RFC3339Milli), + } + switch entry.Level { + case log.DebugLevel: + levelColor = DEBUGColor + case log.WarnLevel: + levelColor = WARNColor + case log.ErrorLevel: + levelColor = ERRORColor + case log.FatalLevel: + levelColor = FATALColor + case log.PanicLevel: + levelColor = PANICColor + default: + levelColor = DEFAULTColor + } + data.Color = colors{ + DataLabel: DataLabelColor, + DataValue: DataValueColor, + Hostname: HostnameColor, + Level: levelColor, + Timestamp: TimestampColor, + } + + for k, v := range entry.Data { + if k == "hostname" { + if data.Hostname == "" { + data.Hostname = v.(string) + } + continue + } + if str, ok := v.(string); ok { + data.Data[k] = "'" + str + "'" + } else { + data.Data[k] = v + } + } + + if err := tempLog.Execute(logLine, data); err != nil { + return "formating error", "formating error" + } + return logLine.String(), fmt.Sprintf("%s> %s: %s", data.Hostname, log.LevelString(entry.Level), entry.Message) +} diff --git a/output/xmpp/main.go b/output/xmpp/main.go index 7583b62..551b9e9 100644 --- a/output/xmpp/main.go +++ b/output/xmpp/main.go @@ -1,6 +1,7 @@ package xmpp import ( + "encoding/xml" "regexp" "strings" @@ -56,15 +57,8 @@ func Init(configInterface interface{}, db *database.DB, bot *bot.Bot) output.Out return nil } go func() { - for { - if err := client.Start(); err != nil { - log.Warn("close connection, try reconnect") - client.Connect(config.Password) - } else { - log.Warn("closed connection") - return - } - } + client.Start() + log.Panic("closed connection") }() go func() { for { @@ -190,12 +184,17 @@ func (out *Output) Default() []*database.Notify { } func (out *Output) Send(e *log.Entry, to *database.Notify) bool { - textByte, err := out.formatter.Format(e) - if err != nil { - logger.Error("during format notify", err) + html, text := formatLog(e) + if html == "" || text == "" { + logger.Error("during format notify") return false } - text := strings.TrimRight(to.RunReplace(string(textByte)), "\n") + html = strings.TrimRight(to.RunReplace(html), "\n") + var body xmpp.XMLElement + xml.Unmarshal([]byte(html), &body) + + text = strings.TrimRight(to.RunReplace(text), "\n") + if to.Protocol == protoGroup { if _, ok := out.channels[to.To]; ok { toJID := xmppbase.NewJID(to.To) @@ -214,23 +213,23 @@ func (out *Output) Send(e *log.Entry, to *database.Notify) bool { out.channels[to.To] = true } } - err := out.client.Send(&xmpp.MessageClient{ + if err := out.client.Send(&xmpp.MessageClient{ Type: xmpp.MessageTypeGroupchat, To: xmppbase.NewJID(to.To), Body: text, - }) - if err != nil { + HTML: &xmpp.HTML{Body: xmpp.HTMLBody{Body: body}}, + }); err != nil { logger.Error("xmpp to ", to.To, " error:", err) } return true } if to.Protocol == proto { - err := out.client.Send(&xmpp.MessageClient{ + if err := out.client.Send(&xmpp.MessageClient{ Type: xmpp.MessageTypeChat, To: xmppbase.NewJID(to.To), Body: text, - }) - if err != nil { + HTML: &xmpp.HTML{Body: xmpp.HTMLBody{Body: body}}, + }); err != nil { logger.Error("xmpp to ", to, " error:", err) } return true