Files
logrus/text_formatter.go
T
Derek Che dcbe8d66af make sure no leading or trailing spaces
This changed printColored and printKeyValue to print in same way
with prefix space instead of trailing space, to make it easier
to slice out when returning in Format;
The test cases are to make sure msg formartting doesn't include
leading or trailing spaces;

Closes #99

Signed-off-by: Derek Che <drc@yahoo-inc.com>
2015-01-04 00:19:36 -08:00

123 lines
2.4 KiB
Go

package logrus
import (
"bytes"
"fmt"
"regexp"
"sort"
"strings"
"time"
)
const (
nocolor = 0
red = 31
green = 32
yellow = 33
blue = 34
)
var (
baseTimestamp time.Time
isTerminal bool
noQuoteNeeded *regexp.Regexp
)
func init() {
baseTimestamp = time.Now()
isTerminal = IsTerminal()
}
func miniTS() int {
return int(time.Since(baseTimestamp) / time.Second)
}
type TextFormatter struct {
// Set to true to bypass checking for a TTY before outputting colors.
ForceColors bool
DisableColors bool
// Set to true to disable timestamp logging (useful when the output
// is redirected to a logging system already adding a timestamp)
DisableTimestamp bool
}
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
var keys []string
for k := range entry.Data {
keys = append(keys, k)
}
sort.Strings(keys)
b := &bytes.Buffer{}
prefixFieldClashes(entry.Data)
isColored := (f.ForceColors || isTerminal) && !f.DisableColors
if isColored {
printColored(b, entry, keys)
} else {
if !f.DisableTimestamp {
printKeyValue(b, "time", entry.Time.Format(time.RFC3339))
}
printKeyValue(b, "level", entry.Level.String())
printKeyValue(b, "msg", entry.Message)
for _, key := range keys {
printKeyValue(b, key, entry.Data[key])
}
}
b.WriteByte('\n')
return b.Bytes()[1:], nil
}
func printColored(b *bytes.Buffer, entry *Entry, keys []string) {
var levelColor int
switch entry.Level {
case WarnLevel:
levelColor = yellow
case ErrorLevel, FatalLevel, PanicLevel:
levelColor = red
default:
levelColor = blue
}
levelText := strings.ToUpper(entry.Level.String())[0:4]
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m[%04d] %-44s", levelColor, levelText, miniTS(), entry.Message)
for _, k := range keys {
v := entry.Data[k]
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v)
}
}
func needsQuoting(text string) bool {
for _, ch := range text {
if !((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch < '9') ||
ch == '-' || ch == '.') {
return false
}
}
return true
}
func printKeyValue(b *bytes.Buffer, key, value interface{}) {
switch value.(type) {
case string:
break
case error:
value = value.(error).Error()
default:
fmt.Fprintf(b, " %v=%v", key, value)
}
if needsQuoting(value.(string)) {
fmt.Fprintf(b, " %v=%s", key, value)
} else {
fmt.Fprintf(b, " %v=%q", key, value)
}
}