lint: nilaway, unnecessary pointers (#3951)

* lint: nilaway

* lint: nilaway, unnecessary pointers

This removes *log.Level from configuration structs and logging
helpers and switches to value log.Level everywhere. It simplifies
defaults and inheritance, removes reliance on ptr.Of, and avoids nil
checks. Uses PanicLevel (natural zero value) as sentinel instead of nil.
This commit is contained in:
mmetc
2025-10-23 13:51:40 +02:00
committed by GitHub
parent ade11550eb
commit 298e75b8df
28 changed files with 68 additions and 76 deletions
+1 -2
View File
@@ -15,7 +15,6 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/crowdsecurity/go-cs-lib/ptr"
"github.com/crowdsecurity/go-cs-lib/trace"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/clialert"
@@ -176,7 +175,7 @@ func (cli *cliRoot) initialize() error {
}
if csConfig.DbConfig != nil {
csConfig.DbConfig.LogLevel = ptr.Of(cli.wantedLogLevel())
csConfig.DbConfig.LogLevel = cli.wantedLogLevel()
}
return nil
+5 -10
View File
@@ -187,14 +187,14 @@ func (f *Flags) Parse() {
flag.Parse()
}
func newLogLevel(curLevelPtr *log.Level, f *Flags) (*log.Level, bool) {
func newLogLevel(curLevel log.Level, f *Flags) (log.Level, bool) {
// mother of all defaults
ret := log.InfoLevel
logLevelViaFlag := true
// keep if already set
if curLevelPtr != nil {
ret = *curLevelPtr
if curLevel != log.PanicLevel {
ret = curLevel
}
// override from flags
@@ -216,12 +216,7 @@ func newLogLevel(curLevelPtr *log.Level, f *Flags) (*log.Level, bool) {
logLevelViaFlag = false
}
if curLevelPtr != nil && ret == *curLevelPtr {
// avoid returning a new ptr to the same value
return curLevelPtr, logLevelViaFlag
}
return &ret, logLevelViaFlag
return ret, logLevelViaFlag
}
// LoadConfig returns a configuration parsed from configuration file
@@ -253,7 +248,7 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
// Configure logging
if err := types.SetDefaultLoggerConfig(cConfig.Common.LogMedia,
cConfig.Common.LogDir, *cConfig.Common.LogLevel,
cConfig.Common.LogDir, cConfig.Common.LogLevel,
cConfig.Common.LogMaxSize, cConfig.Common.LogMaxFiles,
cConfig.Common.LogMaxAge, cConfig.Common.LogFormat, cConfig.Common.CompressLogs,
cConfig.Common.ForceColorLogs, logLevelViaFlag); err != nil {
+2 -2
View File
@@ -120,7 +120,7 @@ func registerDataSource(dataSourceType string, dsGetter func() DataSource) {
}
// setupLogger creates a logger for the datasource to use at runtime.
func setupLogger(source, name string, level *log.Level) (*log.Entry, error) {
func setupLogger(source, name string, level log.Level) (*log.Entry, error) {
clog := log.New()
if err := types.ConfigureLogger(clog, level); err != nil {
return nil, fmt.Errorf("while configuring datasource logger: %w", err)
@@ -177,7 +177,7 @@ func LoadAcquisitionFromDSN(ctx context.Context, dsn string, labels map[string]s
return nil, fmt.Errorf("no acquisition for protocol %s:// - %w", frags[0], err)
}
subLogger, err := setupLogger(dsn, "", nil)
subLogger, err := setupLogger(dsn, "", 0)
if err != nil {
return nil, err
}
@@ -7,7 +7,7 @@ import (
type DataSourceCommonCfg struct {
Mode string `yaml:"mode,omitempty"`
Labels map[string]string `yaml:"labels,omitempty"`
LogLevel *log.Level `yaml:"log_level,omitempty"`
LogLevel log.Level `yaml:"log_level,omitempty"`
Source string `yaml:"source,omitempty"`
Name string `yaml:"name,omitempty"`
UseTimeMachine bool `yaml:"use_time_machine,omitempty"`
+1 -1
View File
@@ -220,7 +220,7 @@ func (l *LokiSource) ConfigureByDSN(_ context.Context, dsn string, labels map[st
if err != nil {
return fmt.Errorf("invalid log_level in dsn: %w", err)
}
l.Config.LogLevel = &level
l.Config.LogLevel = level
l.logger.Logger.SetLevel(level)
}
@@ -196,7 +196,7 @@ func (l *VLSource) ConfigureByDSN(_ context.Context, dsn string, labels map[stri
if err != nil {
return fmt.Errorf("invalid log_level in dsn: %w", err)
}
l.Config.LogLevel = &level
l.Config.LogLevel = level
l.logger.Logger.SetLevel(level)
}
+1 -1
View File
@@ -45,7 +45,7 @@ func ValidateContextExpr(key string, expressions []string) error {
func NewAlertContext(contextToSend map[string][]string, valueLength int) error {
clog := log.New()
if err := types.ConfigureLogger(clog, nil); err != nil {
if err := types.ConfigureLogger(clog, 0); err != nil {
return fmt.Errorf("couldn't create logger for alert context: %w", err)
}
+1 -1
View File
@@ -262,7 +262,7 @@ func NewServer(ctx context.Context, config *csconfig.LocalApiServerCfg) (*APISer
if apiClient.apiClient.IsEnrolled() {
log.Info("Machine is enrolled in the console, Loading PAPI Client")
papiClient, err = NewPAPI(apiClient, dbClient, config.ConsoleConfig, *config.PapiLogLevel)
papiClient, err = NewPAPI(apiClient, dbClient, config.ConsoleConfig, config.PapiLogLevel)
if err != nil {
return nil, err
}
+5 -5
View File
@@ -64,7 +64,7 @@ func LoadTestConfig(t *testing.T) csconfig.Config {
}
apiServerConfig := csconfig.LocalApiServerCfg{
ListenURI: "http://127.0.0.1:8080",
LogLevel: ptr.Of(log.DebugLevel),
LogLevel: log.DebugLevel,
DbConfig: &dbconfig,
ProfilesPath: "./tests/profiles.yaml",
ConsoleConfig: &csconfig.ConsoleConfig{
@@ -388,10 +388,10 @@ func TestLoggingDebugToFileConfig(t *testing.T) {
}
expectedFile := filepath.Join(tempDir, "crowdsec_api.log")
expectedLines := []string{"/test42"}
cfg.LogLevel = ptr.Of(log.DebugLevel)
cfg.LogLevel = log.DebugLevel
// Configure logging
err := types.SetDefaultLoggerConfig(cfg.LogMedia, cfg.LogDir, *cfg.LogLevel, cfg.LogMaxSize, cfg.LogMaxFiles, cfg.LogMaxAge, cfg.LogFormat, cfg.CompressLogs, false, false)
err := types.SetDefaultLoggerConfig(cfg.LogMedia, cfg.LogDir, cfg.LogLevel, cfg.LogMaxSize, cfg.LogMaxFiles, cfg.LogMaxAge, cfg.LogFormat, cfg.CompressLogs, false, false)
require.NoError(t, err)
api, err := NewServer(ctx, &cfg)
@@ -441,10 +441,10 @@ func TestLoggingErrorToFileConfig(t *testing.T) {
DbConfig: &dbconfig,
}
expectedFile := filepath.Join(tempDir, "crowdsec_api.log")
cfg.LogLevel = ptr.Of(log.ErrorLevel)
cfg.LogLevel = log.ErrorLevel
// Configure logging
err := types.SetDefaultLoggerConfig(cfg.LogMedia, cfg.LogDir, *cfg.LogLevel, cfg.LogMaxSize, cfg.LogMaxFiles, cfg.LogMaxAge, cfg.LogFormat, cfg.CompressLogs, false, false)
err := types.SetDefaultLoggerConfig(cfg.LogMedia, cfg.LogDir, cfg.LogLevel, cfg.LogMaxSize, cfg.LogMaxFiles, cfg.LogMaxAge, cfg.LogFormat, cfg.CompressLogs, false, false)
require.NoError(t, err)
api, err := NewServer(ctx, &cfg)
+1 -1
View File
@@ -88,7 +88,7 @@ type PapiPermCheckSuccess struct {
func NewPAPI(apic *apic, dbClient *database.Client, consoleConfig *csconfig.ConsoleConfig, logLevel log.Level) (*Papi, error) {
logger := log.New()
if err := types.ConfigureLogger(logger, &logLevel); err != nil {
if err := types.ConfigureLogger(logger, logLevel); err != nil {
return &Papi{}, fmt.Errorf("creating papi logger: %w", err)
}
+5 -6
View File
@@ -14,9 +14,9 @@ import (
)
var (
Caches []gcache.Cache
Caches = []gcache.Cache{}
CacheNames []string
CacheConfig []CacheCfg
CacheConfig = []CacheCfg{}
)
// UpdateCacheMetrics is called directly by the prom handler
@@ -33,7 +33,7 @@ type CacheCfg struct {
Size int
TTL time.Duration
Strategy string
LogLevel *log.Level
LogLevel log.Level
Logger *log.Entry
}
@@ -44,9 +44,8 @@ func CacheInit(cfg CacheCfg) error {
}
}
// get a default logger
if cfg.LogLevel == nil {
cfg.LogLevel = new(log.Level)
*cfg.LogLevel = log.InfoLevel
if cfg.LogLevel == log.PanicLevel {
cfg.LogLevel = log.InfoLevel
}
clog := log.New()
+9 -14
View File
@@ -2,6 +2,7 @@ package csconfig
import (
"bytes"
"cmp"
"crypto/tls"
"crypto/x509"
"errors"
@@ -67,7 +68,7 @@ type CTICfg struct {
CacheTimeout *time.Duration `yaml:"cache_timeout,omitempty"`
CacheSize *int `yaml:"cache_size,omitempty"`
Enabled *bool `yaml:"enabled,omitempty"`
LogLevel *log.Level `yaml:"log_level,omitempty"`
LogLevel log.Level `yaml:"log_level,omitempty"`
}
func (a *CTICfg) Load() error {
@@ -232,7 +233,7 @@ type LocalApiServerCfg struct {
ConsoleConfigPath string `yaml:"console_path,omitempty"`
ConsoleConfig *ConsoleConfig `yaml:"-"`
Profiles []*ProfileCfg `yaml:"-"`
LogLevel *log.Level `yaml:"log_level"`
LogLevel log.Level `yaml:"log_level"`
UseForwardedForHeaders bool `yaml:"use_forwarded_for_headers,omitempty"`
TrustedProxies *[]string `yaml:"trusted_proxies,omitempty"`
CompressLogs *bool `yaml:"-"`
@@ -241,7 +242,7 @@ type LocalApiServerCfg struct {
LogMaxFiles int `yaml:"-"`
LogFormat string `yaml:"-"`
TrustedIPs []string `yaml:"trusted_ips,omitempty"`
PapiLogLevel *log.Level `yaml:"papi_log_level"`
PapiLogLevel log.Level `yaml:"papi_log_level"`
DisableRemoteLapiRegistration bool `yaml:"disable_remote_lapi_registration,omitempty"`
CapiWhitelistsPath string `yaml:"capi_whitelists_path,omitempty"`
CapiWhitelists *CapiWhitelist `yaml:"-"`
@@ -337,18 +338,12 @@ func (c *Config) LoadAPIServer(inCli bool, skipOnlineCreds bool) error {
return errors.New("no listen_uri or listen_socket specified")
}
// inherit log level from common, then api->server
var logLevel log.Level
if c.API.Server.LogLevel != nil {
logLevel = *c.API.Server.LogLevel
} else if c.Common.LogLevel != nil {
logLevel = *c.Common.LogLevel
} else {
logLevel = log.InfoLevel
}
// inherit log level from api->server, common, and default to info
// 0 = panicLevel, not useful / not allowed
logLevel := cmp.Or(c.API.Server.LogLevel, c.Common.LogLevel, log.InfoLevel)
if c.API.Server.PapiLogLevel == nil {
c.API.Server.PapiLogLevel = &logLevel
if c.API.Server.PapiLogLevel == log.PanicLevel {
c.API.Server.PapiLogLevel = logLevel
}
if c.API.Server.OnlineClient != nil && c.API.Server.OnlineClient.CredentialsFilePath != "" && !skipOnlineCreds {
+3 -3
View File
@@ -172,7 +172,7 @@ func TestLoadAPIServer(t *testing.T) {
CredentialsFilePath: "./testdata/online-api-secrets.yaml",
},
ProfilesPath: "./testdata/profiles.yaml",
PapiLogLevel: &logLevel,
PapiLogLevel: logLevel,
},
},
DbConfig: &DatabaseCfg{
@@ -223,7 +223,7 @@ func TestLoadAPIServer(t *testing.T) {
Profiles: tmpLAPI.Profiles,
ProfilesPath: "./testdata/profiles.yaml",
UseForwardedForHeaders: false,
PapiLogLevel: &logLevel,
PapiLogLevel: logLevel,
AutoRegister: &LocalAPIAutoRegisterCfg{
Enable: ptr.Of(false),
Token: "",
@@ -249,7 +249,7 @@ func TestLoadAPIServer(t *testing.T) {
},
expected: &LocalApiServerCfg{
Enable: ptr.Of(true),
PapiLogLevel: &logLevel,
PapiLogLevel: logLevel,
},
expectedErr: "no database configuration provided",
},
+1 -1
View File
@@ -10,7 +10,7 @@ type CommonCfg struct {
PidDir string `yaml:"pid_dir,omitempty"` // TODO: This is just for backward compat. Remove this later
LogMedia string `yaml:"log_media"`
LogDir string `yaml:"log_dir,omitempty"` // if LogMedia = file
LogLevel *log.Level `yaml:"log_level"`
LogLevel log.Level `yaml:"log_level"`
WorkingDir string `yaml:"working_dir,omitempty"` // TODO: This is just for backward compat. Remove this later
CompressLogs *bool `yaml:"compress_logs,omitempty"`
LogMaxSize int `yaml:"log_max_size,omitempty"`
+1 -2
View File
@@ -110,10 +110,9 @@ func GetConfig() Config {
}
func NewDefaultConfig() *Config {
logLevel := log.InfoLevel
commonCfg := CommonCfg{
LogMedia: "stdout",
LogLevel: &logLevel,
LogLevel: log.InfoLevel,
}
prometheus := PrometheusCfg{
Enabled: true,
+1 -1
View File
@@ -41,7 +41,7 @@ type DatabaseCfg struct {
DbPath string `yaml:"db_path"`
Type string `yaml:"type"`
Flush *FlushDBCfg `yaml:"flush"`
LogLevel *log.Level `yaml:"log_level"`
LogLevel log.Level `yaml:"log_level"`
MaxOpenConns int `yaml:"max_open_conns,omitempty"`
UseWal *bool `yaml:"use_wal,omitempty"`
DecisionBulkSize int `yaml:"decision_bulk_size,omitempty"`
+1 -2
View File
@@ -21,7 +21,6 @@ import (
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/csstring"
"github.com/crowdsecurity/go-cs-lib/ptr"
"github.com/crowdsecurity/go-cs-lib/slicetools"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
@@ -346,7 +345,7 @@ func (pb *PluginBroker) loadNotificationPlugin(ctx context.Context, name string,
pb.pluginMap[name] = &NotifierPlugin{}
l := log.New()
err = types.ConfigureLogger(l, ptr.Of(log.TraceLevel))
err = types.ConfigureLogger(l, log.TraceLevel)
if err != nil {
return nil, err
}
+6 -1
View File
@@ -228,6 +228,11 @@ func safeString(str fmt.Stringer) (s string) {
}
}()
s = str.String()
if str == nil {
// typed nil, happy nilaway
s = "NULL"
} else {
s = str.String()
}
return //nolint:revive // bare return for the defer
}
+1 -2
View File
@@ -8,7 +8,6 @@ import (
log "github.com/sirupsen/logrus"
"github.com/crowdsecurity/go-cs-lib/cstime"
"github.com/crowdsecurity/go-cs-lib/ptr"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
@@ -36,7 +35,7 @@ func NewProfile(profilesCfg []*csconfig.ProfileCfg) ([]*Runtime, error) {
runtime := &Runtime{}
xlog := log.New()
if err := types.ConfigureLogger(xlog, ptr.Of(log.InfoLevel)); err != nil {
if err := types.ConfigureLogger(xlog, log.InfoLevel); err != nil {
return nil, fmt.Errorf("while configuring profiles-specific logger: %w", err)
}
+1 -1
View File
@@ -29,7 +29,7 @@ var (
var ctiClient *cticlient.CrowdsecCTIClient
func InitCrowdsecCTI(key *string, ttl *time.Duration, size *int, logLevel *log.Level) error {
func InitCrowdsecCTI(key *string, ttl *time.Duration, size *int, logLevel log.Level) error {
if key == nil || *key == "" {
log.Warningf("CTI API key not set or empty, CTI will not be available")
return cticlient.ErrDisabled
+4 -4
View File
@@ -114,7 +114,7 @@ func smokeHandler(req *http.Request) *http.Response {
func TestNilClient(t *testing.T) {
defer ShutdownCrowdsecCTI()
if err := InitCrowdsecCTI(ptr.Of(""), nil, nil, nil); !errors.Is(err, cticlient.ErrDisabled) {
if err := InitCrowdsecCTI(ptr.Of(""), nil, nil, 0); !errors.Is(err, cticlient.ErrDisabled) {
t.Fatalf("failed to init CTI : %s", err)
}
@@ -126,7 +126,7 @@ func TestNilClient(t *testing.T) {
func TestInvalidAuth(t *testing.T) {
defer ShutdownCrowdsecCTI()
if err := InitCrowdsecCTI(ptr.Of("asdasd"), nil, nil, nil); err != nil {
if err := InitCrowdsecCTI(ptr.Of("asdasd"), nil, nil, 0); err != nil {
t.Fatalf("failed to init CTI : %s", err)
}
// Replace the client created by InitCrowdsecCTI with one that uses a custom transport
@@ -153,7 +153,7 @@ func TestInvalidAuth(t *testing.T) {
func TestNoKey(t *testing.T) {
defer ShutdownCrowdsecCTI()
err := InitCrowdsecCTI(nil, nil, nil, nil)
err := InitCrowdsecCTI(nil, nil, nil, 0)
require.ErrorIs(t, err, cticlient.ErrDisabled)
// Replace the client created by InitCrowdsecCTI with one that uses a custom transport
ctiClient = cticlient.NewCrowdsecCTIClient(cticlient.WithAPIKey("asdasd"), cticlient.WithHTTPClient(&http.Client{
@@ -170,7 +170,7 @@ func TestCache(t *testing.T) {
defer ShutdownCrowdsecCTI()
cacheDuration := 1 * time.Second
if err := InitCrowdsecCTI(ptr.Of(validApiKey), &cacheDuration, nil, nil); err != nil {
if err := InitCrowdsecCTI(ptr.Of(validApiKey), &cacheDuration, nil, 0); err != nil {
t.Fatalf("failed to init CTI : %s", err)
}
// Replace the client created by InitCrowdsecCTI with one that uses a custom transport
+5
View File
@@ -60,6 +60,11 @@ func (c *Client) CreateOrUpdateAlert(ctx context.Context, machineID string, aler
return "", fmt.Errorf("unable to create alert: %w", err)
}
// happy nilaway
if len(alertIDs) == 0 {
return "", fmt.Errorf("unable to create alert: no IDs returned for alert %s", alertItem.UUID)
}
return alertIDs[0], nil
}
+1 -1
View File
@@ -93,7 +93,7 @@ func NewClient(ctx context.Context, config *csconfig.DatabaseCfg) (*Client, erro
client = ent.NewClient(ent.Driver(drv), entOpt)
if config.LogLevel != nil && *config.LogLevel >= log.DebugLevel {
if config.LogLevel >= log.DebugLevel {
clog.Debugf("Enabling request debug")
client = client.Debug()
+1 -3
View File
@@ -16,8 +16,6 @@ import (
"gopkg.in/tomb.v2"
yaml "gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/ptr"
"github.com/crowdsecurity/crowdsec/pkg/alertcontext"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
@@ -342,7 +340,7 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error {
if bucketFactory.Debug {
clog := log.New()
if err = types.ConfigureLogger(clog, ptr.Of(log.DebugLevel)); err != nil {
if err = types.ConfigureLogger(clog, log.DebugLevel); err != nil {
return fmt.Errorf("while creating bucket-specific logger: %w", err)
}
+1 -2
View File
@@ -13,7 +13,6 @@ import (
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/ptr"
"github.com/crowdsecurity/grokky"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
@@ -413,7 +412,7 @@ func (n *Node) compile(pctx *UnixParserCtx, ectx EnricherCtx) error {
that will be used only for processing this node ;) */
if n.Debug {
clog := log.New()
if err = types.ConfigureLogger(clog, ptr.Of(log.DebugLevel)); err != nil {
if err = types.ConfigureLogger(clog, log.DebugLevel); err != nil {
return fmt.Errorf("while creating bucket-specific logger: %w", err)
}
+1 -1
View File
@@ -88,7 +88,7 @@ func (s *Stash) Compile(logger *log.Entry) (*RuntimeStash, error) {
TTL: rs.TTLVal,
Name: s.Name,
Strategy: s.Strategy,
LogLevel: &logLvl,
LogLevel: logLvl,
}); err != nil {
return nil, fmt.Errorf("while initializing cache: %w", err)
}
+3 -3
View File
@@ -76,7 +76,7 @@ func SetDefaultLoggerConfig(cfgMode string, cfgFolder string, cfgLevel log.Level
return nil
}
func ConfigureLogger(clog *log.Logger, level *log.Level) error {
func ConfigureLogger(clog *log.Logger, level log.Level) error {
/*Configure logs*/
if LogOutput != nil {
clog.SetOutput(LogOutput)
@@ -88,8 +88,8 @@ func ConfigureLogger(clog *log.Logger, level *log.Level) error {
clog.SetLevel(logLevel)
if level != nil && !logLevelViaFlag {
clog.SetLevel(*level)
if level != log.PanicLevel && !logLevelViaFlag {
clog.SetLevel(level)
}
return nil
+4 -4
View File
@@ -33,22 +33,22 @@ teardown() {
@test "config.yaml.local - cscli (log_level)" {
config_set '.common.log_level="warning"'
rune -0 cscli config show --key Config.Common.LogLevel
assert_output "&3"
assert_output "3"
echo "{'common':{'log_level':'debug'}}" >"${CONFIG_YAML}.local"
rune -0 cscli config show --key Config.Common.LogLevel
assert_output "&5"
assert_output "5"
}
@test "config.yaml.local - cscli (log_level - with envvar)" {
config_set '.common.log_level="warning"'
rune -0 cscli config show --key Config.Common.LogLevel
assert_output "&3"
assert_output "3"
export CROWDSEC_LOG_LEVEL=debug
echo "{'common':{'log_level':'${CROWDSEC_LOG_LEVEL}'}}" >"${CONFIG_YAML}.local"
rune -0 cscli config show --key Config.Common.LogLevel
assert_output "&5"
assert_output "5"
}
@test "config.yaml.local - crowdsec (listen_url)" {