new database structur + improve bot
This commit is contained in:
parent
e962b935b3
commit
22402e3e6d
134
bot/command.go
134
bot/command.go
|
@ -3,7 +3,6 @@ package bot
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
timeago "github.com/ararog/timeago"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -14,16 +13,16 @@ type commandFunc func(func(string), string, []string)
|
|||
// list help
|
||||
func (b *Bot) help(answer func(string), from string, params []string) {
|
||||
msg := fmt.Sprintf("Hi %s there are the following commands:\n", from)
|
||||
for cmd := range b.commands {
|
||||
for _, cmd := range b.commands {
|
||||
msg = fmt.Sprintf("%s - !%s\n", msg, cmd)
|
||||
}
|
||||
answer(msg)
|
||||
}
|
||||
|
||||
// add a chat to send log to a chat
|
||||
func (b *Bot) sendTo(answer func(string), from string, params []string) {
|
||||
func (b *Bot) addSend(answer func(string), from string, params []string) {
|
||||
if len(params) < 1 {
|
||||
answer("invalid: CMD IPAddress\n or\n CMD IPAddress to")
|
||||
answer("invalid: CMD IPAddress/Hostname\n or\n CMD IPAddress/Hostname to")
|
||||
return
|
||||
}
|
||||
host := params[0]
|
||||
|
@ -32,18 +31,23 @@ func (b *Bot) sendTo(answer func(string), from string, params []string) {
|
|||
to = params[1]
|
||||
}
|
||||
|
||||
if _, ok := b.db.HostTo[host]; !ok {
|
||||
b.db.HostTo[host] = make(map[string]bool)
|
||||
h := b.db.GetHost(host)
|
||||
if h == nil {
|
||||
h = b.db.NewHost(host)
|
||||
}
|
||||
b.db.HostTo[host][to] = true
|
||||
n, ok := b.db.NotifiesByAddress[to]
|
||||
if !ok {
|
||||
n = b.db.NewNotify(to)
|
||||
}
|
||||
h.AddNotify(n)
|
||||
|
||||
answer(fmt.Sprintf("added %s in list of %s", to, host))
|
||||
}
|
||||
|
||||
//add a chat to send log to a chat
|
||||
func (b *Bot) sendRemove(answer func(string), from string, params []string) {
|
||||
func (b *Bot) delSend(answer func(string), from string, params []string) {
|
||||
if len(params) < 1 {
|
||||
answer("invalid: CMD IPAddress\n or\n CMD IPAddress to")
|
||||
answer("invalid: CMD IPAddress/Hostname\n or\n CMD IPAddress/Hostname to")
|
||||
return
|
||||
}
|
||||
host := params[0]
|
||||
|
@ -52,9 +56,8 @@ func (b *Bot) sendRemove(answer func(string), from string, params []string) {
|
|||
to = params[1]
|
||||
}
|
||||
|
||||
if list, ok := b.db.HostTo[host]; ok {
|
||||
delete(list, to)
|
||||
b.db.HostTo[host] = list
|
||||
if h := b.db.GetHost(host); h != nil {
|
||||
h.DeleteNotify(to)
|
||||
answer(fmt.Sprintf("removed %s in list of %s", to, host))
|
||||
} else {
|
||||
answer("not found host")
|
||||
|
@ -63,7 +66,7 @@ func (b *Bot) sendRemove(answer func(string), from string, params []string) {
|
|||
}
|
||||
|
||||
// list all hostname with the chat where it send to
|
||||
func (b *Bot) sendList(answer func(string), from string, params []string) {
|
||||
func (b *Bot) listSend(answer func(string), from string, params []string) {
|
||||
msg := "sending:\n"
|
||||
all := false
|
||||
of := from
|
||||
|
@ -74,10 +77,10 @@ func (b *Bot) sendList(answer func(string), from string, params []string) {
|
|||
of = params[0]
|
||||
}
|
||||
}
|
||||
for ip, toMap := range b.db.HostTo {
|
||||
for _, host := range b.db.Hosts {
|
||||
toList := ""
|
||||
show := all
|
||||
for to := range toMap {
|
||||
for _, to := range host.Notifies {
|
||||
if all {
|
||||
toList = fmt.Sprintf("%s , %s", toList, to)
|
||||
} else if to == of {
|
||||
|
@ -90,58 +93,81 @@ func (b *Bot) sendList(answer func(string), from string, params []string) {
|
|||
if len(toList) > 3 {
|
||||
toList = toList[3:]
|
||||
}
|
||||
if hostname, ok := b.db.Hostname[ip]; ok {
|
||||
msg = fmt.Sprintf("%s%s (%s): %s\n", msg, ip, hostname, toList)
|
||||
if host.Name != "" {
|
||||
msg = fmt.Sprintf("%s%s (%s): %s\n", msg, host.Address, host.Name, toList)
|
||||
} else {
|
||||
msg = fmt.Sprintf("%s%s: %s\n", msg, ip, toList)
|
||||
msg = fmt.Sprintf("%s%s: %s\n", msg, host.Address, toList)
|
||||
}
|
||||
}
|
||||
|
||||
answer(msg)
|
||||
}
|
||||
|
||||
// add hostname
|
||||
func (b *Bot) addHostname(answer func(string), from string, params []string) {
|
||||
if len(params) < 2 {
|
||||
answer("invalid: CMD IPAddress/Hostname NewHostname")
|
||||
return
|
||||
}
|
||||
addr := params[0]
|
||||
name := params[1]
|
||||
|
||||
h := b.db.GetHost(addr)
|
||||
if h == nil {
|
||||
h = b.db.NewHost(addr)
|
||||
}
|
||||
b.db.ChangeHostname(h, name)
|
||||
|
||||
answer(fmt.Sprintf("set for %s the hostname %s", addr, name))
|
||||
}
|
||||
|
||||
func (b *Bot) delHostname(answer func(string), from string, params []string) {
|
||||
if len(params) < 2 {
|
||||
answer("invalid: CMD IPAddress/Hostname")
|
||||
return
|
||||
}
|
||||
addr := params[0]
|
||||
h := b.db.GetHost(addr)
|
||||
if h != nil {
|
||||
b.db.DeleteHost(h)
|
||||
if h.Name != "" {
|
||||
answer(fmt.Sprintf("remove host %s with hostname %s", h.Address, h.Name))
|
||||
} else {
|
||||
answer(fmt.Sprintf("remove host %s", h.Address))
|
||||
}
|
||||
} else {
|
||||
answer("could not found host")
|
||||
}
|
||||
}
|
||||
|
||||
// list all host with his ip
|
||||
func (b *Bot) listHostname(answer func(string), from string, params []string) {
|
||||
msg := "hostnames:\n"
|
||||
for ip, hostname := range b.db.Hostname {
|
||||
if last, ok := b.db.Lastseen[ip]; ok {
|
||||
got, _ := timeago.TimeAgoWithTime(time.Now(), last)
|
||||
msg = fmt.Sprintf("%s%s - %s (%s)\n", msg, ip, hostname, got)
|
||||
for _, host := range b.db.Hosts {
|
||||
if host.Lastseen.Year() > 1 {
|
||||
got, _ := timeago.TimeAgoFromNowWithTime(host.Lastseen)
|
||||
msg = fmt.Sprintf("%s%s - %s (%s)\n", msg, host.Address, host.Name, got)
|
||||
} else {
|
||||
msg = fmt.Sprintf("%s%s - %s\n", msg, ip, hostname)
|
||||
msg = fmt.Sprintf("%s%s - %s\n", msg, host.Address, host.Name)
|
||||
}
|
||||
}
|
||||
answer(msg)
|
||||
}
|
||||
|
||||
// list all hostname to a ip
|
||||
func (b *Bot) setHostname(answer func(string), from string, params []string) {
|
||||
if len(params) < 2 {
|
||||
answer("invalid: CMD IPAddress NewHostname")
|
||||
return
|
||||
}
|
||||
host := params[0]
|
||||
name := params[1]
|
||||
|
||||
b.db.Hostname[host] = name
|
||||
|
||||
answer(fmt.Sprintf("set for %s the hostname %s", host, name))
|
||||
}
|
||||
|
||||
// set a filter by max
|
||||
func (b *Bot) listMaxfilter(answer func(string), from string, params []string) {
|
||||
msg := "filters: "
|
||||
if len(params) > 0 && params[0] == "all" {
|
||||
msg = fmt.Sprintf("%s\n", msg)
|
||||
for to, filter := range b.db.MaxPrioIn {
|
||||
msg = fmt.Sprintf("%s%s - %s\n", msg, to, filter.String())
|
||||
for _, n := range b.db.Notifies {
|
||||
msg = fmt.Sprintf("%s%s - %s\n", msg, n.Address(), n.MaxPrioIn.String())
|
||||
}
|
||||
} else {
|
||||
of := from
|
||||
if len(params) > 0 {
|
||||
of = params[0]
|
||||
}
|
||||
if filter, ok := b.db.MaxPrioIn[of]; ok {
|
||||
if filter, ok := b.db.NotifiesByAddress[of]; ok {
|
||||
msg = fmt.Sprintf("%s of %s is %s", msg, of, filter)
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +177,7 @@ func (b *Bot) listMaxfilter(answer func(string), from string, params []string) {
|
|||
// set a filter to a mix
|
||||
func (b *Bot) setMaxfilter(answer func(string), from string, params []string) {
|
||||
if len(params) < 1 {
|
||||
answer("invalid: CMD Priority\n or\n CMD IPAddress Priority")
|
||||
answer("invalid: CMD Priority\n or\n CMD Channel Priority")
|
||||
return
|
||||
}
|
||||
to := from
|
||||
|
@ -165,11 +191,15 @@ func (b *Bot) setMaxfilter(answer func(string), from string, params []string) {
|
|||
max, err = log.ParseLevel(params[0])
|
||||
}
|
||||
if err != nil {
|
||||
answer("invalid priority: CMD Priority\n or\n CMD IPAddress Priority")
|
||||
answer("invalid priority: CMD Priority\n or\n CMD Channel Priority")
|
||||
return
|
||||
}
|
||||
n, ok := b.db.NotifiesByAddress[to]
|
||||
if !ok {
|
||||
n = b.db.NewNotify(to)
|
||||
}
|
||||
|
||||
b.db.MaxPrioIn[to] = max
|
||||
n.MaxPrioIn = max
|
||||
|
||||
answer(fmt.Sprintf("set filter for %s to %s", to, max.String()))
|
||||
}
|
||||
|
@ -178,9 +208,9 @@ func (b *Bot) setMaxfilter(answer func(string), from string, params []string) {
|
|||
func (b *Bot) listRegex(answer func(string), from string, params []string) {
|
||||
msg := "regexs:\n"
|
||||
if len(params) > 0 && params[0] == "all" {
|
||||
for to, regexs := range b.db.RegexIn {
|
||||
msg = fmt.Sprintf("%s%s\n-------------\n", msg, to)
|
||||
for expression := range regexs {
|
||||
for _, n := range b.db.Notifies {
|
||||
msg = fmt.Sprintf("%s%s\n-------------\n", msg, n.Address())
|
||||
for expression := range n.RegexIn {
|
||||
msg = fmt.Sprintf("%s - %s\n", msg, expression)
|
||||
}
|
||||
}
|
||||
|
@ -189,9 +219,9 @@ func (b *Bot) listRegex(answer func(string), from string, params []string) {
|
|||
if len(params) > 0 {
|
||||
of = params[0]
|
||||
}
|
||||
if regexs, ok := b.db.RegexIn[of]; ok {
|
||||
msg = fmt.Sprintf("%s%s\n-------------\n", msg, from)
|
||||
for expression := range regexs {
|
||||
if n, ok := b.db.NotifiesByAddress[of]; ok {
|
||||
msg = fmt.Sprintf("%s%s\n-------------\n", msg, of)
|
||||
for expression := range n.RegexIn {
|
||||
msg = fmt.Sprintf("%s - %s\n", msg, expression)
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +237,8 @@ func (b *Bot) addRegex(answer func(string), from string, params []string) {
|
|||
}
|
||||
regex := strings.Join(params, " ")
|
||||
|
||||
if err := b.db.AddRegex(from, regex); err == nil {
|
||||
n := b.db.NotifiesByAddress[from]
|
||||
if err := n.AddRegex(regex); err == nil {
|
||||
answer(fmt.Sprintf("add regex for \"%s\" to %s", from, regex))
|
||||
} else {
|
||||
answer(fmt.Sprintf("\"%s\" is no valid regex expression: %s", regex, err))
|
||||
|
@ -220,7 +251,8 @@ func (b *Bot) delRegex(answer func(string), from string, params []string) {
|
|||
answer("invalid: CMD regex\n or\n CMD channel regex")
|
||||
return
|
||||
}
|
||||
n := b.db.NotifiesByAddress[from]
|
||||
regex := strings.Join(params, " ")
|
||||
delete(b.db.RegexIn[from], regex)
|
||||
delete(n.RegexIn, regex)
|
||||
b.listRegex(answer, from, []string{})
|
||||
}
|
||||
|
|
23
bot/main.go
23
bot/main.go
|
@ -8,26 +8,31 @@ import (
|
|||
)
|
||||
|
||||
type Bot struct {
|
||||
db *database.DB
|
||||
commands map[string]commandFunc
|
||||
db *database.DB
|
||||
commandsMap map[string]commandFunc
|
||||
commands []string
|
||||
}
|
||||
|
||||
func NewBot(db *database.DB) *Bot {
|
||||
b := &Bot{
|
||||
db: db,
|
||||
}
|
||||
b.commands = map[string]commandFunc{
|
||||
b.commandsMap = map[string]commandFunc{
|
||||
"help": b.help,
|
||||
"send-to": b.sendTo,
|
||||
"send-list": b.sendList,
|
||||
"send-rm": b.sendRemove,
|
||||
"hostname-set": b.setHostname,
|
||||
"send-add": b.addSend,
|
||||
"send-list": b.listSend,
|
||||
"send-del": b.delSend,
|
||||
"hostname-set": b.addHostname,
|
||||
"hostname-list": b.listHostname,
|
||||
"hostname-del": b.delHostname,
|
||||
"filter-set": b.setMaxfilter,
|
||||
"filter-list": b.listMaxfilter,
|
||||
"regex-add": b.addRegex,
|
||||
"regex-list": b.listRegex,
|
||||
"regex-rm": b.delRegex,
|
||||
"regex-del": b.delRegex,
|
||||
}
|
||||
for k, _ := range b.commandsMap {
|
||||
b.commands = append(b.commands, k)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
@ -38,7 +43,7 @@ func (b *Bot) Handle(answer func(string), from, msg string) {
|
|||
return
|
||||
}
|
||||
cmdName := msgParts[0][1:]
|
||||
if cmd, ok := b.commands[cmdName]; ok {
|
||||
if cmd, ok := b.commandsMap[cmdName]; ok {
|
||||
cmd(answer, from, msgParts[1:])
|
||||
} else {
|
||||
answer(fmt.Sprintf("not found command: !%s", cmdName))
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Host struct {
|
||||
Name string `json:"name"`
|
||||
Address string `json:"address"`
|
||||
Lastseen time.Time `json:"lastseen,omitempty"`
|
||||
LastseenNotify time.Time `json:"lastseen_notify,omitempty"`
|
||||
Notifies []string `json:"notifies"`
|
||||
NotifiesByAddress map[string]*Notify `json:"-"`
|
||||
}
|
||||
|
||||
func (h *Host) AddNotify(n *Notify) {
|
||||
if _, ok := h.NotifiesByAddress[n.Address()]; !ok {
|
||||
h.Notifies = append(h.Notifies, n.Address())
|
||||
h.NotifiesByAddress[n.Address()] = n
|
||||
}
|
||||
}
|
||||
func (h *Host) DeleteNotify(to string) {
|
||||
delete(h.NotifiesByAddress, to)
|
||||
for i, v := range h.Notifies {
|
||||
if v == to {
|
||||
copy(h.Notifies[i:], h.Notifies[i+1:])
|
||||
h.Notifies = h.Notifies[:len(h.Notifies)-1]
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// -- global notify
|
||||
|
||||
func (db *DB) InitHost() {
|
||||
if db.HostsByAddress == nil {
|
||||
db.HostsByAddress = make(map[string]*Host)
|
||||
}
|
||||
if db.HostsByName == nil {
|
||||
db.HostsByName = make(map[string]*Host)
|
||||
}
|
||||
for _, h := range db.Hosts {
|
||||
if h.NotifiesByAddress == nil {
|
||||
h.NotifiesByAddress = make(map[string]*Notify)
|
||||
}
|
||||
for _, nName := range h.Notifies {
|
||||
h.NotifiesByAddress[nName] = db.NotifiesByAddress[nName]
|
||||
}
|
||||
db.HostsByAddress[h.Address] = h
|
||||
db.HostsByName[h.Name] = h
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DB) AddHost(h *Host) {
|
||||
db.Hosts = append(db.Hosts, h)
|
||||
db.HostsByAddress[h.Address] = h
|
||||
db.HostsByName[h.Name] = h
|
||||
}
|
||||
|
||||
func (db *DB) GetHost(str string) *Host {
|
||||
h, ok := db.HostsByAddress[str]
|
||||
if ok {
|
||||
return h
|
||||
}
|
||||
return db.HostsByName[str]
|
||||
}
|
||||
func (db *DB) DeleteHost(h *Host) {
|
||||
delete(db.HostsByAddress, h.Address)
|
||||
delete(db.HostsByName, h.Name)
|
||||
for i, v := range db.Hosts {
|
||||
if v.Address == h.Address {
|
||||
copy(db.Hosts[i:], db.Hosts[i+1:])
|
||||
db.Hosts[len(db.Hosts)-1] = nil
|
||||
db.Hosts = db.Hosts[:len(db.Hosts)-1]
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (db *DB) ChangeHostname(h *Host, name string) {
|
||||
delete(db.HostsByName, h.Name)
|
||||
h.Name = name
|
||||
db.HostsByName[name] = h
|
||||
}
|
||||
|
||||
func (db *DB) NewHost(addr string) *Host {
|
||||
h := &Host{
|
||||
Address: addr,
|
||||
NotifiesByAddress: make(map[string]*Notify),
|
||||
}
|
||||
db.AddHost(h)
|
||||
return h
|
||||
}
|
132
database/main.go
132
database/main.go
|
@ -4,106 +4,64 @@ import (
|
|||
"regexp"
|
||||
"time"
|
||||
|
||||
"dev.sum7.eu/genofire/golang-lib/file"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const AlertMsg = "alert service from logmania, device did not send new message for a while"
|
||||
|
||||
type DB struct {
|
||||
Hostname map[string]string `json:"hostname"`
|
||||
HostTo map[string]map[string]bool `json:"host_to"`
|
||||
MaxPrioIn map[string]log.Level `json:"maxLevel"`
|
||||
RegexIn map[string]map[string]*regexp.Regexp `json:"regexIn"`
|
||||
Hostname map[string]string `json:"hostname,omitempty"`
|
||||
HostTo map[string]map[string]bool `json:"host_to,omitempty"`
|
||||
MaxPrioIn map[string]log.Level `json:"maxLevel,omitempty"`
|
||||
RegexIn map[string]map[string]*regexp.Regexp `json:"regexIn,omitempty"`
|
||||
Lastseen map[string]time.Time `json:"lastseen,omitempty"`
|
||||
LastseenNotify map[string]time.Time `json:"-"`
|
||||
// new format
|
||||
Hosts []*Host `json:"hosts"`
|
||||
HostsByAddress map[string]*Host `json:"-"`
|
||||
HostsByName map[string]*Host `json:"-"`
|
||||
Notifies []*Notify `json:"notifies"`
|
||||
NotifiesByAddress map[string]*Notify `json:"-"`
|
||||
}
|
||||
|
||||
func (db *DB) SendTo(e *log.Entry) (*log.Entry, []string) {
|
||||
hostname, ok := e.Data["hostname"].(string)
|
||||
func (db *DB) SendTo(e *log.Entry) (*log.Entry, *Host, []*Notify) {
|
||||
addr, ok := e.Data["hostname"].(string)
|
||||
if !ok {
|
||||
return e, nil
|
||||
return e, nil, nil
|
||||
}
|
||||
if to, ok := db.HostTo[hostname]; ok {
|
||||
if e.Message != AlertMsg && hostname != "" {
|
||||
db.Lastseen[hostname] = time.Now()
|
||||
var host *Host
|
||||
if host, ok := db.HostsByAddress[addr]; ok {
|
||||
if e.Message != AlertMsg {
|
||||
host.Lastseen = time.Now()
|
||||
}
|
||||
var toList []string
|
||||
for toEntry, _ := range to {
|
||||
if lvl := db.MaxPrioIn[toEntry]; e.Level >= lvl {
|
||||
var toList []*Notify
|
||||
for _, notify := range host.NotifiesByAddress {
|
||||
if lvl := notify.MaxPrioIn; e.Level >= lvl {
|
||||
continue
|
||||
}
|
||||
if regex, ok := db.RegexIn[toEntry]; ok {
|
||||
stopForTo := false
|
||||
for _, expr := range regex {
|
||||
if expr.MatchString(e.Message) {
|
||||
stopForTo = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
if stopForTo {
|
||||
stopForTo := false
|
||||
for _, expr := range notify.RegexIn {
|
||||
if expr.MatchString(e.Message) {
|
||||
stopForTo = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
toList = append(toList, toEntry)
|
||||
if stopForTo {
|
||||
continue
|
||||
}
|
||||
toList = append(toList, notify)
|
||||
}
|
||||
if replaceHostname, ok := db.Hostname[hostname]; ok {
|
||||
entry := e.WithField("hostname", replaceHostname)
|
||||
if host.Name != "" {
|
||||
entry := e.WithField("hostname", host.Name)
|
||||
entry.Level = e.Level
|
||||
entry.Message = e.Message
|
||||
return entry, toList
|
||||
return entry, host, toList
|
||||
}
|
||||
return e, toList
|
||||
return e, host, toList
|
||||
} else {
|
||||
db.HostTo[hostname] = make(map[string]bool)
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (db *DB) AddRegex(to, expression string) error {
|
||||
regex, err := regexp.Compile(expression)
|
||||
if err == nil {
|
||||
if _, ok := db.RegexIn[to]; !ok {
|
||||
db.RegexIn[to] = make(map[string]*regexp.Regexp)
|
||||
}
|
||||
db.RegexIn[to][expression] = regex
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func ReadDBFile(path string) *DB {
|
||||
var db DB
|
||||
|
||||
if err := file.ReadJSON(path, &db); err == nil {
|
||||
log.Infof("loaded %d hosts", len(db.HostTo))
|
||||
if db.Lastseen == nil {
|
||||
db.Lastseen = make(map[string]time.Time)
|
||||
}
|
||||
if db.LastseenNotify == nil {
|
||||
db.LastseenNotify = make(map[string]time.Time)
|
||||
}
|
||||
if db.RegexIn == nil {
|
||||
db.RegexIn = make(map[string]map[string]*regexp.Regexp)
|
||||
} else {
|
||||
for to, regexs := range db.RegexIn {
|
||||
for exp, _ := range regexs {
|
||||
db.AddRegex(to, exp)
|
||||
}
|
||||
}
|
||||
}
|
||||
return &db
|
||||
} else {
|
||||
log.Error("failed to open db file: ", path, ":", err)
|
||||
}
|
||||
return &DB{
|
||||
Hostname: make(map[string]string),
|
||||
HostTo: make(map[string]map[string]bool),
|
||||
MaxPrioIn: make(map[string]log.Level),
|
||||
RegexIn: make(map[string]map[string]*regexp.Regexp),
|
||||
Lastseen: make(map[string]time.Time),
|
||||
LastseenNotify: make(map[string]time.Time),
|
||||
host = db.NewHost(addr)
|
||||
}
|
||||
return e, host, nil
|
||||
}
|
||||
|
||||
func (db *DB) Alert(expired time.Duration, send func(e *log.Entry) error) {
|
||||
|
@ -111,17 +69,19 @@ func (db *DB) Alert(expired time.Duration, send func(e *log.Entry) error) {
|
|||
|
||||
for range c {
|
||||
now := time.Now()
|
||||
for host, time := range db.Lastseen {
|
||||
if time.Before(now.Add(expired * -2)) {
|
||||
if timeNotify, ok := db.LastseenNotify[host]; !ok || !time.Before(timeNotify) {
|
||||
db.LastseenNotify[host] = now
|
||||
entry := log.NewEntry(log.New())
|
||||
entry.Level = log.ErrorLevel
|
||||
entry.Message = AlertMsg
|
||||
entry.WithField("hostname", host)
|
||||
send(entry)
|
||||
}
|
||||
for _, h := range db.Hosts {
|
||||
if !h.Lastseen.Before(now.Add(expired * -2)) {
|
||||
continue
|
||||
}
|
||||
if h.LastseenNotify.Year() <= 1 && h.Lastseen.Before(h.LastseenNotify) {
|
||||
continue
|
||||
}
|
||||
h.LastseenNotify = now
|
||||
entry := log.NewEntry(log.New())
|
||||
entry.Level = log.ErrorLevel
|
||||
entry.Message = AlertMsg
|
||||
entry.WithField("hostname", h.Address)
|
||||
send(entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Notify struct {
|
||||
Protocoll string `json:"proto"`
|
||||
To string `json:"to"`
|
||||
RegexIn map[string]*regexp.Regexp `json:"regexIn"`
|
||||
MaxPrioIn log.Level `json:"maxLevel"`
|
||||
}
|
||||
|
||||
func (n *Notify) Init() {
|
||||
if n.RegexIn == nil {
|
||||
n.RegexIn = make(map[string]*regexp.Regexp)
|
||||
}
|
||||
for exp, _ := range n.RegexIn {
|
||||
regex, err := regexp.Compile(exp)
|
||||
if err == nil {
|
||||
n.RegexIn[exp] = regex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Notify) AddRegex(expression string) error {
|
||||
regex, err := regexp.Compile(expression)
|
||||
if err == nil {
|
||||
n.RegexIn[expression] = regex
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (n *Notify) Address() string {
|
||||
return n.Protocoll + ":" + n.To
|
||||
}
|
||||
|
||||
// -- global notify
|
||||
|
||||
func (db *DB) InitNotify() {
|
||||
if db.NotifiesByAddress == nil {
|
||||
db.NotifiesByAddress = make(map[string]*Notify)
|
||||
}
|
||||
for _, n := range db.Notifies {
|
||||
n.Init()
|
||||
db.NotifiesByAddress[n.Address()] = n
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DB) AddNotify(n *Notify) {
|
||||
db.Notifies = append(db.Notifies, n)
|
||||
db.NotifiesByAddress[n.Address()] = n
|
||||
}
|
||||
|
||||
func (db *DB) NewNotify(to string) *Notify {
|
||||
addr := strings.Split(to, ":")
|
||||
n := &Notify{
|
||||
Protocoll: addr[0],
|
||||
To: addr[1],
|
||||
RegexIn: make(map[string]*regexp.Regexp),
|
||||
}
|
||||
db.AddNotify(n)
|
||||
return n
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"dev.sum7.eu/genofire/golang-lib/file"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func ReadDBFile(path string) *DB {
|
||||
var db DB
|
||||
|
||||
if err := file.ReadJSON(path, &db); err == nil {
|
||||
log.Infof("loaded %d hosts", len(db.HostTo))
|
||||
|
||||
db.InitNotify()
|
||||
db.InitHost()
|
||||
// import
|
||||
db.update()
|
||||
return &db
|
||||
} else {
|
||||
log.Error("failed to open db file: ", path, ":", err)
|
||||
}
|
||||
adb := &DB{}
|
||||
adb.InitNotify()
|
||||
adb.InitHost()
|
||||
return adb
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package database
|
||||
|
||||
func (db *DB) update() {
|
||||
if db.Hostname != nil {
|
||||
for addr, name := range db.Hostname {
|
||||
h, ok := db.HostsByName[name]
|
||||
if !ok {
|
||||
h = db.NewHost(addr)
|
||||
db.ChangeHostname(h, name)
|
||||
}
|
||||
}
|
||||
db.Hostname = nil
|
||||
}
|
||||
if db.HostTo != nil {
|
||||
for addr, channels := range db.HostTo {
|
||||
h, ok := db.HostsByAddress[addr]
|
||||
if !ok {
|
||||
h = db.NewHost(addr)
|
||||
}
|
||||
for channel := range channels {
|
||||
n, ok := db.NotifiesByAddress[channel]
|
||||
if !ok {
|
||||
n = db.NewNotify(channel)
|
||||
}
|
||||
h.AddNotify(n)
|
||||
}
|
||||
}
|
||||
db.HostTo = nil
|
||||
}
|
||||
if db.MaxPrioIn != nil {
|
||||
for to, prio := range db.MaxPrioIn {
|
||||
notify, ok := db.NotifiesByAddress[to]
|
||||
if !ok {
|
||||
notify = db.NewNotify(to)
|
||||
}
|
||||
notify.MaxPrioIn = prio
|
||||
}
|
||||
db.MaxPrioIn = nil
|
||||
}
|
||||
if db.RegexIn != nil {
|
||||
for to, regexs := range db.RegexIn {
|
||||
notify, ok := db.NotifiesByAddress[to]
|
||||
if !ok {
|
||||
notify = db.NewNotify(to)
|
||||
}
|
||||
for exp, _ := range regexs {
|
||||
notify.AddRegex(exp)
|
||||
}
|
||||
}
|
||||
db.RegexIn = nil
|
||||
}
|
||||
if db.Lastseen != nil {
|
||||
for addr, t := range db.Lastseen {
|
||||
h, ok := db.HostsByAddress[addr]
|
||||
if !ok {
|
||||
h = db.NewHost(addr)
|
||||
}
|
||||
h.Lastseen = t
|
||||
}
|
||||
db.Lastseen = nil
|
||||
}
|
||||
if db.LastseenNotify != nil {
|
||||
for addr, t := range db.LastseenNotify {
|
||||
h, ok := db.HostsByAddress[addr]
|
||||
if !ok {
|
||||
h = db.NewHost(addr)
|
||||
}
|
||||
h.LastseenNotify = t
|
||||
}
|
||||
db.LastseenNotify = nil
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package xmpp
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
xmpp_client "dev.sum7.eu/genofire/yaja/client"
|
||||
xmpp "dev.sum7.eu/genofire/yaja/xmpp"
|
||||
|
@ -16,8 +15,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
proto = "xmpp:"
|
||||
protoGroup = "xmpp-muc:"
|
||||
proto = "xmpp"
|
||||
protoGroup = "xmpp-muc"
|
||||
nickname = "logmania"
|
||||
)
|
||||
|
||||
|
@ -94,9 +93,9 @@ func Init(config *lib.NotifyConfig, db *database.DB, bot *bot.Bot) notify.Notifi
|
|||
msg := element.(*xmpp.MessageClient)
|
||||
from := msg.From.Bare().String()
|
||||
if msg.Type == xmpp.MessageTypeGroupchat {
|
||||
from = protoGroup + from
|
||||
from = protoGroup + ":" + from
|
||||
} else {
|
||||
from = proto + from
|
||||
from = proto + ":" + from
|
||||
}
|
||||
|
||||
bot.Handle(func(answer string) {
|
||||
|
@ -116,10 +115,9 @@ func Init(config *lib.NotifyConfig, db *database.DB, bot *bot.Bot) notify.Notifi
|
|||
}
|
||||
}
|
||||
}()
|
||||
for _, toAddresses := range db.HostTo {
|
||||
for to, _ := range toAddresses {
|
||||
toAddr := strings.TrimPrefix(to, protoGroup)
|
||||
toJID := xmppbase.NewJID(toAddr)
|
||||
for toAddr, toAddresses := range db.NotifiesByAddress {
|
||||
if toAddresses.Protocoll == protoGroup {
|
||||
toJID := xmppbase.NewJID(toAddresses.To)
|
||||
toJID.Resource = nickname
|
||||
err := client.Send(&xmpp.PresenceClient{
|
||||
To: toJID,
|
||||
|
@ -143,19 +141,18 @@ func Init(config *lib.NotifyConfig, db *database.DB, bot *bot.Bot) notify.Notifi
|
|||
}
|
||||
|
||||
func (n *Notifier) Send(e *log.Entry) error {
|
||||
e, to := n.db.SendTo(e)
|
||||
if to == nil {
|
||||
e, _, tos := n.db.SendTo(e)
|
||||
if tos == nil || len(tos) <= 0 {
|
||||
return errors.New("no reciever found")
|
||||
}
|
||||
text, err := n.formatter.Format(e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, toAddr := range to {
|
||||
if strings.HasPrefix(toAddr, protoGroup) {
|
||||
toAddr = strings.TrimPrefix(toAddr, protoGroup)
|
||||
if _, ok := n.channels[toAddr]; ok {
|
||||
toJID := xmppbase.NewJID(toAddr)
|
||||
for _, to := range tos {
|
||||
if to.Protocoll == protoGroup {
|
||||
if _, ok := n.channels[to.To]; ok {
|
||||
toJID := xmppbase.NewJID(to.To)
|
||||
toJID.Resource = nickname
|
||||
err := n.client.Send(&xmpp.PresenceClient{
|
||||
To: toJID,
|
||||
|
@ -163,22 +160,21 @@ func (n *Notifier) Send(e *log.Entry) error {
|
|||
if err != nil {
|
||||
logger.Error("xmpp could not join ", toJID.String(), " error:", err)
|
||||
} else {
|
||||
n.channels[toAddr] = true
|
||||
n.channels[to.To] = true
|
||||
}
|
||||
}
|
||||
err := n.client.Send(&xmpp.MessageClient{
|
||||
Type: xmpp.MessageTypeGroupchat,
|
||||
To: xmppbase.NewJID(toAddr),
|
||||
To: xmppbase.NewJID(to.To),
|
||||
Body: string(text),
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("xmpp to ", toAddr, " error:", err)
|
||||
logger.Error("xmpp to ", to.To, " error:", err)
|
||||
}
|
||||
} else {
|
||||
toAddr = strings.TrimPrefix(toAddr, proto)
|
||||
err := n.client.Send(&xmpp.MessageClient{
|
||||
Type: xmpp.MessageTypeChat,
|
||||
To: xmppbase.NewJID(toAddr),
|
||||
To: xmppbase.NewJID(to.To),
|
||||
Body: string(text),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue