go.temporal.io/server@v1.23.0/common/log/zap_logger_test.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package log 26 27 import ( 28 "bytes" 29 "fmt" 30 "io" 31 "os" 32 "strconv" 33 "strings" 34 "testing" 35 36 "github.com/stretchr/testify/assert" 37 "github.com/stretchr/testify/require" 38 "github.com/stretchr/testify/suite" 39 "go.uber.org/zap" 40 41 "go.temporal.io/server/common/log/tag" 42 "go.temporal.io/server/tests/testutils" 43 ) 44 45 type LogSuite struct { 46 *require.Assertions 47 suite.Suite 48 } 49 50 func TestLogSuite(t *testing.T) { 51 suite.Run(t, new(LogSuite)) 52 } 53 54 func (s *LogSuite) SetupTest() { 55 s.Assertions = require.New(s.T()) 56 } 57 58 func (s *LogSuite) TestParseLogLevel() { 59 s.Equal(zap.DebugLevel, parseZapLevel("debug")) 60 s.Equal(zap.InfoLevel, parseZapLevel("info")) 61 s.Equal(zap.WarnLevel, parseZapLevel("warn")) 62 s.Equal(zap.ErrorLevel, parseZapLevel("error")) 63 s.Equal(zap.FatalLevel, parseZapLevel("fatal")) 64 s.Equal(zap.DPanicLevel, parseZapLevel("dpanic")) 65 s.Equal(zap.PanicLevel, parseZapLevel("panic")) 66 s.Equal(zap.InfoLevel, parseZapLevel("unknown")) 67 } 68 69 func (s *LogSuite) TestNewLogger() { 70 dir := testutils.MkdirTemp(s.T(), "", "config.testNewLogger") 71 72 cfg := Config{ 73 Level: "info", 74 OutputFile: dir + "/test.log", 75 } 76 77 log := BuildZapLogger(cfg) 78 s.NotNil(log) 79 _, err := os.Stat(dir + "/test.log") 80 s.Nil(err) 81 log.DPanic("Development default is false; should not panic here!") 82 s.Panics(nil, func() { 83 log.Panic("Must Panic") 84 }) 85 86 cfg = Config{ 87 Level: "info", 88 OutputFile: dir + "/test.log", 89 Development: true, 90 } 91 log = BuildZapLogger(cfg) 92 s.NotNil(log) 93 _, err = os.Stat(dir + "/test.log") 94 s.Nil(err) 95 s.Panics(nil, func() { 96 log.DPanic("Must panic!") 97 }) 98 s.Panics(nil, func() { 99 log.Panic("Must panic!") 100 }) 101 102 } 103 104 func TestDefaultLogger(t *testing.T) { 105 old := os.Stdout // keep backup of the real stdout 106 r, w, _ := os.Pipe() 107 os.Stdout = w 108 outC := make(chan string) 109 // copy the output in a separate goroutine so logging can't block indefinitely 110 go func() { 111 var buf bytes.Buffer 112 _, err := io.Copy(&buf, r) 113 assert.NoError(t, err) 114 outC <- buf.String() 115 }() 116 117 logger := NewZapLogger(zap.NewExample()) 118 preCaller := caller(1) 119 logger.With(tag.Error(fmt.Errorf("test error"))).Info("test info", tag.WorkflowActionWorkflowStarted) 120 121 // back to normal state 122 require.Nil(t, w.Close()) 123 os.Stdout = old // restoring the real stdout 124 out := <-outC 125 sps := strings.Split(preCaller, ":") 126 par, err := strconv.Atoi(sps[1]) 127 assert.Nil(t, err) 128 lineNum := fmt.Sprintf("%v", par+1) 129 fmt.Println(out, lineNum) 130 assert.Equal(t, `{"level":"info","msg":"test info","error":"test error","wf-action":"add-workflow-started-event","logging-call-at":"zap_logger_test.go:`+lineNum+`"}`+"\n", out) 131 } 132 133 func TestThrottleLogger(t *testing.T) { 134 old := os.Stdout // keep backup of the real stdout 135 r, w, _ := os.Pipe() 136 os.Stdout = w 137 outC := make(chan string) 138 // copy the output in a separate goroutine so logging can't block indefinitely 139 go func() { 140 var buf bytes.Buffer 141 _, err := io.Copy(&buf, r) 142 assert.NoError(t, err) 143 outC <- buf.String() 144 }() 145 146 logger := NewThrottledLogger(NewZapLogger(zap.NewExample()), 147 func() float64 { return 1 }) 148 preCaller := caller(1) 149 With(With(logger, tag.Error(fmt.Errorf("test error"))), tag.ComponentShardContext).Info("test info", tag.WorkflowActionWorkflowStarted) 150 151 // back to normal state 152 require.Nil(t, w.Close()) 153 os.Stdout = old // restoring the real stdout 154 out := <-outC 155 sps := strings.Split(preCaller, ":") 156 par, err := strconv.Atoi(sps[1]) 157 assert.Nil(t, err) 158 lineNum := fmt.Sprintf("%v", par+1) 159 fmt.Println(out, lineNum) 160 assert.Equal(t, `{"level":"info","msg":"test info","error":"test error","component":"shard-context","wf-action":"add-workflow-started-event","logging-call-at":"zap_logger_test.go:`+lineNum+`"}`+"\n", out) 161 } 162 163 func TestEmptyMsg(t *testing.T) { 164 old := os.Stdout // keep backup of the real stdout 165 r, w, _ := os.Pipe() 166 os.Stdout = w 167 outC := make(chan string) 168 // copy the output in a separate goroutine so logging can't block indefinitely 169 go func() { 170 var buf bytes.Buffer 171 _, err := io.Copy(&buf, r) 172 assert.NoError(t, err) 173 outC <- buf.String() 174 }() 175 176 logger := NewZapLogger(zap.NewExample()) 177 preCaller := caller(1) 178 logger.With(tag.Error(fmt.Errorf("test error"))).Info("", tag.WorkflowActionWorkflowStarted) 179 180 // back to normal state 181 require.Nil(t, w.Close()) 182 os.Stdout = old // restoring the real stdout 183 out := <-outC 184 sps := strings.Split(preCaller, ":") 185 par, err := strconv.Atoi(sps[1]) 186 assert.Nil(t, err) 187 lineNum := fmt.Sprintf("%v", par+1) 188 fmt.Println(out, lineNum) 189 assert.Equal(t, `{"level":"info","msg":"`+defaultMsgForEmpty+`","error":"test error","wf-action":"add-workflow-started-event","logging-call-at":"zap_logger_test.go:`+lineNum+`"}`+"\n", out) 190 }