Skip to content

Commit

Permalink
feat: streaks
Browse files Browse the repository at this point in the history
  • Loading branch information
kevincobain2000 committed Jan 19, 2025
1 parent 93f3650 commit 291dd67
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 58 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/MatusOllah/slogcolor v1.4.0
github.com/gravwell/gravwell/v3 v3.8.34
github.com/jasonlvhit/gocron v0.0.1
github.com/k0kubun/pp v3.0.1+incompatible
github.com/kevincobain2000/go-msteams v1.1.1
github.com/mattn/go-isatty v0.0.20
github.com/natefinch/lumberjack v2.0.0+incompatible
Expand All @@ -17,6 +18,7 @@ require (
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ github.com/gravwell/gravwell/v3 v3.8.34/go.mod h1:FsIn6mNCcY7wEswbhxRpLchB9cF5jj
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU=
github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kevincobain2000/go-msteams v1.1.1 h1:vZ8AYvVmiCdC+VZwsw7RFhb89RG/GasX9kvbdKheFN4=
github.com/kevincobain2000/go-msteams v1.1.1/go.mod h1:+HowoQQHg9HLfx3CYQGImGGYw20+kN9rFmUXgxrqBzo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand Down
17 changes: 8 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"flag"
"fmt"
"log/slog"
"os"
Expand All @@ -26,9 +25,6 @@ var caches = make(map[string]*cache.Cache)
func main() {
pkg.Parseflags(&f)
pkg.SetupLoggingStdout(f) // nolint: errcheck
flag.VisitAll(func(f *flag.Flag) {
slog.Info(f.Name, slog.String("value", f.Value.String()))
})
parseProxy()
wantsVersion()
validate()
Expand All @@ -39,7 +35,7 @@ func main() {
}

var err error
newFilePaths, err := pkg.FilesByPattern(f.FilePath, 86400)
newFilePaths, err := pkg.FilesByPattern(f.FilePath, f.FileRecentSecs)
if err != nil {
slog.Error("Error finding files", "error", err.Error())
return
Expand Down Expand Up @@ -132,7 +128,7 @@ func cron() {

func syncFilePaths() {
var err error
newFilePaths, err := pkg.FilesByPattern(f.FilePath, 86400)
newFilePaths, err := pkg.FilesByPattern(f.FilePath, f.FileRecentSecs)
if err != nil {
slog.Error("Error finding files", "error", err.Error())
return
Expand Down Expand Up @@ -183,19 +179,22 @@ func watch(filePath string) {
}

func reportResult(result *pkg.ScanResult) {
slog.Info("File info", "filePath", result.FilePath, "size", result.FileInfo.Size(), "modTime", result.FileInfo.ModTime())
slog.Info("Lines read", "count", result.LinesRead)
slog.Info("Scanning complete", "filePath", result.FilePath)
slog.Info("1st line", "date", result.FirstDate, "line", pkg.Truncate(result.FirstLine, pkg.TruncateMax))
slog.Info("Preview line", "line", pkg.Truncate(result.PreviewLine, pkg.TruncateMax))
slog.Info("Last line", "date", result.LastDate, "line", pkg.Truncate(result.LastLine, pkg.TruncateMax))
slog.Info("Error count", "percent", fmt.Sprintf("%d (%.2f)", result.ErrorCount, result.ErrorPercent)+"%")
slog.Info("Error history", "streaks", result.Streak)
slog.Info("History", "max streak", f.Streak, "current streaks", result.Streak, "symbols", pkg.StreakSymbols(result.Streak, f.Streak, f.Min))
slog.Info("Scan", "count", result.ScanCount)

if result.ErrorCount < f.Min {
if result.ScanCount == 1 {
return
}

if pkg.NonStreakZero(result.Streak, f.Streak) {
if !pkg.NonStreakZero(result.Streak, f.Streak, f.Min) {
slog.Info("Streak not met", "streak", f.Streak, "streaks", result.Streak)
return
}

Expand Down
38 changes: 20 additions & 18 deletions pkg/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@ import (
)

type Flags struct {
FilePath string
FilePathsCap int
Match string
Ignore string
PostCommand string
LogFile string
FilePath string
FilePathsCap int
FileRecentSecs uint64
Match string
Ignore string
PostCommand string
LogFile string

Min int
Streak int
Every uint64
Proxy string
LogLevel int
MemLimit int
MSTeamsHook string
MaxBufferSizeMB int
Test bool
Version bool
Min int
Streak int
Every uint64
Proxy string
LogLevel int
MemLimit int
MSTeamsHook string
MaxBufferMB int
Test bool
Version bool
}

func Parseflags(f *Flags) {
Expand All @@ -33,11 +34,12 @@ func Parseflags(f *Flags) {
flag.StringVar(&f.PostCommand, "post-cmd", "", "run this shell command after every scan when min errors are found")
flag.Uint64Var(&f.Every, "every", 0, "run every n seconds (0 to run once)")
flag.IntVar(&f.LogLevel, "log-level", 0, "log level (0=info, -4=debug, 4=warn, 8=error)")
flag.IntVar(&f.MemLimit, "mem-limit", 256, "memory limit in MB (0 to disable)")
flag.IntVar(&f.MemLimit, "mem-limit", 128, "memory limit in MB (0 to disable)")
flag.IntVar(&f.FilePathsCap, "file-paths-cap", 100, "max number of file paths to watch")
flag.Uint64Var(&f.FileRecentSecs, "file-recent-secs", 86400, "only files modified in the last n seconds, 0 to disable")
flag.IntVar(&f.Min, "min", 1, "on minimum num of matches, it should notify")
flag.IntVar(&f.Streak, "streak", 1, "on minimum num of streak matches, it should notify")
flag.IntVar(&f.MaxBufferSizeMB, "max-buffer-size-mb", 0, "max buffer size in MB, default is 0 (not provided) for go's default 64KB")
flag.IntVar(&f.MaxBufferMB, "mbf", 0, "max buffer in MB, default is 0 (not provided) for go's default 64KB")
flag.BoolVar(&f.Version, "version", false, "")
flag.BoolVar(&f.Test, "test", false, `Quickly test paths or regex
# will test if the input matches the regex
Expand Down
46 changes: 32 additions & 14 deletions pkg/notify.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"log/slog"
"os"
"time"

gmt "github.com/kevincobain2000/go-msteams/src"
)
Expand Down Expand Up @@ -62,18 +63,6 @@ func Notify(result *ScanResult, f Flags, version string) {
Label: "Ignore Pattern",
Message: f.Ignore,
},
{
Label: "Min Errors Threshold",
Message: fmt.Sprintf("%d", f.Min),
},
{
Label: "Lines Read",
Message: fmt.Sprintf("%d", result.LinesRead),
},
{
Label: "Total Errors Found",
Message: fmt.Sprintf("%d (%.2f)", result.ErrorCount, result.ErrorPercent) + "%",
},
{
Label: "First Line",
Message: Truncate(result.FirstLine, TruncateMax),
Expand All @@ -86,11 +75,40 @@ func Notify(result *ScanResult, f Flags, version string) {
Label: "Last Line",
Message: Truncate(result.LastLine, TruncateMax),
},
{
Label: "Details",
Message: fmt.Sprintf(
"Min Threshold: %d, Lines Read: %d\n\rMatches Found: %d, Ratio %.2f%%",
f.Min,
result.LinesRead,
result.ErrorCount,
result.ErrorPercent,
),
},
{
Label: fmt.Sprintf("Streaks (Max %d)", f.Streak),
Message: StreakSymbols(result.Streak, f.Streak, f.Min),
},
}
if result.FirstDate != "" || result.LastDate != "" {
var duration string
if result.FirstDate != "" && result.LastDate != "" {
firstDate, err := time.Parse("2006-01-02 15:04:05", result.FirstDate)
if err != nil {
duration = "X"
} else {
lastDate, err := time.Parse("2006-01-02 15:04:05", result.LastDate)
if err == nil {
duration = lastDate.Sub(firstDate).String()
} else {
duration = "X"
}
}
}

details = append(details, gmt.Details{
Label: "Time Range",
Message: fmt.Sprintf("%s to %s", result.FirstDate, result.LastDate),
Label: "Range",
Message: fmt.Sprintf("%s to %s (Duration: %s)", result.FirstDate, result.LastDate, duration),
})
}

Expand Down
16 changes: 9 additions & 7 deletions pkg/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ func Capped[T any](cap int, slice []T) []T {
return slice[:capped]
}

func NonStreakZero(streaks []int, streak int) bool {
nonZeroStreak := make([]int, 0, len(streaks))
for _, v := range streaks {
if v != 0 {
nonZeroStreak = append(nonZeroStreak, v)
func NonStreakZero(streaks []int, streak int, minimum int) bool {
// check if last three elements are over a minimum
if len(streaks) < streak {
return false
}
for i := 0; i < streak; i++ {
if streaks[len(streaks)-1-i] < minimum {
return false
}
}

return len(nonZeroStreak) <= streak
return true
}
18 changes: 18 additions & 0 deletions pkg/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/sha256"
"encoding/hex"
"log/slog"
"strings"
"sync"

"github.com/gravwell/gravwell/v3/timegrinder"
Expand Down Expand Up @@ -65,3 +66,20 @@ func SearchDate(input string) string {
}
return ts.Format("2006-01-02 15:04:05")
}

func StreakSymbols(arr []int, length int, minimum int) string {
var symbols []string
for _, v := range arr {
if v >= minimum {
symbols = append(symbols, "❌️")
} else {
symbols = append(symbols, "✅️")
}
}
// Fill the rest with grey symbols based on streak length
for i := len(symbols); i < length*StreakMultiplier; i++ {
symbols = append([]string{"🔲"}, symbols...)
}

return strings.Join(symbols, " ")
}
2 changes: 1 addition & 1 deletion pkg/testit.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

func TestIt(filepath string, match string) {
fps, err := FilesByPattern(filepath, 86400)
fps, err := FilesByPattern(filepath, 0)
if err != nil {
slog.Error("Error finding files", "error", err.Error())
}
Expand Down
Loading

0 comments on commit 291dd67

Please sign in to comment.