| // +build !windows |
| |
| // Copyright 2013, Örjan Persson. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package logging |
| |
| import ( |
| "bytes" |
| "fmt" |
| "io" |
| "log" |
| ) |
| |
| type color int |
| |
| const ( |
| ColorBlack = iota + 30 |
| ColorRed |
| ColorGreen |
| ColorYellow |
| ColorBlue |
| ColorMagenta |
| ColorCyan |
| ColorWhite |
| ) |
| |
| var ( |
| colors = []string{ |
| CRITICAL: ColorSeq(ColorMagenta), |
| ERROR: ColorSeq(ColorRed), |
| WARNING: ColorSeq(ColorYellow), |
| NOTICE: ColorSeq(ColorGreen), |
| DEBUG: ColorSeq(ColorCyan), |
| } |
| boldcolors = []string{ |
| CRITICAL: ColorSeqBold(ColorMagenta), |
| ERROR: ColorSeqBold(ColorRed), |
| WARNING: ColorSeqBold(ColorYellow), |
| NOTICE: ColorSeqBold(ColorGreen), |
| DEBUG: ColorSeqBold(ColorCyan), |
| } |
| ) |
| |
| // LogBackend utilizes the standard log module. |
| type LogBackend struct { |
| Logger *log.Logger |
| Color bool |
| ColorConfig []string |
| } |
| |
| // NewLogBackend creates a new LogBackend. |
| func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend { |
| return &LogBackend{Logger: log.New(out, prefix, flag)} |
| } |
| |
| // Log implements the Backend interface. |
| func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error { |
| if b.Color { |
| col := colors[level] |
| if len(b.ColorConfig) > int(level) && b.ColorConfig[level] != "" { |
| col = b.ColorConfig[level] |
| } |
| |
| buf := &bytes.Buffer{} |
| buf.Write([]byte(col)) |
| buf.Write([]byte(rec.Formatted(calldepth + 1))) |
| buf.Write([]byte("\033[0m")) |
| // For some reason, the Go logger arbitrarily decided "2" was the correct |
| // call depth... |
| return b.Logger.Output(calldepth+2, buf.String()) |
| } |
| |
| return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1)) |
| } |
| |
| // ConvertColors takes a list of ints representing colors for log levels and |
| // converts them into strings for ANSI color formatting |
| func ConvertColors(colors []int, bold bool) []string { |
| converted := []string{} |
| for _, i := range colors { |
| if bold { |
| converted = append(converted, ColorSeqBold(color(i))) |
| } else { |
| converted = append(converted, ColorSeq(color(i))) |
| } |
| } |
| |
| return converted |
| } |
| |
| func ColorSeq(color color) string { |
| return fmt.Sprintf("\033[%dm", int(color)) |
| } |
| |
| func ColorSeqBold(color color) string { |
| return fmt.Sprintf("\033[%d;1m", int(color)) |
| } |
| |
| func doFmtVerbLevelColor(layout string, level Level, output io.Writer) { |
| if layout == "bold" { |
| output.Write([]byte(boldcolors[level])) |
| } else if layout == "reset" { |
| output.Write([]byte("\033[0m")) |
| } else { |
| output.Write([]byte(colors[level])) |
| } |
| } |