mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 11:38:59 +02:00
✨ feat(logs) add supports write logs to files (#217)
* ✨ feat(logs) add supports write logs to files * fix(lint) 🚨 fix go lint * 🐛 fix(bug) check path is done only if provided * 📝 doc(vars) add LogFilePath to vars * 🦺 chore(review) update doc, configuration check and logger
This commit is contained in:
Vendored
+3
-3
@@ -11,7 +11,7 @@ import (
|
||||
func Test_Get(t *testing.T) {
|
||||
IPInCache := "10.0.0.10"
|
||||
IPNotInCache := "10.0.0.20"
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO", "")}
|
||||
client.Set(IPInCache, BannedValue, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
@@ -47,7 +47,7 @@ func Test_Get(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_Set(t *testing.T) {
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO", "")}
|
||||
IPInCache := "10.0.0.11"
|
||||
type args struct {
|
||||
clientIP string
|
||||
@@ -88,7 +88,7 @@ func Test_Set(t *testing.T) {
|
||||
func Test_Delete(t *testing.T) {
|
||||
IPInCache := "10.0.0.12"
|
||||
IPNotInCache := "10.0.0.22"
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO", "")}
|
||||
client.Set(IPInCache, BannedValue, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
|
||||
@@ -28,6 +28,9 @@ const (
|
||||
AppsecMode = "appsec"
|
||||
HTTPS = "https"
|
||||
HTTP = "http"
|
||||
LogDEBUG = "DEBUG"
|
||||
LogINFO = "INFO"
|
||||
LogERROR = "ERROR"
|
||||
HcaptchaProvider = "hcaptcha"
|
||||
RecaptchaProvider = "recaptcha"
|
||||
TurnstileProvider = "turnstile"
|
||||
@@ -37,6 +40,7 @@ const (
|
||||
type Config struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
LogLevel string `json:"logLevel,omitempty"`
|
||||
LogFilePath string `json:"logFilePath,omitempty"`
|
||||
CrowdsecMode string `json:"crowdsecMode,omitempty"`
|
||||
CrowdsecAppsecEnabled bool `json:"crowdsecAppsecEnabled,omitempty"`
|
||||
CrowdsecAppsecHost string `json:"crowdsecAppsecHost,omitempty"`
|
||||
@@ -98,7 +102,8 @@ func contains(source []string, target string) bool {
|
||||
func New() *Config {
|
||||
return &Config{
|
||||
Enabled: false,
|
||||
LogLevel: "INFO",
|
||||
LogLevel: LogINFO,
|
||||
LogFilePath: "",
|
||||
CrowdsecMode: LiveMode,
|
||||
CrowdsecAppsecEnabled: false,
|
||||
CrowdsecAppsecHost: "crowdsec:7422",
|
||||
@@ -262,6 +267,17 @@ func ValidateParams(config *Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Check logging configuration
|
||||
|
||||
if !contains([]string{LogERROR, LogDEBUG, LogINFO}, config.LogLevel) {
|
||||
return fmt.Errorf("LogLevel should be one of (%s,%s,%s)", LogDEBUG, LogINFO, LogERROR)
|
||||
}
|
||||
if config.LogFilePath != "" {
|
||||
_, err = os.OpenFile(filepath.Clean(config.LogFilePath), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("LogFilePath is not writable %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -304,7 +320,7 @@ func validateParamsTLS(config *Config) error {
|
||||
|
||||
func validateParamsIPs(listIP []string, key string) error {
|
||||
if len(listIP) > 0 {
|
||||
if _, err := ip.NewChecker(logger.New("INFO"), listIP); err != nil {
|
||||
if _, err := ip.NewChecker(logger.New(LogINFO, ""), listIP); err != nil {
|
||||
return fmt.Errorf("%s must be a list of IP/CIDR :%w", key, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ func Test_GetTLSConfigCrowdsec(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetTLSConfigCrowdsec(tt.args.config, logger.New("INFO"))
|
||||
got, err := GetTLSConfigCrowdsec(tt.args.config, logger.New("INFO", ""))
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getTLSConfigCrowdsec() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
||||
+18
-1
@@ -3,9 +3,11 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Log Logger struct.
|
||||
@@ -16,15 +18,30 @@ type Log struct {
|
||||
}
|
||||
|
||||
// New Set Default log level to info in case log level to defined.
|
||||
func New(logLevel string) *Log {
|
||||
func New(logLevel string, logFilePath string) *Log {
|
||||
logError := log.New(io.Discard, "ERROR: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logInfo := log.New(io.Discard, "INFO: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logDebug := log.New(io.Discard, "DEBUG: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
|
||||
logError.SetOutput(os.Stderr)
|
||||
logInfo.SetOutput(os.Stdout)
|
||||
// we initialize logger to STDOUT/STDERR first so if the file logger cannot be initialized we can inform the user
|
||||
if logLevel == "DEBUG" {
|
||||
logDebug.SetOutput(os.Stdout)
|
||||
}
|
||||
if logFilePath != "" {
|
||||
logFile, err := os.OpenFile(filepath.Clean(logFilePath), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
_ = fmt.Errorf("LogFilePath is not writable %w", err)
|
||||
} else {
|
||||
logInfo.SetOutput(logFile)
|
||||
logError.SetOutput(logFile)
|
||||
if logLevel == "DEBUG" {
|
||||
logDebug.SetOutput(logFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &Log{
|
||||
logError: logError,
|
||||
logInfo: logInfo,
|
||||
|
||||
Reference in New Issue
Block a user