github.com/matrixorigin/matrixone@v1.2.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/catalog" 30 "github.com/matrixorigin/matrixone/pkg/common/moerr" 31 "github.com/matrixorigin/matrixone/pkg/config" 32 "github.com/matrixorigin/matrixone/pkg/defines" 33 "github.com/matrixorigin/matrixone/pkg/logutil" 34 "github.com/matrixorigin/matrixone/pkg/util/batchpipe" 35 "github.com/matrixorigin/matrixone/pkg/util/errutil" 36 "github.com/matrixorigin/matrixone/pkg/util/executor" 37 db_holder "github.com/matrixorigin/matrixone/pkg/util/export/etl/db" 38 ie "github.com/matrixorigin/matrixone/pkg/util/internalExecutor" 39 "github.com/matrixorigin/matrixone/pkg/util/trace" 40 ) 41 42 var gTracerProvider atomic.Value 43 var gTracer trace.Tracer 44 var gTraceContext atomic.Value 45 var gSpanContext atomic.Value 46 47 func init() { 48 SetDefaultSpanContext(&trace.SpanContext{}) 49 SetDefaultContext(context.Background()) 50 tp := newMOTracerProvider(EnableTracer(false)) 51 gTracer = tp.Tracer("default") 52 SetTracerProvider(tp) 53 } 54 55 var inited uint32 56 57 func InitWithConfig(ctx context.Context, SV *config.ObservabilityParameters, opts ...TracerProviderOption) (error, bool) { 58 opts = append(opts, 59 withMOVersion(SV.MoVersion), 60 EnableTracer(!SV.DisableTrace), 61 WithExportInterval(SV.TraceExportInterval), 62 WithLongQueryTime(SV.LongQueryTime), 63 WithLongSpanTime(SV.LongSpanTime.Duration), 64 WithSpanDisable(SV.DisableSpan), 65 WithErrorDisable(SV.DisableError), 66 WithSkipRunningStmt(SV.SkipRunningStmt), 67 WithSQLWriterDisable(SV.DisableSqlWriter), 68 WithAggregatorDisable(SV.DisableStmtAggregation), 69 WithAggregatorWindow(SV.AggregationWindow.Duration), 70 WithSelectThreshold(SV.SelectAggrThreshold.Duration), 71 WithStmtMergeEnable(SV.EnableStmtMerge), 72 WithCUConfig(SV.CU, SV.CUv1), 73 WithTCPPacket(SV.TCPPacket), 74 WithLabels(SV.LabelSelector), 75 76 DebugMode(SV.EnableTraceDebug), 77 WithBufferSizeThreshold(SV.BufferSize), 78 ) 79 return Init(ctx, opts...) 80 } 81 82 // Init initializes the tracer with the given options. 83 // If EnableTracer is set to false, this function does nothing. 84 // If EnableTracer is set to true, the tracer is initialized. 85 // Init only allow called once. 86 func Init(ctx context.Context, opts ...TracerProviderOption) (err error, act bool) { 87 // fix multi-init in standalone 88 if !atomic.CompareAndSwapUint32(&inited, 0, 1) { 89 return nil, false 90 } 91 92 // init TraceProvider 93 SetTracerProvider(newMOTracerProvider(opts...)) 94 config := &GetTracerProvider().tracerProviderConfig 95 96 if !config.disableSpan { 97 // init Tracer 98 gTracer = GetTracerProvider().Tracer("MatrixOne") 99 _, span := gTracer.Start(ctx, "TraceInit") 100 defer span.End() 101 defer trace.SetDefaultTracer(gTracer) 102 } 103 if config.disableError { 104 DisableLogErrorReport(true) 105 } 106 107 // init DefaultContext / DefaultSpanContext 108 var spanId trace.SpanID 109 spanId.SetByUUID(config.getNodeResource().NodeUuid) 110 sc := trace.SpanContextWithIDs(trace.NilTraceID, spanId) 111 SetDefaultSpanContext(&sc) 112 serviceCtx := context.Background() 113 SetDefaultContext(trace.ContextWithSpanContext(serviceCtx, sc)) 114 SetCuConfig(&config.cuConfig, &config.cuConfigV1) 115 116 // init Exporter 117 if err := initExporter(ctx, config); err != nil { 118 return err, true 119 } 120 121 // init all mo_ctl controlled spans 122 trace.InitMOCtledSpan() 123 124 // init tool dependence 125 logutil.SetLogReporter(&logutil.TraceReporter{ReportZap: ReportZap, ContextField: trace.ContextField}) 126 logutil.SpanFieldKey.Store(trace.SpanFieldKey) 127 errutil.SetErrorReporter(ReportError) 128 129 // init db_hodler 130 db_holder.SetLabelSelector(config.labels) 131 132 logutil.Debugf("trace with LongQueryTime: %v", time.Duration(GetTracerProvider().longQueryTime)) 133 logutil.Debugf("trace with LongSpanTime: %v", GetTracerProvider().longSpanTime) 134 logutil.Debugf("trace with DisableSpan: %v", GetTracerProvider().disableSpan) 135 136 return nil, true 137 } 138 139 func initExporter(ctx context.Context, config *tracerProviderConfig) error { 140 if !config.IsEnable() { 141 return nil 142 } 143 if config.needInit { 144 if err := InitSchema(ctx, config.sqlExecutor); err != nil { 145 return err 146 } 147 } 148 defaultReminder := batchpipe.NewConstantClock(config.exportInterval) 149 defaultOptions := []BufferOption{BufferWithReminder(defaultReminder), BufferWithSizeThreshold(config.bufferSizeThreshold)} 150 var p = config.batchProcessor 151 // init BatchProcess for trace/log/error 152 p.Register(&MOSpan{}, NewBufferPipe2CSVWorker(defaultOptions...)) 153 p.Register(&MOZapLog{}, NewBufferPipe2CSVWorker(defaultOptions...)) 154 p.Register(&StatementInfo{}, NewBufferPipe2CSVWorker(defaultOptions...)) 155 p.Register(&MOErrorHolder{}, NewBufferPipe2CSVWorker(defaultOptions...)) 156 logutil.Info("init GlobalBatchProcessor") 157 if !p.Start() { 158 return moerr.NewInternalError(ctx, "trace exporter already started") 159 } 160 config.spanProcessors = append(config.spanProcessors, NewBatchSpanProcessor(p)) 161 logutil.Info("init trace span processor") 162 return nil 163 } 164 165 // InitSchema 166 // PS: only in standalone or CN node can init schema 167 func InitSchema(ctx context.Context, sqlExecutor func() ie.InternalExecutor) error { 168 ctx = defines.AttachAccount(ctx, catalog.System_Account, catalog.System_User, catalog.System_Role) 169 c := &GetTracerProvider().tracerProviderConfig 170 WithSQLExecutor(sqlExecutor).apply(c) 171 if err := InitSchemaByInnerExecutor(ctx, sqlExecutor); err != nil { 172 return err 173 } 174 return nil 175 } 176 177 // InitSchema2 178 // PS: only in system bootstrap init schema with `executor.TxnExecutor` 179 func InitSchemaWithTxn(ctx context.Context, txn executor.TxnExecutor) error { 180 _, err := txn.Exec(sqlCreateDBConst, executor.StatementOption{}) 181 if err != nil { 182 return err 183 } 184 185 var createCost time.Duration 186 defer func() { 187 logutil.Debugf("[Trace] init tables: create cost %d ms", createCost.Milliseconds()) 188 }() 189 190 instant := time.Now() 191 for _, tbl := range tables { 192 _, err = txn.Exec(tbl.ToCreateSql(ctx, true), executor.StatementOption{}) 193 if err != nil { 194 return err 195 } 196 } 197 198 for _, v := range views { 199 _, err = txn.Exec(v.ToCreateSql(ctx, true), executor.StatementOption{}) 200 if err != nil { 201 return err 202 } 203 } 204 createCost = time.Since(instant) 205 return nil 206 } 207 208 func Shutdown(ctx context.Context) error { 209 if !GetTracerProvider().IsEnable() { 210 return nil 211 } 212 GetTracerProvider().SetEnable(false) 213 214 shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) 215 defer cancel() 216 for _, p := range GetTracerProvider().spanProcessors { 217 if err := p.Shutdown(shutdownCtx); err != nil { 218 return err 219 } 220 } 221 logutil.Info("Shutdown trace complete.") 222 return nil 223 } 224 225 type contextHolder struct { 226 ctx context.Context 227 } 228 229 func SetDefaultContext(ctx context.Context) { 230 gTraceContext.Store(&contextHolder{ctx}) 231 } 232 233 func DefaultContext() context.Context { 234 return gTraceContext.Load().(*contextHolder).ctx 235 } 236 237 func SetDefaultSpanContext(sc *trace.SpanContext) { 238 gSpanContext.Store(sc) 239 } 240 241 func DefaultSpanContext() *trace.SpanContext { 242 return gSpanContext.Load().(*trace.SpanContext) 243 } 244 245 func GetNodeResource() *trace.MONodeResource { 246 return GetTracerProvider().getNodeResource() 247 } 248 249 func SetTracerProvider(p *MOTracerProvider) { 250 gTracerProvider.Store(p) 251 } 252 253 // GetTracerProvider returns the global TracerProvider. 254 // It will be initialized at startup. 255 var GetTracerProvider = func() *MOTracerProvider { 256 return gTracerProvider.Load().(*MOTracerProvider) 257 } 258 259 func GetSQLExecutorFactory() func() ie.InternalExecutor { 260 p := GetTracerProvider() 261 if p != nil { 262 p.mux.Lock() 263 defer p.mux.Unlock() 264 return p.tracerProviderConfig.sqlExecutor 265 } 266 return nil 267 } 268 269 type PipeImpl batchpipe.PipeImpl[batchpipe.HasName, any] 270 271 type BatchProcessor interface { 272 Collect(context.Context, batchpipe.HasName) error 273 Start() bool 274 Stop(graceful bool) error 275 Register(name batchpipe.HasName, impl PipeImpl) 276 } 277 278 type DiscardableCollector interface { 279 DiscardableCollect(context.Context, batchpipe.HasName) error 280 } 281 282 var _ BatchProcessor = &NoopBatchProcessor{} 283 284 type NoopBatchProcessor struct { 285 } 286 287 func (n NoopBatchProcessor) Collect(context.Context, batchpipe.HasName) error { return nil } 288 func (n NoopBatchProcessor) Start() bool { return true } 289 func (n NoopBatchProcessor) Stop(bool) error { return nil } 290 func (n NoopBatchProcessor) Register(batchpipe.HasName, PipeImpl) {} 291 292 func GetGlobalBatchProcessor() BatchProcessor { 293 return GetTracerProvider().batchProcessor 294 }