summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/x-cray/logrus-prefixed-formatter
diff options
context:
space:
mode:
authorWim <wim@42.be>2018-02-20 23:41:09 +0100
committerWim <wim@42.be>2018-02-20 23:41:09 +0100
commit6ea368c383ccc19678623c51d8e4ecbbdb0a64ac (patch)
tree0ccce9d453a743c59abf58eb510ccab99128e381 /vendor/github.com/x-cray/logrus-prefixed-formatter
parente92b6de09fd9d983deea17113b28aaba14863735 (diff)
downloadmatterbridge-msglm-6ea368c383ccc19678623c51d8e4ecbbdb0a64ac.tar.gz
matterbridge-msglm-6ea368c383ccc19678623c51d8e4ecbbdb0a64ac.tar.bz2
matterbridge-msglm-6ea368c383ccc19678623c51d8e4ecbbdb0a64ac.zip
Move Sirupsen => sirupsen
Diffstat (limited to 'vendor/github.com/x-cray/logrus-prefixed-formatter')
-rw-r--r--vendor/github.com/x-cray/logrus-prefixed-formatter/LICENSE21
-rw-r--r--vendor/github.com/x-cray/logrus-prefixed-formatter/examples/basic.go59
-rw-r--r--vendor/github.com/x-cray/logrus-prefixed-formatter/examples/themes.go48
-rw-r--r--vendor/github.com/x-cray/logrus-prefixed-formatter/formatter.go366
4 files changed, 494 insertions, 0 deletions
diff --git a/vendor/github.com/x-cray/logrus-prefixed-formatter/LICENSE b/vendor/github.com/x-cray/logrus-prefixed-formatter/LICENSE
new file mode 100644
index 00000000..b41cb238
--- /dev/null
+++ b/vendor/github.com/x-cray/logrus-prefixed-formatter/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Denis Parchenko
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/x-cray/logrus-prefixed-formatter/examples/basic.go b/vendor/github.com/x-cray/logrus-prefixed-formatter/examples/basic.go
new file mode 100644
index 00000000..2a42cb43
--- /dev/null
+++ b/vendor/github.com/x-cray/logrus-prefixed-formatter/examples/basic.go
@@ -0,0 +1,59 @@
+package main
+
+import (
+ "github.com/sirupsen/logrus"
+ prefixed "github.com/x-cray/logrus-prefixed-formatter"
+)
+
+var log = logrus.New()
+
+func init() {
+ formatter := new(prefixed.TextFormatter)
+ log.Formatter = formatter
+ log.Level = logrus.DebugLevel
+}
+
+func main() {
+ defer func() {
+ err := recover()
+ if err != nil {
+ // Fatal message
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 100,
+ }).Fatal("[main] The ice breaks!")
+ }
+ }()
+
+ // You could either provide a map key called `prefix` to add prefix
+ log.WithFields(logrus.Fields{
+ "prefix": "main",
+ "animal": "walrus",
+ "number": 8,
+ }).Debug("Started observing beach")
+
+ // Or you can simply add prefix in square brackets within message itself
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Debug("[main] A group of walrus emerges from the ocean")
+
+ // Warning message
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("[main] The group's number increased tremendously!")
+
+ // Information message
+ log.WithFields(logrus.Fields{
+ "prefix": "sensor",
+ "temperature": -4,
+ }).Info("Temperature changes")
+
+ // Panic message
+ log.WithFields(logrus.Fields{
+ "prefix": "sensor",
+ "animal": "orca",
+ "size": 9009,
+ }).Panic("It's over 9000!")
+}
diff --git a/vendor/github.com/x-cray/logrus-prefixed-formatter/examples/themes.go b/vendor/github.com/x-cray/logrus-prefixed-formatter/examples/themes.go
new file mode 100644
index 00000000..6c911aea
--- /dev/null
+++ b/vendor/github.com/x-cray/logrus-prefixed-formatter/examples/themes.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+ "github.com/sirupsen/logrus"
+ prefixed "github.com/x-cray/logrus-prefixed-formatter"
+)
+
+var log = logrus.New()
+
+func init() {
+ formatter := new(prefixed.TextFormatter)
+ formatter.FullTimestamp = true
+
+ // Set specific colors for prefix and timestamp
+ formatter.SetColorScheme(&prefixed.ColorScheme{
+ PrefixStyle: "blue+b",
+ TimestampStyle: "white+h",
+ })
+
+ log.Formatter = formatter
+ log.Level = logrus.DebugLevel
+}
+
+func main() {
+ log.WithFields(logrus.Fields{
+ "prefix": "main",
+ "animal": "walrus",
+ "number": 8,
+ }).Debug("Started observing beach")
+
+ // Or you can simply add prefix in square brackets within message itself
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Debug("[main] A group of walrus emerges from the ocean")
+
+ // Warning message
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("[main] The group's number increased tremendously!")
+
+ // Information message
+ log.WithFields(logrus.Fields{
+ "prefix": "sensor",
+ "temperature": -4,
+ }).Info("Temperature changes")
+}
diff --git a/vendor/github.com/x-cray/logrus-prefixed-formatter/formatter.go b/vendor/github.com/x-cray/logrus-prefixed-formatter/formatter.go
new file mode 100644
index 00000000..1235bcc3
--- /dev/null
+++ b/vendor/github.com/x-cray/logrus-prefixed-formatter/formatter.go
@@ -0,0 +1,366 @@
+package prefixed
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "regexp"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sirupsen/logrus"
+ "github.com/mgutz/ansi"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+const defaultTimestampFormat = time.RFC3339
+
+var (
+ baseTimestamp time.Time = time.Now()
+ defaultColorScheme *ColorScheme = &ColorScheme{
+ InfoLevelStyle: "green",
+ WarnLevelStyle: "yellow",
+ ErrorLevelStyle: "red",
+ FatalLevelStyle: "red",
+ PanicLevelStyle: "red",
+ DebugLevelStyle: "blue",
+ PrefixStyle: "cyan",
+ TimestampStyle: "black+h",
+ }
+ noColorsColorScheme *compiledColorScheme = &compiledColorScheme{
+ InfoLevelColor: ansi.ColorFunc(""),
+ WarnLevelColor: ansi.ColorFunc(""),
+ ErrorLevelColor: ansi.ColorFunc(""),
+ FatalLevelColor: ansi.ColorFunc(""),
+ PanicLevelColor: ansi.ColorFunc(""),
+ DebugLevelColor: ansi.ColorFunc(""),
+ PrefixColor: ansi.ColorFunc(""),
+ TimestampColor: ansi.ColorFunc(""),
+ }
+ defaultCompiledColorScheme *compiledColorScheme = compileColorScheme(defaultColorScheme)
+)
+
+func miniTS() int {
+ return int(time.Since(baseTimestamp) / time.Second)
+}
+
+type ColorScheme struct {
+ InfoLevelStyle string
+ WarnLevelStyle string
+ ErrorLevelStyle string
+ FatalLevelStyle string
+ PanicLevelStyle string
+ DebugLevelStyle string
+ PrefixStyle string
+ TimestampStyle string
+}
+
+type compiledColorScheme struct {
+ InfoLevelColor func(string) string
+ WarnLevelColor func(string) string
+ ErrorLevelColor func(string) string
+ FatalLevelColor func(string) string
+ PanicLevelColor func(string) string
+ DebugLevelColor func(string) string
+ PrefixColor func(string) string
+ TimestampColor func(string) string
+}
+
+type TextFormatter struct {
+ // Set to true to bypass checking for a TTY before outputting colors.
+ ForceColors bool
+
+ // Force disabling colors. For a TTY colors are enabled by default.
+ DisableColors bool
+
+ // Force formatted layout, even for non-TTY output.
+ ForceFormatting bool
+
+ // Disable timestamp logging. useful when output is redirected to logging
+ // system that already adds timestamps.
+ DisableTimestamp bool
+
+ // Disable the conversion of the log levels to uppercase
+ DisableUppercase bool
+
+ // Enable logging the full timestamp when a TTY is attached instead of just
+ // the time passed since beginning of execution.
+ FullTimestamp bool
+
+ // Timestamp format to use for display when a full timestamp is printed.
+ TimestampFormat string
+
+ // The fields are sorted by default for a consistent output. For applications
+ // that log extremely frequently and don't use the JSON formatter this may not
+ // be desired.
+ DisableSorting bool
+
+ // Wrap empty fields in quotes if true.
+ QuoteEmptyFields bool
+
+ // Can be set to the override the default quoting character "
+ // with something else. For example: ', or `.
+ QuoteCharacter string
+
+ // Pad msg field with spaces on the right for display.
+ // The value for this parameter will be the size of padding.
+ // Its default value is zero, which means no padding will be applied for msg.
+ SpacePadding int
+
+ // Color scheme to use.
+ colorScheme *compiledColorScheme
+
+ // Whether the logger's out is to a terminal.
+ isTerminal bool
+
+ sync.Once
+}
+
+func getCompiledColor(main string, fallback string) func(string) string {
+ var style string
+ if main != "" {
+ style = main
+ } else {
+ style = fallback
+ }
+ return ansi.ColorFunc(style)
+}
+
+func compileColorScheme(s *ColorScheme) *compiledColorScheme {
+ return &compiledColorScheme{
+ InfoLevelColor: getCompiledColor(s.InfoLevelStyle, defaultColorScheme.InfoLevelStyle),
+ WarnLevelColor: getCompiledColor(s.WarnLevelStyle, defaultColorScheme.WarnLevelStyle),
+ ErrorLevelColor: getCompiledColor(s.ErrorLevelStyle, defaultColorScheme.ErrorLevelStyle),
+ FatalLevelColor: getCompiledColor(s.FatalLevelStyle, defaultColorScheme.FatalLevelStyle),
+ PanicLevelColor: getCompiledColor(s.PanicLevelStyle, defaultColorScheme.PanicLevelStyle),
+ DebugLevelColor: getCompiledColor(s.DebugLevelStyle, defaultColorScheme.DebugLevelStyle),
+ PrefixColor: getCompiledColor(s.PrefixStyle, defaultColorScheme.PrefixStyle),
+ TimestampColor: getCompiledColor(s.TimestampStyle, defaultColorScheme.TimestampStyle),
+ }
+}
+
+func (f *TextFormatter) init(entry *logrus.Entry) {
+ if len(f.QuoteCharacter) == 0 {
+ f.QuoteCharacter = "\""
+ }
+ if entry.Logger != nil {
+ f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
+ }
+}
+
+func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
+ switch v := w.(type) {
+ case *os.File:
+ return terminal.IsTerminal(int(v.Fd()))
+ default:
+ return false
+ }
+}
+
+func (f *TextFormatter) SetColorScheme(colorScheme *ColorScheme) {
+ f.colorScheme = compileColorScheme(colorScheme)
+}
+
+func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error) {
+ var b *bytes.Buffer
+ var keys []string = make([]string, 0, len(entry.Data))
+ for k := range entry.Data {
+ keys = append(keys, k)
+ }
+ lastKeyIdx := len(keys) - 1
+
+ if !f.DisableSorting {
+ sort.Strings(keys)
+ }
+ if entry.Buffer != nil {
+ b = entry.Buffer
+ } else {
+ b = &bytes.Buffer{}
+ }
+
+ prefixFieldClashes(entry.Data)
+
+ f.Do(func() { f.init(entry) })
+
+ isFormatted := f.ForceFormatting || f.isTerminal
+
+ timestampFormat := f.TimestampFormat
+ if timestampFormat == "" {
+ timestampFormat = defaultTimestampFormat
+ }
+ if isFormatted {
+ isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
+ var colorScheme *compiledColorScheme
+ if isColored {
+ if f.colorScheme == nil {
+ colorScheme = defaultCompiledColorScheme
+ } else {
+ colorScheme = f.colorScheme
+ }
+ } else {
+ colorScheme = noColorsColorScheme
+ }
+ f.printColored(b, entry, keys, timestampFormat, colorScheme)
+ } else {
+ if !f.DisableTimestamp {
+ f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat), true)
+ }
+ f.appendKeyValue(b, "level", entry.Level.String(), true)
+ if entry.Message != "" {
+ f.appendKeyValue(b, "msg", entry.Message, lastKeyIdx >= 0)
+ }
+ for i, key := range keys {
+ f.appendKeyValue(b, key, entry.Data[key], lastKeyIdx != i)
+ }
+ }
+
+ b.WriteByte('\n')
+ return b.Bytes(), nil
+}
+
+func (f *TextFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry, keys []string, timestampFormat string, colorScheme *compiledColorScheme) {
+ var levelColor func(string) string
+ var levelText string
+ switch entry.Level {
+ case logrus.InfoLevel:
+ levelColor = colorScheme.InfoLevelColor
+ case logrus.WarnLevel:
+ levelColor = colorScheme.WarnLevelColor
+ case logrus.ErrorLevel:
+ levelColor = colorScheme.ErrorLevelColor
+ case logrus.FatalLevel:
+ levelColor = colorScheme.FatalLevelColor
+ case logrus.PanicLevel:
+ levelColor = colorScheme.PanicLevelColor
+ default:
+ levelColor = colorScheme.DebugLevelColor
+ }
+
+ if entry.Level != logrus.WarnLevel {
+ levelText = entry.Level.String()
+ } else {
+ levelText = "warn"
+ }
+
+ if !f.DisableUppercase {
+ levelText = strings.ToUpper(levelText)
+ }
+
+ level := levelColor(fmt.Sprintf("%5s", levelText))
+ prefix := ""
+ message := entry.Message
+
+ if prefixValue, ok := entry.Data["prefix"]; ok {
+ prefix = colorScheme.PrefixColor(" " + prefixValue.(string) + ":")
+ } else {
+ prefixValue, trimmedMsg := extractPrefix(entry.Message)
+ if len(prefixValue) > 0 {
+ prefix = colorScheme.PrefixColor(" " + prefixValue + ":")
+ message = trimmedMsg
+ }
+ }
+
+ messageFormat := "%s"
+ if f.SpacePadding != 0 {
+ messageFormat = fmt.Sprintf("%%-%ds", f.SpacePadding)
+ }
+
+ if f.DisableTimestamp {
+ fmt.Fprintf(b, "%s%s "+messageFormat, level, prefix, message)
+ } else {
+ var timestamp string
+ if !f.FullTimestamp {
+ timestamp = fmt.Sprintf("[%04d]", miniTS())
+ } else {
+ timestamp = fmt.Sprintf("[%s]", entry.Time.Format(timestampFormat))
+ }
+ fmt.Fprintf(b, "%s %s%s "+messageFormat, colorScheme.TimestampColor(timestamp), level, prefix, message)
+ }
+ for _, k := range keys {
+ if k != "prefix" {
+ v := entry.Data[k]
+ fmt.Fprintf(b, " %s=%+v", levelColor(k), v)
+ }
+ }
+}
+
+func (f *TextFormatter) needsQuoting(text string) bool {
+ if f.QuoteEmptyFields && len(text) == 0 {
+ return true
+ }
+ for _, ch := range text {
+ if !((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') ||
+ ch == '-' || ch == '.') {
+ return true
+ }
+ }
+ return false
+}
+
+func extractPrefix(msg string) (string, string) {
+ prefix := ""
+ regex := regexp.MustCompile("^\\[(.*?)\\]")
+ if regex.MatchString(msg) {
+ match := regex.FindString(msg)
+ prefix, msg = match[1:len(match)-1], strings.TrimSpace(msg[len(match):])
+ }
+ return prefix, msg
+}
+
+func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}, appendSpace bool) {
+ b.WriteString(key)
+ b.WriteByte('=')
+ f.appendValue(b, value)
+
+ if appendSpace {
+ b.WriteByte(' ')
+ }
+}
+
+func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
+ switch value := value.(type) {
+ case string:
+ if !f.needsQuoting(value) {
+ b.WriteString(value)
+ } else {
+ fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
+ }
+ case error:
+ errmsg := value.Error()
+ if !f.needsQuoting(errmsg) {
+ b.WriteString(errmsg)
+ } else {
+ fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
+ }
+ default:
+ fmt.Fprint(b, value)
+ }
+}
+
+// This is to not silently overwrite `time`, `msg` and `level` fields when
+// dumping it. If this code wasn't there doing:
+//
+// logrus.WithField("level", 1).Info("hello")
+//
+// would just silently drop the user provided level. Instead with this code
+// it'll be logged as:
+//
+// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
+func prefixFieldClashes(data logrus.Fields) {
+ if t, ok := data["time"]; ok {
+ data["fields.time"] = t
+ }
+
+ if m, ok := data["msg"]; ok {
+ data["fields.msg"] = m
+ }
+
+ if l, ok := data["level"]; ok {
+ data["fields.level"] = l
+ }
+}