bin/crowdsec: avoid writing errors twice when log_media=stdout (#2729)
* bin/crowdsec: avoid writing errors twice when log_media=stdout * lint
This commit is contained in:
parent
fca8883cd9
commit
0ef5f20aa7
3 changed files with 62 additions and 12 deletions
43
cmd/crowdsec/hook.go
Normal file
43
cmd/crowdsec/hook.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConditionalHook struct {
|
||||||
|
Writer io.Writer
|
||||||
|
LogLevels []log.Level
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *ConditionalHook) Fire(entry *log.Entry) error {
|
||||||
|
if hook.Enabled {
|
||||||
|
line, err := entry.String()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = hook.Writer.Write([]byte(line))
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *ConditionalHook) Levels() []log.Level {
|
||||||
|
return hook.LogLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
// The primal logging hook is set up before parsing config.yaml.
|
||||||
|
// Once config.yaml is parsed, the primal hook is disabled if the
|
||||||
|
// configured logger is writing to stderr. Otherwise it's used to
|
||||||
|
// report fatal errors and panics to stderr in addition to the log file.
|
||||||
|
var primalHook = &ConditionalHook{
|
||||||
|
Writer: os.Stderr,
|
||||||
|
LogLevels: []log.Level{log.FatalLevel, log.PanicLevel},
|
||||||
|
Enabled: true,
|
||||||
|
}
|
|
@ -80,11 +80,13 @@ func LoadBuckets(cConfig *csconfig.Config, hub *cwhub.Hub) error {
|
||||||
err error
|
err error
|
||||||
files []string
|
files []string
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, hubScenarioItem := range hub.GetItemMap(cwhub.SCENARIOS) {
|
for _, hubScenarioItem := range hub.GetItemMap(cwhub.SCENARIOS) {
|
||||||
if hubScenarioItem.State.Installed {
|
if hubScenarioItem.State.Installed {
|
||||||
files = append(files, hubScenarioItem.State.LocalPath)
|
files = append(files, hubScenarioItem.State.LocalPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buckets = leakybucket.NewBuckets()
|
buckets = leakybucket.NewBuckets()
|
||||||
|
|
||||||
log.Infof("Loading %d scenario files", len(files))
|
log.Infof("Loading %d scenario files", len(files))
|
||||||
|
@ -99,6 +101,7 @@ func LoadBuckets(cConfig *csconfig.Config, hub *cwhub.Hub) error {
|
||||||
holders[holderIndex].Profiling = true
|
holders[holderIndex].Profiling = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,8 +146,10 @@ func (l labelsMap) Set(label string) error {
|
||||||
if len(split) != 2 {
|
if len(split) != 2 {
|
||||||
return fmt.Errorf("invalid format for label '%s', must be key:value", pair)
|
return fmt.Errorf("invalid format for label '%s', must be key:value", pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
l[split[0]] = split[1]
|
l[split[0]] = split[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,9 +173,11 @@ func (f *Flags) Parse() {
|
||||||
flag.BoolVar(&f.DisableAPI, "no-api", false, "disable local API")
|
flag.BoolVar(&f.DisableAPI, "no-api", false, "disable local API")
|
||||||
flag.BoolVar(&f.DisableCAPI, "no-capi", false, "disable communication with Central API")
|
flag.BoolVar(&f.DisableCAPI, "no-capi", false, "disable communication with Central API")
|
||||||
flag.BoolVar(&f.OrderEvent, "order-event", false, "enforce event ordering with significant performance cost")
|
flag.BoolVar(&f.OrderEvent, "order-event", false, "enforce event ordering with significant performance cost")
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
flag.StringVar(&f.WinSvc, "winsvc", "", "Windows service Action: Install, Remove etc..")
|
flag.StringVar(&f.WinSvc, "winsvc", "", "Windows service Action: Install, Remove etc..")
|
||||||
}
|
}
|
||||||
|
|
||||||
flag.StringVar(&dumpFolder, "dump-data", "", "dump parsers/buckets raw outputs")
|
flag.StringVar(&dumpFolder, "dump-data", "", "dump parsers/buckets raw outputs")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
@ -205,6 +212,7 @@ func newLogLevel(curLevelPtr *log.Level, f *Flags) *log.Level {
|
||||||
// avoid returning a new ptr to the same value
|
// avoid returning a new ptr to the same value
|
||||||
return curLevelPtr
|
return curLevelPtr
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ret
|
return &ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +246,8 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
primalHook.Enabled = (cConfig.Common.LogMedia != "stdout")
|
||||||
|
|
||||||
if err := csconfig.LoadFeatureFlagsFile(configFile, log.StandardLogger()); err != nil {
|
if err := csconfig.LoadFeatureFlagsFile(configFile, log.StandardLogger()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -282,6 +292,7 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
|
||||||
if cConfig.DisableAPI {
|
if cConfig.DisableAPI {
|
||||||
cConfig.Common.Daemonize = false
|
cConfig.Common.Daemonize = false
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("single file mode : log_media=%s daemonize=%t", cConfig.Common.LogMedia, cConfig.Common.Daemonize)
|
log.Infof("single file mode : log_media=%s daemonize=%t", cConfig.Common.LogMedia, cConfig.Common.Daemonize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +302,7 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
|
||||||
|
|
||||||
if cConfig.Common.Daemonize && runtime.GOOS == "windows" {
|
if cConfig.Common.Daemonize && runtime.GOOS == "windows" {
|
||||||
log.Debug("Daemonization is not supported on Windows, disabling")
|
log.Debug("Daemonization is not supported on Windows, disabling")
|
||||||
|
|
||||||
cConfig.Common.Daemonize = false
|
cConfig.Common.Daemonize = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +320,8 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
|
||||||
var crowdsecT0 time.Time
|
var crowdsecT0 time.Time
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
log.AddHook(primalHook)
|
||||||
|
|
||||||
if err := fflag.RegisterAllFeatures(); err != nil {
|
if err := fflag.RegisterAllFeatures(); err != nil {
|
||||||
log.Fatalf("failed to register features: %s", err)
|
log.Fatalf("failed to register features: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -342,5 +356,6 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/sirupsen/logrus/hooks/writer"
|
|
||||||
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/trace"
|
"github.com/crowdsecurity/go-cs-lib/trace"
|
||||||
"github.com/crowdsecurity/go-cs-lib/version"
|
"github.com/crowdsecurity/go-cs-lib/version"
|
||||||
|
@ -24,16 +22,6 @@ func StartRunSvc() error {
|
||||||
|
|
||||||
defer trace.CatchPanic("crowdsec/StartRunSvc")
|
defer trace.CatchPanic("crowdsec/StartRunSvc")
|
||||||
|
|
||||||
// Set a default logger with level=fatal on stderr,
|
|
||||||
// in addition to the one we configure afterwards
|
|
||||||
log.AddHook(&writer.Hook{
|
|
||||||
Writer: os.Stderr,
|
|
||||||
LogLevels: []log.Level{
|
|
||||||
log.PanicLevel,
|
|
||||||
log.FatalLevel,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if cConfig, err = LoadConfig(flags.ConfigFile, flags.DisableAgent, flags.DisableAPI, false); err != nil {
|
if cConfig, err = LoadConfig(flags.ConfigFile, flags.DisableAgent, flags.DisableAPI, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -46,6 +34,7 @@ func StartRunSvc() error {
|
||||||
// Enable profiling early
|
// Enable profiling early
|
||||||
if cConfig.Prometheus != nil {
|
if cConfig.Prometheus != nil {
|
||||||
var dbClient *database.Client
|
var dbClient *database.Client
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if cConfig.DbConfig != nil {
|
if cConfig.DbConfig != nil {
|
||||||
|
@ -55,8 +44,11 @@ func StartRunSvc() error {
|
||||||
return fmt.Errorf("unable to create database client: %s", err)
|
return fmt.Errorf("unable to create database client: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerPrometheus(cConfig.Prometheus)
|
registerPrometheus(cConfig.Prometheus)
|
||||||
|
|
||||||
go servePrometheus(cConfig.Prometheus, dbClient, apiReady, agentReady)
|
go servePrometheus(cConfig.Prometheus, dbClient, apiReady, agentReady)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Serve(cConfig, apiReady, agentReady)
|
return Serve(cConfig, apiReady, agentReady)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue