github.com/matrixorigin/matrixone@v0.7.0/pkg/util/trace/impl/motrace/mo_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  	"github.com/matrixorigin/matrixone/pkg/util/trace"
    27  	"sync"
    28  	"time"
    29  	"unsafe"
    30  
    31  	"github.com/matrixorigin/matrixone/pkg/util/export/table"
    32  )
    33  
    34  //nolint:revive // revive complains about stutter of `trace.TraceFlags`.
    35  
    36  var _ trace.Tracer = &MOTracer{}
    37  
    38  // MOTracer is the creator of Spans.
    39  type MOTracer struct {
    40  	trace.TracerConfig
    41  	provider *MOTracerProvider
    42  }
    43  
    44  func (t *MOTracer) Start(ctx context.Context, name string, opts ...trace.SpanOption) (context.Context, trace.Span) {
    45  	if !t.IsEnable() {
    46  		return ctx, trace.NoopSpan{}
    47  	}
    48  	span := newMOSpan()
    49  	span.init(name, opts...)
    50  	span.tracer = t
    51  
    52  	parent := trace.SpanFromContext(ctx)
    53  	psc := parent.SpanContext()
    54  
    55  	if span.NewRoot || psc.IsEmpty() {
    56  		span.TraceID, span.SpanID = t.provider.idGenerator.NewIDs()
    57  		span.Parent = trace.NoopSpan{}
    58  	} else {
    59  		span.TraceID, span.SpanID, span.Kind = psc.TraceID, t.provider.idGenerator.NewSpanID(), psc.Kind
    60  		span.Parent = parent
    61  	}
    62  
    63  	return trace.ContextWithSpan(ctx, span), span
    64  }
    65  
    66  func (t *MOTracer) Debug(ctx context.Context, name string, opts ...trace.SpanOption) (context.Context, trace.Span) {
    67  	if !t.provider.debugMode {
    68  		return ctx, trace.NoopSpan{}
    69  	}
    70  	return t.Start(ctx, name, opts...)
    71  }
    72  
    73  func (t *MOTracer) IsEnable() bool {
    74  	return t.provider.IsEnable()
    75  }
    76  
    77  var _ trace.Span = (*MOSpan)(nil)
    78  
    79  // MOSpan implement export.IBuffer2SqlItem and export.CsvFields
    80  type MOSpan struct {
    81  	trace.SpanConfig
    82  	Name      string    `json:"name"`
    83  	StartTime time.Time `json:"start_time"`
    84  	EndTime   time.Time `jons:"end_time"`
    85  	Duration  uint64    `json:"duration"`
    86  
    87  	tracer *MOTracer `json:"-"`
    88  }
    89  
    90  var spanPool = &sync.Pool{New: func() any {
    91  	return &MOSpan{}
    92  }}
    93  
    94  func newMOSpan() *MOSpan {
    95  	return spanPool.Get().(*MOSpan)
    96  }
    97  
    98  func (s *MOSpan) init(name string, opts ...trace.SpanOption) {
    99  	s.Name = name
   100  	s.StartTime = time.Now()
   101  	for _, opt := range opts {
   102  		opt.ApplySpanStart(&s.SpanConfig)
   103  	}
   104  }
   105  
   106  func (s *MOSpan) Size() int64 {
   107  	return int64(unsafe.Sizeof(*s)) + int64(len(s.Name))
   108  }
   109  
   110  var zeroTime = time.Time{}
   111  
   112  func (s *MOSpan) Free() {
   113  	s.SpanConfig.Reset()
   114  	s.Parent = nil
   115  	s.Name = ""
   116  	s.tracer = nil
   117  	s.StartTime = zeroTime
   118  	s.EndTime = zeroTime
   119  	spanPool.Put(s)
   120  }
   121  
   122  func (s *MOSpan) GetName() string {
   123  	return spanView.OriginTable.GetName()
   124  }
   125  
   126  func (s *MOSpan) GetTable() *table.Table { return spanView.OriginTable }
   127  
   128  func (s *MOSpan) FillRow(ctx context.Context, row *table.Row) {
   129  	row.Reset()
   130  	row.SetColumnVal(rawItemCol, spanView.Table)
   131  	row.SetColumnVal(spanIDCol, s.SpanID.String())
   132  	row.SetColumnVal(traceIDCol, s.TraceID.String())
   133  	row.SetColumnVal(spanKindCol, s.Kind.String())
   134  	row.SetColumnVal(parentSpanIDCol, s.Parent.SpanContext().SpanID.String())
   135  	row.SetColumnVal(nodeUUIDCol, GetNodeResource().NodeUuid)
   136  	row.SetColumnVal(nodeTypeCol, GetNodeResource().NodeType)
   137  	row.SetColumnVal(spanNameCol, s.Name)
   138  	row.SetColumnVal(startTimeCol, s.StartTime)
   139  	row.SetColumnVal(endTimeCol, s.EndTime)
   140  	row.SetColumnVal(durationCol, uint64(s.EndTime.Sub(s.StartTime))) // Duration
   141  	row.SetColumnVal(resourceCol, s.tracer.provider.resource.String())
   142  }
   143  
   144  func (s *MOSpan) End(options ...trace.SpanEndOption) {
   145  	for _, opt := range options {
   146  		opt.ApplySpanEnd(&s.SpanConfig)
   147  	}
   148  	if s.EndTime.IsZero() {
   149  		s.EndTime = time.Now()
   150  	}
   151  	for _, sp := range s.tracer.provider.spanProcessors {
   152  		sp.OnEnd(s)
   153  	}
   154  }
   155  
   156  func (s *MOSpan) SpanContext() trace.SpanContext {
   157  	return s.SpanConfig.SpanContext
   158  }
   159  
   160  func (s *MOSpan) ParentSpanContext() trace.SpanContext {
   161  	return s.SpanConfig.Parent.SpanContext()
   162  }
   163  
   164  const timestampFormatter = "2006-01-02 15:04:05.000000"
   165  
   166  func Time2DatetimeString(t time.Time) string {
   167  	return t.Format(timestampFormatter)
   168  }