github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/logging/loggers/burrow_format_logger.go (about) 1 // Copyright Monax Industries Limited 2 // SPDX-License-Identifier: Apache-2.0 3 4 package loggers 5 6 import ( 7 "encoding" 8 "encoding/json" 9 "fmt" 10 "sync" 11 "time" 12 13 "github.com/go-kit/kit/log" 14 "github.com/hyperledger/burrow/logging/structure" 15 "github.com/tmthrgd/go-hex" 16 ) 17 18 // Logger that implements some formatting conventions for burrow and burrow-client 19 // This is intended for applying consistent value formatting before the final 'output' logger; 20 // we should avoid prematurely formatting values here if it is useful to let the output logger 21 // decide how it wants to display values. Ideal candidates for 'early' formatting here are types that 22 // we control and generic output loggers are unlikely to know about. 23 type burrowFormatLogger struct { 24 sync.Mutex 25 logger log.Logger 26 options opt 27 } 28 29 type opt byte 30 31 func (o opt) enabled(q opt) bool { 32 return o&q > 0 33 } 34 35 const ( 36 DefaultOptions opt = iota 37 StringifyValues 38 ) 39 40 func NewBurrowFormatLogger(logger log.Logger, options ...opt) *burrowFormatLogger { 41 bfl := &burrowFormatLogger{logger: logger} 42 for _, option := range options { 43 bfl.options |= option 44 } 45 return bfl 46 } 47 48 var _ log.Logger = &burrowFormatLogger{} 49 50 func (bfl *burrowFormatLogger) Log(keyvals ...interface{}) error { 51 if bfl.logger == nil { 52 return nil 53 } 54 keyvals, err := structure.MapKeyValues(keyvals, 55 func(key interface{}, value interface{}) (interface{}, interface{}) { 56 switch v := value.(type) { 57 case string, json.Marshaler, encoding.TextMarshaler: 58 case time.Time: 59 value = v.Format(time.RFC3339Nano) 60 case fmt.Stringer: 61 value = v.String() 62 case []byte: 63 value = hex.EncodeUpperToString(v) 64 } 65 if bfl.options.enabled(StringifyValues) { 66 value = structure.Stringify(value) 67 } 68 return structure.Stringify(key), value 69 }) 70 if err != nil { 71 return err 72 } 73 bfl.Lock() 74 defer bfl.Unlock() 75 return bfl.logger.Log(keyvals...) 76 }