Reputation: 339
I'm new to Go. I have a map which indicates which writers are active:
var writers map[int]bool
I want to iterate over the map, and create a writer which represents all active writers using multiWriter()
I am using the following code snippet:
func setupMultiLoggers() {
var mw io.Writer
for k, v := range writers {
if v != true {
continue
}
switch k {
case 0:
if mw == nil {
mw = writer0
} else {
mw = io.MultiWriter(mw, writer0)
}
case 1:
if mw == nil {
mw = os.Stdout
} else {
mw = io.MultiWriter(mw, os.Stdout)
}
case 2:
if mw == nil {
mw = writer2
} else {
io.MultiWriter(mw, writer2)
}
default:
}
}
log.SetOutput(mw)
}
When initializing the all 3 values of the map to true and then testing writer2, it sometimes works and sometimes doesn't (code in case 2 always executes)
If I just use
log.SetOutput(io.MultiWriter(writer0, os.Stdout, writer2))
It always works as expected.
I cannot seem to understand why my original code doesn't reliably work. I have a feeling there is a more clean way to "concatenate" writers
EDIT: I've found my (stupid) bug. assignment to mw was missing in the third case. Still looking for a more clean way to "concatenate" writers.
Upvotes: 0
Views: 1117
Reputation: 166569
For example,
var writers map[int]bool
var writer0, writer2 io.Writer
func setupMultiLoggers() {
var mw []io.Writer
for k, v := range writers {
if v == false {
continue
}
switch k {
case 0:
mw = append(mw, writer0)
case 1:
mw = append(mw, os.Stdout)
case 2:
mw = append(mw, writer2)
}
}
log.SetOutput(io.MultiWriter(mw...))
}
Upvotes: 1
Reputation: 550
You don't seem to have a map of writers, you have a map of ints to bools. Presumably, the ints represent the file descriptor.
The easiest way to do it would probably to change it from map[int]bool to map[io.Writer]bool, then you can iterate through them and add them to a slice with append.
ws := make([]io.Writer, 0)
for k, v : = range(writers) {
if v != true {
continue
}
ws = append(ws, k)
}
After that, you can just create a multiwriter directly by giving the slice to your MultiWriter call.
w := io.MultiWriter(ws...)
log.SetOutput(w)
(The ...
in a function parameter after a slice means to expand the slice into arguments to the function call)
You can do the same thing while keeping it map[int]bool, but you'll need a switch similar to what you already have to convert your int into an io.Writer
Upvotes: 3