...

Source file src/github.com/sirupsen/logrus/json_formatter_test.go

Documentation: github.com/sirupsen/logrus

     1  package logrus
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"runtime"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestErrorNotLost(t *testing.T) {
    13  	formatter := &JSONFormatter{}
    14  
    15  	b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
    16  	if err != nil {
    17  		t.Fatal("Unable to format entry: ", err)
    18  	}
    19  
    20  	entry := make(map[string]interface{})
    21  	err = json.Unmarshal(b, &entry)
    22  	if err != nil {
    23  		t.Fatal("Unable to unmarshal formatted entry: ", err)
    24  	}
    25  
    26  	if entry["error"] != "wild walrus" {
    27  		t.Fatal("Error field not set")
    28  	}
    29  }
    30  
    31  func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
    32  	formatter := &JSONFormatter{}
    33  
    34  	b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
    35  	if err != nil {
    36  		t.Fatal("Unable to format entry: ", err)
    37  	}
    38  
    39  	entry := make(map[string]interface{})
    40  	err = json.Unmarshal(b, &entry)
    41  	if err != nil {
    42  		t.Fatal("Unable to unmarshal formatted entry: ", err)
    43  	}
    44  
    45  	if entry["omg"] != "wild walrus" {
    46  		t.Fatal("Error field not set")
    47  	}
    48  }
    49  
    50  func TestFieldClashWithTime(t *testing.T) {
    51  	formatter := &JSONFormatter{}
    52  
    53  	b, err := formatter.Format(WithField("time", "right now!"))
    54  	if err != nil {
    55  		t.Fatal("Unable to format entry: ", err)
    56  	}
    57  
    58  	entry := make(map[string]interface{})
    59  	err = json.Unmarshal(b, &entry)
    60  	if err != nil {
    61  		t.Fatal("Unable to unmarshal formatted entry: ", err)
    62  	}
    63  
    64  	if entry["fields.time"] != "right now!" {
    65  		t.Fatal("fields.time not set to original time field")
    66  	}
    67  
    68  	if entry["time"] != "0001-01-01T00:00:00Z" {
    69  		t.Fatal("time field not set to current time, was: ", entry["time"])
    70  	}
    71  }
    72  
    73  func TestFieldClashWithMsg(t *testing.T) {
    74  	formatter := &JSONFormatter{}
    75  
    76  	b, err := formatter.Format(WithField("msg", "something"))
    77  	if err != nil {
    78  		t.Fatal("Unable to format entry: ", err)
    79  	}
    80  
    81  	entry := make(map[string]interface{})
    82  	err = json.Unmarshal(b, &entry)
    83  	if err != nil {
    84  		t.Fatal("Unable to unmarshal formatted entry: ", err)
    85  	}
    86  
    87  	if entry["fields.msg"] != "something" {
    88  		t.Fatal("fields.msg not set to original msg field")
    89  	}
    90  }
    91  
    92  func TestFieldClashWithLevel(t *testing.T) {
    93  	formatter := &JSONFormatter{}
    94  
    95  	b, err := formatter.Format(WithField("level", "something"))
    96  	if err != nil {
    97  		t.Fatal("Unable to format entry: ", err)
    98  	}
    99  
   100  	entry := make(map[string]interface{})
   101  	err = json.Unmarshal(b, &entry)
   102  	if err != nil {
   103  		t.Fatal("Unable to unmarshal formatted entry: ", err)
   104  	}
   105  
   106  	if entry["fields.level"] != "something" {
   107  		t.Fatal("fields.level not set to original level field")
   108  	}
   109  }
   110  
   111  func TestFieldClashWithRemappedFields(t *testing.T) {
   112  	formatter := &JSONFormatter{
   113  		FieldMap: FieldMap{
   114  			FieldKeyTime:  "@timestamp",
   115  			FieldKeyLevel: "@level",
   116  			FieldKeyMsg:   "@message",
   117  		},
   118  	}
   119  
   120  	b, err := formatter.Format(WithFields(Fields{
   121  		"@timestamp": "@timestamp",
   122  		"@level":     "@level",
   123  		"@message":   "@message",
   124  		"timestamp":  "timestamp",
   125  		"level":      "level",
   126  		"msg":        "msg",
   127  	}))
   128  	if err != nil {
   129  		t.Fatal("Unable to format entry: ", err)
   130  	}
   131  
   132  	entry := make(map[string]interface{})
   133  	err = json.Unmarshal(b, &entry)
   134  	if err != nil {
   135  		t.Fatal("Unable to unmarshal formatted entry: ", err)
   136  	}
   137  
   138  	for _, field := range []string{"timestamp", "level", "msg"} {
   139  		if entry[field] != field {
   140  			t.Errorf("Expected field %v to be untouched; got %v", field, entry[field])
   141  		}
   142  
   143  		remappedKey := fmt.Sprintf("fields.%s", field)
   144  		if remapped, ok := entry[remappedKey]; ok {
   145  			t.Errorf("Expected %s to be empty; got %v", remappedKey, remapped)
   146  		}
   147  	}
   148  
   149  	for _, field := range []string{"@timestamp", "@level", "@message"} {
   150  		if entry[field] == field {
   151  			t.Errorf("Expected field %v to be mapped to an Entry value", field)
   152  		}
   153  
   154  		remappedKey := fmt.Sprintf("fields.%s", field)
   155  		if remapped, ok := entry[remappedKey]; ok {
   156  			if remapped != field {
   157  				t.Errorf("Expected field %v to be copied to %s; got %v", field, remappedKey, remapped)
   158  			}
   159  		} else {
   160  			t.Errorf("Expected field %v to be copied to %s; was absent", field, remappedKey)
   161  		}
   162  	}
   163  }
   164  
   165  func TestFieldsInNestedDictionary(t *testing.T) {
   166  	formatter := &JSONFormatter{
   167  		DataKey: "args",
   168  	}
   169  
   170  	logEntry := WithFields(Fields{
   171  		"level": "level",
   172  		"test":  "test",
   173  	})
   174  	logEntry.Level = InfoLevel
   175  
   176  	b, err := formatter.Format(logEntry)
   177  	if err != nil {
   178  		t.Fatal("Unable to format entry: ", err)
   179  	}
   180  
   181  	entry := make(map[string]interface{})
   182  	err = json.Unmarshal(b, &entry)
   183  	if err != nil {
   184  		t.Fatal("Unable to unmarshal formatted entry: ", err)
   185  	}
   186  
   187  	args := entry["args"].(map[string]interface{})
   188  
   189  	for _, field := range []string{"test", "level"} {
   190  		if value, present := args[field]; !present || value != field {
   191  			t.Errorf("Expected field %v to be present under 'args'; untouched", field)
   192  		}
   193  	}
   194  
   195  	for _, field := range []string{"test", "fields.level"} {
   196  		if _, present := entry[field]; present {
   197  			t.Errorf("Expected field %v not to be present at top level", field)
   198  		}
   199  	}
   200  
   201  	// with nested object, "level" shouldn't clash
   202  	if entry["level"] != "info" {
   203  		t.Errorf("Expected 'level' field to contain 'info'")
   204  	}
   205  }
   206  
   207  func TestJSONEntryEndsWithNewline(t *testing.T) {
   208  	formatter := &JSONFormatter{}
   209  
   210  	b, err := formatter.Format(WithField("level", "something"))
   211  	if err != nil {
   212  		t.Fatal("Unable to format entry: ", err)
   213  	}
   214  
   215  	if b[len(b)-1] != '\n' {
   216  		t.Fatal("Expected JSON log entry to end with a newline")
   217  	}
   218  }
   219  
   220  func TestJSONMessageKey(t *testing.T) {
   221  	formatter := &JSONFormatter{
   222  		FieldMap: FieldMap{
   223  			FieldKeyMsg: "message",
   224  		},
   225  	}
   226  
   227  	b, err := formatter.Format(&Entry{Message: "oh hai"})
   228  	if err != nil {
   229  		t.Fatal("Unable to format entry: ", err)
   230  	}
   231  	s := string(b)
   232  	if !(strings.Contains(s, "message") && strings.Contains(s, "oh hai")) {
   233  		t.Fatal("Expected JSON to format message key")
   234  	}
   235  }
   236  
   237  func TestJSONLevelKey(t *testing.T) {
   238  	formatter := &JSONFormatter{
   239  		FieldMap: FieldMap{
   240  			FieldKeyLevel: "somelevel",
   241  		},
   242  	}
   243  
   244  	b, err := formatter.Format(WithField("level", "something"))
   245  	if err != nil {
   246  		t.Fatal("Unable to format entry: ", err)
   247  	}
   248  	s := string(b)
   249  	if !strings.Contains(s, "somelevel") {
   250  		t.Fatal("Expected JSON to format level key")
   251  	}
   252  }
   253  
   254  func TestJSONTimeKey(t *testing.T) {
   255  	formatter := &JSONFormatter{
   256  		FieldMap: FieldMap{
   257  			FieldKeyTime: "timeywimey",
   258  		},
   259  	}
   260  
   261  	b, err := formatter.Format(WithField("level", "something"))
   262  	if err != nil {
   263  		t.Fatal("Unable to format entry: ", err)
   264  	}
   265  	s := string(b)
   266  	if !strings.Contains(s, "timeywimey") {
   267  		t.Fatal("Expected JSON to format time key")
   268  	}
   269  }
   270  
   271  func TestFieldDoesNotClashWithCaller(t *testing.T) {
   272  	SetReportCaller(false)
   273  	formatter := &JSONFormatter{}
   274  
   275  	b, err := formatter.Format(WithField("func", "howdy pardner"))
   276  	if err != nil {
   277  		t.Fatal("Unable to format entry: ", err)
   278  	}
   279  
   280  	entry := make(map[string]interface{})
   281  	err = json.Unmarshal(b, &entry)
   282  	if err != nil {
   283  		t.Fatal("Unable to unmarshal formatted entry: ", err)
   284  	}
   285  
   286  	if entry["func"] != "howdy pardner" {
   287  		t.Fatal("func field replaced when ReportCaller=false")
   288  	}
   289  }
   290  
   291  func TestFieldClashWithCaller(t *testing.T) {
   292  	SetReportCaller(true)
   293  	formatter := &JSONFormatter{}
   294  	e := WithField("func", "howdy pardner")
   295  	e.Caller = &runtime.Frame{Function: "somefunc"}
   296  	b, err := formatter.Format(e)
   297  	if err != nil {
   298  		t.Fatal("Unable to format entry: ", err)
   299  	}
   300  
   301  	entry := make(map[string]interface{})
   302  	err = json.Unmarshal(b, &entry)
   303  	if err != nil {
   304  		t.Fatal("Unable to unmarshal formatted entry: ", err)
   305  	}
   306  
   307  	if entry["fields.func"] != "howdy pardner" {
   308  		t.Fatalf("fields.func not set to original func field when ReportCaller=true (got '%s')",
   309  			entry["fields.func"])
   310  	}
   311  
   312  	if entry["func"] != "somefunc" {
   313  		t.Fatalf("func not set as expected when ReportCaller=true (got '%s')",
   314  			entry["func"])
   315  	}
   316  
   317  	SetReportCaller(false) // return to default value
   318  }
   319  
   320  func TestJSONDisableTimestamp(t *testing.T) {
   321  	formatter := &JSONFormatter{
   322  		DisableTimestamp: true,
   323  	}
   324  
   325  	b, err := formatter.Format(WithField("level", "something"))
   326  	if err != nil {
   327  		t.Fatal("Unable to format entry: ", err)
   328  	}
   329  	s := string(b)
   330  	if strings.Contains(s, FieldKeyTime) {
   331  		t.Error("Did not prevent timestamp", s)
   332  	}
   333  }
   334  
   335  func TestJSONEnableTimestamp(t *testing.T) {
   336  	formatter := &JSONFormatter{}
   337  
   338  	b, err := formatter.Format(WithField("level", "something"))
   339  	if err != nil {
   340  		t.Fatal("Unable to format entry: ", err)
   341  	}
   342  	s := string(b)
   343  	if !strings.Contains(s, FieldKeyTime) {
   344  		t.Error("Timestamp not present", s)
   345  	}
   346  }
   347  

View as plain text