github.com/matrixorigin/matrixone@v1.2.0/pkg/util/trace/impl/motrace/report_error.go (about) 1 // Copyright 2022 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 motrace 16 17 import ( 18 "context" 19 "errors" 20 "fmt" 21 "sync" 22 "sync/atomic" 23 "time" 24 "unsafe" 25 26 "github.com/cockroachdb/errors/errbase" 27 "github.com/matrixorigin/matrixone/pkg/common/moerr" 28 "github.com/matrixorigin/matrixone/pkg/logutil" 29 "github.com/matrixorigin/matrixone/pkg/util/errutil" 30 "github.com/matrixorigin/matrixone/pkg/util/export/table" 31 "github.com/matrixorigin/matrixone/pkg/util/trace" 32 "go.uber.org/zap" 33 ) 34 35 // MOErrorHolder implement export.IBuffer2SqlItem and export.CsvFields 36 type MOErrorHolder struct { 37 Error error `json:"error"` 38 Timestamp time.Time `json:"timestamp"` 39 } 40 41 var errorPool = sync.Pool{ 42 New: func() any { 43 return &MOErrorHolder{} 44 }, 45 } 46 47 func newMOErrorHolder(err error, t time.Time) *MOErrorHolder { 48 h := errorPool.Get().(*MOErrorHolder) 49 h.Error = err 50 h.Timestamp = t 51 return h 52 } 53 54 func (h *MOErrorHolder) GetName() string { 55 return errorView.OriginTable.GetName() 56 } 57 58 func (h *MOErrorHolder) Size() int64 { 59 return int64(32*8) + int64(unsafe.Sizeof(h)) 60 } 61 func (h *MOErrorHolder) Free() { 62 h.Error = nil 63 errorPool.Put(h) 64 } 65 66 func (h *MOErrorHolder) GetTable() *table.Table { return errorView.OriginTable } 67 68 func (h *MOErrorHolder) FillRow(ctx context.Context, row *table.Row) { 69 row.Reset() 70 row.SetColumnVal(rawItemCol, table.StringField(errorView.Table)) 71 row.SetColumnVal(timestampCol, table.TimeField(h.Timestamp)) 72 row.SetColumnVal(nodeUUIDCol, table.StringField(GetNodeResource().NodeUuid)) 73 row.SetColumnVal(nodeTypeCol, table.StringField(GetNodeResource().NodeType)) 74 row.SetColumnVal(errorCol, table.StringField(h.Error.Error())) 75 row.SetColumnVal(stackCol, table.StringField(fmt.Sprintf(errorFormatter.Load().(string), h.Error))) 76 var moError *moerr.Error 77 if errors.As(h.Error, &moError) { 78 row.SetColumnVal(errCodeCol, table.StringField(fmt.Sprintf("%d", moError.ErrorCode()))) 79 } 80 if ct := errutil.GetContextTracer(h.Error); ct != nil && ct.Context() != nil { 81 span := trace.SpanFromContext(ct.Context()) 82 row.SetColumnVal(traceIDCol, table.StringField(span.SpanContext().TraceID.String())) 83 row.SetColumnVal(spanIDCol, table.StringField(span.SpanContext().SpanID.String())) 84 row.SetColumnVal(spanKindCol, table.StringField(span.SpanContext().Kind.String())) 85 } 86 } 87 88 func (h *MOErrorHolder) Format(s fmt.State, verb rune) { errbase.FormatError(h.Error, s, verb) } 89 90 var disableLogErrorReport atomic.Bool 91 92 func DisableLogErrorReport(disable bool) { 93 disableLogErrorReport.Store(disable) 94 } 95 96 // ReportError send to BatchProcessor 97 func ReportError(ctx context.Context, err error, depth int) { 98 // context ctl 99 if errutil.NoReportFromContext(ctx) { 100 return 101 } 102 // global ctl 103 if disableLogErrorReport.Load() { 104 return 105 } 106 // log every time 107 msg := fmt.Sprintf("error: %v", err) 108 sc := trace.SpanFromContext(ctx).SpanContext() 109 if sc.IsEmpty() { 110 logutil.GetErrorLogger().WithOptions(zap.AddCallerSkip(depth)).Error(msg) 111 } else { 112 logutil.GetErrorLogger().WithOptions(zap.AddCallerSkip(depth)).Error(msg, trace.ContextField(ctx)) 113 } 114 // record ctrl 115 if !GetTracerProvider().IsEnable() { 116 return 117 } 118 if ctx == nil { 119 ctx = DefaultContext() 120 } 121 e := newMOErrorHolder(err, time.Now()) 122 GetGlobalBatchProcessor().Collect(ctx, e) 123 }