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  }