Example #1
0
func (h *LogrusHandler) joinKVs(skipUnchanged bool, sep string) []string {

	kv := make([]string, 0, len(h.Fields))
	for k, v := range h.Fields {
		if !h.Opts.shouldShowKey(k) {
			continue
		}

		if skipUnchanged {
			if lastV, ok := h.last[k]; ok && lastV == v {
				continue
			}
		}

		kstr := rgbterm.FgString(k, h.Opts.KeyRGB.R, h.Opts.KeyRGB.G, h.Opts.KeyRGB.B)

		var vstr string
		if h.Opts.Truncates && len(v) > h.Opts.TruncateLength {
			vstr = v[:h.Opts.TruncateLength] + "..."
		} else {
			vstr = v
		}
		vstr = rgbterm.FgString(vstr, h.Opts.ValRGB.R, h.Opts.ValRGB.G, h.Opts.ValRGB.B)
		kv = append(kv, kstr+sep+vstr)
	}

	sort.Strings(kv)

	if h.Opts.SortLongest {
		sort.Stable(byLongest(kv))
	}

	return kv
}
Example #2
0
func ColorString(color Color, str string) string {

	logger.Logger.Println("BEFORE!!!", spew.Sdump(str))

	c := rgbterm.FgString(str, color.R, color.G, color.B)
	c = strings.Replace(c, "\x1b", "\033", -1)

	tt := cc.New(cc.FgGreen).SprintFunc()

	logger.Logger.Println("AFTER!!!", spew.Sdump(c), spew.Sdump(tt("TEST")))
	return c
}
Example #3
0
func main() {
	app := newApp()

	prefix := rgbterm.FgString(app.Name+"> ", 99, 99, 99)

	log.SetFlags(0)
	log.SetPrefix(prefix)
	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}
}
Example #4
0
// Prettify the output in a logrus like fashion.
func (h *LogrusHandler) Prettify(skipUnchanged bool) []byte {
	defer h.clear()
	if h.out == nil {
		if h.Opts == nil {
			h.Opts = DefaultOptions
		}
		h.buf = bytes.NewBuffer(nil)
		h.out = tabwriter.NewWriter(h.buf, 0, 1, 0, '\t', 0)
	}

	var msg string
	if h.Message == "" {
		msg = rgbterm.FgString("<no msg>", 190, 190, 190)
	} else {
		msg = rgbterm.FgString(h.Message, 255, 255, 255)
	}

	lvl := strings.ToUpper(h.Level)[:imin(4, len(h.Level))]
	var level string
	switch h.Level {
	case "debug":
		level = rgbterm.FgString(lvl, 221, 28, 119)
	case "info":
		level = rgbterm.FgString(lvl, 20, 172, 190)
	case "warn", "warning":
		level = rgbterm.FgString(lvl, 255, 245, 32)
	case "error":
		level = rgbterm.FgString(lvl, 255, 0, 0)
	case "fatal", "panic":
		level = rgbterm.BgString(lvl, 255, 0, 0)
	default:
		level = rgbterm.FgString(lvl, 221, 28, 119)
	}

	_, _ = fmt.Fprintf(h.out, "%s |%s| %s\t %s",
		rgbterm.FgString(h.Time.Format(time.Stamp), 99, 99, 99),
		level,
		msg,
		strings.Join(h.joinKVs(skipUnchanged, "="), "\t "),
	)

	_ = h.out.Flush()

	return h.buf.Bytes()
}
Example #5
0
func ColorStringF(color Color, format string, args ...interface{}) string {
	return rgbterm.FgString(fmt.Sprintf(format, args), color.R, color.G, color.B)
}
Example #6
0
func (ss *terminalSink) Error(message string) {
	messageTime := time.Now().Format(time.RFC3339)
	leveledMessage := fmt.Sprintf("[ERROR  ] %s %s", messageTime, message)
	colouredMessage := rgbterm.FgString(leveledMessage, 220, 50, 47)
	fmt.Println(colouredMessage)
}
Example #7
0
func (ss *terminalSink) Debug(message string) {
	messageTime := time.Now().Format(time.RFC3339)
	leveledMessage := fmt.Sprintf("[DEBUG  ] %s %s", messageTime, message)
	colouredMessage := rgbterm.FgString(leveledMessage, 42, 161, 152)
	fmt.Println(colouredMessage)
}
Example #8
0
func (ss *terminalSink) Warning(message string) {
	messageTime := time.Now().Format(time.RFC3339)
	leveledMessage := fmt.Sprintf("[WARNING] %s %s", messageTime, message)
	colouredMessage := rgbterm.FgString(leveledMessage, 181, 137, 0)
	fmt.Println(colouredMessage)
}
Example #9
0
// Fprint is used by all of the logging functions to send output to the output
// stream.
//
// flags sets the output flags to use when writing the output.
//
// logLevel is the level of the output.
//
// calldepth is the number of stack frames to skip when getting the file
// name of original calling function for file name output.
//
// text is the string to append to the assembled log format output. If the text
// is prefixed with newlines, they will be stripped out and placed in front of
// the completed output (test with template applied) before writing it to the
// stream.
//
// stream will be used as the output stream the text will be written to. If
// stream is nil, the stream value contained in the logger object is used.
//
// Fprint returns the number of bytes written to the stream or an error.
func (l *Logger) Fprint(flags int, logLevel level, calldepth int,
	text string, stream io.Writer) (n int, err error) {

	if (logLevel != LEVEL_PRINT && l.level != LEVEL_PRINT) &&
		logLevel < l.level {
		return
	}

	// Check for string excludes
	if len(l.excludeStrings) > 0 {
		for _, val := range l.excludeStrings {
			if strings.Contains(text, val) {
				return
			}
		}
	}

	now := time.Now()
	var pgmC uintptr
	var file, fName string
	var line int
	var id string
	var indentCount int

	l.mu.Lock()
	defer l.mu.Unlock()

	if flags&(LlongFileName|LshortFileName|LfunctionName) != 0 ||
		len(l.excludeFuncNames) > 0 {

		// release lock while getting caller info - it's expensive.
		// l.mu.Unlock()

		pgmC, file, line, _ = runtime.Caller(calldepth)

		if flags&LshortFileName != 0 {
			short := file
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					short = file[i+1:]
					break
				}
			}
			file = short
		}

		if flags&LfunctionName != 0 || len(l.excludeFuncNames) > 0 {
			fAtPC := runtime.FuncForPC(pgmC)
			fName = fAtPC.Name()
			for i := len(fName) - 1; i >= 0; i-- {
				if fName[i] == '.' {
					fName = fName[i+1:]
					break
				}
			}
		}

		// l.mu.Lock()
	}

	// Check func name excludes and return if matches are found
	if len(fName) > 0 {
		for _, name := range l.excludeFuncNames {
			if strings.Contains(fName, name) {
				return
			}
		}
	}

	l.buf = l.buf[:0] // Reset!

	trimText := strings.TrimLeft(text, "\t\v\r\n")
	trimedCount := len(text) - len(trimText)
	if trimedCount > 0 {
		l.buf = append(l.buf, trimText...)
	} else {
		l.buf = append(l.buf, text...)
	}

	var date string
	var seperator string

	if flags&Ldate != 0 {
		date = now.Format(l.dateFormat)
	}

	if flags&Lseperator != 0 {
		seperator = l.seperator
	}

	if flags&LlineNumber == 0 {
		line = 0
	}

	if flags&(LshortFileName|LlongFileName) == 0 {
		file = ""
	}

	if flags&LfunctionName == 0 {
		fName = ""
	}

	var indent string
	if indentCount > 0 || flags&Lindent != 0 {
		for i := 0; i < indentCount+l.indent; i++ {
			for j := 0; j < l.tabStop; j++ {
				if flags&LshowIndent != 0 && j == 0 {
					indent += "|"
				} else if flags&LshowIndent != 0 {
					indent += "."
				} else {
					indent += " "
				}
			}
		}
		if len(indent) > 0 && string(indent[0]) != " " {
			indent = rgbterm.FgString(indent, defaultIndentColor[0],
				defaultIndentColor[1], defaultIndentColor[2])
		}
	}

	var label string
	if flags&Llabel != 0 {
		if flags&Lcolor != 0 {
			label = logLevel.AnsiLabel()
		} else {
			label = logLevel.Label()
		}
	}

	f := &format{
		Seperator:    seperator,
		LogLabel:     label,
		Date:         date,
		FileName:     file,
		FunctionName: fName,
		LineNumber:   line,
		Indent:       indent,
		Id:           id,
		Text:         string(l.buf),
	}

	var out bytes.Buffer
	var strippedText, finalText string

	err = l.template.Execute(&out, f)
	if err != nil {
		panic(err)
	}

	if flags&Lcolor == 0 {
		strippedText = stripAnsi(out.String())
	}

	if trimedCount > 0 && flags&Lcolor == 0 {
		finalText = text[:trimedCount] + strippedText
	} else if trimedCount > 0 && flags&Lcolor != 0 {
		finalText = text[:trimedCount] + out.String()
	} else if flags&Lcolor == 0 {
		finalText = strippedText
	} else {
		finalText = out.String()
	}

	if stream == nil {
		n, err = l.Write([]byte(finalText))
	} else {
		n, err = stream.Write([]byte(finalText))
	}

	return
}
Example #10
0
// Colorized returns the colorized label for console output using ANSI escape
// sequences.
func (l Label) Colorized() string {
	if l.level == LEVEL_PRINT {
		return l.name
	}
	return rgbterm.FgString(l.name, l.colorRGB[0], l.colorRGB[1], l.colorRGB[2])
}
Example #11
0
	// at all.
	LEVEL_ERROR

	// LEVEL_CRITICAL messages are used when something is completely broken
	// and unrecoverable. Critical messages are usually followed by
	// os.Exit().
	LEVEL_CRITICAL

	// LEVEL_PRINT shows output for the standard Print functions and above.
	LEVEL_PRINT
)

