Skip to content

Commit

Permalink
Merge pull request sirupsen#844 from loren-osborn/pull/652_AddTraceLe…
Browse files Browse the repository at this point in the history
…velLogging

Added TRACE level logging.
  • Loading branch information
dgsb authored Oct 20, 2018
2 parents eb0072e + 2df5f1a commit deb7a53
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
logrus
vendor
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,10 @@ A list of currently known of service hook can be found in this wiki [page](https

#### Level logging

Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.

```go
log.Trace("Something very low level.")
log.Debug("Useful debugging information.")
log.Info("Something noteworthy happened!")
log.Warn("You should probably take a look at this.")
Expand Down
28 changes: 23 additions & 5 deletions entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func init() {
var ErrorKey = "error"

// An entry is the final or intermediate Logrus logging entry. It contains all
// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
// passed around as much as you wish to avoid field duplication.
// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
// reused and passed around as much as you wish to avoid field duplication.
type Entry struct {
Logger *Logger

Expand All @@ -35,11 +35,11 @@ type Entry struct {
// Time at which the log entry was created
Time time.Time

// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
Level Level

// Message passed to Debug, Info, Warn, Error, Fatal or Panic
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
Message string

// When formatter is called in entry.log(), a Buffer may be set to entry
Expand Down Expand Up @@ -162,6 +162,12 @@ func (entry *Entry) write() {
}
}

func (entry *Entry) Trace(args ...interface{}) {
if entry.Logger.IsLevelEnabled(TraceLevel) {
entry.log(TraceLevel, fmt.Sprint(args...))
}
}

func (entry *Entry) Debug(args ...interface{}) {
if entry.Logger.IsLevelEnabled(DebugLevel) {
entry.log(DebugLevel, fmt.Sprint(args...))
Expand Down Expand Up @@ -210,6 +216,12 @@ func (entry *Entry) Panic(args ...interface{}) {

// Entry Printf family functions

func (entry *Entry) Tracef(format string, args ...interface{}) {
if entry.Logger.IsLevelEnabled(TraceLevel) {
entry.Trace(fmt.Sprintf(format, args...))
}
}

func (entry *Entry) Debugf(format string, args ...interface{}) {
if entry.Logger.IsLevelEnabled(DebugLevel) {
entry.Debug(fmt.Sprintf(format, args...))
Expand Down Expand Up @@ -257,6 +269,12 @@ func (entry *Entry) Panicf(format string, args ...interface{}) {

// Entry Println family functions

func (entry *Entry) Traceln(args ...interface{}) {
if entry.Logger.IsLevelEnabled(TraceLevel) {
entry.Trace(entry.sprintlnn(args...))
}
}

func (entry *Entry) Debugln(args ...interface{}) {
if entry.Logger.IsLevelEnabled(DebugLevel) {
entry.Debug(entry.sprintlnn(args...))
Expand Down
8 changes: 7 additions & 1 deletion example_basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func Example_basic() {
log.Formatter = new(logrus.TextFormatter) //default
log.Formatter.(*logrus.TextFormatter).DisableColors = true // remove colors
log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
log.Level = logrus.DebugLevel
log.Level = logrus.TraceLevel
log.Out = os.Stdout

// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
Expand All @@ -37,6 +37,11 @@ func Example_basic() {
}
}()

log.WithFields(logrus.Fields{
"animal": "walrus",
"number": 0,
}).Trace("Went to the beach")

log.WithFields(logrus.Fields{
"animal": "walrus",
"number": 8,
Expand All @@ -62,6 +67,7 @@ func Example_basic() {
}).Panic("It's over 9000!")

// Output:
// level=trace msg="Went to the beach" animal=walrus number=0
// level=debug msg="Started observing beach" animal=walrus number=8
// level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
// level=warning msg="The group's number increased tremendously!" number=122 omg=true
Expand Down
15 changes: 15 additions & 0 deletions exported.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ func WithTime(t time.Time) *Entry {
return std.WithTime(t)
}

// Trace logs a message at level Trace on the standard logger.
func Trace(args ...interface{}) {
std.Trace(args...)
}

// Debug logs a message at level Debug on the standard logger.
func Debug(args ...interface{}) {
std.Debug(args...)
Expand Down Expand Up @@ -117,6 +122,11 @@ func Fatal(args ...interface{}) {
std.Fatal(args...)
}

// Tracef logs a message at level Trace on the standard logger.
func Tracef(format string, args ...interface{}) {
std.Tracef(format, args...)
}

// Debugf logs a message at level Debug on the standard logger.
func Debugf(format string, args ...interface{}) {
std.Debugf(format, args...)
Expand Down Expand Up @@ -157,6 +167,11 @@ func Fatalf(format string, args ...interface{}) {
std.Fatalf(format, args...)
}

// Traceln logs a message at level Trace on the standard logger.
func Traceln(args ...interface{}) {
std.Traceln(args...)
}

// Debugln logs a message at level Debug on the standard logger.
func Debugln(args ...interface{}) {
std.Debugln(args...)
Expand Down
2 changes: 2 additions & 0 deletions hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func (hook *TestHook) Fire(entry *Entry) error {

func (hook *TestHook) Levels() []Level {
return []Level{
TraceLevel,
DebugLevel,
InfoLevel,
WarnLevel,
Expand Down Expand Up @@ -53,6 +54,7 @@ func (hook *ModifyHook) Fire(entry *Entry) error {

func (hook *ModifyHook) Levels() []Level {
return []Level{
TraceLevel,
DebugLevel,
InfoLevel,
WarnLevel,
Expand Down
2 changes: 1 addition & 1 deletion hooks/syslog/syslog.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
return hook.Writer.Warning(line)
case logrus.InfoLevel:
return hook.Writer.Info(line)
case logrus.DebugLevel:
case logrus.DebugLevel, logrus.TraceLevel:
return hook.Writer.Debug(line)
default:
return nil
Expand Down
24 changes: 24 additions & 0 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ func (logger *Logger) WithTime(t time.Time) *Entry {
return entry.WithTime(t)
}

func (logger *Logger) Tracef(format string, args ...interface{}) {
if logger.IsLevelEnabled(TraceLevel) {
entry := logger.newEntry()
entry.Tracef(format, args...)
logger.releaseEntry(entry)
}
}

func (logger *Logger) Debugf(format string, args ...interface{}) {
if logger.IsLevelEnabled(DebugLevel) {
entry := logger.newEntry()
Expand Down Expand Up @@ -189,6 +197,14 @@ func (logger *Logger) Panicf(format string, args ...interface{}) {
}
}

func (logger *Logger) Trace(args ...interface{}) {
if logger.IsLevelEnabled(TraceLevel) {
entry := logger.newEntry()
entry.Trace(args...)
logger.releaseEntry(entry)
}
}

func (logger *Logger) Debug(args ...interface{}) {
if logger.IsLevelEnabled(DebugLevel) {
entry := logger.newEntry()
Expand Down Expand Up @@ -252,6 +268,14 @@ func (logger *Logger) Panic(args ...interface{}) {
}
}

func (logger *Logger) Traceln(args ...interface{}) {
if logger.IsLevelEnabled(TraceLevel) {
entry := logger.newEntry()
entry.Traceln(args...)
logger.releaseEntry(entry)
}
}

func (logger *Logger) Debugln(args ...interface{}) {
if logger.IsLevelEnabled(DebugLevel) {
entry := logger.newEntry()
Expand Down
16 changes: 16 additions & 0 deletions logrus.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type Level uint32
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
func (level Level) String() string {
switch level {
case TraceLevel:
return "trace"
case DebugLevel:
return "debug"
case InfoLevel:
Expand Down Expand Up @@ -47,6 +49,8 @@ func ParseLevel(lvl string) (Level, error) {
return InfoLevel, nil
case "debug":
return DebugLevel, nil
case "trace":
return TraceLevel, nil
}

var l Level
Expand All @@ -61,6 +65,7 @@ var AllLevels = []Level{
WarnLevel,
InfoLevel,
DebugLevel,
TraceLevel,
}

// These are the different logging levels. You can set the logging level to log
Expand All @@ -82,6 +87,8 @@ const (
InfoLevel
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
DebugLevel
// TraceLevel level. Designates finer-grained informational events than the Debug.
TraceLevel
)

// Won't compile if StdLogger can't be realized by a log.Logger
Expand Down Expand Up @@ -148,3 +155,12 @@ type FieldLogger interface {
// IsFatalEnabled() bool
// IsPanicEnabled() bool
}

// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
// here for consistancy. Do not use. Use Logger or Entry instead.
type Ext1FieldLogger interface {
FieldLogger
Tracef(format string, args ...interface{})
Trace(args ...interface{})
Traceln(args ...interface{})
}
31 changes: 29 additions & 2 deletions logrus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
}

func TestConvertLevelToString(t *testing.T) {
assert.Equal(t, "trace", TraceLevel.String())
assert.Equal(t, "debug", DebugLevel.String())
assert.Equal(t, "info", InfoLevel.String())
assert.Equal(t, "warning", WarnLevel.String())
Expand Down Expand Up @@ -368,6 +369,14 @@ func TestParseLevel(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, DebugLevel, l)

l, err = ParseLevel("trace")
assert.Nil(t, err)
assert.Equal(t, TraceLevel, l)

l, err = ParseLevel("TRACE")
assert.Nil(t, err)
assert.Equal(t, TraceLevel, l)

l, err = ParseLevel("invalid")
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
}
Expand Down Expand Up @@ -444,9 +453,12 @@ func TestReplaceHooks(t *testing.T) {
}

// Compile test
func TestLogrusInterface(t *testing.T) {
func TestLogrusInterfaces(t *testing.T) {
var buffer bytes.Buffer
fn := func(l FieldLogger) {
// This verifies FieldLogger and Ext1FieldLogger work as designed.
// Please don't use them. Use Logger and Entry directly.
fn := func(xl Ext1FieldLogger) {
var l FieldLogger = xl
b := l.WithField("key", "value")
b.Debug("Test")
}
Expand Down Expand Up @@ -494,6 +506,7 @@ func TestLogLevelEnabled(t *testing.T) {
assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))

log.SetLevel(FatalLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
Expand All @@ -502,6 +515,7 @@ func TestLogLevelEnabled(t *testing.T) {
assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))

log.SetLevel(ErrorLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
Expand All @@ -510,6 +524,7 @@ func TestLogLevelEnabled(t *testing.T) {
assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))

log.SetLevel(WarnLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
Expand All @@ -518,6 +533,7 @@ func TestLogLevelEnabled(t *testing.T) {
assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))

log.SetLevel(InfoLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
Expand All @@ -526,6 +542,7 @@ func TestLogLevelEnabled(t *testing.T) {
assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))

log.SetLevel(DebugLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
Expand All @@ -534,4 +551,14 @@ func TestLogLevelEnabled(t *testing.T) {
assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, true, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))

log.SetLevel(TraceLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, true, log.IsLevelEnabled(DebugLevel))
assert.Equal(t, true, log.IsLevelEnabled(TraceLevel))
}
2 changes: 1 addition & 1 deletion text_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
var levelColor int
switch entry.Level {
case DebugLevel:
case DebugLevel, TraceLevel:
levelColor = gray
case WarnLevel:
levelColor = yellow
Expand Down
2 changes: 2 additions & 0 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
var printFunc func(args ...interface{})

switch level {
case TraceLevel:
printFunc = entry.Trace
case DebugLevel:
printFunc = entry.Debug
case InfoLevel:
Expand Down

0 comments on commit deb7a53

Please sign in to comment.