github.com/matrixorigin/matrixone@v0.7.0/pkg/util/trace/impl/motrace/trace.go (about)

     1  // Copyright The OpenTelemetry Authors
     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  // Portions of this file are additionally subject to the following
    16  // copyright.
    17  //
    18  // Copyright (C) 2022 Matrix Origin.
    19  //
    20  // Modified the behavior and the interface of the step.
    21  
    22  package motrace
    23  
    24  import (
    25  	"context"
    26  	"sync/atomic"
    27  	"time"
    28  
    29  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    30  	"github.com/matrixorigin/matrixone/pkg/config"
    31  	"github.com/matrixorigin/matrixone/pkg/logutil"
    32  	"github.com/matrixorigin/matrixone/pkg/util/batchpipe"
    33  	"github.com/matrixorigin/matrixone/pkg/util/errutil"
    34  	ie "github.com/matrixorigin/matrixone/pkg/util/internalExecutor"
    35  	"github.com/matrixorigin/matrixone/pkg/util/trace"
    36  )
    37  
    38  var gTracerProvider atomic.Value
    39  var gTracer trace.Tracer
    40  var gTraceContext atomic.Value
    41  var gSpanContext atomic.Value
    42  
    43  func init() {
    44  	SetDefaultSpanContext(&trace.SpanContext{})
    45  	SetDefaultContext(context.Background())
    46  	tp := newMOTracerProvider(EnableTracer(false))
    47  	gTracer = tp.Tracer("default")
    48  	SetTracerProvider(tp)
    49  }
    50  
    51  var inited uint32
    52  
    53  func InitWithConfig(ctx context.Context, SV *config.ObservabilityParameters, opts ...TracerProviderOption) error {
    54  	opts = append(opts,
    55  		withMOVersion(SV.MoVersion),
    56  		EnableTracer(!SV.DisableTrace),
    57  		WithBatchProcessMode(SV.BatchProcessor),
    58  		WithExportInterval(SV.TraceExportInterval),
    59  		WithLongQueryTime(SV.LongQueryTime),
    60  		DebugMode(SV.EnableTraceDebug),
    61  	)
    62  	return Init(ctx, opts...)
    63  }
    64  
    65  func Init(ctx context.Context, opts ...TracerProviderOption) error {
    66  	// fix multi-init in standalone
    67  	if !atomic.CompareAndSwapUint32(&inited, 0, 1) {
    68  		return nil
    69  	}
    70  
    71  	// init TraceProvider
    72  	SetTracerProvider(newMOTracerProvider(opts...))
    73  	config := &GetTracerProvider().tracerProviderConfig
    74  
    75  	// init Tracer
    76  	gTracer = GetTracerProvider().Tracer("MatrixOne")
    77  	_, span := gTracer.Start(ctx, "TraceInit")
    78  	defer span.End()
    79  	defer trace.SetDefaultTracer(gTracer)
    80  
    81  	// init DefaultContext / DefaultSpanContext
    82  	var spanId trace.SpanID
    83  	spanId.SetByUUID(config.getNodeResource().NodeUuid)
    84  	sc := trace.SpanContextWithIDs(trace.NilTraceID, spanId)
    85  	SetDefaultSpanContext(&sc)
    86  	serviceCtx := context.Background()
    87  	SetDefaultContext(trace.ContextWithSpanContext(serviceCtx, sc))
    88  
    89  	// init Exporter
    90  	if err := initExporter(ctx, config); err != nil {
    91  		return err
    92  	}
    93  
    94  	// init tool dependence
    95  	logutil.SetLogReporter(&logutil.TraceReporter{ReportZap: ReportZap, ContextField: trace.ContextField})
    96  	logutil.SpanFieldKey.Store(trace.SpanFieldKey)
    97  	errutil.SetErrorReporter(ReportError)
    98  
    99  	logutil.Infof("trace with LongQueryTime: %v", time.Duration(GetTracerProvider().longQueryTime))
   100  
   101  	return nil
   102  }
   103  
   104  func initExporter(ctx context.Context, config *tracerProviderConfig) error {
   105  	if !config.IsEnable() {
   106  		return nil
   107  	}
   108  	if config.needInit {
   109  		if err := InitSchema(ctx, config.sqlExecutor); err != nil {
   110  			return err
   111  		}
   112  	}
   113  	defaultReminder := batchpipe.NewConstantClock(config.exportInterval)
   114  	defaultOptions := []BufferOption{BufferWithReminder(defaultReminder)}
   115  	var p = config.batchProcessor
   116  	// init BatchProcess for trace/log/error
   117  	switch {
   118  	case config.batchProcessMode == InternalExecutor:
   119  		// register buffer pipe implements
   120  		panic(moerr.NewNotSupported(ctx, "not support process mode: %s", config.batchProcessMode))
   121  	case config.batchProcessMode == FileService:
   122  		p.Register(&MOSpan{}, NewBufferPipe2CSVWorker(defaultOptions...))
   123  		p.Register(&MOZapLog{}, NewBufferPipe2CSVWorker(defaultOptions...))
   124  		p.Register(&StatementInfo{}, NewBufferPipe2CSVWorker(defaultOptions...))
   125  		p.Register(&MOErrorHolder{}, NewBufferPipe2CSVWorker(defaultOptions...))
   126  	default:
   127  		return moerr.NewInternalError(ctx, "unknown batchProcessMode: %s", config.batchProcessMode)
   128  	}
   129  	logutil.Info("init GlobalBatchProcessor")
   130  	if !p.Start() {
   131  		return moerr.NewInternalError(ctx, "trace exporter already started")
   132  	}
   133  	config.spanProcessors = append(config.spanProcessors, NewBatchSpanProcessor(p))
   134  	logutil.Info("init trace span processor")
   135  	return nil
   136  }
   137  
   138  // InitSchema
   139  // PS: only in standalone or CN node can init schema
   140  func InitSchema(ctx context.Context, sqlExecutor func() ie.InternalExecutor) error {
   141  	config := &GetTracerProvider().tracerProviderConfig
   142  	switch config.batchProcessMode {
   143  	case InternalExecutor, FileService:
   144  		if err := InitSchemaByInnerExecutor(ctx, sqlExecutor); err != nil {
   145  			return err
   146  		}
   147  	default:
   148  		return moerr.NewInternalError(ctx, "unknown batchProcessMode: %s", config.batchProcessMode)
   149  	}
   150  	return nil
   151  }
   152  
   153  func Shutdown(ctx context.Context) error {
   154  	if !GetTracerProvider().IsEnable() {
   155  		return nil
   156  	}
   157  	GetTracerProvider().SetEnable(false)
   158  
   159  	shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
   160  	defer cancel()
   161  	for _, p := range GetTracerProvider().spanProcessors {
   162  		if err := p.Shutdown(shutdownCtx); err != nil {
   163  			return err
   164  		}
   165  	}
   166  	logutil.Info("Shutdown trace complete.")
   167  	return nil
   168  }
   169  
   170  type contextHolder struct {
   171  	ctx context.Context
   172  }
   173  
   174  func SetDefaultContext(ctx context.Context) {
   175  	gTraceContext.Store(&contextHolder{ctx})
   176  }
   177  
   178  func DefaultContext() context.Context {
   179  	return gTraceContext.Load().(*contextHolder).ctx
   180  }
   181  
   182  func SetDefaultSpanContext(sc *trace.SpanContext) {
   183  	gSpanContext.Store(sc)
   184  }
   185  
   186  func DefaultSpanContext() *trace.SpanContext {
   187  	return gSpanContext.Load().(*trace.SpanContext)
   188  }
   189  
   190  func GetNodeResource() *trace.MONodeResource {
   191  	return GetTracerProvider().getNodeResource()
   192  }
   193  
   194  func SetTracerProvider(p *MOTracerProvider) {
   195  	gTracerProvider.Store(p)
   196  }
   197  func GetTracerProvider() *MOTracerProvider {
   198  	return gTracerProvider.Load().(*MOTracerProvider)
   199  }
   200  
   201  type PipeImpl batchpipe.PipeImpl[batchpipe.HasName, any]
   202  
   203  type BatchProcessor interface {
   204  	Collect(context.Context, batchpipe.HasName) error
   205  	Start() bool
   206  	Stop(graceful bool) error
   207  	Register(name batchpipe.HasName, impl PipeImpl)
   208  }
   209  
   210  var _ BatchProcessor = &NoopBatchProcessor{}
   211  
   212  type NoopBatchProcessor struct {
   213  }
   214  
   215  func (n NoopBatchProcessor) Collect(context.Context, batchpipe.HasName) error { return nil }
   216  func (n NoopBatchProcessor) Start() bool                                      { return true }
   217  func (n NoopBatchProcessor) Stop(bool) error                                  { return nil }
   218  func (n NoopBatchProcessor) Register(batchpipe.HasName, PipeImpl)             {}
   219  
   220  func GetGlobalBatchProcessor() BatchProcessor {
   221  	return GetTracerProvider().batchProcessor
   222  }