3 // FuncHandler returns a Handler that logs records with the given
12 // Function handler wraps the declared function and returns the handler for it
13 func FuncHandler(fn func(r *Record) error) LogHandler {
14 return funcHandler(fn)
17 // The type decleration for the function
18 type funcHandler func(r *Record) error
20 // The implementation of the Log
21 func (h funcHandler) Log(r *Record) error {
25 // This function allows you to do a full declaration for the log,
26 // it is recommended you use FuncHandler instead
27 func HandlerFunc(log func(message string, time time.Time, level LogLevel, call CallStack, context ContextMap) error) LogHandler {
28 return remoteHandler(log)
31 // The type used for the HandlerFunc
32 type remoteHandler func(message string, time time.Time, level LogLevel, call CallStack, context ContextMap) error
34 // The Log implementation
35 func (c remoteHandler) Log(record *Record) error {
36 return c(record.Message, record.Time, record.Level, record.Call, record.Context)
39 // SyncHandler can be wrapped around a handler to guarantee that
40 // only a single Log operation can proceed at a time. It's necessary
41 // for thread-safe concurrent writes.
42 func SyncHandler(h LogHandler) LogHandler {
44 return FuncHandler(func(r *Record) error {
51 // LazyHandler writes all values to the wrapped handler after evaluating
52 // any lazy functions in the record's context. It is already wrapped
53 // around StreamHandler and SyslogHandler in this library, you'll only need
54 // it if you write your own Handler.
55 func LazyHandler(h LogHandler) LogHandler {
56 return FuncHandler(func(r *Record) error {
57 for k, v := range r.Context {
58 if lz, ok := v.(Lazy); ok {
59 value, err := evaluateLazy(lz)
61 r.Context[errorKey] = "bad lazy " + k
72 func evaluateLazy(lz Lazy) (interface{}, error) {
73 t := reflect.TypeOf(lz.Fn)
75 if t.Kind() != reflect.Func {
76 return nil, fmt.Errorf("INVALID_LAZY, not func: %+v", lz.Fn)
80 return nil, fmt.Errorf("INVALID_LAZY, func takes args: %+v", lz.Fn)
84 return nil, fmt.Errorf("INVALID_LAZY, no func return val: %+v", lz.Fn)
87 value := reflect.ValueOf(lz.Fn)
88 results := value.Call([]reflect.Value{})
89 if len(results) == 1 {
90 return results[0].Interface(), nil
92 values := make([]interface{}, len(results))
93 for i, v := range results {
94 values[i] = v.Interface()