skeema/log.go

86 строки
2.1 KiB
Go

package main
import (
"bytes"
"fmt"
"os"
"strings"
"github.com/mitchellh/go-wordwrap"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh/terminal"
)
func init() {
stderr := int(os.Stderr.Fd())
formatter := &customFormatter{}
if terminal.IsTerminal(stderr) {
formatter.isTerminal = true
formatter.width, _, _ = terminal.GetSize(stderr)
if formatter.width > 0 && formatter.width < 80 {
formatter.width = 80
}
} else if strings.HasSuffix(os.Args[0], ".test") {
formatter.isTerminal = true
}
log.SetFormatter(formatter)
}
type customFormatter struct {
isTerminal bool
width int
}
func (f *customFormatter) Format(entry *log.Entry) ([]byte, error) {
var b *bytes.Buffer
if entry.Buffer != nil {
b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
var startColor, endColor, spacing string
if f.isTerminal {
endColor = "\x1b[0m"
switch entry.Level {
case log.DebugLevel:
startColor = "\x1b[36;1m" // bright cyan
case log.InfoLevel:
startColor = "\x1b[32;1m" // bright green
case log.WarnLevel:
startColor = "\x1b[33;1m" // bright yellow
case log.ErrorLevel, log.FatalLevel, log.PanicLevel:
startColor = "\x1b[31;1m" // bright red
default:
endColor = "" // no color
}
}
levelName := strings.ToUpper(entry.Level.String())
if levelName == "WARNING" {
levelName = "WARN"
}
if len(levelName) == 4 { // align level for INFO or WARN; other levels are all 5 chars
spacing = " "
}
levelText := fmt.Sprintf("[%s%s%s]%s ", startColor, levelName, endColor, spacing)
message := entry.Message
if f.isTerminal && f.width > 0 {
headerLen := 28 // length of line header, e.g. "2019-08-20 16:53:57 [INFO] "
message = wordwrap.WrapString(message, uint(f.width-headerLen))
spacer := fmt.Sprintf("\n%*s", headerLen, " ")
message = strings.Replace(message, "\n", spacer, -1)
}
fmt.Fprintf(b, "%s %s%s\n", entry.Time.Format("2006-01-02 15:04:05"), levelText, message)
return b.Bytes(), nil
}
func countAndNoun(n int, singular, plural string) string {
if n == 1 {
return fmt.Sprintf("1 %s", singular)
} else if n == 0 {
return fmt.Sprintf("no %s", plural)
}
return fmt.Sprintf("%d %s", n, plural)
}