github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/message/interface.go (about) 1 package message 2 3 import "github.com/mongodb/grip/level" 4 5 // Composer defines an interface with a "String()" method that 6 // returns the message in string format. Objects that implement this 7 // interface, in combination to the Compose[*] operations, the 8 // String() method is only caled if the priority of the method is 9 // greater than the threshold priority. This makes it possible to 10 // defer building log messages (that may be somewhat expensive to 11 // generate) until it's certain that we're going to be outputting the 12 // message. 13 type Composer interface { 14 // Returns the content of the message as a string for use in 15 // line-printing logging engines. 16 String() string 17 18 // A "raw" format of the logging output for use by some Sender 19 // implementations that write logged items to interfaces that 20 // accept JSON or another structured format. 21 Raw() interface{} 22 23 // Returns "true" when the message has content and should be 24 // logged, and false otherwise. When false, the sender can 25 // (and should!) ignore messages even if they are otherwise 26 // above the logging threshold. 27 Loggable() bool 28 29 // Annotate makes it possible for Senders and Journalers to 30 // add structured data to a log message. May return an error 31 // when the key alrady exists. 32 Annotate(string, interface{}) error 33 34 // Priority returns the priority of the message. 35 Priority() level.Priority 36 SetPriority(level.Priority) error 37 } 38 39 // ErrorComposer defines an interface to a Composer that also includes an error. 40 type ErrorComposer interface { 41 Composer 42 Error() string 43 } 44 45 // ConvertToComposer can coerce unknown objects into Composer 46 // instances, as possible. This method will override the priority of 47 // composers set to it. 48 func ConvertToComposer(p level.Priority, message interface{}) Composer { 49 return convert(p, message, true) 50 } 51 52 // ConvertToComposerWithLevel can coerce unknown objects into 53 // Composers, but will only override the priority of Composers. 54 func ConvertToComposerWithLevel(p level.Priority, message interface{}) Composer { 55 return convert(p, message, false) 56 } 57 58 func convert(p level.Priority, message interface{}, overRideLevel bool) Composer { 59 switch message := message.(type) { 60 case Composer: 61 if overRideLevel || message.Priority() != level.Invalid { 62 _ = message.SetPriority(p) 63 } 64 return message 65 case []Composer: 66 out := NewGroupComposer(message) 67 // this only sets constituent 68 // messages priority when its not otherwise set. 69 _ = out.SetPriority(p) 70 return out 71 case string: 72 return NewDefaultMessage(p, message) 73 case error: 74 return NewErrorMessage(p, message) 75 case []string: 76 return newLinesFromStrings(p, message) 77 case []interface{}: 78 return NewLineMessage(p, message...) 79 case []byte: 80 return NewBytesMessage(p, message) 81 case Fields: 82 return NewFields(p, message) 83 case map[string]interface{}: 84 return NewFields(p, Fields(message)) 85 case [][]string: 86 grp := make([]Composer, len(message)) 87 for idx := range message { 88 grp[idx] = newLinesFromStrings(p, message[idx]) 89 } 90 out := NewGroupComposer(grp) 91 return out 92 case [][]byte: 93 grp := make([]Composer, len(message)) 94 for idx := range message { 95 grp[idx] = NewBytesMessage(p, message[idx]) 96 } 97 out := NewGroupComposer(grp) 98 return out 99 case []map[string]interface{}: 100 grp := make([]Composer, len(message)) 101 for idx := range message { 102 grp[idx] = NewFields(p, message[idx]) 103 } 104 out := NewGroupComposer(grp) 105 return out 106 case []Fields: 107 grp := make([]Composer, len(message)) 108 for idx := range message { 109 grp[idx] = NewFields(p, message[idx]) 110 } 111 out := NewGroupComposer(grp) 112 return out 113 case nil: 114 return NewLineMessage(p) 115 default: 116 return NewFormattedMessage(p, "%+v", message) 117 } 118 }