github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/x/log/config_test.go (about)

     1  // Copyright (c) 2021 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package log
    22  
    23  import (
    24  	"io/ioutil"
    25  	"os"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/require"
    32  	"go.uber.org/zap/zapcore"
    33  )
    34  
    35  func TestLoggerConfiguration(t *testing.T) {
    36  	tmpfile, err := ioutil.TempFile("", "logtest")
    37  	require.NoError(t, err)
    38  
    39  	defer tmpfile.Close()
    40  	defer os.Remove(tmpfile.Name())
    41  
    42  	cfg := Configuration{
    43  		Fields: map[string]interface{}{
    44  			"my-field": "my-val",
    45  		},
    46  		Level: "error",
    47  		File:  tmpfile.Name(),
    48  	}
    49  
    50  	log, err := cfg.BuildLogger()
    51  	require.NoError(t, err)
    52  
    53  	log.Info("should not appear")
    54  	log.Warn("should not appear")
    55  	log.Error("this should appear")
    56  
    57  	b, err := ioutil.ReadAll(tmpfile)
    58  	require.NoError(t, err)
    59  
    60  	data := string(b)
    61  	require.Equal(t, 1, strings.Count(data, "\n"), data)
    62  	require.True(t, strings.Contains(data, `"msg":"this should appear"`))
    63  	require.True(t, strings.Contains(data, `"my-field":"my-val"`))
    64  	require.True(t, strings.Contains(data, `"level":"error"`))
    65  }
    66  
    67  func TestLoggerEncoderConfiguraion(t *testing.T) {
    68  	logTime := time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
    69  	logEntry := zapcore.Entry{
    70  		LoggerName: "main",
    71  		Level:      zapcore.InfoLevel,
    72  		Message:    `hello`,
    73  		Time:       logTime,
    74  		Stack:      "fake-stack",
    75  		Caller:     zapcore.EntryCaller{Defined: true, File: "foo.go", Line: 42, Function: "foo.Foo"},
    76  	}
    77  
    78  	tests := []struct {
    79  		name     string
    80  		cfg      encoderConfig
    81  		expected string
    82  	}{
    83  		{
    84  			name: "empty encoder config",
    85  			cfg:  encoderConfig{},
    86  			expected: `{"level":"info","ts":0,"logger":"main","caller":"foo.go:42","msg":"hello",` +
    87  				`"stacktrace":"fake-stack"}` + zapcore.DefaultLineEnding,
    88  		},
    89  		{
    90  			name: "encoder custom",
    91  			cfg: encoderConfig{
    92  				MessageKey:     "M",
    93  				LevelKey:       "L",
    94  				TimeKey:        "T",
    95  				NameKey:        "N",
    96  				CallerKey:      "C",
    97  				FunctionKey:    "F",
    98  				StacktraceKey:  "S",
    99  				LineEnding:     "\r\n",
   100  				EncodeLevel:    "capital",
   101  				EncodeTime:     "rfc3339nano",
   102  				EncodeDuration: "string",
   103  				EncodeCaller:   "short",
   104  				EncodeName:     "full",
   105  			},
   106  			expected: `{"L":"INFO","T":"1970-01-01T00:00:00Z","N":"main","C":"foo.go:42","F":"foo.Foo","M":"hello",` +
   107  				`"S":"fake-stack"}` + "\r\n",
   108  		},
   109  	}
   110  	for _, tt := range tests {
   111  		t.Run(tt.name, func(t *testing.T) {
   112  			logCfg := Configuration{
   113  				EncoderConfig: tt.cfg,
   114  			}
   115  			ec := logCfg.newEncoderConfig()
   116  			json := zapcore.NewJSONEncoder(ec)
   117  			jsonOut, jsonErr := json.EncodeEntry(logEntry, nil)
   118  			assert.NoError(t, jsonErr, "Unexpected error JSON-encoding entry")
   119  			assert.Equal(t, tt.expected, jsonOut.String())
   120  		})
   121  	}
   122  }
   123  
   124  func TestGettingLoggerZapConfig(t *testing.T) {
   125  	tmpfile, err := ioutil.TempFile("", "logtest")
   126  	require.NoError(t, err)
   127  
   128  	defer func() {
   129  		err = tmpfile.Close()
   130  		err = os.Remove(tmpfile.Name())
   131  	}()
   132  
   133  	cfg := Configuration{
   134  		Fields: map[string]interface{}{
   135  			"my-field": "my-val",
   136  		},
   137  		Level: "error",
   138  		File:  tmpfile.Name(),
   139  	}
   140  
   141  	log, zapConfig, err := cfg.BuildLoggerAndReturnConfig()
   142  	require.NoError(t, err)
   143  
   144  	log.Info("should not appear")
   145  	log.Warn("should not appear")
   146  	log.Error("this should appear")
   147  
   148  	zapConfig.Level.SetLevel(zapcore.InfoLevel)
   149  	log.Info("info should now appear")
   150  	log.Warn("warn should now appear")
   151  	b, err := ioutil.ReadAll(tmpfile)
   152  	require.NoError(t, err)
   153  
   154  	data := string(b)
   155  	require.Equal(t, 3, strings.Count(data, "\n"), data)
   156  	require.True(t, strings.Contains(data, `"msg":"this should appear"`))
   157  	require.True(t, strings.Contains(data, `"my-field":"my-val"`))
   158  	require.True(t, strings.Contains(data, `"level":"error"`))
   159  	require.True(t, strings.Contains(data, `"msg":"info should now appear"`))
   160  	require.True(t, strings.Contains(data, `"msg":"warn should now appear"`))
   161  }