[TASK] add journald json with udp

This commit is contained in:
Martin Geno 2017-08-17 21:45:58 +02:00
parent d7ed44e809
commit 5e453e234d
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
7 changed files with 151 additions and 2 deletions

View File

@ -56,7 +56,7 @@ func (b *Bot) sendRemove(answer func(string), from string, params []string) {
if list, ok := b.state.HostTo[host]; ok { if list, ok := b.state.HostTo[host]; ok {
delete(list, to) delete(list, to)
b.state.HostTo[host] = list b.state.HostTo[host] = list
answer(fmt.Sprintf("added %s in list of %s", to, host)) answer(fmt.Sprintf("removed %s in list of %s", to, host))
} else { } else {
answer("not found host") answer("not found host")
} }

View File

@ -18,6 +18,7 @@ type Config struct {
type NotifyConfig struct { type NotifyConfig struct {
StateFile string `toml:"state_file"` StateFile string `toml:"state_file"`
AlertCheck Duration `toml:"alert_check"` AlertCheck Duration `toml:"alert_check"`
Console bool `toml:"debug"`
XMPP struct { XMPP struct {
Host string `toml:"host"` Host string `toml:"host"`
Username string `toml:"username"` Username string `toml:"username"`
@ -38,6 +39,10 @@ type ReceiveConfig struct {
Type string `toml:"type"` Type string `toml:"type"`
Address string `toml:"address"` Address string `toml:"address"`
} `toml:"syslog"` } `toml:"syslog"`
JournaldJSON struct {
Type string `toml:"type"`
Address string `toml:"address"`
} `toml:"journald_json"`
} }
// read configuration from a file (use toml as file-format) // read configuration from a file (use toml as file-format)

View File

@ -1,6 +1,11 @@
[notify] [notify]
state_file = "/tmp/logmania.state.json" state_file = "/tmp/logmania.state.json"
debug = true
[receive.syslog] [receive.syslog]
type = "udp" type = "udp"
address = ":10001" address = ":10001"
[receive.journald_json]
type = "udp"
address = ":10002"

View File

@ -25,18 +25,23 @@ type Notifier struct {
notify.Notifier notify.Notifier
TimeFormat string TimeFormat string
ShowTime bool ShowTime bool
Debug bool
} }
func Init(config *lib.NotifyConfig, state *configNotify.NotifyState, bot *bot.Bot) notify.Notifier { func Init(config *lib.NotifyConfig, state *configNotify.NotifyState, bot *bot.Bot) notify.Notifier {
return &Notifier{ return &Notifier{
TimeFormat: "2006-01-02 15:04:05", TimeFormat: "2006-01-02 15:04:05",
ShowTime: true, ShowTime: true,
Debug: config.Console,
} }
} }
// handle a log entry (print it on the terminal with color) // handle a log entry (print it on the terminal with color)
func (n *Notifier) Send(e *log.Entry) { func (n *Notifier) Send(e *log.Entry) {
if e.Hostname != "" { if e == nil || n == nil {
return
}
if e.Hostname != "" && !n.Debug {
return return
} }
v := []interface{}{} v := []interface{}{}

View File

@ -1,5 +1,6 @@
package all package all
import ( import (
_ "github.com/genofire/logmania/receive/journald_json"
_ "github.com/genofire/logmania/receive/syslog" _ "github.com/genofire/logmania/receive/syslog"
) )

View File

@ -0,0 +1,71 @@
package journald_json
import (
"encoding/json"
"strconv"
"github.com/genofire/logmania/log"
)
type JournalMessage struct {
Cursor string `json:"__CURSOR"`
RealtimeTimestamp string `json:"__REALTIME_TIMESTAMP"`
MonotonicTimestamp string `json:"__MONOTONIC_TIMESTAMP"`
TimestampMonotonic string `json:"TIMESTAMP_MONOTONIC"`
TimestampBoottime string `json:"TIMESTAMP_BOOTTIME"`
SourceMonotonicTimestamp string `json:"_SOURCE_MONOTONIC_TIMESTAMP"`
UID string `json:"_UID"`
GID string `json:"_GID"`
Transport string `json:"_TRANSPORT"`
Priority string `json:"PRIORITY"`
SyslogFacility string `json:"SYSLOG_FACILITY"`
SyslogIdentifier string `json:"SYSLOG_IDENTIFIER"`
SystemdCGroup string `json:"_SYSTEMD_CGROUP"`
SystemdUnit string `json:"_SYSTEMD_UNIT"`
SystemdSlice string `json:"_SYSTEMD_SLICE"`
SystemdInvocationID string `json:"_SYSTEMD_INVOCATION_ID"`
BootID string `json:"_BOOT_ID"`
MachineID string `json:"_MACHINE_ID"`
Hostname string `json:"_HOSTNAME"`
Message string `json:"MESSAGE"`
}
var PriorityMap = map[int]log.LogLevel{
0: log.PanicLevel, // emerg
1: log.PanicLevel, // alert
2: log.PanicLevel, // crit
3: log.ErrorLevel, // err
4: log.WarnLevel, // warn
5: log.InfoLevel, // notice
6: log.InfoLevel, // info
7: log.DebugLevel, // debug
}
func toLogEntry(msg []byte, from string) *log.Entry {
data := &JournalMessage{}
mapEntry := make(map[string]interface{})
err := json.Unmarshal(msg, data)
if err != nil {
return nil
}
err = json.Unmarshal(msg, mapEntry)
prio, err := strconv.Atoi(data.Priority)
if err != nil {
return nil
}
e := &log.Entry{
Level: PriorityMap[prio],
Hostname: from,
Service: data.SyslogIdentifier,
Text: data.Message,
Fields: mapEntry,
}
if data.SystemdUnit == "" {
e.Service = data.SystemdUnit
}
return e
}

View File

@ -0,0 +1,62 @@
package journald_json
import (
"net"
"github.com/genofire/logmania/lib"
"github.com/genofire/logmania/log"
"github.com/genofire/logmania/receive"
)
type Receiver struct {
receive.Receiver
exportChannel chan *log.Entry
serverSocket *net.UDPConn
}
func Init(config *lib.ReceiveConfig, exportChannel chan *log.Entry) receive.Receiver {
addr, err := net.ResolveUDPAddr(config.JournaldJSON.Type, config.JournaldJSON.Address)
ln, err := net.ListenUDP(config.JournaldJSON.Type, addr)
if err != nil {
log.Error("journald-json init ", err)
return nil
}
recv := &Receiver{
serverSocket: ln,
exportChannel: exportChannel,
}
log.Info("journald-json init")
return recv
}
const maxDataGramSize = 8192
func (rc *Receiver) Listen() {
log.Info("journald-json listen")
for {
buf := make([]byte, maxDataGramSize)
n, src, err := rc.serverSocket.ReadFromUDP(buf)
if err != nil {
log.Warn("failed to accept connection", err)
continue
}
raw := make([]byte, n)
copy(raw, buf)
entry := toLogEntry(raw, src.IP.String())
if entry != nil {
rc.exportChannel <- entry
}
}
}
func (rc *Receiver) Close() {
rc.serverSocket.Close()
}
func init() {
receive.AddReceiver("journald_json", Init)
}