149 lines
3.8 KiB
Go
149 lines
3.8 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"flag"
|
|||
|
"fmt"
|
|||
|
"strings"
|
|||
|
|
|||
|
"github.com/nxadm/tail"
|
|||
|
)
|
|||
|
|
|||
|
// ParseChat Parses a string, returns the payload of the chat
|
|||
|
// *sigh*
|
|||
|
// This took effing forever to get right.
|
|||
|
// "Lets start with Regex, cannot go wrong".
|
|||
|
// You have this string:
|
|||
|
// <20><>[ 2022.02.09 10:05:43 ] Kaysee Guru > EX-GBT clr nd
|
|||
|
// Cool. Looks easy.
|
|||
|
// .*\[ (.*?) (.*?) \] (.*?) > (.*)
|
|||
|
// regex101.com says its good
|
|||
|
// And no matter what I do just does not work for some magical reason.
|
|||
|
//
|
|||
|
// Lets do this with splitting by space and compare it with that. Do a bunch of ifs, it works in test aaaaaand....
|
|||
|
// It doesn't work.
|
|||
|
//
|
|||
|
// By now I have a somewhat reliable version, but it fails to look for the word MOTD.
|
|||
|
// I should prolly look into runes()
|
|||
|
// This is terrible
|
|||
|
func ParseChat(chatline string) (LineDate string, LineTime string, LineUser string, Payload []string) {
|
|||
|
logLine := chatline[3:]
|
|||
|
|
|||
|
//var LineDate string
|
|||
|
//var LineTime string
|
|||
|
//var LineUser string
|
|||
|
var LinePayload string
|
|||
|
//var Payload []string
|
|||
|
var splitpos int
|
|||
|
|
|||
|
splitpos = strings.Index(logLine, ">")
|
|||
|
LineDate = logLine[4:24]
|
|||
|
LineTime = logLine[24:42]
|
|||
|
LineUser = logLine[46 : splitpos-2]
|
|||
|
LinePayload = logLine[splitpos+4:]
|
|||
|
LinePayload = shorten(LinePayload)
|
|||
|
Payload = strings.Fields(LinePayload)
|
|||
|
|
|||
|
//fmt.Println(logLine)
|
|||
|
//fmt.Println(LineDate)
|
|||
|
//fmt.Println(LineTime)
|
|||
|
//fmt.Println(LineUser)
|
|||
|
//fmt.Println(splitpos)
|
|||
|
//fmt.Println(LinePayload)
|
|||
|
//fmt.Println(Payload)
|
|||
|
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
func shorten(payload string) (logLine string) {
|
|||
|
runes := []rune(payload)
|
|||
|
for pos, char := range runes {
|
|||
|
if pos%2 == 0 && char != 13 {
|
|||
|
logLine = logLine + string(char)
|
|||
|
}
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// CompareElements Compares a log msg with systems we wish to track
|
|||
|
func CompareElements(alerts []string, payload []string) bool {
|
|||
|
|
|||
|
for _, word := range payload {
|
|||
|
for _, alert := range alerts {
|
|||
|
|
|||
|
if strings.EqualFold(word, alert) {
|
|||
|
//fmt.Println("Found (EF): ", alert, "in", word)
|
|||
|
return true
|
|||
|
} //else {
|
|||
|
// fmt.Println(word, "!=", alert)
|
|||
|
//}
|
|||
|
|
|||
|
// In the odd case somebody links "C-V6DQ*"
|
|||
|
if len(word) > 6 {
|
|||
|
//alert = alert[:len(word)]
|
|||
|
word = word[:6]
|
|||
|
}
|
|||
|
|
|||
|
// In case of partials like "C-V"
|
|||
|
if len(word) < 6 && len(word) >= 3 {
|
|||
|
//word = word[:5]
|
|||
|
alert = alert[:len(word)]
|
|||
|
}
|
|||
|
|
|||
|
if strings.EqualFold(word, alert) {
|
|||
|
//fmt.Println("Found: ", alert, "in", word)
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// playBeep Play a beep
|
|||
|
// Honestly, I tried to play alert.mp3, but after two executions I got a segfault and thought 0x07 it is!
|
|||
|
func playBeep() {
|
|||
|
fmt.Print("\a")
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
|
|||
|
// Deal with parameters first.
|
|||
|
LogLocation := flag.String("l", "", "Location of the log-file to track.")
|
|||
|
LogSystemsRaw := flag.String("s", "jita,Perimeter,New Caldari,Sobaseki", "comma-seperated list of systems")
|
|||
|
//LogAlarm := flag.String("a", "alert.mp3", "Audio file to play when an alert needs to be triggered")
|
|||
|
flag.Parse()
|
|||
|
|
|||
|
// Split the CSV string into different parts
|
|||
|
LogSystems := strings.Split(*LogSystemsRaw, ",")
|
|||
|
|
|||
|
// Do the main loop and start parsing the logfiles
|
|||
|
t, err := tail.TailFile(*LogLocation, tail.Config{Follow: true})
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
|
|||
|
for line := range t.Lines {
|
|||
|
// Cast a line to a text, trim the trash
|
|||
|
logLine := string(line.Text)
|
|||
|
logLine = strings.Trim(logLine, "\n")
|
|||
|
|
|||
|
// Figure out if this is a message we want to deal with
|
|||
|
// > is critical in this regard because it is the start of the message
|
|||
|
// and everything behind it until it hits ] is the username
|
|||
|
splitpos := strings.Index(logLine, ">")
|
|||
|
if -1 == splitpos {
|
|||
|
continue
|
|||
|
}
|
|||
|
|
|||
|
// Somehow I cannot filter out this stuff.
|
|||
|
// EVE System > Channel MOTD
|
|||
|
LineDate, LineTime, LineUser, Payload := ParseChat(logLine)
|
|||
|
|
|||
|
if CompareElements(LogSystems, Payload) {
|
|||
|
playBeep()
|
|||
|
fmt.Println("On", LineDate, "at", LineTime, "", LineUser, "posted", Payload)
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|