cscli metrics: rename buckets -> scenarios (#2848)
* cscli metrics: rename buckets -> scenarios * update lint configuration * lint
This commit is contained in:
parent
717fc97ca0
commit
e976614645
6 changed files with 35 additions and 17 deletions
|
@ -73,6 +73,10 @@ linters-settings:
|
||||||
- pkg: "github.com/pkg/errors"
|
- pkg: "github.com/pkg/errors"
|
||||||
desc: "errors.Wrap() is deprecated in favor of fmt.Errorf()"
|
desc: "errors.Wrap() is deprecated in favor of fmt.Errorf()"
|
||||||
|
|
||||||
|
wsl:
|
||||||
|
# Allow blocks to end with comments
|
||||||
|
allow-trailing-comment: true
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
enable-all: true
|
||||||
disable:
|
disable:
|
||||||
|
@ -105,6 +109,7 @@ linters:
|
||||||
# - durationcheck # check for two durations multiplied together
|
# - durationcheck # check for two durations multiplied together
|
||||||
# - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
|
# - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
|
||||||
# - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
|
# - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
|
||||||
|
# - execinquery # execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds
|
||||||
# - exportloopref # checks for pointers to enclosing loop variables
|
# - exportloopref # checks for pointers to enclosing loop variables
|
||||||
# - funlen # Tool for detection of long functions
|
# - funlen # Tool for detection of long functions
|
||||||
# - ginkgolinter # enforces standards of using ginkgo and gomega
|
# - ginkgolinter # enforces standards of using ginkgo and gomega
|
||||||
|
@ -203,7 +208,6 @@ linters:
|
||||||
#
|
#
|
||||||
# Too strict / too many false positives (for now?)
|
# Too strict / too many false positives (for now?)
|
||||||
#
|
#
|
||||||
- execinquery # execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds
|
|
||||||
- exhaustruct # Checks if all structure fields are initialized
|
- exhaustruct # Checks if all structure fields are initialized
|
||||||
- forbidigo # Forbids identifiers
|
- forbidigo # Forbids identifiers
|
||||||
- gochecknoglobals # check that no global variables exist
|
- gochecknoglobals # check that no global variables exist
|
||||||
|
|
|
@ -46,7 +46,6 @@ type (
|
||||||
var (
|
var (
|
||||||
ErrMissingConfig = errors.New("prometheus section missing, can't show metrics")
|
ErrMissingConfig = errors.New("prometheus section missing, can't show metrics")
|
||||||
ErrMetricsDisabled = errors.New("prometheus is not enabled, can't show metrics")
|
ErrMetricsDisabled = errors.New("prometheus is not enabled, can't show metrics")
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type metricSection interface {
|
type metricSection interface {
|
||||||
|
@ -59,7 +58,7 @@ type metricStore map[string]metricSection
|
||||||
func NewMetricStore() metricStore {
|
func NewMetricStore() metricStore {
|
||||||
return metricStore{
|
return metricStore{
|
||||||
"acquisition": statAcquis{},
|
"acquisition": statAcquis{},
|
||||||
"buckets": statBucket{},
|
"scenarios": statBucket{},
|
||||||
"parsers": statParser{},
|
"parsers": statParser{},
|
||||||
"lapi": statLapi{},
|
"lapi": statLapi{},
|
||||||
"lapi-machine": statLapiMachine{},
|
"lapi-machine": statLapiMachine{},
|
||||||
|
@ -110,7 +109,7 @@ func (ms metricStore) Fetch(url string) error {
|
||||||
|
|
||||||
mAcquis := ms["acquisition"].(statAcquis)
|
mAcquis := ms["acquisition"].(statAcquis)
|
||||||
mParser := ms["parsers"].(statParser)
|
mParser := ms["parsers"].(statParser)
|
||||||
mBucket := ms["buckets"].(statBucket)
|
mBucket := ms["scenarios"].(statBucket)
|
||||||
mLapi := ms["lapi"].(statLapi)
|
mLapi := ms["lapi"].(statLapi)
|
||||||
mLapiMachine := ms["lapi-machine"].(statLapiMachine)
|
mLapiMachine := ms["lapi-machine"].(statLapiMachine)
|
||||||
mLapiBouncer := ms["lapi-bouncer"].(statLapiBouncer)
|
mLapiBouncer := ms["lapi-bouncer"].(statLapiBouncer)
|
||||||
|
@ -361,7 +360,7 @@ cscli metrics --url http://lapi.local:6060/metrics show acquisition parsers
|
||||||
cscli metrics list`,
|
cscli metrics list`,
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.ExactArgs(0),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(_ *cobra.Command, _ []string) error {
|
||||||
return cli.show(nil, url, noUnit)
|
return cli.show(nil, url, noUnit)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -383,7 +382,7 @@ func (cli *cliMetrics) expandSectionGroups(args []string) []string {
|
||||||
for _, section := range args {
|
for _, section := range args {
|
||||||
switch section {
|
switch section {
|
||||||
case "engine":
|
case "engine":
|
||||||
ret = append(ret, "acquisition", "parsers", "buckets", "stash", "whitelists")
|
ret = append(ret, "acquisition", "parsers", "scenarios", "stash", "whitelists")
|
||||||
case "lapi":
|
case "lapi":
|
||||||
ret = append(ret, "alerts", "decisions", "lapi", "lapi-bouncer", "lapi-decisions", "lapi-machine")
|
ret = append(ret, "alerts", "decisions", "lapi", "lapi-bouncer", "lapi-decisions", "lapi-machine")
|
||||||
case "appsec":
|
case "appsec":
|
||||||
|
@ -413,10 +412,13 @@ cscli metrics show
|
||||||
cscli metrics show engine
|
cscli metrics show engine
|
||||||
|
|
||||||
# Show some specific metrics, show empty tables, connect to a different url
|
# Show some specific metrics, show empty tables, connect to a different url
|
||||||
cscli metrics show acquisition parsers buckets stash --url http://lapi.local:6060/metrics
|
cscli metrics show acquisition parsers scenarios stash --url http://lapi.local:6060/metrics
|
||||||
|
|
||||||
|
# To list available metric types, use "cscli metrics list"
|
||||||
|
cscli metrics list; cscli metrics list -o json
|
||||||
|
|
||||||
# Show metrics in json format
|
# Show metrics in json format
|
||||||
cscli metrics show acquisition parsers buckets stash -o json`,
|
cscli metrics show acquisition parsers scenarios stash -o json`,
|
||||||
// Positional args are optional
|
// Positional args are optional
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
|
@ -467,12 +469,14 @@ func (cli *cliMetrics) list() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal metric types: %w", err)
|
return fmt.Errorf("failed to marshal metric types: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(x))
|
fmt.Println(string(x))
|
||||||
case "raw":
|
case "raw":
|
||||||
x, err := yaml.Marshal(allMetrics)
|
x, err := yaml.Marshal(allMetrics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal metric types: %w", err)
|
return fmt.Errorf("failed to marshal metric types: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(x))
|
fmt.Println(string(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -13,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNilTable means a nil pointer was passed instead of a table instance. This is a programming error.
|
// ErrNilTable means a nil pointer was passed instead of a table instance. This is a programming error.
|
||||||
var ErrNilTable = fmt.Errorf("nil table")
|
var ErrNilTable = errors.New("nil table")
|
||||||
|
|
||||||
func lapiMetricsToTable(t *table.Table, stats map[string]map[string]map[string]int) int {
|
func lapiMetricsToTable(t *table.Table, stats map[string]map[string]map[string]int) int {
|
||||||
// stats: machine -> route -> method -> count
|
// stats: machine -> route -> method -> count
|
||||||
|
@ -44,6 +45,7 @@ func lapiMetricsToTable(t *table.Table, stats map[string]map[string]map[string]i
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(row...)
|
t.AddRow(row...)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +84,7 @@ func wlMetricsToTable(t *table.Table, stats map[string]map[string]map[string]int
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(row...)
|
t.AddRow(row...)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,6 +123,7 @@ func metricsToTable(t *table.Table, stats map[string]map[string]int, keys []stri
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(row...)
|
t.AddRow(row...)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +131,7 @@ func metricsToTable(t *table.Table, stats map[string]map[string]int, keys []stri
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s statBucket) Description() (string, string) {
|
func (s statBucket) Description() (string, string) {
|
||||||
return "Bucket Metrics",
|
return "Scenario Metrics",
|
||||||
`Measure events in different scenarios. Current count is the number of buckets during metrics collection. ` +
|
`Measure events in different scenarios. Current count is the number of buckets during metrics collection. ` +
|
||||||
`Overflows are past event-producing buckets, while Expired are the ones that didn’t receive enough events to Overflow.`
|
`Overflows are past event-producing buckets, while Expired are the ones that didn’t receive enough events to Overflow.`
|
||||||
}
|
}
|
||||||
|
@ -143,13 +147,13 @@ func (s statBucket) Process(bucket, metric string, val int) {
|
||||||
func (s statBucket) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
func (s statBucket) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
||||||
t := newTable(out)
|
t := newTable(out)
|
||||||
t.SetRowLines(false)
|
t.SetRowLines(false)
|
||||||
t.SetHeaders("Bucket", "Current Count", "Overflows", "Instantiated", "Poured", "Expired")
|
t.SetHeaders("Scenario", "Current Count", "Overflows", "Instantiated", "Poured", "Expired")
|
||||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||||
|
|
||||||
keys := []string{"curr_count", "overflow", "instantiation", "pour", "underflow"}
|
keys := []string{"curr_count", "overflow", "instantiation", "pour", "underflow"}
|
||||||
|
|
||||||
if numRows, err := metricsToTable(t, s, keys, noUnit); err != nil {
|
if numRows, err := metricsToTable(t, s, keys, noUnit); err != nil {
|
||||||
log.Warningf("while collecting bucket stats: %s", err)
|
log.Warningf("while collecting scenario stats: %s", err)
|
||||||
} else if numRows > 0 || showEmpty {
|
} else if numRows > 0 || showEmpty {
|
||||||
title, _ := s.Description()
|
title, _ := s.Description()
|
||||||
renderTableTitle(out, "\n"+title+":")
|
renderTableTitle(out, "\n"+title+":")
|
||||||
|
@ -352,6 +356,7 @@ func (s statStash) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
||||||
strconv.Itoa(astats.Count),
|
strconv.Itoa(astats.Count),
|
||||||
}
|
}
|
||||||
t.AddRow(row...)
|
t.AddRow(row...)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +405,9 @@ func (s statLapi) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
||||||
sl,
|
sl,
|
||||||
strconv.Itoa(astats[sl]),
|
strconv.Itoa(astats[sl]),
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(row...)
|
t.AddRow(row...)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -515,6 +522,7 @@ func (s statLapiDecision) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
||||||
strconv.Itoa(hits.Empty),
|
strconv.Itoa(hits.Empty),
|
||||||
strconv.Itoa(hits.NonEmpty),
|
strconv.Itoa(hits.NonEmpty),
|
||||||
)
|
)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,6 +568,7 @@ func (s statDecision) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
||||||
action,
|
action,
|
||||||
strconv.Itoa(hits),
|
strconv.Itoa(hits),
|
||||||
)
|
)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,6 +603,7 @@ func (s statAlert) Table(out io.Writer, noUnit bool, showEmpty bool) {
|
||||||
scenario,
|
scenario,
|
||||||
strconv.Itoa(hits),
|
strconv.Itoa(hits),
|
||||||
)
|
)
|
||||||
|
|
||||||
numRows++
|
numRows++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,7 @@ func TestDistanceHelper(t *testing.T) {
|
||||||
ret, err := expr.Run(vm, env)
|
ret, err := expr.Run(vm, env)
|
||||||
if test.valid {
|
if test.valid {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, test.dist, ret)
|
assert.InDelta(t, test.dist, ret, 0.000001)
|
||||||
} else {
|
} else {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
@ -592,7 +592,7 @@ func TestAtof(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
output, err := expr.Run(program, test.env)
|
output, err := expr.Run(program, test.env)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, test.result, output)
|
require.InDelta(t, test.result, output, 0.000001)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ statics:
|
||||||
|
|
||||||
> `filter: "Line.Src endsWith '/foobar'"`
|
> `filter: "Line.Src endsWith '/foobar'"`
|
||||||
|
|
||||||
- *optional* `filter` : an [expression](https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md) that will be evaluated against the runtime of a line (`Event`)
|
- *optional* `filter` : an [expression](https://github.com/antonmedv/expr/blob/master/docs/language-definition.md) that will be evaluated against the runtime of a line (`Event`)
|
||||||
- if the `filter` is present and returns false, node is not evaluated
|
- if the `filter` is present and returns false, node is not evaluated
|
||||||
- if `filter` is absent or present and returns true, node is evaluated
|
- if `filter` is absent or present and returns true, node is evaluated
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ services:
|
||||||
and must all return true for a service to be detected (implied *and* clause, no
|
and must all return true for a service to be detected (implied *and* clause, no
|
||||||
short-circuit). A missing or empty `when:` section is evaluated as true.
|
short-circuit). A missing or empty `when:` section is evaluated as true.
|
||||||
The [expression
|
The [expression
|
||||||
engine](https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md)
|
engine](https://github.com/antonmedv/expr/blob/master/docs/language-definition.md)
|
||||||
is the same one used by CrowdSec parser filters. You can force the detection of
|
is the same one used by CrowdSec parser filters. You can force the detection of
|
||||||
a process by using the `cscli setup detect... --force-process <processname>`
|
a process by using the `cscli setup detect... --force-process <processname>`
|
||||||
flag. It will always behave as if `<processname>` was running.
|
flag. It will always behave as if `<processname>` was running.
|
||||||
|
|
Loading…
Reference in a new issue