Approach to using multiple loggers


(Crashkid) #1

I’m writing a kubernetes controller that will have multiple log destinations: stdout/stderr, splunk and an external telemetry system. Note: I’m using logrus

Right now I’m tracking the loggers with a map:

// my config struct simplified
type Config struct {
    Loggers *map[string]log.Logger
    // other stuff
}

func NewConfig() *Config {
    config := Config{}
    // init stuff
    return &config
}

Cfg := NewConfig()

// Setup default stderr logger
(*Cfg.Loggers)["default"] = *log.New()
// Configure my default logger

// Setup a splunk logger
// this will actually be however I integrate splunk, for now just another vanilla Logger
(*Cfg.Loggers)["splunk"] = *log.New()

// Sample log entry
(*Cfg.Loggers)["default"].Debugf("ERROR: %s", err)

Is this a sensible way of going about this? Is there a better way to do this?

I just have two concerns with this approach:

  1. The log statements are long and cumbersome, need some kind of alias mechanism to shorten log calls in my code. See the sample log entry above.
  2. I need a way to send a message to all log endpoints at once with a single statement, preferably using some built-in mechanism and not needing custom wrapper function(s)

Sorry, very new to go and not sure if I’m going about this the most idiomatic way.


(Ivan Matmati) #2

Hi,
A few remarks.

1- I wouldn’t use pointer to map, it seems pointless to me.
Then you could simply your call with

Cfg.Loggers["default"] =...

2 - Use fan out pattern with channel. It seems the best way to operate according your description . You can find a descripton of that in this blog : https://divan.dev/posts/go_concurrency_visualize/