github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/sink/metrics/statistics.go (about) 1 // Copyright 2020 PingCAP, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package metrics 15 16 import ( 17 "context" 18 "time" 19 20 "github.com/pingcap/tiflow/cdc/model" 21 "github.com/pingcap/tiflow/pkg/config" 22 "github.com/pingcap/tiflow/pkg/sink" 23 "github.com/prometheus/client_golang/prometheus" 24 ) 25 26 // NewStatistics creates a statistics 27 func NewStatistics(ctx context.Context, 28 changefeed model.ChangeFeedID, 29 sinkType sink.Type, 30 ) *Statistics { 31 statistics := &Statistics{ 32 sinkType: sinkType, 33 captureAddr: config.GetGlobalServerConfig().AdvertiseAddr, 34 changefeedID: changefeed, 35 } 36 37 namespcae := statistics.changefeedID.Namespace 38 changefeedID := statistics.changefeedID.ID 39 s := sinkType.String() 40 statistics.metricExecDDLHis = ExecDDLHistogram.WithLabelValues(namespcae, changefeedID, s) 41 statistics.metricExecBatchHis = ExecBatchHistogram.WithLabelValues(namespcae, changefeedID, s) 42 statistics.metricTotalWriteBytesCnt = TotalWriteBytesCounter.WithLabelValues(namespcae, changefeedID, s) 43 statistics.metricRowSizeHis = LargeRowSizeHistogram.WithLabelValues(namespcae, changefeedID, s) 44 statistics.metricExecErrCnt = ExecutionErrorCounter.WithLabelValues(namespcae, changefeedID, s) 45 return statistics 46 } 47 48 // Statistics maintains some status and metrics of the Sink 49 // Note: All methods of Statistics should be thread-safe. 50 type Statistics struct { 51 sinkType sink.Type 52 captureAddr string 53 changefeedID model.ChangeFeedID 54 55 // Histogram for DDL Executing duration. 56 metricExecDDLHis prometheus.Observer 57 // Histogram for DML batch size. 58 metricExecBatchHis prometheus.Observer 59 // Counter for total bytes of DML. 60 metricTotalWriteBytesCnt prometheus.Counter 61 // Histogram for Row size. 62 metricRowSizeHis prometheus.Observer 63 // Counter for sink error. 64 metricExecErrCnt prometheus.Counter 65 } 66 67 // ObserveRows stats all received `RowChangedEvent`s. 68 func (b *Statistics) ObserveRows(rows ...*model.RowChangedEvent) { 69 for _, row := range rows { 70 // only track row with data size larger than `rowSizeLowBound` to reduce 71 // the overhead of calling `Observe` method. 72 if row.ApproximateDataSize >= largeRowSizeLowBound { 73 b.metricRowSizeHis.Observe(float64(row.ApproximateDataSize)) 74 } 75 } 76 } 77 78 // RecordBatchExecution stats batch executors which return (batchRowCount, error). 79 func (b *Statistics) RecordBatchExecution(executor func() (int, int64, error)) error { 80 batchSize, batchWriteBytes, err := executor() 81 if err != nil { 82 b.metricExecErrCnt.Inc() 83 return err 84 } 85 b.metricExecBatchHis.Observe(float64(batchSize)) 86 b.metricTotalWriteBytesCnt.Add(float64(batchWriteBytes)) 87 return nil 88 } 89 90 // RecordDDLExecution record the time cost of execute ddl 91 func (b *Statistics) RecordDDLExecution(executor func() error) error { 92 start := time.Now() 93 if err := executor(); err != nil { 94 b.metricExecErrCnt.Inc() 95 return err 96 } 97 b.metricExecDDLHis.Observe(time.Since(start).Seconds()) 98 return nil 99 } 100 101 // Close release some internal resources. 102 func (b *Statistics) Close() { 103 ExecDDLHistogram.DeleteLabelValues(b.changefeedID.Namespace, b.changefeedID.ID) 104 ExecBatchHistogram.DeleteLabelValues(b.changefeedID.Namespace, b.changefeedID.ID) 105 LargeRowSizeHistogram.DeleteLabelValues(b.changefeedID.Namespace, b.changefeedID.ID) 106 ExecutionErrorCounter.DeleteLabelValues(b.changefeedID.Namespace, b.changefeedID.ID) 107 }