Skip to content

Commit

Permalink
feature(metrics): Metrics default to 'ms' and 'b' for 'ci' flag #3477 #…
Browse files Browse the repository at this point in the history
…3476

Signed-off-by: João Reigota <[email protected]>
  • Loading branch information
cx-joao-reigota committed Jun 1, 2021
1 parent d494d5e commit d3d0922
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 41 deletions.
20 changes: 14 additions & 6 deletions internal/console/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func preRun(cmd *cobra.Command) error {
if err != nil {
return errors.New(initError + err.Error())
}
err = metrics.InitializeMetrics(cmd.InheritedFlags().Lookup("profiling"))
err = metrics.InitializeMetrics(cmd.InheritedFlags().Lookup("profiling"), cmd.InheritedFlags().Lookup("ci"))
if err != nil {
return errors.New(initError + err.Error())
}
Expand Down Expand Up @@ -593,18 +593,14 @@ func scan(changedDefaultQueryPath bool) error {
return err
}

elapsed := time.Since(scanStartTime)

summary := getSummary(t, results, scanStartTime, time.Now(), path)

if err := resolveOutputs(&summary, files.Combine(), inspector.GetFailedQueries(), printer); err != nil {
log.Err(err)
return err
}

elapsedStrFormat := "Scan duration: %v\n"
fmt.Printf(elapsedStrFormat, elapsed)
log.Info().Msgf(elapsedStrFormat, elapsed)
printScanDuration(time.Since(scanStartTime))

exitCode := consoleHelpers.ResultsExitCode(&summary)
if consoleHelpers.ShowError("results") && exitCode != 0 {
Expand All @@ -613,6 +609,18 @@ func scan(changedDefaultQueryPath bool) error {
return nil
}

func printScanDuration(elapsed time.Duration) {
if ci {
elapsedStrFormat := "Scan duration: %vms\n"
fmt.Printf(elapsedStrFormat, elapsed.Milliseconds())
log.Info().Msgf(elapsedStrFormat, elapsed.Milliseconds())
} else {
elapsedStrFormat := "Scan duration: %v\n"
fmt.Printf(elapsedStrFormat, elapsed)
log.Info().Msgf(elapsedStrFormat, elapsed)
}
}

func getSummary(t *tracker.CITracker, results []model.Vulnerability, start, end time.Time, scannedPaths []string) model.Summary {
counters := model.Counters{
ScannedFiles: t.FoundFiles,
Expand Down
4 changes: 4 additions & 0 deletions internal/metrics/cpu_metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ var cpuMap = map[string]float64{
"hrs": float64(time.Hour),
}

func (c *cpuMetric) getDefault() string {
return "ms"
}

// Start - start gathering metrics for CPU usage
func (c *cpuMetric) start() {
c.idx = 1
Expand Down
4 changes: 4 additions & 0 deletions internal/metrics/mem_metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func (c *memMetric) start() {
}
}

func (c *memMetric) getDefault() string {
return "B"
}

// Stop - stop gathering metrics for Memory usage
func (c *memMetric) stop() {
c.close()
Expand Down
18 changes: 15 additions & 3 deletions internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"math"
"strconv"
"strings"

"github.com/google/pprof/profile"
Expand All @@ -26,6 +27,7 @@ type metricType interface {
getWriter() *bytes.Buffer
getIndex() int
getMap() map[string]float64
getDefault() string
}

// Metrics - structure to keep information relevant to the metrics calculation
Expand All @@ -36,10 +38,11 @@ type Metrics struct {
location string
Disable bool
total int64
ci bool
}

// InitializeMetrics - creates a new instance of a Metrics based on the type of metrics specified
func InitializeMetrics(metric *pflag.Flag) error {
func InitializeMetrics(metric, ci *pflag.Flag) error {
metricStr := metric.Value.String()
var err error
switch strings.ToLower(metricStr) {
Expand All @@ -63,6 +66,7 @@ func InitializeMetrics(metric *pflag.Flag) error {
// Create temporary dir to keep pprof file
if !Metric.Disable {
Metric.metricsID = metricStr
Metric.ci, _ = strconv.ParseBool(ci.Value.String())
}

return err
Expand Down Expand Up @@ -100,7 +104,8 @@ func (m *Metrics) Stop() {

total := getTotal(p, m.metric.getIndex())
log.Info().
Msgf("Total %s usage for %s: %s", strings.ToUpper(m.metricsID), m.location, formatTotal(total, m.metric.getMap()))
Msgf("Total %s usage for %s: %s", strings.ToUpper(m.metricsID),
m.location, m.formatTotal(total, m.metric.getMap(), m.metric.getDefault()))
m.total = total
}

Expand All @@ -127,10 +132,17 @@ func getTotal(prof *profile.Profile, idx int) int64 {
}

// formatTotal parses total value into a human readble way
func formatTotal(b int64, typeMap map[string]float64) string {
func (m *Metrics) formatTotal(b int64, typeMap map[string]float64, defaultMetric string) string {
value := float64(b)
var formatter float64
var mesure string
if m.ci {
metric := value / typeMap[defaultMetric]
if math.IsNaN(metric) {
metric = 0
}
return fmt.Sprintf("%.f%s", metric, defaultMetric)
}
for k, u := range typeMap {
if u >= formatter && (value/u) >= 1.0 {
formatter = u
Expand Down
124 changes: 92 additions & 32 deletions internal/metrics/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
func TestMetrics_InitializeMetrics(t *testing.T) {
type args struct {
metric mockFlagValue
ci mockFlagValue
}
tests := []struct {
name string
Expand All @@ -23,6 +24,7 @@ func TestMetrics_InitializeMetrics(t *testing.T) {
name: "test_initialize_metrics_cpu",
args: args{
metric: "cpu",
ci: "true",
},
wantErr: false,
disable: false,
Expand All @@ -31,6 +33,7 @@ func TestMetrics_InitializeMetrics(t *testing.T) {
name: "test_initialize_metrics_mem",
args: args{
metric: "mem",
ci: "true",
},
wantErr: false,
disable: false,
Expand All @@ -39,6 +42,7 @@ func TestMetrics_InitializeMetrics(t *testing.T) {
name: "test_initialize_metrics_empty",
args: args{
metric: "",
ci: "true",
},
wantErr: false,
disable: true,
Expand All @@ -47,6 +51,7 @@ func TestMetrics_InitializeMetrics(t *testing.T) {
name: "test_initialize_metrics_unknown",
args: args{
metric: "unknown",
ci: "true",
},
wantErr: true,
disable: true,
Expand All @@ -57,7 +62,10 @@ func TestMetrics_InitializeMetrics(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
err := InitializeMetrics(&pflag.Flag{
Value: tt.args.metric,
})
},
&pflag.Flag{
Value: tt.args.ci,
})
if (err != nil) != tt.wantErr {
t.Errorf("InitializeMetrics = %v, wantErr = %v", err, tt.wantErr)
}
Expand All @@ -79,85 +87,131 @@ func (m mockFlagValue) Type() string {
return string(m)
}

func TestMetrics_formatTotal(t *testing.T) {
func TestMetrics_formatTotal(t *testing.T) { //nolint
type args struct {
b int64
typeMap map[string]float64
b int64
typeMap map[string]float64
defaultMetric string
}
tests := []struct {
name string
args args
want string
name string
args args
want string
metric metricType
ci bool
}{
{
name: "test_format_total_cpu",
args: args{
b: 100,
typeMap: cpuMap,
b: 100,
typeMap: cpuMap,
defaultMetric: "ms",
},
want: "100.00ns",
metric: &cpuMetric{},
want: "100.00ns",
ci: false,
},
{
name: "test_format_total_cpu_ms",
args: args{
b: 10000000,
typeMap: cpuMap,
b: 10000000,
typeMap: cpuMap,
defaultMetric: "ms",
},
want: "10.00ms",
metric: &cpuMetric{},
want: "10.00ms",
ci: false,
},
{
name: "test_format_total_cpu_h",
args: args{
b: 10000000000000,
typeMap: cpuMap,
b: 10000000000000,
typeMap: cpuMap,
defaultMetric: "ms",
},
want: "2.78hrs",
metric: &cpuMetric{},
want: "2.78hrs",
ci: false,
},
{
name: "test_format_total_mem_b",
args: args{
b: 100,
typeMap: memoryMap,
b: 100,
typeMap: memoryMap,
defaultMetric: "B",
},
want: "100.00B",
metric: &memMetric{},
want: "100.00B",
ci: false,
},
{
name: "test_format_total_mem_mb",
args: args{
b: 10000000,
typeMap: memoryMap,
b: 10000000,
typeMap: memoryMap,
defaultMetric: "B",
},
want: "9.54MB",
metric: &memMetric{},
want: "9.54MB",
ci: false,
},
{
name: "test_format_total_mem_tb",
args: args{
b: 10000000000000,
typeMap: memoryMap,
b: 10000000000000,
typeMap: memoryMap,
defaultMetric: "B",
},
want: "9.09TB",
metric: &memMetric{},
want: "9.09TB",
ci: false,
},
{
name: "test_format_total_cpu_nan",
args: args{
b: 0,
typeMap: cpuMap,
b: 0,
typeMap: cpuMap,
defaultMetric: "B",
},
want: "0.00",
metric: &memMetric{},
want: "0.00",
ci: false,
},
{
name: "test_format_total_mem_nan",
args: args{
b: 0,
typeMap: memoryMap,
b: 0,
typeMap: memoryMap,
defaultMetric: "B",
},
want: "0.00",
metric: &memMetric{},
want: "0.00",
ci: false,
},
{
name: "test_format_total_mem_mb_ci",
args: args{
b: 10000000,
typeMap: memoryMap,
defaultMetric: "B",
},
metric: &memMetric{},
want: "10000000B",
ci: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := formatTotal(tt.args.b, tt.args.typeMap)
m := Metrics{
metric: tt.metric,
metricsID: "test",
location: "",
total: 0,
Disable: false,
ci: tt.ci,
}
got := m.formatTotal(tt.args.b, tt.args.typeMap, tt.args.defaultMetric)
require.Equal(t, tt.want, got)
})
}
Expand All @@ -170,6 +224,7 @@ func TestMetrics_Start_Stop(t *testing.T) {
type feilds struct {
value mockFlagValue
allocation []string
ci mockFlagValue
}
tests := []struct {
name string
Expand All @@ -185,6 +240,7 @@ func TestMetrics_Start_Stop(t *testing.T) {
feilds: feilds{
value: "cpu",
allocation: []string{"1", "2", "3"},
ci: "false",
},
disabled: false,
},
Expand All @@ -195,6 +251,7 @@ func TestMetrics_Start_Stop(t *testing.T) {
},
feilds: feilds{
value: "mem",
ci: "false",
allocation: []string{
"1", "2", "3", "4", "5",
"6", "7", "8", "9", "10",
Expand All @@ -211,6 +268,7 @@ func TestMetrics_Start_Stop(t *testing.T) {
},
feilds: feilds{
value: "",
ci: "false",
allocation: []string{"1", "2", "3"},
},
disabled: true,
Expand All @@ -221,6 +279,8 @@ func TestMetrics_Start_Stop(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
err := InitializeMetrics(&pflag.Flag{
Value: tt.feilds.value,
}, &pflag.Flag{
Value: tt.feilds.ci,
})
require.NoError(t, err)
metricFunc(tt.feilds.allocation, tt.args.location)
Expand Down

0 comments on commit d3d0922

Please sign in to comment.