func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
	prefixFieldClashes(entry.Data, f.FieldMap)
	keys := make([]string, 0, len(entry.Data))
	for k := range entry.Data {
		keys = append(keys, k)
	}
	fixedKeys := make([]string, 0, 4+len(entry.Data))
	if !f.DisableTimestamp {
		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
	}
	fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel))
	if entry.Message != "" {
		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg))
	}
	if entry.err != "" {
		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
	}
	if !f.DisableSorting {
		if f.SortingFunc == nil {
			sort.Strings(keys)
			fixedKeys = append(fixedKeys, keys...)
		} else {
			if !f.isColored() {
				fixedKeys = append(fixedKeys, keys...)
				f.SortingFunc(fixedKeys)
			} else {
				f.SortingFunc(keys)
			}
		}
	} else {
		fixedKeys = append(fixedKeys, keys...)
	}
	var b *bytes.Buffer
	if entry.Buffer != nil {
		b = entry.Buffer
	} else {
		b = &bytes.Buffer{}
	}
	f.terminalInitOnce.Do(func() { f.init(entry) })
	timestampFormat := f.TimestampFormat
	if timestampFormat == "" {
		timestampFormat = defaultTimestampFormat
	}
	if f.isColored() {
		f.printColored(b, entry, keys, timestampFormat)
	} else {
		for _, key := range fixedKeys {
			var value interface{}
			switch key {
			case f.FieldMap.resolve(FieldKeyTime):
				value = entry.Time.Format(timestampFormat)
			case f.FieldMap.resolve(FieldKeyLevel):
				value = entry.Level.String()
			case f.FieldMap.resolve(FieldKeyMsg):
				value = entry.Message
			case f.FieldMap.resolve(FieldKeyLogrusError):
				value = entry.err
			default:
				value = entry.Data[key]
			}
			f.appendKeyValue(b, key, value)
		}
	}
	b.WriteByte('\n')
	return b.Bytes(), nil
}
Format renders a single log entry
package logrus
import (
	"bytes"
	"fmt"
	"os"
	"sort"
	"strings"
	"sync"
	"time"
)
const (
	nocolor = 0
	red     = 31
	green   = 32
	yellow  = 33
	blue    = 36
	gray    = 37
)
var (
	baseTimestamp time.Time
	emptyFieldMap FieldMap
)
func init() {
	baseTimestamp = time.Now()
}
type TextFormatter struct {
	ForceColors bool
	DisableColors bool
	EnvironmentOverrideColors bool
	DisableTimestamp bool
	FullTimestamp bool
	TimestampFormat string
	DisableSorting bool
	SortingFunc func([]string)
	DisableLevelTruncation bool
	QuoteEmptyFields bool
	isTerminal bool
	FieldMap FieldMap
	terminalInitOnce sync.Once
}
func (f *TextFormatter) init(entry *Entry) {
	if entry.Logger != nil {
		f.isTerminal = checkIfTerminal(entry.Logger.Out)
		if f.isTerminal {
			initTerminal(entry.Logger.Out)
		}
	}
}
func (f *TextFormatter) isColored() bool {
	isColored := f.ForceColors || f.isTerminal
	if f.EnvironmentOverrideColors {
		if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" {
			isColored = true
		} else if ok && force == "0" {
			isColored = false
		} else if os.Getenv("CLICOLOR") == "0" {
			isColored = false
		}
	}
	return isColored && !f.DisableColors
}