// sanitizeLabels ensures that all the labels in groupingLabels and the // `instance` label are present in each MetricFamily in metricFamilies. The // label values from groupingLabels are set in each MetricFamily, no matter // what. After that, if the 'instance' label is not present at all in a // MetricFamily, it will be created (with an empty string as value). // // Finally, sanitizeLabels sorts the label pairs of all metrics. func sanitizeLabels( metricFamilies map[string]*dto.MetricFamily, groupingLabels map[string]string, ) { gLabelsNotYetDone := make(map[string]string, len(groupingLabels)) for _, mf := range metricFamilies { metric: for _, m := range mf.GetMetric() { for ln, lv := range groupingLabels { gLabelsNotYetDone[ln] = lv } hasInstanceLabel := false for _, lp := range m.GetLabel() { ln := lp.GetName() if lv, ok := gLabelsNotYetDone[ln]; ok { lp.Value = proto.String(lv) delete(gLabelsNotYetDone, ln) } if ln == string(model.InstanceLabel) { hasInstanceLabel = true } if len(gLabelsNotYetDone) == 0 && hasInstanceLabel { sort.Sort(prometheus.LabelPairSorter(m.Label)) continue metric } } for ln, lv := range gLabelsNotYetDone { m.Label = append(m.Label, &dto.LabelPair{ Name: proto.String(ln), Value: proto.String(lv), }) if ln == string(model.InstanceLabel) { hasInstanceLabel = true } delete(gLabelsNotYetDone, ln) // To prepare map for next metric. } if !hasInstanceLabel { m.Label = append(m.Label, &dto.LabelPair{ Name: proto.String(string(model.InstanceLabel)), Value: proto.String(""), }) } sort.Sort(prometheus.LabelPairSorter(m.Label)) } } }
// sanitizeLabels ensures that all the labels in groupingLabels and // requiredLabels are present in each MetricFamily in metricFamilies. The label // values from groupingLabels are set in each MetricFamily, no matter what. In // contrast, requiredLabels contains only label names and no label values. Only // if any of those labels are not present at all in a MetricFamily, they will be // created (with an empty string as value). // // Finally, sanitizeLabels sorts the label pairs of all metrics. func sanitizeLabels( metricFamilies map[string]*dto.MetricFamily, groupingLabels map[string]string, requiredLabels map[string]struct{}, ) { gLabelsNotYetDone := make(map[string]string, len(groupingLabels)) rLabelsNotYetDone := make(map[string]struct{}, len(requiredLabels)) for _, mf := range metricFamilies { metric: for _, m := range mf.GetMetric() { for ln, lv := range groupingLabels { gLabelsNotYetDone[ln] = lv } for ln := range requiredLabels { rLabelsNotYetDone[ln] = struct{}{} } for _, lp := range m.GetLabel() { ln := lp.GetName() delete(rLabelsNotYetDone, ln) if lv, ok := gLabelsNotYetDone[ln]; ok { lp.Value = proto.String(lv) delete(gLabelsNotYetDone, ln) } if len(gLabelsNotYetDone)+len(rLabelsNotYetDone) == 0 { sort.Sort(prometheus.LabelPairSorter(m.Label)) continue metric } } for ln, lv := range gLabelsNotYetDone { m.Label = append(m.Label, &dto.LabelPair{ Name: proto.String(ln), Value: proto.String(lv), }) delete(rLabelsNotYetDone, ln) delete(gLabelsNotYetDone, ln) // To prepare map for next metric. } for ln := range rLabelsNotYetDone { m.Label = append(m.Label, &dto.LabelPair{ Name: proto.String(ln), Value: proto.String(""), }) delete(rLabelsNotYetDone, ln) // To prepare map for next metric. } sort.Sort(prometheus.LabelPairSorter(m.Label)) } } }
func ExampleLabelPairSorter() { labelPairs := []*dto.LabelPair{ &dto.LabelPair{Name: proto.String("status"), Value: proto.String("404")}, &dto.LabelPair{Name: proto.String("method"), Value: proto.String("get")}, } sort.Sort(prometheus.LabelPairSorter(labelPairs)) fmt.Println(labelPairs) // Output: // [name:"method" value:"get" name:"status" value:"404" ] }