github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/thirdparty/eventlog/log.go (about) 1 package eventlog 2 3 import ( 4 "fmt" 5 "time" 6 7 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 8 "github.com/ipfs/go-ipfs/util" // TODO remove IPFS dependency 9 ) 10 11 // StandardLogger provides API compatibility with standard printf loggers 12 // eg. go-logging 13 type StandardLogger interface { 14 Debug(args ...interface{}) 15 Debugf(format string, args ...interface{}) 16 Error(args ...interface{}) 17 Errorf(format string, args ...interface{}) 18 Fatal(args ...interface{}) 19 Fatalf(format string, args ...interface{}) 20 Info(args ...interface{}) 21 Infof(format string, args ...interface{}) 22 Panic(args ...interface{}) 23 Panicf(format string, args ...interface{}) 24 Warning(args ...interface{}) 25 Warningf(format string, args ...interface{}) 26 } 27 28 // EventLogger extends the StandardLogger interface to allow for log items 29 // containing structured metadata 30 type EventLogger interface { 31 StandardLogger 32 33 // Event merges structured data from the provided inputs into a single 34 // machine-readable log event. 35 // 36 // If the context contains metadata, a copy of this is used as the base 37 // metadata accumulator. 38 // 39 // If one or more loggable objects are provided, these are deep-merged into base blob. 40 // 41 // Next, the event name is added to the blob under the key "event". If 42 // the key "event" already exists, it will be over-written. 43 // 44 // Finally the timestamp and package name are added to the accumulator and 45 // the metadata is logged. 46 Event(ctx context.Context, event string, m ...Loggable) 47 48 EventBegin(ctx context.Context, event string, m ...Loggable) *EventInProgress 49 } 50 51 // Logger retrieves an event logger by name 52 func Logger(system string) EventLogger { 53 54 // TODO if we would like to adjust log levels at run-time. Store this event 55 // logger in a map (just like the util.Logger impl) 56 return &eventLogger{system: system, StandardLogger: util.Logger(system)} 57 } 58 59 // eventLogger implements the EventLogger and wraps a go-logging Logger 60 type eventLogger struct { 61 StandardLogger 62 63 system string 64 // TODO add log-level 65 } 66 67 func (el *eventLogger) EventBegin(ctx context.Context, event string, metadata ...Loggable) *EventInProgress { 68 start := time.Now() 69 el.Event(ctx, fmt.Sprintf("%sBegin", event), metadata...) 70 71 eip := &EventInProgress{} 72 eip.doneFunc = func(additional []Loggable) { 73 74 metadata = append(metadata, additional...) // anything added during the operation 75 metadata = append(metadata, LoggableMap(map[string]interface{}{ // finally, duration of event 76 "duration": time.Now().Sub(start), 77 })) 78 79 el.Event(ctx, event, metadata...) 80 } 81 return eip 82 } 83 84 func (el *eventLogger) Event(ctx context.Context, event string, metadata ...Loggable) { 85 86 // short circuit if theres nothing to write to 87 if !WriterGroup.Active() { 88 return 89 } 90 91 // Collect loggables for later logging 92 var loggables []Loggable 93 94 // get any existing metadata from the context 95 existing, err := MetadataFromContext(ctx) 96 if err != nil { 97 existing = Metadata{} 98 } 99 loggables = append(loggables, existing) 100 101 for _, datum := range metadata { 102 loggables = append(loggables, datum) 103 } 104 105 e := entry{ 106 loggables: loggables, 107 system: el.system, 108 event: event, 109 } 110 111 e.Log() // TODO replace this when leveled-logs have been implemented 112 } 113 114 type EventInProgress struct { 115 loggables []Loggable 116 doneFunc func([]Loggable) 117 } 118 119 // Append adds loggables to be included in the call to Done 120 func (eip *EventInProgress) Append(l Loggable) { 121 eip.loggables = append(eip.loggables, l) 122 } 123 124 // SetError includes the provided error 125 func (eip *EventInProgress) SetError(err error) { 126 eip.loggables = append(eip.loggables, LoggableMap{ 127 "error": err.Error(), 128 }) 129 } 130 131 // Done creates a new Event entry that includes the duration and appended 132 // loggables. 133 func (eip *EventInProgress) Done() { 134 eip.doneFunc(eip.loggables) // create final event with extra data 135 } 136 137 // Close is an alias for done 138 func (eip *EventInProgress) Close() error { 139 eip.Done() 140 return nil 141 }