diff --git a/commonctx/logger.go b/commonctx/logger.go index 0787435..fa498db 100644 --- a/commonctx/logger.go +++ b/commonctx/logger.go @@ -13,5 +13,18 @@ func AddMainLogger(ctx context.Context, logger *logrus.Entry) context.Context { } func GetLogger(ctx context.Context) *logrus.Entry { - return ctx.Value(LoggerKey).(*logrus.Entry) + if log := ctx.Value(LoggerKey); log != nil { + return log.(*logrus.Entry) + } + return nil +} + +func GetLoggerWithFields(ctx context.Context, fields logrus.Fields) *logrus.Entry { + if log := ctx.Value(LoggerKey); log != nil { + log := log.(*logrus.Entry) + log = log.WithFields(fields) + AddMainLogger(ctx, log) + return log + } + return nil } diff --git a/log/config.go b/log/config.go index 253eb1e..2c29604 100644 --- a/log/config.go +++ b/log/config.go @@ -19,7 +19,7 @@ import ( const envPrefix = "LOG_" // CONFIG_FILE is the default file that will be searched to apply configuration from the filesystem. -const defaultConfigFile = "log.yaml" +const defaultConfigFile = "conf/log.yaml" // SECRET_NAME is the default name of the secret that will be searched in vault. const defaultSecretName = "log" diff --git a/log/hooks/gelf/config.go b/log/hooks/gelf/config.go index 04ce500..c01b878 100644 --- a/log/hooks/gelf/config.go +++ b/log/hooks/gelf/config.go @@ -9,9 +9,8 @@ import ( // ConfigStruct is the configuration for GELF Provider. type ConfigStruct struct { - Host string `yaml:"host"` - Port int `yaml:"port"` - ExtrasFields map[string]interface{} `yaml:"extra_fields"` + Host string `yaml:"host"` + Port int `yaml:"port"` } // IsValid will check that the Gelf configuration is valid. diff --git a/log/hooks/gelf/hook.go b/log/hooks/gelf/hook.go index e5ecce8..220aaff 100644 --- a/log/hooks/gelf/hook.go +++ b/log/hooks/gelf/hook.go @@ -19,7 +19,7 @@ func NewHook(c *ConfigStruct) (logrus.Hook, error) { hook := graylog.NewAsyncGraylogHook( fmt.Sprintf("%s:%d", c.Host, c.Port), - c.ExtrasFields, + nil, ) defer hook.Flush() diff --git a/middleware/recovery.go b/middleware/recovery.go index ad74dc0..d38120c 100644 --- a/middleware/recovery.go +++ b/middleware/recovery.go @@ -3,8 +3,11 @@ package middleware import ( "fmt" "net/http" + "runtime/debug" + "strings" "git.dev.m-and-m.ovh/mderasse/gocommon/commonctx" + "github.com/sirupsen/logrus" ) type recoveryFuncSignature func(w http.ResponseWriter, r *http.Request) @@ -17,13 +20,14 @@ type recoveryMiddleware struct { func (rm *recoveryMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { - // log the error - log := commonctx.GetLogger(r.Context()) + log := commonctx.GetLoggerWithFields(r.Context(), logrus.Fields{ + "error": err, + "stacktrace": fmt.Sprintf("%v\n%s", err, getStackrace()), + }) if log == nil { fmt.Print("Impossible to log the panic as the logger is not part of the context\n") } else { - // Probably have to catch a stacktrace + Info about the error log.Error("A Panic happened and has been caught") } // execute the recovery function @@ -33,9 +37,15 @@ func (rm *recoveryMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) rm.handler.ServeHTTP(w, r) } +func getStackrace() string { + stackLines := strings.Split(string(debug.Stack()), "\n") + // removing a few first line as they are either that function or the middleware + return strings.Join(stackLines[9:], "\n") +} + // NewRecoveryMiddleware will declare a new middleware on the provided handler. It will recover any panic and log it. // By default, the middleware will return a default error object in json with a 500 Http code. That can be overide by providing a recoveryFunc. -func NewRecoveryMiddleware(h http.Handler, recoveryFunc recoveryFuncSignature) *recoveryMiddleware { +func NewRecoveryMiddleware(h http.Handler, recoveryFunc recoveryFuncSignature) http.Handler { recovery := &recoveryMiddleware{ handler: h, respFunc: recoveryFunc, diff --git a/tracing/config.go b/tracing/config.go index 03df409..2566b48 100644 --- a/tracing/config.go +++ b/tracing/config.go @@ -18,7 +18,7 @@ import ( const envPrefix = "TRACING_" // CONFIG_FILE is the default file that will be searched to apply configuration from the filesystem. -const defaultConfigFile = "tracing.yaml" +const defaultConfigFile = "conf/tracing.yaml" // SECRET_NAME is the default name of the secret that will be searched in vault. const defaultSecretName = "tracing"