forked from falcosecurity/event-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbench.go
125 lines (99 loc) · 3.87 KB
/
bench.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"errors"
"time"
"github.com/falcosecurity/event-generator/pkg/counter"
"github.com/falcosecurity/event-generator/pkg/runner"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var errRoundDurationMustBeLongerThanSleep = errors.New("--round-duration must be longer than --sleep")
// NewBench instantiates the bench subcommand.
func NewBench() *cobra.Command {
c, runEWithOpts := newRunTemplate()
c.Use = "bench [regexp]"
c.Short = "Benchmark for Falco"
c.Long = `Benchmark a running Falco instance.
This command generates a high number of Event Per Second (EPS), to test the events throughput allowed by Falco.
The number of EPS is controlled by the "--sleep" option: reduce the sleeping duration to increase the EPS.
If the "--loop" option is set, the sleeping duration is halved on each round.
The "--pid" option can be used to monitor the Falco process.
N.B.:
- the Falco gRPC Output must be enabled to use this command
- "outputs.rate" and "outputs.max_burst" values within the Falco configuration must be increased,
otherwise EPS will be rate-limited by the throttling mechanism
- since not all actions can be used for benchmarking,
only those actions matching the given regular expression are used
One commmon way to use this command is as following:
event-generator bench "ChangeThreadNamespace|ReadSensitiveFileUntrusted" --all --loop --sleep 10ms --pid $(pidof -s falco)
` + runWarningMessage
c.Args = cobra.ExactArgs(1)
flags := c.Flags()
var pid int
flags.IntVar(&pid, "pid", 0, "A process PID to monitor while benchmarking (e.g. the falco process)")
var roundDuration time.Duration
flags.DurationVar(&roundDuration, "round-duration", time.Second*5, "Duration of a benchmark round")
var pollingTimeout time.Duration
flags.DurationVar(&pollingTimeout, "polling-interval", time.Millisecond*100, "Duration of gRPC APIs polling timeout")
var humanize bool
flags.BoolVar(&humanize, "humanize", true, "Humanize values when printing statistics")
var dryRun bool
flags.BoolVar(&dryRun, "dry-run", false, "Do not connect to Falco gRPC API")
grpcCfg := grpcFlags(flags)
l := logger.StandardLogger()
c.RunE = func(c *cobra.Command, args []string) error {
evts, err := parseEventsArg(args[0])
if err != nil {
return err
}
loop, err := flags.GetBool("loop")
if err != nil {
return err
}
sleep, err := flags.GetDuration("sleep")
if err != nil {
return err
}
if roundDuration <= sleep {
return errRoundDurationMustBeLongerThanSleep
}
opts := append([]counter.Option(nil),
counter.WithActions(evts),
counter.WithLogger(l),
counter.WithLoop(loop),
counter.WithSleep(sleep),
counter.WithRoundDuration(roundDuration),
counter.WithPollingTimeout(pollingTimeout),
counter.WithHumanize(humanize),
counter.WithDryRun(dryRun),
)
if pid != 0 {
opts = append(opts, counter.WithPid(pid))
}
p, err := counter.New(c.Context(), grpcCfg, opts...)
if err != nil {
return err
}
return runEWithOpts(c, args,
runner.WithPlugin(p),
// override runner options:
runner.WithQuiet(true), // reduce runner verbosity
runner.WithSleep(time.Duration(0)), // no sleep, since sleeping will be controlled by the plugin
runner.WithLoop(true), // always loop
)
}
return c
}