github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/selfmonitor/metrics_vector_imp_test.go (about) 1 // Copyright 2024 iLogtail 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 package selfmonitor 16 17 import ( 18 "fmt" 19 "strconv" 20 "testing" 21 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func Test_MetricVectorWithEmptyLabel(t *testing.T) { 26 v := NewCumulativeCounterMetricVector("test", nil, nil) 27 v.WithLabels(LabelPair{Key: "test_label", Value: "test_value"}).Add(1) 28 29 v.WithLabels().Add(1) 30 collector, ok := v.(MetricCollector) 31 assert.True(t, ok) 32 collectedMetrics := collector.Collect() 33 assert.Equal(t, 1, len(collectedMetrics)) 34 35 for _, v := range collectedMetrics { 36 counter, ok := v.(*cumulativeCounterImp) 37 assert.True(t, ok) 38 assert.Equal(t, "test", counter.Name()) 39 assert.Equal(t, 1.0, counter.Collect().Value) 40 } 41 } 42 43 func Test_MetricVectorWithConstLabel(t *testing.T) { 44 v := NewCumulativeCounterMetricVector("test", map[string]string{"host": "host1", "plugin_id": "2"}, nil) 45 v.WithLabels(LabelPair{Key: "test_label", Value: "test_value"}).Add(1) 46 47 v.WithLabels().Add(2) 48 collector, ok := v.(MetricCollector) 49 assert.True(t, ok) 50 collectedMetrics := collector.Collect() 51 assert.Equal(t, 1, len(collectedMetrics)) 52 53 expectedContents := []map[string]string{ 54 {"host": "host1", "plugin_id": "2", "test_label": "test_value", "__name__": "test", "test": "2.0000"}, 55 } 56 for i, v := range collectedMetrics { 57 counter, ok := v.(*cumulativeCounterImp) 58 assert.True(t, ok) 59 assert.Equal(t, "test", counter.Name()) 60 assert.Equal(t, 2.0, counter.Collect().Value) 61 records := v.Export() 62 for k, v := range records { 63 assert.Equal(t, expectedContents[i][k], v) 64 } 65 } 66 } 67 68 func Test_CounterMetricVectorWithDynamicLabel(t *testing.T) { 69 metricName := "test_counter_vector" 70 v := NewCumulativeCounterMetricVector(metricName, 71 map[string]string{"host": "host1", "plugin_id": "3"}, 72 []string{"label1", "label2", "label3", "label5"}, 73 ) 74 75 v.WithLabels(LabelPair{Key: "label4", Value: "value4"}).Add(1) 76 v.WithLabels().Add(-1) 77 seriesCount := 500 78 for i := 0; i < seriesCount; i++ { 79 v.WithLabels(LabelPair{Key: "label1", Value: fmt.Sprintf("value_%d", i)}).Add(int64(i)) 80 } 81 82 collector, ok := v.(MetricCollector) 83 assert.True(t, ok) 84 collectedMetrics := collector.Collect() 85 assert.Equal(t, seriesCount+1, len(collectedMetrics)) 86 87 expectedContents := []map[string]string{} 88 89 for i := 0; i < seriesCount; i++ { 90 expectedContents = append(expectedContents, map[string]string{ 91 "host": "host1", 92 "plugin_id": "3", 93 "label1": fmt.Sprintf("value_%d", i), 94 "label2": defaultTagValue, 95 "label3": defaultTagValue, 96 "label5": defaultTagValue, 97 "__name__": metricName, 98 "test_counter_vector": fmt.Sprintf("%d.0000", i), 99 }) 100 } 101 102 for _, metric := range collectedMetrics { 103 counter, ok := metric.(*cumulativeCounterImp) 104 assert.True(t, ok) 105 assert.Equal(t, metricName, counter.Name()) 106 valueAsIndex := int(counter.Collect().Value) 107 records := metric.Export() 108 if valueAsIndex >= 0 { 109 for k, v := range records { 110 assert.Equal(t, expectedContents[valueAsIndex][k], v) 111 } 112 } 113 } 114 } 115 116 func Test_AverageMetricVectorWithDynamicLabel(t *testing.T) { 117 metricName := "test_average_vector" 118 v := NewAverageMetricVector(metricName, 119 map[string]string{"host": "host1", "plugin_id": "3"}, 120 []string{"label1", "label2", "label3", "label5"}, 121 ) 122 123 v.WithLabels(LabelPair{Key: "label4", Value: "value4"}).Add(1) 124 v.WithLabels().Add(-1) 125 seriesCount := 500 126 for i := 0; i < seriesCount; i++ { 127 v.WithLabels(LabelPair{Key: "label1", Value: fmt.Sprintf("value_%d", i)}).Add(int64(i)) 128 } 129 130 collector, ok := v.(MetricCollector) 131 assert.True(t, ok) 132 collectedMetrics := collector.Collect() 133 assert.Equal(t, seriesCount+1, len(collectedMetrics)) 134 135 expectedContents := []map[string]string{} 136 137 for i := 0; i < seriesCount; i++ { 138 expectedContents = append(expectedContents, map[string]string{ 139 "host": "host1", 140 "plugin_id": "3", 141 "label1": fmt.Sprintf("value_%d", i), 142 "label2": defaultTagValue, 143 "label3": defaultTagValue, 144 "label5": defaultTagValue, 145 "__name__": metricName, 146 metricName: fmt.Sprintf("%d.0000", i), 147 }) 148 } 149 150 for i, metric := range collectedMetrics { 151 counter, ok := metric.(*averageImp) 152 assert.True(t, ok) 153 assert.Equal(t, metricName, counter.Name()) 154 valueAsIndex := int(counter.Collect().Value) 155 records := metric.Export() 156 if valueAsIndex >= 0 { 157 for k, v := range records { 158 if expectedContents[valueAsIndex][k] != v { 159 t.Errorf("index: %d, actual: %v vs expcted: %v", i, v, expectedContents[valueAsIndex][k]) 160 } 161 } 162 } 163 } 164 } 165 166 func Test_LatencyMetricVectorWithDynamicLabel(t *testing.T) { 167 metricName := "test_latency_vector" 168 v := NewLatencyMetricVector(metricName, 169 map[string]string{"host": "host1", "plugin_id": "3"}, 170 []string{"label1", "label2", "label3", "label5"}, 171 ) 172 173 v.WithLabels(LabelPair{Key: "label4", Value: "value4"}).Observe(0) 174 seriesCount := 500 175 176 v.WithLabels().Observe(float64(seriesCount * 2 * 1000)) 177 for i := 0; i < seriesCount; i++ { 178 v.WithLabels(LabelPair{Key: "label1", Value: fmt.Sprintf("value_%d", i)}).Observe(float64(i * 1000)) 179 } 180 181 collector, ok := v.(MetricCollector) 182 assert.True(t, ok) 183 collectedMetrics := collector.Collect() 184 assert.Equal(t, seriesCount+1, len(collectedMetrics)) 185 186 expectedContents := []map[string]string{} 187 188 for i := 0; i < seriesCount; i++ { 189 expectedContents = append(expectedContents, map[string]string{ 190 "host": "host1", 191 "plugin_id": "3", 192 "label1": fmt.Sprintf("value_%d", i), 193 "label2": defaultTagValue, 194 "label3": defaultTagValue, 195 "label5": defaultTagValue, 196 "__name__": metricName, 197 metricName: fmt.Sprintf("%d.0000", i), 198 }) 199 } 200 201 for i, metric := range collectedMetrics { 202 latency, ok := metric.(*latencyImp) 203 assert.True(t, ok) 204 assert.Equal(t, metricName, latency.Name()) 205 records := metric.Export() 206 valueAsIndex := 0 // int(latency.Collect().Value / 1000) 207 metricName := func() string { 208 for k, v := range records { 209 if k == SelfMetricNameKey { 210 return v 211 } 212 } 213 return "" 214 }() 215 for k, v := range records { 216 if k == metricName { 217 valueAsIndexF, _ := strconv.ParseFloat(v, 64) 218 valueAsIndex = int(valueAsIndexF) 219 break 220 } 221 } 222 if valueAsIndex >= 0 && valueAsIndex < len(expectedContents) { 223 for k, v := range records { 224 if expectedContents[valueAsIndex][k] != v { 225 t.Errorf("index: %d, actual: %v vs expcted: %v", i, v, expectedContents[valueAsIndex][k]) 226 } 227 } 228 } 229 } 230 } 231 232 func Test_GaugeMetricVectorWithDynamicLabel(t *testing.T) { 233 metricName := "test_gauge_vector" 234 v := NewGaugeMetricVector(metricName, 235 map[string]string{"host": "host1", "plugin_id": "3"}, 236 []string{"label1", "label2", "label3", "label5"}, 237 ) 238 239 v.WithLabels(LabelPair{Key: "label4", Value: "value4"}).Set(0) 240 seriesCount := 500 241 v.WithLabels().Set(float64(seriesCount * 2 * 1000)) 242 243 for i := 0; i < seriesCount; i++ { 244 v.WithLabels(LabelPair{Key: "label1", Value: fmt.Sprintf("value_%d", i)}).Set(float64(i)) 245 } 246 247 collector, ok := v.(MetricCollector) 248 assert.True(t, ok) 249 collectedMetrics := collector.Collect() 250 assert.Equal(t, seriesCount+1, len(collectedMetrics)) 251 252 expectedContents := []map[string]string{} 253 254 for i := 0; i < seriesCount; i++ { 255 expectedContents = append(expectedContents, map[string]string{ 256 "host": "host1", 257 "plugin_id": "3", 258 "label1": fmt.Sprintf("value_%d", i), 259 "label2": defaultTagValue, 260 "label3": defaultTagValue, 261 "label5": defaultTagValue, 262 "__name__": metricName, 263 metricName: fmt.Sprintf("%d.0000", i), 264 }) 265 } 266 267 for i, metric := range collectedMetrics { 268 counter, ok := metric.(*gaugeImp) 269 assert.True(t, ok) 270 assert.Equal(t, metricName, counter.Name()) 271 valueAsIndex := int(counter.Collect().Value) 272 records := metric.Export() 273 if valueAsIndex >= 0 && valueAsIndex < len(expectedContents) { 274 for k, v := range records { 275 if expectedContents[valueAsIndex][k] != v { 276 t.Errorf("index: %d, actual: %v vs expcted: %v", i, v, expectedContents[valueAsIndex][k]) 277 } 278 } 279 } 280 } 281 } 282 283 func Test_StrMetricVectorWithDynamicLabel(t *testing.T) { 284 metricName := "test_str_vector" 285 v := NewStringMetricVector(metricName, 286 map[string]string{"host": "host1", "plugin_id": "3"}, 287 []string{"label1", "label2", "label3", "label5"}, 288 ) 289 290 v.WithLabels(LabelPair{Key: "label4", Value: "value4"}).Set("string") 291 seriesCount := 500 292 293 v.WithLabels().Set(strconv.Itoa(seriesCount * 2 * 1000)) 294 295 for i := 0; i < seriesCount; i++ { 296 v.WithLabels(LabelPair{Key: "label1", Value: fmt.Sprintf("value_%d", i)}).Set(strconv.Itoa(i)) 297 } 298 299 collector, ok := v.(MetricCollector) 300 assert.True(t, ok) 301 collectedMetrics := collector.Collect() 302 assert.Equal(t, seriesCount+1, len(collectedMetrics)) 303 304 expectedContents := []map[string]string{} 305 306 for i := 0; i < seriesCount; i++ { 307 expectedContents = append(expectedContents, map[string]string{ 308 "host": "host1", 309 "plugin_id": "3", 310 "label1": fmt.Sprintf("value_%d", i), 311 "label2": defaultTagValue, 312 "label3": defaultTagValue, 313 "label5": defaultTagValue, 314 "__name__": metricName, 315 metricName: strconv.Itoa(i), 316 }) 317 } 318 319 for i, metric := range collectedMetrics { 320 counter, ok := metric.(*strMetricImp) 321 assert.True(t, ok) 322 assert.Equal(t, metricName, counter.Name()) 323 valueAsIndex, err := strconv.Atoi(counter.Collect().Value) 324 assert.NoError(t, err) 325 records := metric.Export() 326 if valueAsIndex >= 0 && valueAsIndex < len(expectedContents) { 327 for k, v := range records { 328 if expectedContents[valueAsIndex][k] != v { 329 t.Errorf("index: %d, actual: %v vs expcted: %v", i, v, expectedContents[valueAsIndex][k]) 330 } 331 } 332 } 333 } 334 } 335 336 func Test_NewCounterMetricAndRegister(t *testing.T) { 337 metricsRecord := &MetricsRecord{} 338 counter := NewCumulativeCounterMetricAndRegister(metricsRecord, "test_counter") 339 counter.Add(1) 340 value := counter.Collect() 341 assert.Equal(t, 1.0, value.Value) 342 }