| package scruffy | 
 |  | 
 | import ( | 
 | 	"github.com/prometheus/client_golang/prometheus" | 
 |  | 
 | 	"source.monogon.dev/go/algorithm/cartesian" | 
 | ) | 
 |  | 
 | // A labelDefinition describes a key/value pair that's a metric dimension. It | 
 | // consists of the label key/name (a string), and a list of possible values of | 
 | // this key. The list of values will be used to initialize the metrics at startup | 
 | // with zero values. | 
 | // | 
 | // The initialValues system is intended to be used with labels that are | 
 | // low-cardinality enums, e.g. the name of a subsystem. | 
 | // | 
 | // All labelDefinitions for a single metric will then create a cartesian product | 
 | // of all initialValues. | 
 | type labelDefinition struct { | 
 | 	// name/key of the label. | 
 | 	name string | 
 | 	// initialValues defines the default values for this label key/name that will be | 
 | 	// used to generate a list of initial zero-filled metrics. | 
 | 	initialValues []string | 
 | } | 
 |  | 
 | // labelDefinitions is a list of labelDefinition which define the label | 
 | // dimensions of a metric. All the initialValues of the respective | 
 | // labelDefinitions will create a cartesian set of default zero-filled metric | 
 | // values when the metric susbsystem gets initialized. These zero values will | 
 | // then get overridden by real data as it is collected. | 
 | type labelDefinitions []labelDefinition | 
 |  | 
 | // initialLabels generates the list of initial labels key/values that should be | 
 | // used to generate zero-filled metrics on startup. This is a cartesian product | 
 | // of all initialValues of all labelDefinitions. | 
 | func (l labelDefinitions) initialLabels() []prometheus.Labels { | 
 | 	// Nothing to do if this is an empty labelDefinitions. | 
 | 	if len(l) == 0 { | 
 | 		return nil | 
 | 	} | 
 |  | 
 | 	// Given: | 
 | 	// | 
 | 	// labelDefinitions := []labelDefinition{ | 
 | 	//    { name: "a", initialValues: []string{"foo", "bar"}}, | 
 | 	//    { name: "b", initialValues: []string{"baz", "barf"}}, | 
 | 	// } | 
 | 	// | 
 | 	// This creates: | 
 | 	// | 
 | 	// values := []string{ | 
 | 	//    { "foo", "bar" }, // label 'a' | 
 | 	//    { "baz", "barf" }, // label 'b' | 
 | 	// } | 
 | 	var values [][]string | 
 | 	for _, ld := range l { | 
 | 		values = append(values, ld.initialValues) | 
 | 	} | 
 |  | 
 | 	// Given the above: | 
 | 	// | 
 | 	// valuesProduct := []string{ | 
 | 	//    //  a      b | 
 | 	//    { "foo", "baz" }, | 
 | 	//    { "foo", "barf" }, | 
 | 	//    { "bar", "baz" }, | 
 | 	//    { "bar", "barf" }, | 
 | 	// } | 
 | 	valuesProduct := cartesian.Product[string](values...) | 
 |  | 
 | 	// This converts valuesProduct into an actual prometheus-compatible type, | 
 | 	// re-attaching the label names back into the columns as seen above. | 
 | 	var res []prometheus.Labels | 
 | 	for _, vp := range valuesProduct { | 
 | 		labels := make(prometheus.Labels) | 
 | 		for i, lv := range vp { | 
 | 			labelDef := l[i] | 
 | 			labels[labelDef.name] = lv | 
 | 		} | 
 | 		res = append(res, labels) | 
 | 	} | 
 | 	return res | 
 | } | 
 |  | 
 | // names returns the keys/names of all the metric labels from these | 
 | // labelDefinitions. | 
 | func (l labelDefinitions) names() []string { | 
 | 	var res []string | 
 | 	for _, ld := range l { | 
 | 		res = append(res, ld.name) | 
 | 	} | 
 | 	return res | 
 | } |