github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/lsmkv/metrics.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package lsmkv 13 14 import ( 15 "time" 16 17 "github.com/prometheus/client_golang/prometheus" 18 "github.com/weaviate/weaviate/usecases/monitoring" 19 ) 20 21 type ( 22 NsObserver func(ns int64) 23 Setter func(val uint64) 24 TimeObserver func(start time.Time) 25 ) 26 27 type Metrics struct { 28 CompactionReplace *prometheus.GaugeVec 29 CompactionSet *prometheus.GaugeVec 30 CompactionMap *prometheus.GaugeVec 31 CompactionRoaringSet *prometheus.GaugeVec 32 ActiveSegments *prometheus.GaugeVec 33 bloomFilters prometheus.ObserverVec 34 SegmentObjects *prometheus.GaugeVec 35 SegmentSize *prometheus.GaugeVec 36 SegmentCount *prometheus.GaugeVec 37 startupDurations prometheus.ObserverVec 38 startupDiskIO prometheus.ObserverVec 39 objectCount prometheus.Gauge 40 memtableDurations prometheus.ObserverVec 41 memtableSize *prometheus.GaugeVec 42 DimensionSum *prometheus.GaugeVec 43 44 groupClasses bool 45 } 46 47 func NewMetrics(promMetrics *monitoring.PrometheusMetrics, className, 48 shardName string, 49 ) *Metrics { 50 if promMetrics.Group { 51 className = "n/a" 52 shardName = "n/a" 53 } 54 55 replace := promMetrics.AsyncOperations.MustCurryWith(prometheus.Labels{ 56 "operation": "compact_lsm_segments_stratreplace", 57 "class_name": className, 58 "shard_name": shardName, 59 }) 60 61 set := promMetrics.AsyncOperations.MustCurryWith(prometheus.Labels{ 62 "operation": "compact_lsm_segments_stratset", 63 "class_name": className, 64 "shard_name": shardName, 65 }) 66 67 roaringSet := promMetrics.AsyncOperations.MustCurryWith(prometheus.Labels{ 68 "operation": "compact_lsm_segments_stratroaringset", 69 "class_name": className, 70 "shard_name": shardName, 71 }) 72 73 stratMap := promMetrics.AsyncOperations.MustCurryWith(prometheus.Labels{ 74 "operation": "compact_lsm_segments_stratmap", 75 "class_name": className, 76 "shard_name": shardName, 77 }) 78 79 return &Metrics{ 80 groupClasses: promMetrics.Group, 81 CompactionReplace: replace, 82 CompactionSet: set, 83 CompactionMap: stratMap, 84 CompactionRoaringSet: roaringSet, 85 ActiveSegments: promMetrics.LSMSegmentCount.MustCurryWith(prometheus.Labels{ 86 "class_name": className, 87 "shard_name": shardName, 88 }), 89 bloomFilters: promMetrics.LSMBloomFilters.MustCurryWith(prometheus.Labels{ 90 "class_name": className, 91 "shard_name": shardName, 92 }), 93 SegmentObjects: promMetrics.LSMSegmentObjects.MustCurryWith(prometheus.Labels{ 94 "class_name": className, 95 "shard_name": shardName, 96 }), 97 SegmentSize: promMetrics.LSMSegmentSize.MustCurryWith(prometheus.Labels{ 98 "class_name": className, 99 "shard_name": shardName, 100 }), 101 SegmentCount: promMetrics.LSMSegmentCountByLevel.MustCurryWith(prometheus.Labels{ 102 "class_name": className, 103 "shard_name": shardName, 104 }), 105 startupDiskIO: promMetrics.StartupDiskIO.MustCurryWith(prometheus.Labels{ 106 "class_name": className, 107 "shard_name": shardName, 108 }), 109 startupDurations: promMetrics.StartupDurations.MustCurryWith(prometheus.Labels{ 110 "class_name": className, 111 "shard_name": shardName, 112 }), 113 objectCount: promMetrics.ObjectCount.With(prometheus.Labels{ 114 "class_name": className, 115 "shard_name": shardName, 116 }), 117 memtableDurations: promMetrics.LSMMemtableDurations.MustCurryWith(prometheus.Labels{ 118 "class_name": className, 119 "shard_name": shardName, 120 }), 121 memtableSize: promMetrics.LSMMemtableSize.MustCurryWith(prometheus.Labels{ 122 "class_name": className, 123 "shard_name": shardName, 124 }), 125 DimensionSum: promMetrics.VectorDimensionsSum.MustCurryWith(prometheus.Labels{ 126 "class_name": className, 127 "shard_name": shardName, 128 }), 129 } 130 } 131 132 func noOpTimeObserver(start time.Time) { 133 // do nothing 134 } 135 136 func noOpNsObserver(startNs int64) { 137 // do nothing 138 } 139 140 func noOpSetter(val uint64) { 141 // do nothing 142 } 143 144 func (m *Metrics) MemtableOpObserver(path, strategy, op string) NsObserver { 145 if m == nil { 146 return noOpNsObserver 147 } 148 149 if m.groupClasses { 150 path = "n/a" 151 } 152 153 curried := m.memtableDurations.With(prometheus.Labels{ 154 "operation": op, 155 "path": path, 156 "strategy": strategy, 157 }) 158 159 return func(startNs int64) { 160 took := float64(time.Now().UnixNano()-startNs) / float64(time.Millisecond) 161 curried.Observe(took) 162 } 163 } 164 165 func (m *Metrics) MemtableSizeSetter(path, strategy string) Setter { 166 if m == nil || m.groupClasses { 167 // this metric would set absolute values, that's not possible in 168 // grouped mode, each call would essentially overwrite the last 169 return noOpSetter 170 } 171 172 curried := m.memtableSize.With(prometheus.Labels{ 173 "path": path, 174 "strategy": strategy, 175 }) 176 177 return func(size uint64) { 178 curried.Set(float64(size)) 179 } 180 } 181 182 func (m *Metrics) BloomFilterObserver(strategy, operation string) TimeObserver { 183 if m == nil { 184 return noOpTimeObserver 185 } 186 187 curried := m.bloomFilters.With(prometheus.Labels{ 188 "strategy": strategy, 189 "operation": operation, 190 }) 191 192 return func(before time.Time) { 193 curried.Observe(float64(time.Since(before)) / float64(time.Millisecond)) 194 } 195 } 196 197 func (m *Metrics) TrackStartupReadWALDiskIO(read int64, nanoseconds int64) { 198 if m == nil { 199 return 200 } 201 202 seconds := float64(nanoseconds) / float64(time.Second) 203 throughput := float64(read) / float64(seconds) 204 m.startupDiskIO.With(prometheus.Labels{"operation": "lsm_recover_wal"}).Observe(throughput) 205 } 206 207 func (m *Metrics) TrackStartupBucket(start time.Time) { 208 if m == nil { 209 return 210 } 211 212 took := float64(time.Since(start)) / float64(time.Millisecond) 213 m.startupDurations.With(prometheus.Labels{"operation": "lsm_startup_bucket"}).Observe(took) 214 } 215 216 func (m *Metrics) TrackStartupBucketRecovery(start time.Time) { 217 if m == nil { 218 return 219 } 220 221 took := float64(time.Since(start)) / float64(time.Millisecond) 222 m.startupDurations.With(prometheus.Labels{"operation": "lsm_startup_bucket_recovery"}).Observe(took) 223 } 224 225 func (m *Metrics) ObjectCount(count int) { 226 if m == nil { 227 return 228 } 229 230 m.objectCount.Set(float64(count)) 231 }