github.com/matrixorigin/matrixone@v1.2.0/pkg/util/trace/impl/motrace/report_log_test.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package motrace 16 17 import ( 18 "context" 19 "sync/atomic" 20 "testing" 21 "time" 22 23 "github.com/prashantv/gostub" 24 "github.com/stretchr/testify/require" 25 "go.uber.org/zap" 26 "go.uber.org/zap/zapcore" 27 28 "github.com/matrixorigin/matrixone/pkg/common/runtime" 29 "github.com/matrixorigin/matrixone/pkg/logutil" 30 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 31 "github.com/matrixorigin/matrixone/pkg/util/batchpipe" 32 "github.com/matrixorigin/matrixone/pkg/util/stack" 33 "github.com/matrixorigin/matrixone/pkg/util/trace" 34 ) 35 36 func TestReportZap(t *testing.T) { 37 type args struct { 38 jsonEncoder zapcore.Encoder 39 entry zapcore.Entry 40 fields []zapcore.Field 41 } 42 spanField := trace.ContextField(trace.ContextWithSpanContext(context.Background(), trace.SpanContext{})) 43 entry := zapcore.Entry{ 44 Level: zapcore.InfoLevel, 45 Time: time.Unix(0, 0), 46 LoggerName: "test", 47 Message: "info message", 48 Caller: zapcore.NewEntryCaller(uintptr(stack.Caller(3)), "file", 123, true), 49 } 50 encoder := zapcore.NewJSONEncoder( 51 zapcore.EncoderConfig{ 52 StacktraceKey: "stacktrace", 53 SkipLineEnding: true, 54 LineEnding: zapcore.DefaultLineEnding, 55 EncodeLevel: zapcore.LowercaseLevelEncoder, 56 EncodeTime: zapcore.EpochTimeEncoder, 57 EncodeDuration: zapcore.SecondsDurationEncoder, 58 EncodeCaller: zapcore.ShortCallerEncoder, 59 }) 60 intField := zap.Int("key", 1) 61 strField := zap.String("str", "1") 62 boolField := zap.Bool("bool", true) 63 tests := []struct { 64 name string 65 args args 66 want string 67 }{ 68 { 69 name: "normal", 70 args: args{ 71 jsonEncoder: encoder, 72 entry: entry, 73 fields: []zapcore.Field{intField}, 74 }, 75 want: `{"key":1}`, 76 }, 77 { 78 name: "remove first span", 79 args: args{ 80 jsonEncoder: encoder, 81 entry: entry, 82 fields: []zapcore.Field{spanField, intField, strField}, 83 }, 84 want: `{"str":"1","key":1}`, 85 }, 86 { 87 name: "remove middle span", 88 args: args{ 89 jsonEncoder: encoder, 90 entry: entry, 91 fields: []zapcore.Field{intField, spanField, strField}, 92 }, 93 want: `{"key":1,"str":"1"}`, 94 }, 95 { 96 name: "remove double middle span", 97 args: args{ 98 jsonEncoder: encoder, 99 entry: entry, 100 fields: []zapcore.Field{intField, spanField, spanField, strField, boolField}, 101 }, 102 want: `{"key":1,"bool":true,"str":"1"}`, 103 }, 104 { 105 name: "remove end span", 106 args: args{ 107 jsonEncoder: encoder, 108 entry: entry, 109 fields: []zapcore.Field{intField, strField, spanField, spanField}, 110 }, 111 want: `{"key":1,"str":"1"}`, 112 }, 113 { 114 name: "remove multi span", 115 args: args{ 116 jsonEncoder: encoder, 117 entry: entry, 118 fields: []zapcore.Field{intField, strField, spanField, boolField, spanField, spanField}, 119 }, 120 want: `{"key":1,"str":"1","bool":true}`, 121 }, 122 } 123 for _, tt := range tests { 124 t.Run(tt.name, func(t *testing.T) { 125 got, err := ReportZap(tt.args.jsonEncoder, tt.args.entry, tt.args.fields) 126 require.Equal(t, nil, err) 127 require.Equal(t, tt.want, got.String()) 128 }) 129 } 130 } 131 132 var _ BatchProcessor = (*dummyCollectorCounter)(nil) 133 var _ DiscardableCollector = (*dummyCollectorCounter)(nil) 134 135 type dummyCollectorCounter struct { 136 collectCnt atomic.Int64 137 discardCnt atomic.Int64 138 } 139 140 func newDummyCollectorCounter() *dummyCollectorCounter { 141 return &dummyCollectorCounter{} 142 } 143 144 func (d *dummyCollectorCounter) DiscardableCollect(ctx context.Context, name batchpipe.HasName) error { 145 d.discardCnt.Add(1) 146 return nil 147 } 148 149 func (d *dummyCollectorCounter) Collect(ctx context.Context, name batchpipe.HasName) error { 150 d.collectCnt.Add(1) 151 return nil 152 } 153 154 func (d *dummyCollectorCounter) Start() bool { return true } 155 func (d *dummyCollectorCounter) Stop(graceful bool) error { return nil } 156 func (d *dummyCollectorCounter) Register(name batchpipe.HasName, impl PipeImpl) {} 157 158 func TestReportZap_Discardable(t *testing.T) { 159 160 exportMux.Lock() 161 defer exportMux.Unlock() 162 163 // Setup a Runtime 164 runtime.SetupProcessLevelRuntime(runtime.NewRuntime(metadata.ServiceType_CN, "test", logutil.GetGlobalLogger())) 165 166 collector := newDummyCollectorCounter() 167 p := newMOTracerProvider(WithFSWriterFactory(&dummyFileWriterFactory{}), EnableTracer(true), WithBatchProcessor(collector)) 168 stubs := gostub.Stub(&GetTracerProvider, func() *MOTracerProvider { 169 return p 170 }) 171 defer stubs.Reset() 172 173 logutil.Info("normal log 1") 174 require.Equal(t, int64(1), collector.collectCnt.Load()) 175 176 logutil.Info("discard log 1", logutil.Discardable()) 177 require.Equal(t, int64(1), collector.discardCnt.Load()) 178 179 logger := runtime.ProcessLevelRuntime().Logger().With(logutil.Discardable()) 180 logger.Info("discard log 2") 181 require.Equal(t, int64(2), collector.discardCnt.Load()) 182 logger.Info("discard log 3") 183 require.Equal(t, int64(3), collector.discardCnt.Load()) 184 185 logutil.Info("normal log 2") 186 require.Equal(t, int64(2), collector.collectCnt.Load()) 187 }