// FatalHandler makes critical errors exit the program // immediately, much like the log.Fatal* methods from the // standard log package func FatalHandler(h log.Handler) log.Handler { return log.FuncHandler(func(r *log.Record) error { err := h.Log(r) if r.Lvl == log.LvlCrit { os.Exit(1) } return err }) }
// FuncAndLineHandler creates a log handler that adds the calling function's // name and line number as context. func FuncAndLineHandler(h log.Handler, lvl log.Lvl) log.Handler { return log.FuncHandler(func(r *log.Record) error { if r.Lvl <= lvl { call := stack.Call(r.CallPC[0]) r.Ctx = append(r.Ctx, "fn", fmt.Sprintf("%+v", call)) r.Ctx = append(r.Ctx, "ln", fmt.Sprint(call)) return h.Log(r) } return nil }) }
// EscalateErrHandler wraps another handler and passes all records through // unchanged except if the logged context contains a non-nil error // value in its context. In that case, the record's level is raised // to LvlError unless it was already more serious (LvlCrit). // // This allows you to log the result of all functions for debugging // and still capture error conditions when in production with a single // log line. As an example, the following the log record will be written // out only if there was an error writing a value to redis: // // logger := logext.EscalateErrHandler( // log.LvlFilterHandler(log.LvlInfo, log.StdoutHandler)) // // reply, err := redisConn.Do("SET", "foo", "bar") // logger.Debug("Wrote value to redis", "reply", reply, "err", err) // if err != nil { // return err // } // func EscalateErrHandler(h log.Handler) log.Handler { return log.FuncHandler(func(r *log.Record) error { if r.Lvl > log.LvlError { for i := 1; i < len(r.Ctx); i++ { if v, ok := r.Ctx[i].(error); ok && v != nil { r.Lvl = log.LvlError break } } } return h.Log(r) }) }
func errorMultiHandler(normalHandler, errorHandler log.Handler) log.Handler { return log.FuncHandler(func(r *log.Record) error { if len(r.Ctx) > 1 { _, ok := r.Ctx[1].(error) if ok { r.Ctx = r.Ctx[2:] errorHandler.Log(r) } else { normalHandler.Log(r) } } else { normalHandler.Log(r) } return nil }) }