func WriteWithColor(w io.Writer, s string, color Color) error {
	var err error
	writer := func(buf []byte) {
		if err != nil {
			return
		}
		_, err = w.Write(buf)
	}
	if color != NoColor {
		writer(AnsiColorPrefix)
		writer([]byte(strconv.FormatInt(int64(color), 10)))
		writer(AnsiColorSuffix)
	}
	if err == nil {
		_, err = io.WriteString(w, s)
	}
	if color != NoColor {
		writer(AnsiColorPrefix)
		writer([]byte(strconv.FormatInt(int64(NoColor), 10)))
		writer(AnsiColorSuffix)
	}
	return err
}
WriteWithColor outputs a string with the specified ANSI color.
package logr
import (
	"bytes"
	"io"
	"runtime"
	"strconv"
)
type Formatter interface {
	IsStacktraceNeeded() bool
	Format(rec *LogRec, level Level, buf *bytes.Buffer) (*bytes.Buffer, error)
}
const (
	DefTimestampFormat = "2006-01-02 15:04:05.000 Z07:00"
	TimestampMillisFormat = "Jan _2 15:04:05.000"
)
type Writer struct {
	io.Writer
}
func (w Writer) Writes(elems ...[]byte) (int, error) {
	var count int
	for _, e := range elems {
		if c, err := w.Write(e); err != nil {
			return count + c, err
		} else {
			count += c
		}
	}
	return count, nil
}
type DefaultFormatter struct {
}
func (p *DefaultFormatter) IsStacktraceNeeded() bool {
	return false
}
func (p *DefaultFormatter) Format(rec *LogRec, level Level, buf *bytes.Buffer) (*bytes.Buffer, error) {
	if buf == nil {
		buf = &bytes.Buffer{}
	}
	timestampFmt := DefTimestampFormat
	buf.WriteString(rec.Time().Format(timestampFmt))
	buf.Write(Space)
	buf.WriteString(level.Name)
	buf.Write(Space)
	buf.WriteString(rec.Msg())
	buf.Write(Space)
	fields := rec.Fields()
	if len(fields) > 0 {
		if err := WriteFields(buf, fields, Space, NoColor); err != nil {
			return nil, err
		}
	}
	if level.Stacktrace {
		frames := rec.StackFrames()
		if len(frames) > 0 {
			buf.Write(Newline)
			if err := WriteStacktrace(buf, rec.StackFrames()); err != nil {
				return nil, err
			}
		}
	}
	buf.Write(Newline)
	return buf, nil
}
func WriteFields(w io.Writer, fields []Field, separator []byte, color Color) error {
	ws := Writer{w}
	sep := []byte{}
	for _, field := range fields {
		if err := writeField(ws, field, sep, color); err != nil {
			return err
		}
		sep = separator
	}
	return nil
}
func writeField(ws Writer, field Field, sep []byte, color Color) error {
	if len(sep) != 0 {
		if _, err := ws.Write(sep); err != nil {
			return err
		}
	}
	if err := WriteWithColor(ws, field.Key, color); err != nil {
		return err
	}
	if _, err := ws.Write(Equals); err != nil {
		return err
	}
	return field.ValueString(ws, shouldQuote)
}
func shouldQuote(val string) bool {
	for _, c := range val {
		if !((c >= '0' && c <= '9') ||
			(c >= 'a' && c <= 'z') ||
			(c >= 'A' && c <= 'Z') ||
			c == '-' || c == '.' || c == '_' || c == '/' || c == '@' || c == '^' || c == '+') {
			return true
		}
	}
	return false
}
func WriteStacktrace(w io.Writer, frames []runtime.Frame) error {
	ws := Writer{w}
	for _, frame := range frames {
		if frame.Function != "" {
			if _, err := ws.Writes(Space, Space, []byte(frame.Function), Newline); err != nil {
				return err
			}
		}
		if frame.File != "" {
			s := strconv.FormatInt(int64(frame.Line), 10)
			if _, err := ws.Writes([]byte{' ', ' ', ' ', ' ', ' ', ' '}, []byte(frame.File), Colon, []byte(s), Newline); err != nil {
				return err
			}
		}
	}
	return nil
}