remove dependencies on enescakir/emoji, gotest.tools (#2837)

* wrap emoji package in pkg/emoji
* remove dependency on enescakir/emoji
* remove dependency on gotest.tools
* lint (whitespace)
This commit is contained in:
mmetc 2024-02-23 16:05:01 +01:00 committed by GitHub
parent 4bf640c6e8
commit a23fe06d68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 140 additions and 67 deletions

View file

@ -5,9 +5,9 @@ import (
"time"
"github.com/aquasecurity/table"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
func getBouncersTable(out io.Writer, bouncers []*ent.Bouncer) {
@ -17,11 +17,9 @@ func getBouncersTable(out io.Writer, bouncers []*ent.Bouncer) {
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
for _, b := range bouncers {
var revoked string
if !b.Revoked {
revoked = emoji.CheckMark.String()
} else {
revoked = emoji.Prohibited.String()
revoked := emoji.CheckMark
if b.Revoked {
revoked = emoji.Prohibited
}
t.AddRow(b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType)

View file

@ -4,9 +4,9 @@ import (
"io"
"github.com/aquasecurity/table"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
func cmdConsoleStatusTable(out io.Writer, consoleCfg csconfig.ConsoleConfig) {
@ -17,28 +17,28 @@ func cmdConsoleStatusTable(out io.Writer, consoleCfg csconfig.ConsoleConfig) {
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft)
for _, option := range csconfig.CONSOLE_CONFIGS {
activated := string(emoji.CrossMark)
activated := emoji.CrossMark
switch option {
case csconfig.SEND_CUSTOM_SCENARIOS:
if *consoleCfg.ShareCustomScenarios {
activated = string(emoji.CheckMarkButton)
activated = emoji.CheckMarkButton
}
case csconfig.SEND_MANUAL_SCENARIOS:
if *consoleCfg.ShareManualDecisions {
activated = string(emoji.CheckMarkButton)
activated = emoji.CheckMarkButton
}
case csconfig.SEND_TAINTED_SCENARIOS:
if *consoleCfg.ShareTaintedScenarios {
activated = string(emoji.CheckMarkButton)
activated = emoji.CheckMarkButton
}
case csconfig.SEND_CONTEXT:
if *consoleCfg.ShareContext {
activated = string(emoji.CheckMarkButton)
activated = emoji.CheckMarkButton
}
case csconfig.CONSOLE_MANAGEMENT:
if *consoleCfg.ConsoleManagement {
activated = string(emoji.CheckMarkButton)
activated = emoji.CheckMarkButton
}
}

View file

@ -11,13 +11,13 @@ import (
"text/template"
"github.com/AlecAivazis/survey/v2"
"github.com/enescakir/emoji"
"github.com/fatih/color"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/crowdsec/pkg/dumps"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
)

View file

@ -5,8 +5,8 @@ import (
"io"
"github.com/aquasecurity/table"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
)
@ -17,9 +17,9 @@ func hubTestResultTable(out io.Writer, testResult map[string]bool) {
t.SetAlignment(table.AlignLeft)
for testName, success := range testResult {
status := emoji.CheckMarkButton.String()
status := emoji.CheckMarkButton
if !success {
status = emoji.CrossMark.String()
status = emoji.CrossMark
}
t.AddRow(testName, status)
@ -50,11 +50,12 @@ func hubTestParserCoverageTable(out io.Writer, coverage []hubtest.Coverage) {
parserTested := 0
for _, test := range coverage {
status := emoji.RedCircle.String()
status := emoji.RedCircle
if test.TestsCount > 0 {
status = emoji.GreenCircle.String()
status = emoji.GreenCircle
parserTested++
}
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
}
@ -70,11 +71,12 @@ func hubTestAppsecRuleCoverageTable(out io.Writer, coverage []hubtest.Coverage)
parserTested := 0
for _, test := range coverage {
status := emoji.RedCircle.String()
status := emoji.RedCircle
if test.TestsCount > 0 {
status = emoji.GreenCircle.String()
status = emoji.GreenCircle
parserTested++
}
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
}
@ -90,11 +92,12 @@ func hubTestScenarioCoverageTable(out io.Writer, coverage []hubtest.Coverage) {
parserTested := 0
for _, test := range coverage {
status := emoji.RedCircle.String()
status := emoji.RedCircle
if test.TestsCount > 0 {
status = emoji.GreenCircle.String()
status = emoji.GreenCircle
parserTested++
}
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
}

View file

@ -5,9 +5,9 @@ import (
"time"
"github.com/aquasecurity/table"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
func getAgentsTable(out io.Writer, machines []*ent.Machine) {
@ -17,17 +17,16 @@ func getAgentsTable(out io.Writer, machines []*ent.Machine) {
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
for _, m := range machines {
var validated string
validated := emoji.Prohibited
if m.IsValidated {
validated = emoji.CheckMark.String()
} else {
validated = emoji.Prohibited.String()
validated = emoji.CheckMark
}
hb, active := getLastHeartbeat(m)
if !active {
hb = emoji.Warning.String() + " " + hb
hb = emoji.Warning + " " + hb
}
t.AddRow(m.MachineId, m.IpAddress, m.UpdatedAt.Format(time.RFC3339), validated, m.Version, m.AuthType, hb)
}

View file

@ -6,7 +6,8 @@ import (
"strings"
"github.com/aquasecurity/table"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
func notificationListTable(out io.Writer, ncfgs map[string]NotificationsCfg) {
@ -14,24 +15,31 @@ func notificationListTable(out io.Writer, ncfgs map[string]NotificationsCfg) {
t.SetHeaders("Active", "Name", "Type", "Profile name")
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
keys := make([]string, 0, len(ncfgs))
for k := range ncfgs {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return len(ncfgs[keys[i]].Profiles) > len(ncfgs[keys[j]].Profiles)
})
for _, k := range keys {
b := ncfgs[k]
profilesList := []string{}
for _, p := range b.Profiles {
profilesList = append(profilesList, p.Name)
}
active := emoji.CheckMark.String()
active := emoji.CheckMark
if len(profilesList) == 0 {
active = emoji.Prohibited.String()
active = emoji.Prohibited
}
t.AddRow(active, b.Config.Name, b.Config.Type, strings.Join(profilesList, ", "))
}
t.Render()
}

View file

@ -6,9 +6,9 @@ import (
"strconv"
"github.com/aquasecurity/table"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
func listHubItemTable(out io.Writer, title string, items []*cwhub.Item) {
@ -21,6 +21,7 @@ func listHubItemTable(out io.Writer, title string, items []*cwhub.Item) {
status := fmt.Sprintf("%v %s", item.State.Emoji(), item.State.Text())
t.AddRow(item.Name, status, item.State.LocalVersion, item.State.LocalPath)
}
renderTableTitle(out, title)
t.Render()
}
@ -42,6 +43,7 @@ func scenarioMetricsTable(out io.Writer, itemName string, metrics map[string]int
if metrics["instantiation"] == 0 {
return
}
t := newTable(out)
t.SetHeaders("Current Count", "Overflows", "Instantiated", "Poured", "Expired")
@ -72,6 +74,7 @@ func parserMetricsTable(out io.Writer, itemName string, metrics map[string]map[s
strconv.Itoa(stats["parsed"]),
strconv.Itoa(stats["unparsed"]),
)
showTable = true
}
}

3
go.mod
View file

@ -33,7 +33,6 @@ require (
github.com/dghubble/sling v1.3.0
github.com/docker/docker v24.0.7+incompatible
github.com/docker/go-connections v0.4.0
github.com/enescakir/emoji v1.0.0
github.com/fatih/color v1.15.0
github.com/fsnotify/fsnotify v1.6.0
github.com/gin-gonic/gin v1.9.1
@ -92,7 +91,6 @@ require (
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.0
k8s.io/apiserver v0.28.4
)
@ -210,6 +208,7 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gotest.tools/v3 v3.5.0 // indirect
k8s.io/api v0.28.4 // indirect
k8s.io/apimachinery v0.28.4 // indirect
k8s.io/klog/v2 v2.100.1 // indirect

2
go.sum
View file

@ -124,8 +124,6 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/enescakir/emoji v1.0.0 h1:W+HsNql8swfCQFtioDGDHCHri8nudlK1n5p2rHCJoog=
github.com/enescakir/emoji v1.0.0/go.mod h1:Bt1EKuLnKDTYpLALApstIkAjdDrS/8IAgTkKp+WKFD0=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=

View file

@ -2,6 +2,7 @@ package loki_test
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
@ -13,19 +14,17 @@ import (
"testing"
"time"
"context"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
tomb "gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/cstest"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/loki"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
tomb "gopkg.in/tomb.v2"
"gotest.tools/v3/assert"
)
func TestConfiguration(t *testing.T) {
log.Infof("Test 'TestConfigure'")
tests := []struct {
@ -127,22 +126,26 @@ query: >
subLogger := log.WithFields(log.Fields{
"type": "loki",
})
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
lokiSource := loki.LokiSource{}
err := lokiSource.Configure([]byte(test.config), subLogger)
cstest.AssertErrorContains(t, err, test.expectedErr)
if test.password != "" {
p := lokiSource.Config.Auth.Password
if test.password != p {
t.Fatalf("Password mismatch : %s != %s", test.password, p)
}
}
if test.waitForReady != 0 {
if lokiSource.Config.WaitForReady != test.waitForReady {
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
}
}
if test.delayFor != 0 {
if lokiSource.Config.DelayFor != test.delayFor {
t.Fatalf("Wrong DelayFor %v != %v", lokiSource.Config.DelayFor, test.delayFor)
@ -154,6 +157,7 @@ query: >
func TestConfigureDSN(t *testing.T) {
log.Infof("Test 'TestConfigureDSN'")
tests := []struct {
name string
dsn string
@ -218,7 +222,9 @@ func TestConfigureDSN(t *testing.T) {
"type": "loki",
"name": test.name,
})
t.Logf("Test : %s", test.name)
lokiSource := &loki.LokiSource{}
err := lokiSource.ConfigureByDSN(test.dsn, map[string]string{"type": "testtype"}, subLogger, "")
cstest.AssertErrorContains(t, err, test.expectedErr)
@ -234,17 +240,20 @@ func TestConfigureDSN(t *testing.T) {
t.Fatalf("Password mismatch : %s != %s", test.password, p)
}
}
if test.scheme != "" {
url, _ := url.Parse(lokiSource.Config.URL)
if test.scheme != url.Scheme {
t.Fatalf("Schema mismatch : %s != %s", test.scheme, url.Scheme)
}
}
if test.waitForReady != 0 {
if lokiSource.Config.WaitForReady != test.waitForReady {
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
}
}
if test.delayFor != 0 {
if lokiSource.Config.DelayFor != test.delayFor {
t.Fatalf("Wrong DelayFor %v != %v", lokiSource.Config.DelayFor, test.delayFor)
@ -272,27 +281,36 @@ func feedLoki(logger *log.Entry, n int, title string) error {
Line: fmt.Sprintf("Log line #%d %v", i, title),
}
}
buff, err := json.Marshal(streams)
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodPost, "http://127.0.0.1:3100/loki/api/v1/push", bytes.NewBuffer(buff))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Scope-OrgID", "1234")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
b, _ := io.ReadAll(resp.Body)
logger.Error(string(b))
return fmt.Errorf("Bad post status %d", resp.StatusCode)
}
logger.Info(n, " Events sent")
return nil
}
@ -300,9 +318,11 @@ func TestOneShotAcquisition(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping test on windows")
}
log.SetOutput(os.Stdout)
log.SetLevel(log.InfoLevel)
log.Info("Test 'TestStreamingAcquisition'")
title := time.Now().String() // Loki will be messy, with a lot of stuff, lets use a unique key
tests := []struct {
config string
@ -327,6 +347,7 @@ since: 1h
})
lokiSource := loki.LokiSource{}
err := lokiSource.Configure([]byte(ts.config), subLogger)
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
@ -338,19 +359,23 @@ since: 1h
out := make(chan types.Event)
read := 0
go func() {
for {
<-out
read++
}
}()
lokiTomb := tomb.Tomb{}
err = lokiSource.OneShotAcquisition(out, &lokiTomb)
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
assert.Equal(t, 20, read)
assert.Equal(t, 20, read)
}
}
@ -358,9 +383,11 @@ func TestStreamingAcquisition(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping test on windows")
}
log.SetOutput(os.Stdout)
log.SetLevel(log.InfoLevel)
log.Info("Test 'TestStreamingAcquisition'")
title := time.Now().String()
tests := []struct {
name string
@ -396,6 +423,7 @@ query: >
expectedLines: 20,
},
}
for _, ts := range tests {
t.Run(ts.name, func(t *testing.T) {
logger := log.New()
@ -407,10 +435,12 @@ query: >
out := make(chan types.Event)
lokiTomb := tomb.Tomb{}
lokiSource := loki.LokiSource{}
err := lokiSource.Configure([]byte(ts.config), subLogger)
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
err = lokiSource.StreamingAcquisition(out, &lokiTomb)
cstest.AssertErrorContains(t, err, ts.streamErr)
@ -418,22 +448,26 @@ query: >
return
}
time.Sleep(time.Second * 2) //We need to give time to start reading from the WS
time.Sleep(time.Second * 2) // We need to give time to start reading from the WS
readTomb := tomb.Tomb{}
readCtx, cancel := context.WithTimeout(context.Background(), time.Second*10)
count := 0
readTomb.Go(func() error {
defer cancel()
for {
select {
case <-readCtx.Done():
return readCtx.Err()
case evt := <-out:
count++
if !strings.HasSuffix(evt.Line.Raw, title) {
return fmt.Errorf("Incorrect suffix : %s", evt.Line.Raw)
}
if count == ts.expectedLines {
return nil
}
@ -447,20 +481,23 @@ query: >
}
err = readTomb.Wait()
cancel()
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
assert.Equal(t, count, ts.expectedLines)
assert.Equal(t, ts.expectedLines, count)
})
}
}
func TestStopStreaming(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping test on windows")
}
config := `
mode: tail
source: loki
@ -476,24 +513,30 @@ query: >
})
title := time.Now().String()
lokiSource := loki.LokiSource{}
err := lokiSource.Configure([]byte(config), subLogger)
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
out := make(chan types.Event)
lokiTomb := &tomb.Tomb{}
err = lokiSource.StreamingAcquisition(out, lokiTomb)
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
time.Sleep(time.Second * 2)
err = feedLoki(subLogger, 1, title)
if err != nil {
t.Fatalf("Unexpected error : %s", err)
}
lokiTomb.Kill(nil)
err = lokiTomb.Wait()
if err != nil {
t.Fatalf("Unexpected error : %s", err)
@ -519,5 +562,6 @@ func (l *LogValue) MarshalJSON() ([]byte, error) {
if err != nil {
return nil, err
}
return []byte(fmt.Sprintf(`["%d",%s]`, l.Time.UnixNano(), string(line))), nil
}

View file

@ -7,7 +7,8 @@ import (
"slices"
"github.com/Masterminds/semver/v3"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
const (
@ -84,7 +85,7 @@ func (s *ItemState) Text() string {
}
// Emoji returns the status of the item as an emoji (eg. emoji.Warning).
func (s *ItemState) Emoji() emoji.Emoji {
func (s *ItemState) Emoji() string {
switch {
case s.IsLocal():
return emoji.House

View file

@ -13,7 +13,7 @@ import (
"os"
"path/filepath"
"github.com/enescakir/emoji"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)
// Upgrade downloads and applies the last version of the item from the hub.
@ -60,6 +60,7 @@ func (i *Item) Upgrade(force bool) (bool, error) {
// TODO: use a better way to communicate this
fmt.Printf("updated %s\n", i.Name)
i.hub.logger.Infof("%v %s: updated", emoji.Package, i.Name)
updated = true
}
@ -151,7 +152,7 @@ func (i *Item) FetchLatest() ([]byte, string, error) {
i.hub.logger.Errorf("Downloaded version doesn't match index, please 'hub update'")
i.hub.logger.Debugf("got %s, expected %s", meow, i.Versions[i.Version].Digest)
return nil, "", fmt.Errorf("invalid download hash")
return nil, "", errors.New("invalid download hash")
}
return body, url, nil

View file

@ -1,6 +1,7 @@
package dumps
import (
"errors"
"fmt"
"io"
"os"
@ -8,13 +9,15 @@ import (
"strings"
"time"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/go-cs-lib/maptools"
"github.com/enescakir/emoji"
"github.com/fatih/color"
diff "github.com/r3labs/diff/v2"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/maptools"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
type ParserResult struct {
@ -56,7 +59,7 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
var lastStage string
//Loop over stages to find last successful one with at least one parser
// Loop over stages to find last successful one with at least one parser
for i := len(stages) - 2; i >= 0; i-- {
if len(pdump[stages[i]]) != 0 {
lastStage = stages[i]
@ -73,7 +76,7 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
sort.Strings(parsers)
if len(parsers) == 0 {
return nil, fmt.Errorf("no parser found. Please install the appropriate parser and retry")
return nil, errors.New("no parser found. Please install the appropriate parser and retry")
}
lastParser := parsers[len(parsers)-1]
@ -90,14 +93,15 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
}
func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpOpts) {
//note : we can use line -> time as the unique identifier (of acquisition)
// note : we can use line -> time as the unique identifier (of acquisition)
state := make(map[time.Time]map[string]map[string]ParserResult)
assoc := make(map[time.Time]string, 0)
parser_order := make(map[string][]string)
for stage, parsers := range parserResults {
//let's process parsers in the order according to idx
// let's process parsers in the order according to idx
parser_order[stage] = make([]string, len(parsers))
for pname, parser := range parsers {
if len(parser) > 0 {
parser_order[stage][parser[0].Idx-1] = pname
@ -128,14 +132,14 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
continue
}
//it might be bucket overflow being reprocessed, skip this
// it might be bucket overflow being reprocessed, skip this
if _, ok := state[evt.Line.Time]; !ok {
state[evt.Line.Time] = make(map[string]map[string]ParserResult)
assoc[evt.Line.Time] = evt.Line.Raw
}
//there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
if _, ok := state[evt.Line.Time]["buckets"]; !ok {
state[evt.Line.Time]["buckets"] = make(map[string]ParserResult)
}
@ -148,7 +152,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
red := color.New(color.FgRed).SprintFunc()
green := color.New(color.FgGreen).SprintFunc()
whitelistReason := ""
//get each line
// get each line
for tstamp, rawstr := range assoc {
if opts.SkipOk {
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
@ -161,8 +165,8 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
skeys := make([]string, 0, len(state[tstamp]))
for k := range state[tstamp] {
//there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
if k == "buckets" {
continue
}
@ -216,6 +220,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
whitelistReason = parsers[parser].Evt.WhitelistReason
}
}
updated++
case "delete":
deleted++
@ -277,7 +282,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
sep = "├"
}
//did the event enter the bucket pour phase ?
// did the event enter the bucket pour phase ?
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
fmt.Printf("\t%s-------- parser success %s\n", sep, emoji.GreenCircle)
} else if whitelistReason != "" {
@ -286,7 +291,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
fmt.Printf("\t%s-------- parser failure %s\n", sep, emoji.RedCircle)
}
//now print bucket info
// now print bucket info
if len(state[tstamp]["buckets"]) > 0 {
fmt.Printf("\t├ Scenarios\n")
}
@ -294,8 +299,8 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
bnames := make([]string, 0, len(state[tstamp]["buckets"]))
for k := range state[tstamp]["buckets"] {
//there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
if k == "OK" {
continue
}

14
pkg/emoji/emoji.go Normal file
View file

@ -0,0 +1,14 @@
package emoji
const (
CheckMarkButton = "\u2705" // ✅
CheckMark = "\u2714\ufe0f" // ✔️
CrossMark = "\u274c" // ❌
GreenCircle = "\U0001f7e2" // 🟢
House = "\U0001f3e0" // 🏠
Package = "\U0001f4e6" // 📦
Prohibited = "\U0001f6ab" // 🚫
QuestionMark = "\u2753" // ❓
RedCircle = "\U0001f534" // 🔴
Warning = "\u26a0\ufe0f" // ⚠️
)