refact "cscli metrics" par 1 (#2805)
This commit is contained in:
parent
4160bb8102
commit
5ff8a03195
4 changed files with 50 additions and 44 deletions
|
@ -195,7 +195,7 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
|
|||
cmd.AddCommand(NewCLIVersion().NewCommand())
|
||||
cmd.AddCommand(NewConfigCmd())
|
||||
cmd.AddCommand(NewCLIHub(getconfig).NewCommand())
|
||||
cmd.AddCommand(NewMetricsCmd())
|
||||
cmd.AddCommand(NewCLIMetrics(getconfig).NewCommand())
|
||||
cmd.AddCommand(NewCLIDashboard(getconfig).NewCommand())
|
||||
cmd.AddCommand(NewCLIDecisions(getconfig).NewCommand())
|
||||
cmd.AddCommand(NewCLIAlerts().NewCommand())
|
||||
|
|
|
@ -19,8 +19,19 @@ import (
|
|||
"github.com/crowdsecurity/go-cs-lib/trace"
|
||||
)
|
||||
|
||||
type cliMetrics struct {
|
||||
cfg configGetter
|
||||
}
|
||||
|
||||
func NewCLIMetrics(getconfig configGetter) *cliMetrics {
|
||||
return &cliMetrics{
|
||||
cfg: getconfig,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FormatPrometheusMetrics is a complete rip from prom2json
|
||||
func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error {
|
||||
func FormatPrometheusMetrics(out io.Writer, url string, formatType string, noUnit bool) error {
|
||||
mfChan := make(chan *dto.MetricFamily, 1024)
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
|
@ -256,9 +267,9 @@ func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error
|
|||
}
|
||||
|
||||
if formatType == "human" {
|
||||
acquisStatsTable(out, acquis_stats)
|
||||
bucketStatsTable(out, buckets_stats)
|
||||
parserStatsTable(out, parsers_stats)
|
||||
acquisStatsTable(out, acquis_stats, noUnit)
|
||||
bucketStatsTable(out, buckets_stats, noUnit)
|
||||
parserStatsTable(out, parsers_stats, noUnit)
|
||||
lapiStatsTable(out, lapi_stats)
|
||||
lapiMachineStatsTable(out, lapi_machine_stats)
|
||||
lapiBouncerStatsTable(out, lapi_bouncer_stats)
|
||||
|
@ -266,8 +277,8 @@ func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error
|
|||
decisionStatsTable(out, decisions_stats)
|
||||
alertStatsTable(out, alerts_stats)
|
||||
stashStatsTable(out, stash_stats)
|
||||
appsecMetricsToTable(out, appsec_engine_stats)
|
||||
appsecRulesToTable(out, appsec_rule_stats)
|
||||
appsecMetricsToTable(out, appsec_engine_stats, noUnit)
|
||||
appsecRulesToTable(out, appsec_rule_stats, noUnit)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -304,52 +315,47 @@ func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error
|
|||
return nil
|
||||
}
|
||||
|
||||
var noUnit bool
|
||||
|
||||
func runMetrics(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
|
||||
url, err := flags.GetString("url")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (cli *cliMetrics) run(url string, noUnit bool) error {
|
||||
cfg := cli.cfg()
|
||||
|
||||
if url != "" {
|
||||
csConfig.Cscli.PrometheusUrl = url
|
||||
cfg.Cscli.PrometheusUrl = url
|
||||
}
|
||||
|
||||
noUnit, err = flags.GetBool("no-unit")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if csConfig.Prometheus == nil {
|
||||
if cfg.Prometheus == nil {
|
||||
return fmt.Errorf("prometheus section missing, can't show metrics")
|
||||
}
|
||||
|
||||
if !csConfig.Prometheus.Enabled {
|
||||
if !cfg.Prometheus.Enabled {
|
||||
return fmt.Errorf("prometheus is not enabled, can't show metrics")
|
||||
}
|
||||
|
||||
if err = FormatPrometheusMetrics(color.Output, csConfig.Cscli.PrometheusUrl, csConfig.Cscli.Output); err != nil {
|
||||
if err := FormatPrometheusMetrics(color.Output, cfg.Cscli.PrometheusUrl, cfg.Cscli.Output, noUnit); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewMetricsCmd() *cobra.Command {
|
||||
cmdMetrics := &cobra.Command{
|
||||
func (cli *cliMetrics) NewCommand() *cobra.Command {
|
||||
var (
|
||||
url string
|
||||
noUnit bool
|
||||
)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "metrics",
|
||||
Short: "Display crowdsec prometheus metrics.",
|
||||
Long: `Fetch metrics from the prometheus server and display them in a human-friendly way`,
|
||||
Args: cobra.ExactArgs(0),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runMetrics,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return cli.run(url, noUnit)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmdMetrics.PersistentFlags()
|
||||
flags.StringP("url", "u", "", "Prometheus url (http://<ip>:<port>/metrics)")
|
||||
flags.Bool("no-unit", false, "Show the real number instead of formatted with units")
|
||||
flags := cmd.Flags()
|
||||
flags.StringVarP(&url, "url", "u", "", "Prometheus url (http://<ip>:<port>/metrics)")
|
||||
flags.BoolVar(&noUnit, "no-unit", false, "Show the real number instead of formatted with units")
|
||||
|
||||
return cmdMetrics
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func lapiMetricsToTable(t *table.Table, stats map[string]map[string]map[string]i
|
|||
return numRows
|
||||
}
|
||||
|
||||
func metricsToTable(t *table.Table, stats map[string]map[string]int, keys []string) (int, error) {
|
||||
func metricsToTable(t *table.Table, stats map[string]map[string]int, keys []string, noUnit bool) (int, error) {
|
||||
if t == nil {
|
||||
return 0, fmt.Errorf("nil table")
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func metricsToTable(t *table.Table, stats map[string]map[string]int, keys []stri
|
|||
return numRows, nil
|
||||
}
|
||||
|
||||
func bucketStatsTable(out io.Writer, stats map[string]map[string]int) {
|
||||
func bucketStatsTable(out io.Writer, stats map[string]map[string]int, noUnit bool) {
|
||||
t := newTable(out)
|
||||
t.SetRowLines(false)
|
||||
t.SetHeaders("Bucket", "Current Count", "Overflows", "Instantiated", "Poured", "Expired")
|
||||
|
@ -89,7 +89,7 @@ func bucketStatsTable(out io.Writer, stats map[string]map[string]int) {
|
|||
|
||||
keys := []string{"curr_count", "overflow", "instantiation", "pour", "underflow"}
|
||||
|
||||
if numRows, err := metricsToTable(t, stats, keys); err != nil {
|
||||
if numRows, err := metricsToTable(t, stats, keys, noUnit); err != nil {
|
||||
log.Warningf("while collecting bucket stats: %s", err)
|
||||
} else if numRows > 0 {
|
||||
renderTableTitle(out, "\nBucket Metrics:")
|
||||
|
@ -97,7 +97,7 @@ func bucketStatsTable(out io.Writer, stats map[string]map[string]int) {
|
|||
}
|
||||
}
|
||||
|
||||
func acquisStatsTable(out io.Writer, stats map[string]map[string]int) {
|
||||
func acquisStatsTable(out io.Writer, stats map[string]map[string]int, noUnit bool) {
|
||||
t := newTable(out)
|
||||
t.SetRowLines(false)
|
||||
t.SetHeaders("Source", "Lines read", "Lines parsed", "Lines unparsed", "Lines poured to bucket")
|
||||
|
@ -105,7 +105,7 @@ func acquisStatsTable(out io.Writer, stats map[string]map[string]int) {
|
|||
|
||||
keys := []string{"reads", "parsed", "unparsed", "pour"}
|
||||
|
||||
if numRows, err := metricsToTable(t, stats, keys); err != nil {
|
||||
if numRows, err := metricsToTable(t, stats, keys, noUnit); err != nil {
|
||||
log.Warningf("while collecting acquis stats: %s", err)
|
||||
} else if numRows > 0 {
|
||||
renderTableTitle(out, "\nAcquisition Metrics:")
|
||||
|
@ -113,13 +113,13 @@ func acquisStatsTable(out io.Writer, stats map[string]map[string]int) {
|
|||
}
|
||||
}
|
||||
|
||||
func appsecMetricsToTable(out io.Writer, metrics map[string]map[string]int) {
|
||||
func appsecMetricsToTable(out io.Writer, metrics map[string]map[string]int, noUnit bool) {
|
||||
t := newTable(out)
|
||||
t.SetRowLines(false)
|
||||
t.SetHeaders("Appsec Engine", "Processed", "Blocked")
|
||||
t.SetAlignment(table.AlignLeft, table.AlignLeft)
|
||||
keys := []string{"processed", "blocked"}
|
||||
if numRows, err := metricsToTable(t, metrics, keys); err != nil {
|
||||
if numRows, err := metricsToTable(t, metrics, keys, noUnit); err != nil {
|
||||
log.Warningf("while collecting appsec stats: %s", err)
|
||||
} else if numRows > 0 {
|
||||
renderTableTitle(out, "\nAppsec Metrics:")
|
||||
|
@ -127,14 +127,14 @@ func appsecMetricsToTable(out io.Writer, metrics map[string]map[string]int) {
|
|||
}
|
||||
}
|
||||
|
||||
func appsecRulesToTable(out io.Writer, metrics map[string]map[string]map[string]int) {
|
||||
func appsecRulesToTable(out io.Writer, metrics map[string]map[string]map[string]int, noUnit bool) {
|
||||
for appsecEngine, appsecEngineRulesStats := range metrics {
|
||||
t := newTable(out)
|
||||
t.SetRowLines(false)
|
||||
t.SetHeaders("Rule ID", "Triggered")
|
||||
t.SetAlignment(table.AlignLeft, table.AlignLeft)
|
||||
keys := []string{"triggered"}
|
||||
if numRows, err := metricsToTable(t, appsecEngineRulesStats, keys); err != nil {
|
||||
if numRows, err := metricsToTable(t, appsecEngineRulesStats, keys, noUnit); err != nil {
|
||||
log.Warningf("while collecting appsec rules stats: %s", err)
|
||||
} else if numRows > 0 {
|
||||
renderTableTitle(out, fmt.Sprintf("\nAppsec '%s' Rules Metrics:", appsecEngine))
|
||||
|
@ -144,7 +144,7 @@ func appsecRulesToTable(out io.Writer, metrics map[string]map[string]map[string]
|
|||
|
||||
}
|
||||
|
||||
func parserStatsTable(out io.Writer, stats map[string]map[string]int) {
|
||||
func parserStatsTable(out io.Writer, stats map[string]map[string]int, noUnit bool) {
|
||||
t := newTable(out)
|
||||
t.SetRowLines(false)
|
||||
t.SetHeaders("Parsers", "Hits", "Parsed", "Unparsed")
|
||||
|
@ -152,7 +152,7 @@ func parserStatsTable(out io.Writer, stats map[string]map[string]int) {
|
|||
|
||||
keys := []string{"hits", "parsed", "unparsed"}
|
||||
|
||||
if numRows, err := metricsToTable(t, stats, keys); err != nil {
|
||||
if numRows, err := metricsToTable(t, stats, keys, noUnit); err != nil {
|
||||
log.Warningf("while collecting parsers stats: %s", err)
|
||||
} else if numRows > 0 {
|
||||
renderTableTitle(out, "\nParser Metrics:")
|
||||
|
|
|
@ -66,7 +66,7 @@ func collectMetrics() ([]byte, []byte, error) {
|
|||
}
|
||||
|
||||
humanMetrics := bytes.NewBuffer(nil)
|
||||
err := FormatPrometheusMetrics(humanMetrics, csConfig.Cscli.PrometheusUrl, "human")
|
||||
err := FormatPrometheusMetrics(humanMetrics, csConfig.Cscli.PrometheusUrl, "human", false)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("could not fetch promtheus metrics: %s", err)
|
||||
|
|
Loading…
Reference in a new issue