소스 검색

refact "cscli metrics" par 1 (#2805)

mmetc 1 년 전
부모
커밋
5ff8a03195
4개의 변경된 파일50개의 추가작업 그리고 44개의 파일을 삭제
  1. 1 1
      cmd/crowdsec-cli/main.go
  2. 37 31
      cmd/crowdsec-cli/metrics.go
  3. 11 11
      cmd/crowdsec-cli/metrics_table.go
  4. 1 1
      cmd/crowdsec-cli/support.go

+ 1 - 1
cmd/crowdsec-cli/main.go

@@ -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())

+ 37 - 31
cmd/crowdsec-cli/metrics.go

@@ -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
-	}
-
-	noUnit, err = flags.GetBool("no-unit")
-	if err != nil {
-		return err
+		cfg.Cscli.PrometheusUrl = url
 	}
 
-	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
 }

+ 11 - 11
cmd/crowdsec-cli/metrics_table.go

@@ -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:")

+ 1 - 1
cmd/crowdsec-cli/support.go

@@ -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)