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  }