[TASK] add journald json with udp
This commit is contained in:
parent
d7ed44e809
commit
5e453e234d
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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{}{}
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in New Issue