var (
	defaultDate           = time.RFC3339
	defaultSeperator      = "::"
	defaultSeperatorColor = rgbterm.FgString("::", 0, 255, 135) // Green
	defaultIndentColor    = []uint8{0, 135, 175}                // Grayish blue
)

// Flags are used to control the formatting of the logging output.
const (
	// These flags define which text to prefix to each log entry generated
	// by the Logger. Bits or'ed together to control what's printed.
	Ldate = 1 << iota

	// Full file name and line number: /a/b/c/d.go:23
	LlongFileName

	// Base file name and line number: d.go:23. overrides LshortFileName
	LshortFileName
Example #12
0
var date = "Mon 20060102 15:04:05"

var fprintOutputTests = []struct {
	template   string
	seperator  string
	level      level
	dateFormat string
	flags      int
	text       string
	expect     string
	expectErr  bool
}{
	// Test with color seperator
	{
		template:   logFmt,
		seperator:  rgbterm.FgString("TEST>", 0, 255, 0),
		level:      LEVEL_PRINT,
		dateFormat: date,
		flags:      LstdFlags,
		text:       "test number 1",
		// The %s format specifier is the placeholder for the date.
		expect:    "%s \x1b[38;5;46mTEST>\x1b[0;00m test number 1",
		expectErr: false,
	},
	// Test output with coloring turned off
	{
		template:   logFmt,
		seperator:  "TEST>",
		level:      LEVEL_PRINT,
		dateFormat: date,
		flags:      Ldate | Lseperator,
Example #13
0
// This code is MIT licensed. See the LICENSE file for more info.

package logs

import (
	"fmt"
	"testing"

	"github.com/aybabtme/rgbterm"
)

var colorTests = []struct {
	escapeCodes string
	output      string
}{
	{rgbterm.FgString("red foreground color", 255, 0, 0),
		"\x1b[38;5;196mred foreground color\x1b[0;00m"},
	{rgbterm.FgString("green foreground color", 0, 255, 0),
		"\x1b[38;5;46mgreen foreground color\x1b[0;00m"},
	{rgbterm.FgString("blue foreground color", 0, 0, 255),
		"\x1b[38;5;21mblue foreground color\x1b[0;00m"},
}

func TestColors(t *testing.T) {
	for i, v := range colorTests {
		if out := v.escapeCodes; out != v.output {
			fmt.Println(v.escapeCodes)
			t.Errorf("Test Number: %d\nGot:\t%q\nExpect:\t%q\n", i,
				v.escapeCodes, v.output)
		}
	}