bot filter list by channel + add regex filter of recieve
This commit is contained in:
parent
a37c94c4d5
commit
b4487cdde4
101
bot/command.go
101
bot/command.go
|
@ -2,6 +2,10 @@ package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
timeago "github.com/ararog/timeago"
|
||||||
|
|
||||||
"github.com/genofire/logmania/log"
|
"github.com/genofire/logmania/log"
|
||||||
)
|
)
|
||||||
|
@ -37,7 +41,7 @@ func (b *Bot) sendTo(answer func(string), from string, params []string) {
|
||||||
answer(fmt.Sprintf("added %s in list of %s", to, host))
|
answer(fmt.Sprintf("added %s in list of %s", to, host))
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO add a chat to send log to a chat
|
//add a chat to send log to a chat
|
||||||
func (b *Bot) sendRemove(answer func(string), from string, params []string) {
|
func (b *Bot) sendRemove(answer func(string), from string, params []string) {
|
||||||
if len(params) < 1 {
|
if len(params) < 1 {
|
||||||
answer("invalid: CMD IPAddress\n or\n CMD IPAddress to")
|
answer("invalid: CMD IPAddress\n or\n CMD IPAddress to")
|
||||||
|
@ -62,10 +66,27 @@ func (b *Bot) sendRemove(answer func(string), from string, params []string) {
|
||||||
// list all hostname with the chat where it send to
|
// list all hostname with the chat where it send to
|
||||||
func (b *Bot) sendList(answer func(string), from string, params []string) {
|
func (b *Bot) sendList(answer func(string), from string, params []string) {
|
||||||
msg := "sending:\n"
|
msg := "sending:\n"
|
||||||
|
all := false
|
||||||
|
of := from
|
||||||
|
if len(params) > 0 {
|
||||||
|
if params[0] == "all" {
|
||||||
|
all = true
|
||||||
|
} else {
|
||||||
|
of = params[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
for ip, toMap := range b.state.HostTo {
|
for ip, toMap := range b.state.HostTo {
|
||||||
toList := ""
|
toList := ""
|
||||||
|
show := all
|
||||||
for to := range toMap {
|
for to := range toMap {
|
||||||
toList = fmt.Sprintf("%s , %s", toList, to)
|
if all {
|
||||||
|
toList = fmt.Sprintf("%s , %s", toList, to)
|
||||||
|
} else if to == of {
|
||||||
|
show = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !show {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if len(toList) > 3 {
|
if len(toList) > 3 {
|
||||||
toList = toList[3:]
|
toList = toList[3:]
|
||||||
|
@ -76,6 +97,7 @@ func (b *Bot) sendList(answer func(string), from string, params []string) {
|
||||||
msg = fmt.Sprintf("%s%s: %s\n", msg, ip, toList)
|
msg = fmt.Sprintf("%s%s: %s\n", msg, ip, toList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
answer(msg)
|
answer(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +105,12 @@ func (b *Bot) sendList(answer func(string), from string, params []string) {
|
||||||
func (b *Bot) listHostname(answer func(string), from string, params []string) {
|
func (b *Bot) listHostname(answer func(string), from string, params []string) {
|
||||||
msg := "hostnames:\n"
|
msg := "hostnames:\n"
|
||||||
for ip, hostname := range b.state.Hostname {
|
for ip, hostname := range b.state.Hostname {
|
||||||
msg = fmt.Sprintf("%s%s - %s\n", msg, ip, hostname)
|
if last, ok := b.state.Lastseen[ip]; ok {
|
||||||
|
got, _ := timeago.TimeAgoWithTime(time.Now(), last)
|
||||||
|
msg = fmt.Sprintf("%s%s - %s (%s)\n", msg, ip, hostname, got)
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintf("%s%s - %s\n", msg, ip, hostname)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
answer(msg)
|
answer(msg)
|
||||||
}
|
}
|
||||||
|
@ -104,9 +131,20 @@ func (b *Bot) setHostname(answer func(string), from string, params []string) {
|
||||||
|
|
||||||
// set a filter by max
|
// set a filter by max
|
||||||
func (b *Bot) listMaxfilter(answer func(string), from string, params []string) {
|
func (b *Bot) listMaxfilter(answer func(string), from string, params []string) {
|
||||||
msg := "filters:\n"
|
msg := "filters: "
|
||||||
for to, filter := range b.state.MaxPrioIn {
|
if len(params) > 0 && params[0] == "all" {
|
||||||
msg = fmt.Sprintf("%s%s - %s\n", msg, to, filter.String())
|
msg = fmt.Sprintf("%s\n", msg)
|
||||||
|
for to, filter := range b.state.MaxPrioIn {
|
||||||
|
msg = fmt.Sprintf("%s%s - %s\n", msg, to, filter.String())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
of := from
|
||||||
|
if len(params) > 0 {
|
||||||
|
of = params[0]
|
||||||
|
}
|
||||||
|
if filter, ok := b.state.MaxPrioIn[of]; ok {
|
||||||
|
msg = fmt.Sprintf("%s of %s is %s", msg, of, filter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
answer(msg)
|
answer(msg)
|
||||||
}
|
}
|
||||||
|
@ -129,3 +167,54 @@ func (b *Bot) setMaxfilter(answer func(string), from string, params []string) {
|
||||||
|
|
||||||
answer(fmt.Sprintf("set filter for %s to %s", to, max.String()))
|
answer(fmt.Sprintf("set filter for %s to %s", to, max.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// list of regex filter
|
||||||
|
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.state.RegexIn {
|
||||||
|
msg = fmt.Sprintf("%s%s\n-------------\n", msg, to)
|
||||||
|
for expression := range regexs {
|
||||||
|
msg = fmt.Sprintf("%s - %s\n", msg, expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
of := from
|
||||||
|
if len(params) > 0 {
|
||||||
|
of = params[0]
|
||||||
|
}
|
||||||
|
if regexs, ok := b.state.RegexIn[of]; ok {
|
||||||
|
msg = fmt.Sprintf("%s%s\n-------------\n", msg, from)
|
||||||
|
for expression := range regexs {
|
||||||
|
msg = fmt.Sprintf("%s - %s\n", msg, expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
answer(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a regex filter
|
||||||
|
func (b *Bot) addRegex(answer func(string), from string, params []string) {
|
||||||
|
if len(params) < 1 {
|
||||||
|
answer("invalid: CMD regex\n or\n CMD channel regex")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
regex := strings.Join(params, " ")
|
||||||
|
|
||||||
|
if err := b.state.AddRegex(from, 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// del a regex filter
|
||||||
|
func (b *Bot) delRegex(answer func(string), from string, params []string) {
|
||||||
|
if len(params) < 1 {
|
||||||
|
answer("invalid: CMD regex\n or\n CMD channel regex")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
regex := strings.Join(params, " ")
|
||||||
|
delete(b.state.RegexIn[from], regex)
|
||||||
|
b.listRegex(answer, from, []string{})
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ func NewBot(state *configNotify.NotifyState) *Bot {
|
||||||
"hostname-list": b.listHostname,
|
"hostname-list": b.listHostname,
|
||||||
"filter-set": b.setMaxfilter,
|
"filter-set": b.setMaxfilter,
|
||||||
"filter-list": b.listMaxfilter,
|
"filter-list": b.listMaxfilter,
|
||||||
|
"regex-add": b.addRegex,
|
||||||
|
"regex-list": b.listRegex,
|
||||||
|
"regex-rm": b.delRegex,
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,20 +11,34 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type NotifyState struct {
|
type NotifyState struct {
|
||||||
Hostname map[string]string `json:"hostname"`
|
Hostname map[string]string `json:"hostname"`
|
||||||
HostTo map[string]map[string]bool `json:"host_to"`
|
HostTo map[string]map[string]bool `json:"host_to"`
|
||||||
MaxPrioIn map[string]log.LogLevel `json:"maxLevel"`
|
MaxPrioIn map[string]log.LogLevel `json:"maxLevel"`
|
||||||
RegexIn map[string]map[string]bool `json:"regexIn"`
|
RegexIn map[string]map[string]*regexp.Regexp `json:"regexIn"`
|
||||||
regexIn map[string]map[string]*regexp.Regexp `json:"-"`
|
Lastseen map[string]time.Time `json:"lastseen,omitempty"`
|
||||||
|
LastseenNotify map[string]time.Time `json:"lastseen_notify,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *NotifyState) SendTo(e *log.Entry) []string {
|
func (state *NotifyState) SendTo(e *log.Entry) []string {
|
||||||
if to, ok := state.HostTo[e.Hostname]; ok {
|
if to, ok := state.HostTo[e.Hostname]; ok {
|
||||||
|
state.Lastseen[e.Hostname] = time.Now()
|
||||||
var toList []string
|
var toList []string
|
||||||
for toEntry, _ := range to {
|
for toEntry, _ := range to {
|
||||||
if lvl := state.MaxPrioIn[toEntry]; e.Level < lvl {
|
if lvl := state.MaxPrioIn[toEntry]; e.Level < lvl {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if regex, ok := state.RegexIn[toEntry]; ok {
|
||||||
|
stopForTo := false
|
||||||
|
for _, expr := range regex {
|
||||||
|
if expr.MatchString(e.Text) {
|
||||||
|
stopForTo = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if stopForTo {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
toList = append(toList, toEntry)
|
toList = append(toList, toEntry)
|
||||||
}
|
}
|
||||||
if hostname, ok := state.Hostname[e.Hostname]; ok {
|
if hostname, ok := state.Hostname[e.Hostname]; ok {
|
||||||
|
@ -37,12 +51,38 @@ func (state *NotifyState) SendTo(e *log.Entry) []string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (state *NotifyState) AddRegex(to, expression string) error {
|
||||||
|
regex, err := regexp.Compile(expression)
|
||||||
|
if err == nil {
|
||||||
|
if _, ok := state.RegexIn[to]; !ok {
|
||||||
|
state.RegexIn[to] = make(map[string]*regexp.Regexp)
|
||||||
|
}
|
||||||
|
state.RegexIn[to][expression] = regex
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func ReadStateFile(path string) *NotifyState {
|
func ReadStateFile(path string) *NotifyState {
|
||||||
var state NotifyState
|
var state NotifyState
|
||||||
if f, err := os.Open(path); err == nil { // transform data to legacy meshviewer
|
if f, err := os.Open(path); err == nil { // transform data to legacy meshviewer
|
||||||
if err = json.NewDecoder(f).Decode(&state); err == nil {
|
if err = json.NewDecoder(f).Decode(&state); err == nil {
|
||||||
fmt.Println("loaded", len(state.HostTo), "hosts")
|
fmt.Println("loaded", len(state.HostTo), "hosts")
|
||||||
state.regexIn = make(map[string]map[string]*regexp.Regexp)
|
if state.Lastseen == nil {
|
||||||
|
state.Lastseen = make(map[string]time.Time)
|
||||||
|
}
|
||||||
|
if state.LastseenNotify == nil {
|
||||||
|
state.LastseenNotify = make(map[string]time.Time)
|
||||||
|
}
|
||||||
|
if state.RegexIn == nil {
|
||||||
|
state.RegexIn = make(map[string]map[string]*regexp.Regexp)
|
||||||
|
} else {
|
||||||
|
for to, regexs := range state.RegexIn {
|
||||||
|
for exp, _ := range regexs {
|
||||||
|
state.AddRegex(to, exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return &state
|
return &state
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("failed to unmarshal nodes:", err)
|
fmt.Println("failed to unmarshal nodes:", err)
|
||||||
|
@ -51,11 +91,12 @@ func ReadStateFile(path string) *NotifyState {
|
||||||
fmt.Println("failed to open state notify file: ", path, ":", err)
|
fmt.Println("failed to open state notify file: ", path, ":", err)
|
||||||
}
|
}
|
||||||
return &NotifyState{
|
return &NotifyState{
|
||||||
Hostname: make(map[string]string),
|
Hostname: make(map[string]string),
|
||||||
HostTo: make(map[string]map[string]bool),
|
HostTo: make(map[string]map[string]bool),
|
||||||
MaxPrioIn: make(map[string]log.LogLevel),
|
MaxPrioIn: make(map[string]log.LogLevel),
|
||||||
RegexIn: make(map[string]map[string]bool),
|
RegexIn: make(map[string]map[string]*regexp.Regexp),
|
||||||
regexIn: make(map[string]map[string]*regexp.Regexp),
|
Lastseen: make(map[string]time.Time),
|
||||||
|
LastseenNotify: make(map[string]time.Time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue