| package logrus |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "strconv" |
| "strings" |
| "testing" |
| |
| "github.com/stretchr/testify/assert" |
| ) |
| |
| func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) { |
| var buffer bytes.Buffer |
| var fields Fields |
| |
| logger := New() |
| logger.Out = &buffer |
| logger.Formatter = new(JSONFormatter) |
| |
| log(logger) |
| |
| err := json.Unmarshal(buffer.Bytes(), &fields) |
| assert.Nil(t, err) |
| |
| assertions(fields) |
| } |
| |
| func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) { |
| var buffer bytes.Buffer |
| |
| logger := New() |
| logger.Out = &buffer |
| logger.Formatter = &TextFormatter{ |
| DisableColors: true, |
| } |
| |
| log(logger) |
| |
| fields := make(map[string]string) |
| for _, kv := range strings.Split(buffer.String(), " ") { |
| if !strings.Contains(kv, "=") { |
| continue |
| } |
| kvArr := strings.Split(kv, "=") |
| key := strings.TrimSpace(kvArr[0]) |
| val := kvArr[1] |
| if kvArr[1][0] == '"' { |
| var err error |
| val, err = strconv.Unquote(val) |
| assert.NoError(t, err) |
| } |
| fields[key] = val |
| } |
| assertions(fields) |
| } |
| |
| func TestPrint(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Print("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test") |
| assert.Equal(t, fields["level"], "info") |
| }) |
| } |
| |
| func TestInfo(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Info("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test") |
| assert.Equal(t, fields["level"], "info") |
| }) |
| } |
| |
| func TestWarn(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Warn("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test") |
| assert.Equal(t, fields["level"], "warning") |
| }) |
| } |
| |
| func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Infoln("test", "test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test test") |
| }) |
| } |
| |
| func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Infoln("test", 10) |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test 10") |
| }) |
| } |
| |
| func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Infoln(10, 10) |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "10 10") |
| }) |
| } |
| |
| func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Infoln(10, 10) |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "10 10") |
| }) |
| } |
| |
| func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Info("test", 10) |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test10") |
| }) |
| } |
| |
| func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.Info("test", "test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "testtest") |
| }) |
| } |
| |
| func TestWithFieldsShouldAllowAssignments(t *testing.T) { |
| var buffer bytes.Buffer |
| var fields Fields |
| |
| logger := New() |
| logger.Out = &buffer |
| logger.Formatter = new(JSONFormatter) |
| |
| localLog := logger.WithFields(Fields{ |
| "key1": "value1", |
| }) |
| |
| localLog.WithField("key2", "value2").Info("test") |
| err := json.Unmarshal(buffer.Bytes(), &fields) |
| assert.Nil(t, err) |
| |
| assert.Equal(t, "value2", fields["key2"]) |
| assert.Equal(t, "value1", fields["key1"]) |
| |
| buffer = bytes.Buffer{} |
| fields = Fields{} |
| localLog.Info("test") |
| err = json.Unmarshal(buffer.Bytes(), &fields) |
| assert.Nil(t, err) |
| |
| _, ok := fields["key2"] |
| assert.Equal(t, false, ok) |
| assert.Equal(t, "value1", fields["key1"]) |
| } |
| |
| func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.WithField("msg", "hello").Info("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test") |
| }) |
| } |
| |
| func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.WithField("msg", "hello").Info("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["msg"], "test") |
| assert.Equal(t, fields["fields.msg"], "hello") |
| }) |
| } |
| |
| func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.WithField("time", "hello").Info("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["fields.time"], "hello") |
| }) |
| } |
| |
| func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) { |
| LogAndAssertJSON(t, func(log *Logger) { |
| log.WithField("level", 1).Info("test") |
| }, func(fields Fields) { |
| assert.Equal(t, fields["level"], "info") |
| assert.Equal(t, fields["fields.level"], 1) |
| }) |
| } |
| |
| func TestDefaultFieldsAreNotPrefixed(t *testing.T) { |
| LogAndAssertText(t, func(log *Logger) { |
| ll := log.WithField("herp", "derp") |
| ll.Info("hello") |
| ll.Info("bye") |
| }, func(fields map[string]string) { |
| for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} { |
| if _, ok := fields[fieldName]; ok { |
| t.Fatalf("should not have prefixed %q: %v", fieldName, fields) |
| } |
| } |
| }) |
| } |
| |
| func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) { |
| |
| var buffer bytes.Buffer |
| var fields Fields |
| |
| logger := New() |
| logger.Out = &buffer |
| logger.Formatter = new(JSONFormatter) |
| |
| llog := logger.WithField("context", "eating raw fish") |
| |
| llog.Info("looks delicious") |
| |
| err := json.Unmarshal(buffer.Bytes(), &fields) |
| assert.NoError(t, err, "should have decoded first message") |
| assert.Len(t, fields, 4, "should only have msg/time/level/context fields") |
| assert.Equal(t, fields["msg"], "looks delicious") |
| assert.Equal(t, fields["context"], "eating raw fish") |
| |
| buffer.Reset() |
| |
| llog.Warn("omg it is!") |
| |
| err = json.Unmarshal(buffer.Bytes(), &fields) |
| assert.NoError(t, err, "should have decoded second message") |
| assert.Len(t, fields, 4, "should only have msg/time/level/context fields") |
| assert.Equal(t, fields["msg"], "omg it is!") |
| assert.Equal(t, fields["context"], "eating raw fish") |
| assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry") |
| |
| } |
| |
| func TestConvertLevelToString(t *testing.T) { |
| assert.Equal(t, "debug", DebugLevel.String()) |
| assert.Equal(t, "info", InfoLevel.String()) |
| assert.Equal(t, "warning", WarnLevel.String()) |
| assert.Equal(t, "error", ErrorLevel.String()) |
| assert.Equal(t, "fatal", FatalLevel.String()) |
| assert.Equal(t, "panic", PanicLevel.String()) |
| } |
| |
| func TestParseLevel(t *testing.T) { |
| l, err := ParseLevel("panic") |
| assert.Nil(t, err) |
| assert.Equal(t, PanicLevel, l) |
| |
| l, err = ParseLevel("fatal") |
| assert.Nil(t, err) |
| assert.Equal(t, FatalLevel, l) |
| |
| l, err = ParseLevel("error") |
| assert.Nil(t, err) |
| assert.Equal(t, ErrorLevel, l) |
| |
| l, err = ParseLevel("warn") |
| assert.Nil(t, err) |
| assert.Equal(t, WarnLevel, l) |
| |
| l, err = ParseLevel("warning") |
| assert.Nil(t, err) |
| assert.Equal(t, WarnLevel, l) |
| |
| l, err = ParseLevel("info") |
| assert.Nil(t, err) |
| assert.Equal(t, InfoLevel, l) |
| |
| l, err = ParseLevel("debug") |
| assert.Nil(t, err) |
| assert.Equal(t, DebugLevel, l) |
| |
| l, err = ParseLevel("invalid") |
| assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error()) |
| } |