func Warning(v interface{}) {
	std.Warning(v)
}
Warning produce a "Warning" log with the default logger
package logging
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/teambition/gear"
)
var crlfEscaper = strings.NewReplacer("\r", "\\r", "\n", "\\n")
type Messager interface {
	fmt.Stringer
	Format() (string, error)
}
type Log map[string]interface{}
func (l Log) Format() (string, error) {
	res, err := json.Marshal(l)
	if err == nil {
		return string(res), nil
	}
	return "", err
}
func (l Log) GoString() string {
	count := len(l)
	buf := bytes.NewBufferString("Log{")
	for key, value := range l {
		if count--; count == 0 {
			fmt.Fprintf(buf, "%s:%#v}", key, value)
		} else {
			fmt.Fprintf(buf, "%s:%#v, ", key, value)
		}
	}
	return buf.String()
}
func (l Log) String() string {
	return l.GoString()
}
func (l Log) KV(key string, value interface{}) Log {
	l[key] = value
	return l
}
func (l Log) From(log Log) Log {
	for key, val := range log {
		l[key] = val
	}
	return l
}
func (l Log) Into(log Log) Log {
	for key, val := range l {
		log[key] = val
	}
	return log
}
func (l Log) With(log map[string]interface{}) Log {
	cp := l.Into(Log{})
	for key, val := range log {
		cp[key] = val
	}
	return cp
}
func (l Log) Reset() {
	for key := range l {
		delete(l, key)
	}
}
type Level uint8
const (
	EmergLevel Level = iota
	AlertLevel
	CritLevel
	ErrLevel
	WarningLevel
	NoticeLevel
	InfoLevel
	DebugLevel
)
const CritiLevel = CritLevel
func (l Level) String() string {
	switch l {
	case EmergLevel:
		return "emerg"
	case AlertLevel:
		return "alert"
	case CritLevel:
		return "crit"
	case ErrLevel:
		return "err"
	case WarningLevel:
		return "warning"
	case NoticeLevel:
		return "notice"
	case InfoLevel:
		return "info"
	case DebugLevel:
		return "debug"
	default:
		return "log"
	}
}
func ParseLevel(lvl string) (Level, error) {
	switch strings.ToLower(lvl) {
	case "emergency", "emerg":
		return EmergLevel, nil
	case "alert":
		return AlertLevel, nil
	case "critical", "crit", "criti":
		return CritLevel, nil
	case "error", "err":
		return ErrLevel, nil
	case "warning", "warn":
		return WarningLevel, nil
	case "notice":
		return NoticeLevel, nil
	case "info":
		return InfoLevel, nil
	case "debug":
		return DebugLevel, nil
	}
	var l Level
	return l, fmt.Errorf("not a valid gear logging Level: %q", lvl)
}
func SetLoggerLevel(logger *Logger, lvl string) error {
	level, err := ParseLevel(lvl)
	if err == nil {
		logger.SetLevel(level)
	}
	return err
}
var std = New(os.Stderr)
func Default(devMode ...bool) *Logger {
	if len(devMode) > 0 && devMode[0] {
		std.SetLogConsume(developmentConsume)
	}
	return std
}
func developmentConsume(log Log, ctx *gear.Context) {
	std.mu.Lock()  
	defer std.mu.Unlock()
	end := time.Now().UTC()
	FprintWithColor(std.Out, fmt.Sprintf("%s", log["ip"]), ColorGreen)
	fmt.Fprintf(std.Out, ` - - [%s] "%s %s %s" `, end.Format(std.tf), log["method"], log["uri"], log["proto"])
	status := log["status"].(int)
	FprintWithColor(std.Out, strconv.Itoa(status), colorStatus(status))
	resTime := float64(end.Sub(ctx.StartAt)) / 1e6
	fmt.Fprintln(std.Out, fmt.Sprintf(" %d %.3fms", log["length"], resTime))
}
func New(w io.Writer) *Logger {
	logger := &Logger{Out: w}
	logger.SetLevel(DebugLevel)
	logger.SetTimeFormat("2006-01-02T15:04:05.000Z")
	logger.SetLogFormat("[%s] %s %s")
	logger.init = func(log Log, ctx *gear.Context) {
		log["start"] = ctx.StartAt.Format(logger.tf)
		log["ip"] = ctx.IP().String()
		log["scheme"] = ctx.Scheme()
		log["proto"] = ctx.Req.Proto
		log["method"] = ctx.Method
		log["uri"] = ctx.Req.RequestURI
		if s := ctx.GetHeader(gear.HeaderOrigin); s != "" {
			log["origin"] = s
		}
		if s := ctx.GetHeader(gear.HeaderReferer); s != "" {
			log["referer"] = s
		}
		if s := ctx.GetHeader(gear.HeaderXCanary); s != "" {
			log["xCanary"] = s
		}
		log["userAgent"] = ctx.GetHeader(gear.HeaderUserAgent)
	}
	logger.consume = func(log Log, ctx *gear.Context) {
		end := time.Now().UTC()
		log["duration"] = end.Sub(ctx.StartAt) / 1e6  
		if s := ctx.GetHeader(gear.HeaderXRequestID); s != "" {
			log["xRequestId"] = s
		} else if s := ctx.Res.Get(gear.HeaderXRequestID); s != "" {
			log["xRequestId"] = s
		}
		if router := gear.GetRouterPatternFromCtx(ctx); router != "" {
			log["router"] = fmt.Sprintf("%s %s", ctx.Method, router)
		}
		if err := logger.output(end, InfoLevel, log); err != nil {
			logger.output(end, ErrLevel, err)
		}
	}
	return logger
}
type Logger struct {
	Out     io.Writer
	json    bool
	l       Level                     
	tf, lf  string                    
	mu      sync.Mutex                
	init    func(Log, *gear.Context)  
	consume func(Log, *gear.Context)  
}
func (l *Logger) checkLogLevel(level Level) bool {
	return level <= l.l
}
func (l *Logger) Emerg(v interface{}) {
	l.output(time.Now().UTC(), EmergLevel, v)
}
func (l *Logger) Alert(v interface{}) {
	if l.checkLogLevel(AlertLevel) {
		l.output(time.Now().UTC(), AlertLevel, v)
	}
}
func (l *Logger) Crit(v interface{}) {
	if l.checkLogLevel(CritLevel) {
		l.output(time.Now().UTC(), CritLevel, v)
	}
}
func (l *Logger) Err(v interface{}) {
	if l.checkLogLevel(ErrLevel) {
		l.output(time.Now().UTC(), ErrLevel, v)
	}
}
func (l *Logger) Warning(v interface{}) {
	if l.checkLogLevel(WarningLevel) {
		l.output(time.Now().UTC(), WarningLevel, v)
	}
}
func (l *Logger) Notice(v interface{}) {
	if l.checkLogLevel(NoticeLevel) {
		l.output(time.Now().UTC(), NoticeLevel, v)
	}
}
func (l *Logger) Info(v interface{}) {
	if l.checkLogLevel(InfoLevel) {
		l.output(time.Now().UTC(), InfoLevel, v)
	}
}
func (l *Logger) Debug(v interface{}) {
	if l.checkLogLevel(DebugLevel) {
		l.output(time.Now().UTC(), DebugLevel, v)
	}
}
func (l *Logger) Debugf(format string, args ...interface{}) {
	if l.checkLogLevel(DebugLevel) {
		l.output(time.Now().UTC(), DebugLevel, fmt.Sprintf(format, args...))
	}
}
func (l *Logger) Panic(v interface{}) {
	s := format(v)
	l.Emerg(s)
	panic(s)
}
var exit = func() { os.Exit(1) }
func (l *Logger) Fatal(v interface{}) {
	l.Emerg(v)
	exit()
}
func (l *Logger) Print(args ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	fmt.Fprint(l.Out, args...)
}
func (l *Logger) Printf(format string, args ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	fmt.Fprintf(l.Out, format, args...)
}
func (l *Logger) Println(args ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	fmt.Fprintln(l.Out, args...)
}
func (l *Logger) output(t time.Time, level Level, v interface{}) (err error) {
	if l.json {
		var log Log
		if level > ErrLevel {
			log = format2Log(v)
		} else {
			log = formatError2Log(v)
		}
		log["time"] = t.Format(l.tf)
		log["level"] = level.String()
		return l.OutputJSON(log)
	}
	var s string
	if level > ErrLevel {
		s = format(v)
	} else {
		s = formatError(v)
	}
	return l.Output(t, level, s)
}
func (l *Logger) Output(t time.Time, level Level, s string) (err error) {
	l.mu.Lock()
	defer l.mu.Unlock()
	if l := len(s); l > 0 && s[l-1] == '\n' {
		s = s[0 : l-1]
	}
	_, err = fmt.Fprintf(l.Out, l.lf, t.UTC().Format(l.tf), level.String(), crlfEscaper.Replace(s))
	if err == nil {
		l.Out.Write([]byte{'\n'})
	}
	return
}
func (l *Logger) OutputJSON(log Log) (err error) {
	l.mu.Lock()
	defer l.mu.Unlock()
	var str string
	if str, err = log.Format(); err == nil {
		_, err = fmt.Fprint(l.Out, crlfEscaper.Replace(str))
		if err == nil {
			l.Out.Write([]byte{'\n'})
		}
	}
	return
}
func (l *Logger) GetLevel() Level {
	l.mu.Lock()
	defer l.mu.Unlock()
	return l.l
}
func (l *Logger) SetLevel(level Level) *Logger {
	l.mu.Lock()
	defer l.mu.Unlock()
	if level > DebugLevel {
		panic(gear.Err.WithMsg("invalid logger level"))
	}
	l.l = level
	return l
}
func (l *Logger) SetJSONLog() *Logger {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.json = true
	return l
}
func (l *Logger) SetTimeFormat(timeFormat string) *Logger {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.tf = timeFormat
	return l
}
func (l *Logger) SetLogFormat(logFormat string) *Logger {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.lf = logFormat
	return l
}
func (l *Logger) SetLogInit(fn func(Log, *gear.Context)) *Logger {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.init = fn
	return l
}
func (l *Logger) SetLogConsume(fn func(Log, *gear.Context)) *Logger {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.consume = fn
	return l
}
func (l *Logger) New(ctx *gear.Context) (interface{}, error) {
	log := Log{}
	l.init(log, ctx)
	return log, nil
}
func (l *Logger) FromCtx(ctx *gear.Context) Log {
	any, _ := ctx.Any(l)
	return any.(Log)
}
func (l *Logger) SetTo(ctx *gear.Context, key string, val interface{}) {
	any, _ := ctx.Any(l)
	any.(Log)[key] = val
}
func (l *Logger) Serve(ctx *gear.Context) error {
	log := l.FromCtx(ctx)
	ctx.OnEnd(func() {
		if len(log) == 0 {
			return
		}
		log["status"] = ctx.Res.Status()
		log["length"] = len(ctx.Res.Body())
		if ctx.Res.Status() == 500 {
			if body, _ := ctx.Any("GEAR_REQUEST_BODY"); body != nil {
				if b, ok := body.([]byte); ok {
					log["requestBody"] = string(b)
					if contentType, _ := ctx.Any("GEAR_REQUEST_CONTENT_TYPE"); contentType != nil {
						log["requestContentType"] = contentType
					}
				}
			}
			if b := ctx.Res.Body(); b != nil {
				log["responseBody"] = string(b)
				log["responseContentType"] = ctx.Res.Get(gear.HeaderContentType)
			}
		}
		l.consume(log, ctx)
	})
	return nil
}
func Emerg(v interface{}) {
	std.Emerg(v)
}
func Alert(v interface{}) {
	std.Alert(v)
}
func Crit(v interface{}) {
	std.Crit(v)
}
func Err(v interface{}) {
	std.Err(v)
}