// Log will format a JSON map and write it to Out func (j *JSONLogger) Log(keyvals ...interface{}) error { n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd m := make(map[string]interface{}, n) for i := 0; i < len(keyvals); i += 2 { var k, v interface{} if i == len(keyvals)-1 { k, v = j.MissingValueKey, keyvals[i] } else { k, v = keyvals[i], keyvals[i+1] } m[mapKey(k)] = mapValue(v) } return errors.Annotate(json.NewEncoder(j.Out).Encode(m), "cannot JSON encode log") }
// Log writes the keyvalus in logfmt format to Out func (l *LogfmtLogger) Log(keyvals ...interface{}) error { // The Logger interface requires implementations to be safe for concurrent // use by multiple goroutines. For this implementation that means making // only one call to l.w.Write() for each call to Log. We first collect all // of the bytes into b, and then call l.w.Write(b). if len(keyvals)%2 != 0 { keyvals = append(keyvals[0:len(keyvals)-1:len(keyvals)-1], l.MissingValueKey, keyvals[len(keyvals)-1]) } b, err := logfmt.MarshalKeyvals(keyvals...) if err != nil { return err } b = append(b, '\n') if _, err := l.Out.Write(b); err != nil { return errors.Annotate(err, "cannot write out logfmt for log") } return nil }
// Zk creates a zookeeper readable backing func Zk(zkConnector ZkConnector, conf *ZkConfig) (ReaderWriter, error) { conf = pointer.FillDefaultFrom(conf, DefaultZkConfig).(*ZkConfig) ret := &zkConfig{ rootLogger: log.NewContext(conf.Logger).With(logkey.DistconfBacking, "zk"), shouldQuit: make(chan struct{}), callbacks: callbackMap{ callbacks: make(map[string][]backingCallbackFunction), }, refreshDelay: atomicDuration{ refreshRetryDelay: time.Millisecond * 500, }, } var err error ret.conn, ret.eventChan, err = zkConnector.Connect() if err != nil { return nil, errors.Annotate(err, "cannot create zk connection") } go ret.drainEventChan(conf.Logger) return ret, nil }