github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/log/mdc.go (about) 1 package log 2 3 import ( 4 "context" 5 "sync" 6 7 "github.com/sirupsen/logrus" 8 ) 9 10 type mdcKey string 11 12 const contextKeyMdc mdcKey = "mapped-diagnostic-context" 13 14 // ContextWithMdc returns a new context with attached MDC 15 func ContextWithMdc(ctx context.Context) context.Context { 16 if nil == MdcFromContext(ctx) { 17 return context.WithValue(ctx, contextKeyMdc, NewMappedDiagnosticContext()) 18 } 19 20 return ctx 21 } 22 23 // MdcFromContext returns the attached *MDC or nil if there is none 24 func MdcFromContext(ctx context.Context) *MDC { 25 ptr, ok := ctx.Value(contextKeyMdc).(*MDC) 26 if !ok { 27 return nil 28 } 29 return ptr 30 } 31 32 // MDC provides a mechanism to enrich the log messages with 33 // information, which might not be available at the time/scope 34 // where the logging actually occurs. 35 type MDC struct { 36 mdc map[string]interface{} 37 lock sync.Mutex 38 } 39 40 // NewMappedDiagnosticContext creates a new MDC instance 41 func NewMappedDiagnosticContext() *MDC { 42 return &MDC{ 43 mdc: make(map[string]interface{}), 44 lock: sync.Mutex{}, 45 } 46 } 47 48 // Set adds or overwrites a key-value pair in the MDC 49 func (mdc *MDC) Set(key string, value interface{}) { 50 mdc.lock.Lock() 51 defer mdc.lock.Unlock() 52 53 mdc.mdc[key] = value 54 } 55 56 // SetIfNotEmpty adds or overwrites a key-value pair in the MDC 57 // but only if the value is not empty 58 func (mdc *MDC) SetIfNotEmpty(key string, value string) { 59 if value != "" { 60 mdc.Set(key, value) 61 } 62 } 63 64 func (mdc *MDC) appendFields(entry *logrus.Entry) *logrus.Entry { 65 if len(mdc.mdc) == 0 { 66 return entry 67 } 68 69 return entry.WithFields(mdc.mdc) 70 }