func appendKVsAndNewLine(b *bytes.Buffer, entry *log.Entry) {
	var keys []string = make([]string, 0, len(entry.Data))
	for k := range entry.Data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, key := range keys {
		if key == fieldFileName || key == fieldLineNumber || key == FieldForceFlush {
			continue
		}
		var value interface{} = entry.Data[key]
		var stringifiedValue string
		if err, ok := value.(error); ok {
			stringifiedValue = err.Error()
		} else if stringer, ok := value.(fmt.Stringer); ok {
			stringifiedValue = stringer.String()
		} else {
			fmt.Fprintf(b, " %v=%#v", key, value)
			continue
		}
		b.WriteByte(' ')
		b.WriteString(key)
		b.WriteByte('=')
		b.WriteString(stringifiedValue)
	}
	b.WriteByte('\n')
}
appendKeysAndNewLine writes the KV pairs attached to the entry to the end of the buffer, then
finishes it with a newline.
package logutils
import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path"
	"runtime"
	"sort"
	"strings"
	"sync"
	"time"
	"github.com/prometheus/client_golang/prometheus"
	log "github.com/sirupsen/logrus"
)
const (
	FieldForceFlush = "__flush__"
	fieldFileName = "__file__"
	fieldLineNumber = "__line__"
)
func FilterLevels(maxLevel log.Level) []log.Level {
	levels := []log.Level{}
	for _, l := range log.AllLevels {
		if l <= maxLevel {
			levels = append(levels, l)
		}
	}
	return levels
}
type Formatter struct {
	Component string
}
func (f *Formatter) Format(entry *log.Entry) ([]byte, error) {
	stamp := entry.Time.Format("2006-01-02 15:04:05.000")
	levelStr := strings.ToUpper(entry.Level.String())
	pid := os.Getpid()
	fileName := entry.Data[fieldFileName]
	lineNo := entry.Data[fieldLineNumber]
	b := entry.Buffer
	if b == nil {
		b = &bytes.Buffer{}
	}
	if f.Component != "" {
		fmt.Fprintf(b, "%s [%s][%d] %s/%v %v: %v", stamp, levelStr, pid, f.Component, fileName, lineNo, entry.Message)
	} else {
		fmt.Fprintf(b, "%s [%s][%d] %v %v: %v", stamp, levelStr, pid, fileName, lineNo, entry.Message)
	}
	appendKVsAndNewLine(b, entry)
	return b.Bytes(), nil
}
func FormatForSyslog(entry *log.Entry) string {
	levelStr := strings.ToUpper(entry.Level.String())
	fileName := entry.Data[fieldFileName]
	lineNo := entry.Data[fieldLineNumber]
	b := entry.Buffer
	if b == nil {
		b = &bytes.Buffer{}
	}
	fmt.Fprintf(b, "%s %v %v: %v", levelStr, fileName, lineNo, entry.Message)
	appendKVsAndNewLine(b, entry)
	return b.String()
}