github.com/matrixorigin/matrixone@v0.7.0/pkg/logutil/report.go (about) 1 // Copyright 2021 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 logutil 16 17 import ( 18 "context" 19 "io" 20 "sync/atomic" 21 22 "go.uber.org/zap" 23 "go.uber.org/zap/buffer" 24 "go.uber.org/zap/zapcore" 25 ) 26 27 var gLogConfigs atomic.Value 28 29 func EnableStoreDB() bool { 30 return !gLogConfigs.Load().(*LogConfig).DisableStore 31 } 32 33 func setGlobalLogConfig(cfg *LogConfig) { 34 gLogConfigs.Store(cfg) 35 } 36 37 func getGlobalLogConfig() *LogConfig { 38 return gLogConfigs.Load().(*LogConfig) 39 } 40 41 type ZapSink struct { 42 enc zapcore.Encoder 43 out zapcore.WriteSyncer 44 } 45 46 // zapReporter should be trace.ReportZap 47 var zapReporter atomic.Value 48 49 // contextField should be trace.ContextField function 50 var contextField atomic.Value 51 52 type TraceReporter struct { 53 ReportZap reportZapFunc 54 ContextField contextFieldFunc 55 } 56 57 type reportZapFunc func(zapcore.Encoder, zapcore.Entry, []zapcore.Field) (*buffer.Buffer, error) 58 type contextFieldFunc func(context.Context) zap.Field 59 60 func noopReportZap(zapcore.Encoder, zapcore.Entry, []zapcore.Field) (*buffer.Buffer, error) { 61 return buffer.NewPool().Get(), nil 62 } 63 func noopContextField(context.Context) zap.Field { return zap.String("span", "{}") } 64 65 func SetLogReporter(r *TraceReporter) { 66 if r.ReportZap != nil { 67 zapReporter.Store(r.ReportZap) 68 } 69 if r.ContextField != nil { 70 contextField.Store(r.ContextField) 71 } 72 } 73 74 func GetReportZapFunc() reportZapFunc { 75 return zapReporter.Load().(reportZapFunc) 76 } 77 78 func GetContextFieldFunc() contextFieldFunc { 79 return contextField.Load().(contextFieldFunc) 80 } 81 82 var _ zapcore.Encoder = (*TraceLogEncoder)(nil) 83 84 type TraceLogEncoder struct { 85 zapcore.Encoder 86 spanContextField zap.Field 87 } 88 89 func (e *TraceLogEncoder) Clone() zapcore.Encoder { 90 return &TraceLogEncoder{ 91 Encoder: e.Encoder.Clone(), 92 } 93 } 94 95 var SpanFieldKey atomic.Value 96 97 func (e *TraceLogEncoder) AddObject(key string, val zapcore.ObjectMarshaler) error { 98 if key == SpanFieldKey.Load().(string) { 99 //e.sp = obj.(*trace.SpanContext) 100 e.spanContextField = zap.Object(key, val) 101 return nil 102 } 103 return e.Encoder.AddObject(key, val) 104 } 105 106 func (e *TraceLogEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) { 107 if e.spanContextField.Key == SpanFieldKey.Load().(string) { 108 fields = append(fields, e.spanContextField) 109 } 110 for _, v := range fields { 111 if v.Type == zapcore.BoolType && v.Key == MOInternalFiledKeyNoopReport { 112 return e.Encoder.EncodeEntry(entry, fields[:0]) 113 } 114 } 115 return GetReportZapFunc()(e.Encoder, entry, fields) 116 } 117 118 const MOInternalFiledKeyNoopReport = "MOInternalFiledKeyNoopReport" 119 120 func newTraceLogEncoder() *TraceLogEncoder { 121 // default like zap.NewProductionEncoderConfig(), but clean core-elems ENCODE 122 e := &TraceLogEncoder{ 123 Encoder: zapcore.NewJSONEncoder( 124 zapcore.EncoderConfig{ 125 StacktraceKey: "", 126 SkipLineEnding: true, 127 LineEnding: zapcore.DefaultLineEnding, 128 EncodeLevel: zapcore.LowercaseLevelEncoder, 129 EncodeTime: zapcore.EpochTimeEncoder, 130 EncodeDuration: zapcore.SecondsDurationEncoder, 131 EncodeCaller: zapcore.ShortCallerEncoder, 132 }), 133 } 134 return e 135 } 136 137 func getTraceLogSinks() (zapcore.Encoder, zapcore.WriteSyncer) { 138 return newTraceLogEncoder(), zapcore.AddSync(io.Discard) 139 } 140 141 func init() { 142 SpanFieldKey.Store("") 143 }