fix(logs): Small refacto and allow multiple providers at the same time
This commit is contained in:
parent
bef0d38f1e
commit
99bca634d2
@ -28,7 +28,7 @@ const defaultSecretName = "log"
|
||||
type ConfigStruct struct {
|
||||
Level *string `yaml:"level"`
|
||||
EnableStdOut *bool `yaml:"ensable_std_out"`
|
||||
Provider *ProviderName `yaml:"provider"`
|
||||
Providers []ProviderName `yaml:"providers"`
|
||||
FileConfig *file.ConfigStruct `yaml:"file_config"`
|
||||
GelfConfig *gelf.ConfigStruct `yaml:"gelf_config"`
|
||||
}
|
||||
@ -37,7 +37,7 @@ func newDefaultConfig() *ConfigStruct {
|
||||
return &ConfigStruct{
|
||||
Level: convert.ToPointer("debug"),
|
||||
EnableStdOut: convert.ToPointer(true),
|
||||
Provider: convert.ToPointer(ProviderName_NONE),
|
||||
Providers: []ProviderName{ProviderName_NONE},
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,9 +102,13 @@ func (c *ConfigStruct) applyEnv() error {
|
||||
c.EnableStdOut = convert.ToPointer(b)
|
||||
}
|
||||
|
||||
if v := os.Getenv(fmt.Sprintf("%s%s", envPrefix, "PROVIDER")); v != "" {
|
||||
p := ProviderName(v)
|
||||
c.Provider = convert.ToPointer(p)
|
||||
if v := os.Getenv(fmt.Sprintf("%s%s", envPrefix, "PROVIDERS")); v != "" {
|
||||
providersStr := strings.Split(v, ",")
|
||||
var providers []ProviderName
|
||||
for _, ps := range providersStr {
|
||||
providers = append(providers, ProviderName(ps))
|
||||
}
|
||||
c.Providers = providers
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -123,8 +127,8 @@ func (c *ConfigStruct) applyDefault() {
|
||||
c.EnableStdOut = defaultConfig.EnableStdOut
|
||||
}
|
||||
|
||||
if c.Provider == nil || *c.Provider == "" {
|
||||
c.Provider = defaultConfig.Provider
|
||||
if c.Providers == nil || len(c.Providers) == 0 {
|
||||
c.Providers = defaultConfig.Providers
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,36 +145,40 @@ func (c *ConfigStruct) IsValid() error {
|
||||
return errors.NotValidf("Invalid Level. Allowed values: %s", strings.Join(convert.StringerSliceToStringSlice(logrus.AllLevels), ", "))
|
||||
}
|
||||
|
||||
if c.Provider == nil {
|
||||
return errors.NotValidf("Provider is empty")
|
||||
} else if !c.Provider.IsValid() {
|
||||
return errors.NotValidf("Invalid Provider. Allowed values: %s", strings.Join(convert.StringerSliceToStringSlice(GetListProviderName()), ", "))
|
||||
if c.Providers == nil || len(c.Providers) == 0 {
|
||||
return errors.NotValidf("Providers is empty")
|
||||
}
|
||||
|
||||
// Validating configuration for the chosen provider.
|
||||
switch *c.Provider {
|
||||
case ProviderName_FILE:
|
||||
if c.FileConfig == nil {
|
||||
return errors.NotValidf("file configuration is empty")
|
||||
for _, provider := range c.Providers {
|
||||
if !provider.IsValid() {
|
||||
return errors.NotValidf("Invalid Provider %s. Allowed values: %s", provider.String(), strings.Join(convert.StringerSliceToStringSlice(GetListProviderName()), ", "))
|
||||
}
|
||||
err := c.FileConfig.IsValid()
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
|
||||
switch provider {
|
||||
case ProviderName_FILE:
|
||||
if c.FileConfig == nil {
|
||||
return errors.NotValidf("file configuration is empty")
|
||||
}
|
||||
err := c.FileConfig.IsValid()
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
case ProviderName_GELF:
|
||||
if c.GelfConfig == nil {
|
||||
return errors.NotValidf("GELF configuration is empty")
|
||||
}
|
||||
err := c.GelfConfig.IsValid()
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
case ProviderName_NONE:
|
||||
if !*c.EnableStdOut {
|
||||
return errors.NotValidf("Provider set to none with StdOut disabled make no sense")
|
||||
}
|
||||
default:
|
||||
return errors.NotValidf("Provider not handled")
|
||||
}
|
||||
case ProviderName_GELF:
|
||||
if c.GelfConfig == nil {
|
||||
return errors.NotValidf("GELF configuration is empty")
|
||||
}
|
||||
err := c.GelfConfig.IsValid()
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
case ProviderName_NONE:
|
||||
if !*c.EnableStdOut {
|
||||
return errors.NotValidf("Provider set to none with StdOut disabled make no sense")
|
||||
}
|
||||
default:
|
||||
return errors.NotValidf("Provider not handled")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -16,6 +16,13 @@ import (
|
||||
// be available in the queue.
|
||||
var BufSize uint = 8192
|
||||
|
||||
// defaultFormater will be use if no formatter is given.
|
||||
var defaultFormater = &logrus.TextFormatter{
|
||||
DisableColors: true,
|
||||
TimestampFormat: time.RFC3339Nano,
|
||||
QuoteEmptyFields: true,
|
||||
}
|
||||
|
||||
// Hook will write logs to a file.
|
||||
type Hook struct {
|
||||
Level logrus.Level
|
||||
@ -27,19 +34,21 @@ type Hook struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
// XXX: Maybe just take a formatter in input
|
||||
|
||||
// NewFileHook creates a hook to be added to an instance of logger.
|
||||
func NewFileHook(w io.Writer, of OutputFormat) *Hook {
|
||||
func NewFileHook(w io.Writer, f logrus.Formatter) *Hook {
|
||||
if w == nil {
|
||||
logrus.Error("Can't create File Hook with an empty writer")
|
||||
return nil
|
||||
}
|
||||
|
||||
if f == nil {
|
||||
f = defaultFormater
|
||||
}
|
||||
|
||||
hook := &Hook{
|
||||
Level: logrus.DebugLevel,
|
||||
synchronous: true,
|
||||
f: handleFormat(of),
|
||||
f: f,
|
||||
w: w,
|
||||
}
|
||||
|
||||
@ -49,16 +58,20 @@ func NewFileHook(w io.Writer, of OutputFormat) *Hook {
|
||||
// NewAsyncFileHook creates a hook to be added to an instance of logger.
|
||||
// The hook created will be asynchronous, and it's the responsibility of the user to call the Flush method
|
||||
// before exiting to empty the log queue.
|
||||
func NewAsyncFileHook(w io.Writer, of OutputFormat) *Hook {
|
||||
func NewAsyncFileHook(w io.Writer, f logrus.Formatter) *Hook {
|
||||
if w == nil {
|
||||
logrus.Error("Can't create File Hook with an empty writer")
|
||||
return nil
|
||||
}
|
||||
|
||||
if f == nil {
|
||||
f = defaultFormater
|
||||
}
|
||||
|
||||
hook := &Hook{
|
||||
Level: logrus.DebugLevel,
|
||||
buf: make(chan logrus.Entry, BufSize),
|
||||
f: handleFormat(of),
|
||||
f: f,
|
||||
w: w,
|
||||
}
|
||||
|
||||
@ -80,23 +93,6 @@ func (hook *Hook) Flush() {
|
||||
hook.wg.Wait()
|
||||
}
|
||||
|
||||
// handleFormat will take a OutputFormat and will transform it in a formatter.
|
||||
func handleFormat(of OutputFormat) logrus.Formatter {
|
||||
|
||||
if of == OutputFormat_JSON {
|
||||
return &logrus.JSONFormatter{
|
||||
PrettyPrint: false,
|
||||
TimestampFormat: time.RFC3339Nano,
|
||||
}
|
||||
}
|
||||
|
||||
return &logrus.TextFormatter{
|
||||
DisableColors: true,
|
||||
TimestampFormat: time.RFC3339Nano,
|
||||
QuoteEmptyFields: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Fire is called when a log event is fired.
|
||||
// We assume the entry will be altered by another hook,
|
||||
// otherwise we might be logging something wrong to Graylog.
|
||||
|
@ -70,7 +70,24 @@ func NewHook(c *ConfigStruct) (logrus.Hook, error) {
|
||||
w = fh
|
||||
}
|
||||
|
||||
h := NewAsyncFileHook(w, outputFormat)
|
||||
h := NewAsyncFileHook(w, handleFormat(outputFormat))
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// handleFormat will take a OutputFormat and will transform it in a formatter.
|
||||
func handleFormat(of OutputFormat) logrus.Formatter {
|
||||
|
||||
if of == OutputFormat_JSON {
|
||||
return &logrus.JSONFormatter{
|
||||
PrettyPrint: false,
|
||||
TimestampFormat: time.RFC3339Nano,
|
||||
}
|
||||
}
|
||||
|
||||
return &logrus.TextFormatter{
|
||||
DisableColors: true,
|
||||
TimestampFormat: time.RFC3339Nano,
|
||||
QuoteEmptyFields: true,
|
||||
}
|
||||
}
|
||||
|
52
log/log.go
52
log/log.go
@ -11,8 +11,8 @@ import (
|
||||
"git.dev.m-and-m.ovh/mderasse/gocommon/log/hooks/gelf"
|
||||
)
|
||||
|
||||
// InitLog will try to initialize logger by trying to retrieve config from multiple source.
|
||||
func InitLog() (*logrus.Logger, error) {
|
||||
// Init will try to initialize logger by trying to retrieve config from multiple source.
|
||||
func Init() (*logrus.Logger, error) {
|
||||
|
||||
// loading configuration
|
||||
c, err := loadConfig()
|
||||
@ -23,8 +23,8 @@ func InitLog() (*logrus.Logger, error) {
|
||||
return initFromSource(c)
|
||||
}
|
||||
|
||||
// InitLogFromCustomVaultSecret will initialize logger with a vault secret.
|
||||
func InitLogFromCustomVaultSecret(secret string) (*logrus.Logger, error) {
|
||||
// InitFromCustomVaultSecret will initialize logger with a vault secret.
|
||||
func InitFromCustomVaultSecret(secret string) (*logrus.Logger, error) {
|
||||
|
||||
c, err := loadConfigFromVault(secret)
|
||||
if err != nil {
|
||||
@ -34,8 +34,8 @@ func InitLogFromCustomVaultSecret(secret string) (*logrus.Logger, error) {
|
||||
return initFromSource(c)
|
||||
}
|
||||
|
||||
// InitLogFromCustomFile will initialize logger with a config file.
|
||||
func InitLogFromCustomFile(path string) (*logrus.Logger, error) {
|
||||
// InitFromCustomFile will initialize logger with a config file.
|
||||
func InitFromCustomFile(path string) (*logrus.Logger, error) {
|
||||
|
||||
c, err := loadConfigFromFile(path)
|
||||
if err != nil {
|
||||
@ -53,11 +53,11 @@ func initFromSource(c *ConfigStruct) (*logrus.Logger, error) {
|
||||
|
||||
c.applyDefault()
|
||||
|
||||
return InitLogFromCustomConfig(c)
|
||||
return InitFromCustomConfig(c)
|
||||
}
|
||||
|
||||
// InitLogFromCustomConfig will initialize logger from a gaven config.
|
||||
func InitLogFromCustomConfig(c *ConfigStruct) (*logrus.Logger, error) {
|
||||
// InitFromCustomConfig will initialize logger from a gaven config.
|
||||
func InitFromCustomConfig(c *ConfigStruct) (*logrus.Logger, error) {
|
||||
|
||||
err := c.IsValid()
|
||||
if err != nil {
|
||||
@ -79,23 +79,25 @@ func InitLogFromCustomConfig(c *ConfigStruct) (*logrus.Logger, error) {
|
||||
log.SetOutput(io.Discard)
|
||||
}
|
||||
|
||||
switch *c.Provider {
|
||||
case ProviderName_FILE:
|
||||
hook, err := file.NewHook(c.FileConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
for _, provider := range c.Providers {
|
||||
switch provider {
|
||||
case ProviderName_FILE:
|
||||
hook, err := file.NewHook(c.FileConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
log.AddHook(hook)
|
||||
case ProviderName_GELF:
|
||||
hook, err := gelf.NewHook(c.GelfConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
log.AddHook(hook)
|
||||
case ProviderName_NONE:
|
||||
fallthrough
|
||||
default:
|
||||
return nil, errors.BadRequestf("Provider is not handled.")
|
||||
}
|
||||
log.AddHook(hook)
|
||||
case ProviderName_GELF:
|
||||
hook, err := gelf.NewHook(c.GelfConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
log.AddHook(hook)
|
||||
case ProviderName_NONE:
|
||||
fallthrough
|
||||
default:
|
||||
return nil, errors.BadRequestf("Provider is not handled.")
|
||||
}
|
||||
|
||||
return log, nil
|
||||
|
Loading…
Reference in New Issue
Block a user