AddOrSetMetric - given a metric, see if there's another metric with the same labels. If not, add metric to list If yes, call mergeFn to merge the two metrics in-place, and updating existing metric
(metric *dto.Metric, mergeFn func(existing *dto.Metric, new *dto.Metric))
| 946 | // AddOrSetMetric - given a metric, see if there's another metric with the same labels. If not, add metric to list |
| 947 | // If yes, call mergeFn to merge the two metrics in-place, and updating existing metric |
| 948 | func (m *MetricMap) AddOrSetMetric(metric *dto.Metric, mergeFn func(existing *dto.Metric, new *dto.Metric)) { |
| 949 | var metricLabels []string |
| 950 | for _, labelPair := range metric.GetLabel() { |
| 951 | metricLabels = append(metricLabels, fmt.Sprintf("%s=%s", labelPair.GetName(), labelPair.GetValue())) |
| 952 | } |
| 953 | |
| 954 | metricKey := strings.Join(metricLabels, ",") |
| 955 | |
| 956 | m.lock.Lock() |
| 957 | defer m.lock.Unlock() |
| 958 | |
| 959 | if metrics, found := m.metrics[metricKey]; found { |
| 960 | // we might have hash collision, so let's iterate through the list to make sure the item is actually what we want |
| 961 | for _, existingMetric := range metrics { |
| 962 | same := m.compareLabels(existingMetric.metric.GetLabel(), metric.GetLabel()) |
| 963 | if same { |
| 964 | existingMetric.lock.Lock() |
| 965 | mergeFn(existingMetric.metric, metric) |
| 966 | existingMetric.lock.Unlock() |
| 967 | return |
| 968 | } |
| 969 | } |
| 970 | // only get there if we don't have the same metric, so let's append it |
| 971 | m.metrics[metricKey] = append(m.metrics[metricKey], &Metric{metric: metric}) |
| 972 | return |
| 973 | } |
| 974 | |
| 975 | // no such key, so let's add it |
| 976 | m.metrics[metricKey] = []*Metric{{metric: metric}} |
| 977 | } |
| 978 | |
| 979 | func (m *MetricMap) compareLabels(labels1, labels2 []*dto.LabelPair) bool { |
| 980 | if len(labels1) != len(labels2) { |
no test coverage detected