Open dpup opened 5 years ago
hmm yea definitely should be, sounds like a bug to me, thanks for reporting!
Just an FYI that we're seeing this regularly now. A refinement on the original data, the code is essentially calling logger.Info("...")
from multiple goroutines.
I have some more info about how this bug occurs:
logger.WithFields(fields)
in order to create the logger
instance that is shared between multiple goroutines.logger.Info(...)
may then run concurrently with other code that writes additional keys/values to that fields
instance.fields
is a log.Fields
, which is implemented with a map underneath, if a read and a write collide, we can get this error. It's not safe to concurrently read from and write to a map (as I learned today while investigating this).We can address this in our own code by ensuring that fields
is never written to after it's used to make a logger
(by copying it).
But I wonder if it would also make sense to prevent this type of mistake at the apex/log level?
func (f Fields) Fields() Fields
should make a shallow copy of the underlying map instead of just returning the Fields
struct?func (e *Entry) WithFields(fields Fielder) *Entry
should make a copy of fields.Fields()
before appending it to the list of fields objects?Either of those options would ensure that no further writes to a fields map can occur that would be concurrent with a call to log something.
Hi, opening a PR to fix the issue, please let me know if there's anything to improve there :)
We experienced a crash today that I'm having trouble diagnosing. The error occurred when calling
logger.Info
inside a goroutine. There were several parallel tasks, all which log when they complete. This code has been running, unchanged for months and I don't believe we've had any issues before.Are
logger.WithField
andlogger.WithError
intended to be threadsafe?Thanks in advance.
The error occurs at line 155 in
(e *Entry) mergedFields