log/logger.go
func (l *Logger) Output(callDepth int, level Level, msg string) {
	if l.level > level {
		return
	}

	buf := l.bufs.Get().([]byte)
	buf = buf[0:0]
	defer l.bufs.Put(buf)

	if l.flag&Ltime > 0 {
		now := time.Now().Format(timeFormat)
		buf = append(buf, '[')
		buf = append(buf, now...)
		buf = append(buf, "] "...)
	}

	if l.flag&Llevel > 0 {
		buf = append(buf, '[')
		buf = append(buf, level.String()...)
		buf = append(buf, "] "...)
	}

	if l.flag&Lfile > 0 {
		_, file, line, ok := runtime.Caller(callDepth)
		if !ok {
			file = "???"
			line = 0
		} else {
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					file = file[i+1:]
					break
				}
			}
		}

		buf = append(buf, file...)
		buf = append(buf, ':')

		buf = strconv.AppendInt(buf, int64(line), 10)
		buf = append(buf, ' ')
	}

	buf = append(buf, msg...)
	if len(msg) == 0 || msg[len(msg)-1] != '\n' {
		buf = append(buf, '\n')
	}

	l.hLock.Lock()
	l.handler.Write(buf)
	l.hLock.Unlock()
}
func (l *Logger) Output(callDepth int, level Level, msg string) {
	if l.level > level {
		return
	}

	buf := l.bufs.Get().([]byte)
	buf = buf[0:0]
	defer l.bufs.Put(buf)

	if l.flag&Ltime > 0 {
		now := time.Now().Format(timeFormat)
		buf = append(buf, '[')
		buf = append(buf, now...)
		buf = append(buf, "] "...)
	}

	if l.flag&Llevel > 0 {
		buf = append(buf, '[')
		buf = append(buf, level.String()...)
		buf = append(buf, "] "...)
	}

	if l.flag&Lfile > 0 {
		_, file, line, ok := runtime.Caller(callDepth)
		if !ok {
			file = "???"
			line = 0
		} else {
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					file = file[i+1:]
					break
				}
			}
		}

		buf = append(buf, file...)
		buf = append(buf, ':')

		buf = strconv.AppendInt(buf, int64(line), 10)
		buf = append(buf, ' ')
	}

	buf = append(buf, msg...)
	if len(msg) == 0 || msg[len(msg)-1] != '\n' {
		buf = append(buf, '\n')
	}

	l.hLock.Lock()
	l.handler.Write(buf)
	l.hLock.Unlock()
}
// Output records the log with special callstack depth and log level.