Skip to content

Commit 388bace

Browse files
authored
refact cmd/crowdsec: remove globals, lint, etc (#4163)
* remove global additionalLabels * remove (unused) global lastProcessedItem * metrics.go * tighter var scope * cmd/crowdsec: use flagset
1 parent 53de72c commit 388bace

File tree

5 files changed

+66
-68
lines changed

5 files changed

+66
-68
lines changed

cmd/crowdsec/flags.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"os"
67
"runtime"
78
"strings"
89

@@ -18,7 +19,7 @@ type Flags struct {
1819

1920
PrintVersion bool
2021
SingleFileType string
21-
Labels map[string]string
22+
Labels labelsMap
2223
OneShotDSN string
2324
TestMode bool
2425
DisableAgent bool
@@ -54,36 +55,44 @@ func (l *labelsMap) Set(label string) error {
5455
return nil
5556
}
5657

57-
func (f *Flags) parse() {
58-
flag.StringVar(&f.ConfigFile, "c", csconfig.DefaultConfigPath("config.yaml"), "configuration file")
58+
func parseFlags(argv []string) (Flags, error) {
59+
var f Flags
5960

60-
var trace, debug, info, warn, erro, fatal bool
61+
fs := flag.NewFlagSet("crowdsec", flag.ExitOnError)
62+
fs.SetOutput(os.Stderr)
63+
64+
fs.StringVar(&f.ConfigFile, "c", csconfig.DefaultConfigPath("config.yaml"), "configuration file")
6165

62-
flag.BoolVar(&trace, "trace", false, "set log level to 'trace' (VERY verbose)")
63-
flag.BoolVar(&debug, "debug", false, "set log level to 'debug'")
64-
flag.BoolVar(&info, "info", false, "set log level to 'info'")
65-
flag.BoolVar(&warn, "warning", false, "set log level to 'warning'")
66-
flag.BoolVar(&erro, "error", false, "set log level to 'error'")
67-
flag.BoolVar(&fatal, "fatal", false, "set log level to 'fatal'")
68-
69-
flag.BoolVar(&f.PrintVersion, "version", false, "display version")
70-
flag.StringVar(&f.OneShotDSN, "dsn", "", "Process a single data source in time-machine")
71-
flag.StringVar(&f.Transform, "transform", "", "expr to apply on the event after acquisition")
72-
flag.StringVar(&f.SingleFileType, "type", "", "Labels.type for file in time-machine")
73-
flag.Var(&additionalLabels, "label", "Additional Labels for file in time-machine")
74-
flag.BoolVar(&f.TestMode, "t", false, "only test configs")
75-
flag.BoolVar(&f.DisableAgent, "no-cs", false, "disable crowdsec agent")
76-
flag.BoolVar(&f.DisableAPI, "no-api", false, "disable local API")
77-
flag.BoolVar(&f.DisableCAPI, "no-capi", false, "disable communication with Central API")
78-
flag.BoolVar(&f.OrderEvent, "order-event", false, "enforce event ordering with significant performance cost")
66+
var trace, debug, info, warn, erro, fatal bool
67+
fs.BoolVar(&trace, "trace", false, "set log level to 'trace' (VERY verbose)")
68+
fs.BoolVar(&debug, "debug", false, "set log level to 'debug'")
69+
fs.BoolVar(&info, "info", false, "set log level to 'info'")
70+
fs.BoolVar(&warn, "warning", false, "set log level to 'warning'")
71+
fs.BoolVar(&erro, "error", false, "set log level to 'error'")
72+
fs.BoolVar(&fatal, "fatal", false, "set log level to 'fatal'")
73+
74+
fs.BoolVar(&f.PrintVersion, "version", false, "display version")
75+
fs.StringVar(&f.OneShotDSN, "dsn", "", "Process a single data source in time-machine")
76+
fs.StringVar(&f.Transform, "transform", "", "expr to apply on the event after acquisition")
77+
fs.StringVar(&f.SingleFileType, "type", "", "Labels.type for file in time-machine")
78+
f.Labels = make(labelsMap)
79+
fs.Var(&f.Labels, "label", "Additional Labels for file in time-machine")
80+
fs.BoolVar(&f.TestMode, "t", false, "only test configs")
81+
fs.BoolVar(&f.DisableAgent, "no-cs", false, "disable crowdsec agent")
82+
fs.BoolVar(&f.DisableAPI, "no-api", false, "disable local API")
83+
fs.BoolVar(&f.DisableCAPI, "no-capi", false, "disable communication with Central API")
84+
fs.BoolVar(&f.OrderEvent, "order-event", false, "enforce event ordering with significant performance cost")
7985

8086
if runtime.GOOS == "windows" {
81-
flag.StringVar(&f.WinSvc, "winsvc", "", "Windows service Action: Install, Remove etc..")
87+
fs.StringVar(&f.WinSvc, "winsvc", "", "Windows service Action: Install, Remove etc..")
8288
}
8389

84-
flag.StringVar(&f.DumpDir, "dump-data", "", "dump parsers/buckets raw outputs")
85-
flag.StringVar(&f.CPUProfile, "cpu-profile", "", "write cpu profile to file")
86-
flag.Parse()
90+
fs.StringVar(&f.DumpDir, "dump-data", "", "dump parsers/buckets raw outputs")
91+
fs.StringVar(&f.CPUProfile, "cpu-profile", "", "write cpu profile to file")
92+
93+
if err := fs.Parse(argv); err != nil {
94+
return f, err
95+
}
8796

8897
// Set the log level selected by the --trace, --debug, --info, etc. flags,
8998
// giving precedence to the most verbose flag if multiple are set. If no flag is specified,
@@ -102,4 +111,11 @@ func (f *Flags) parse() {
102111
case fatal:
103112
f.LogLevel = log.FatalLevel
104113
}
114+
115+
if len(fs.Args()) > 0 {
116+
return f, fmt.Errorf("argument provided but not defined: %s", fs.Args()[0])
117+
118+
}
119+
120+
return f, nil
105121
}

cmd/crowdsec/main.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ package main
33
import (
44
"context"
55
"errors"
6-
"flag"
76
"fmt"
87
_ "net/http/pprof"
98
"os"
109
"path/filepath"
1110
"runtime/pprof"
1211
"time"
1312

13+
"github.com/fatih/color"
1414
log "github.com/sirupsen/logrus"
1515
"gopkg.in/tomb.v2"
1616

@@ -47,8 +47,6 @@ var (
4747
inputLineChan chan pipeline.Event
4848
inputEventChan chan pipeline.Event
4949
outputEventChan chan pipeline.Event // the buckets init returns its own chan that is used for multiplexing
50-
// settings
51-
lastProcessedItem time.Time // keep track of last item timestamp in time-machine. it is used to GC buckets when we dump them.
5250
pluginBroker csplugin.PluginBroker
5351
)
5452

@@ -77,7 +75,6 @@ func LoadBuckets(cConfig *csconfig.Config, hub *cwhub.Hub) error {
7775

7876
func LoadAcquisition(ctx context.Context, cConfig *csconfig.Config, hub *cwhub.Hub) ([]acquisition.DataSource, error) {
7977
if flags.SingleFileType != "" && flags.OneShotDSN != "" {
80-
flags.Labels = additionalLabels
8178
flags.Labels["type"] = flags.SingleFileType
8279

8380
ds, err := acquisition.LoadAcquisitionFromDSN(ctx, flags.OneShotDSN, flags.Labels, flags.Transform, hub)
@@ -100,10 +97,6 @@ func LoadAcquisition(ctx context.Context, cConfig *csconfig.Config, hub *cwhub.H
10097
return dataSources, nil
10198
}
10299

103-
var (
104-
additionalLabels = make(labelsMap)
105-
)
106-
107100
// LoadConfig returns a configuration parsed from configuration file
108101
func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet bool) (*csconfig.Config, error) {
109102
cConfig, _, err := csconfig.NewConfig(configFile, disableAgent, disableAPI, quiet)
@@ -199,7 +192,7 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
199192
// or uptime of the application
200193
var crowdsecT0 time.Time
201194

202-
func run() error {
195+
func run(flags Flags) error {
203196
if flags.CPUProfile != "" {
204197
f, err := os.Create(flags.CPUProfile)
205198
if err != nil {
@@ -245,22 +238,22 @@ func main() {
245238

246239
crowdsecT0 = time.Now()
247240

248-
// Handle command line arguments
249-
flags.parse()
250-
251-
if len(flag.Args()) > 0 {
252-
fmt.Fprintf(os.Stderr, "argument provided but not defined: %s\n", flag.Args()[0])
253-
flag.Usage()
254-
// the flag package exits with 2 in case of unknown flag
241+
parsedFlags, err := parseFlags(os.Args[1:])
242+
if err != nil {
243+
fmt.Fprintln(os.Stderr, color.RedString("Error:"), err)
244+
// the flag package exits with 2 in case of unknown flag,
245+
// we do the same for extra arguments
255246
os.Exit(2)
256247
}
257248

249+
flags = parsedFlags
250+
258251
if flags.PrintVersion {
259252
os.Stdout.WriteString(cwversion.FullString())
260-
os.Exit(0)
253+
return
261254
}
262255

263-
if err := run(); err != nil {
256+
if err := run(flags); err != nil {
264257
log.Fatal(err)
265258
}
266259
}

cmd/crowdsec/metrics.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package main
22

33
import (
4-
"fmt"
4+
"net"
55
"net/http"
6+
"strconv"
67

78
"github.com/prometheus/client_golang/prometheus"
89
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -19,8 +20,8 @@ import (
1920

2021
func computeDynamicMetrics(next http.Handler, dbClient *database.Client) http.HandlerFunc {
2122
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
22-
// catch panics here because they are not handled by servePrometheus
2323
defer trace.CatchPanic("crowdsec/computeDynamicMetrics")
24+
2425
// update cache metrics (stash)
2526
cache.UpdateCacheMetrics()
2627
// update cache metrics (regexp)
@@ -36,7 +37,7 @@ func computeDynamicMetrics(next http.Handler, dbClient *database.Client) http.Ha
3637

3738
decisions, err := dbClient.QueryDecisionCountByScenario(ctx)
3839
if err != nil {
39-
log.Errorf("Error querying decisions for metrics: %v", err)
40+
log.WithError(err).Error("querying decisions for metrics")
4041
next.ServeHTTP(w, r)
4142

4243
return
@@ -56,7 +57,7 @@ func computeDynamicMetrics(next http.Handler, dbClient *database.Client) http.Ha
5657

5758
alerts, err := dbClient.AlertsCountPerScenario(ctx, alertsFilter)
5859
if err != nil {
59-
log.Errorf("Error querying alerts for metrics: %v", err)
60+
log.WithError(err).Error("querying alerts for metrics")
6061
next.ServeHTTP(w, r)
6162

6263
return
@@ -76,7 +77,7 @@ func registerPrometheus(config *csconfig.PrometheusCfg) {
7677
}
7778

7879
if err := metrics.RegisterMetrics(config.Level); err != nil {
79-
log.Errorf("Error registering prometheus metrics: %v", err)
80+
log.WithError(err).Error("registering prometheus metrics")
8081
return
8182
}
8283
}
@@ -92,10 +93,10 @@ func servePrometheus(config *csconfig.PrometheusCfg, dbClient *database.Client,
9293

9394
http.Handle("/metrics", computeDynamicMetrics(promhttp.Handler(), dbClient))
9495

95-
if err := http.ListenAndServe(fmt.Sprintf("%s:%d", config.ListenAddr, config.ListenPort), nil); err != nil {
96+
if err := http.ListenAndServe(net.JoinHostPort(config.ListenAddr, strconv.Itoa(config.ListenPort)), nil); err != nil {
9697
// in time machine, we most likely have the LAPI using the port
9798
if !flags.haveTimeMachine() {
98-
log.Warningf("prometheus: %s", err)
99+
log.WithError(err).Warning("serving metrics")
99100
}
100101
}
101102
}

cmd/crowdsec/pour.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ func runPour(ctx context.Context, input chan pipeline.Event, holders []leaky.Buc
6666
} else {
6767
metrics.GlobalBucketPourKo.Inc()
6868
}
69-
70-
if parsed.MarshaledTime != "" {
71-
if err := lastProcessedItem.UnmarshalText([]byte(parsed.MarshaledTime)); err != nil {
72-
log.Warningf("failed to parse time from event: %s", err)
73-
}
74-
}
7569
}
7670
}
7771
}

cmd/crowdsec/serve.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,6 @@ func unregisterWatcher(ctx context.Context, cConfig *csconfig.Config) (bool, err
235235
}
236236

237237
func HandleSignals(ctx context.Context, cConfig *csconfig.Config) error {
238-
var (
239-
newConfig *csconfig.Config
240-
err error
241-
)
242-
243238
signalChan := make(chan os.Signal, 1)
244239

245240
// We add os.Interrupt mostly to ease windows development,
@@ -265,24 +260,23 @@ func HandleSignals(ctx context.Context, cConfig *csconfig.Config) error {
265260
case syscall.SIGHUP:
266261
log.Warning("SIGHUP received, reloading")
267262

268-
if err = shutdown(s, cConfig); err != nil {
263+
if err := shutdown(s, cConfig); err != nil {
269264
exitChan <- fmt.Errorf("failed shutdown: %w", err)
270265
return
271266
}
272267

273-
if newConfig, err = reloadHandler(ctx, s); err != nil {
268+
newConfig, err := reloadHandler(ctx, s)
269+
if err != nil {
274270
exitChan <- fmt.Errorf("reload handler failure: %w", err)
275271
return
276272
}
277273

278-
if newConfig != nil {
279-
cConfig = newConfig
280-
}
274+
cConfig = newConfig
281275
// ctrl+C, kill -SIGINT XXXX, kill -SIGTERM XXXX
282276
case os.Interrupt, syscall.SIGTERM:
283277
log.Warning("SIGTERM received, shutting down")
284278

285-
if err = shutdown(s, cConfig); err != nil {
279+
if err := shutdown(s, cConfig); err != nil {
286280
exitChan <- fmt.Errorf("failed shutdown: %w", err)
287281
return
288282
}
@@ -292,7 +286,7 @@ func HandleSignals(ctx context.Context, cConfig *csconfig.Config) error {
292286
}
293287
}()
294288

295-
err = <-exitChan
289+
err := <-exitChan
296290
if err == nil {
297291
log.Warning("Crowdsec service shutting down")
298292
}

0 commit comments

Comments
 (0)