promauto: make it available to avoid reflect when building labels
Signed-off-by: Eugene <eugene@amberpixels.io>
This commit is contained in:
parent
83a2a655ae
commit
5b52b012e1
|
@ -43,6 +43,13 @@ func SetupGlobalPromauto(factoryArg ...promauto.Factory) {
|
|||
}
|
||||
}
|
||||
|
||||
// CustomLabelsProvider is an interface that allows to convert anything to a prometheus.Labels
|
||||
// It allows to provide your own FAST implementation of Struct->prometheus.Labels conversion
|
||||
// without using reflection.
|
||||
type CustomLabelsProvider interface {
|
||||
ToPrometheusLabels() prometheus.Labels
|
||||
}
|
||||
|
||||
// promsafeTag is the tag name used for promsafe labels inside structs.
|
||||
// The tag is optional, as if not present, field is used with snake_cased FieldName.
|
||||
// It's useful to use a tag when you want to override the default naming or exclude a field from the metric.
|
||||
|
@ -273,6 +280,10 @@ func extractLabelsWithValues(labelProvider labelsProviderMarker) prometheus.Labe
|
|||
return nil
|
||||
}
|
||||
|
||||
if clp, ok := labelProvider.(CustomLabelsProvider); ok {
|
||||
return clp.ToPrometheusLabels()
|
||||
}
|
||||
|
||||
// TODO: let's handle defaults as well, why not?
|
||||
|
||||
// Here, then, it can be only a struct, that is a parent of StructLabelProvider
|
||||
|
@ -291,13 +302,20 @@ func extractLabelValues(labelProvider labelsProviderMarker) []string {
|
|||
}
|
||||
|
||||
// extractLabelNames extracts labels names from a given labelsProviderMarker (parent instance of aStructLabelProvider)
|
||||
// Deprecated: refactor is required. Order of result slice is not guaranteed.
|
||||
func extractLabelNames(labelProvider labelsProviderMarker) []string {
|
||||
if any(labelProvider) == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var labels prometheus.Labels
|
||||
if clp, ok := labelProvider.(CustomLabelsProvider); ok {
|
||||
labels = clp.ToPrometheusLabels()
|
||||
} else {
|
||||
labels = extractLabelFromStruct(labelProvider)
|
||||
}
|
||||
|
||||
// Here, then, it can be only a struct, that is a parent of StructLabelProvider
|
||||
labels := extractLabelFromStruct(labelProvider)
|
||||
labelNames := make([]string, 0, len(labels))
|
||||
for k := range labels {
|
||||
labelNames = append(labelNames, k)
|
||||
|
|
|
@ -21,6 +21,10 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus/promsafe"
|
||||
)
|
||||
|
||||
// Important: This is not a test file. These are only examples!
|
||||
// These can be considered smoke tests, but nothing more.
|
||||
// TODO: Write real tests
|
||||
|
||||
func ExampleNewCounterVecT_multiple_labels_manual() {
|
||||
// Manually registering with multiple labels
|
||||
|
||||
|
@ -140,6 +144,35 @@ func ExampleNewCounterVecT_pointer_to_labels_promauto() {
|
|||
// Output:
|
||||
}
|
||||
|
||||
// FastMyLabels is a struct that will have a custom method that converts to prometheus.Labels
|
||||
type FastMyLabels struct {
|
||||
promsafe.StructLabelProvider
|
||||
EventType string
|
||||
Source string
|
||||
}
|
||||
|
||||
// ToPrometheusLabels does a fast conversion to labels. No reflection involved.
|
||||
func (f FastMyLabels) ToPrometheusLabels() prometheus.Labels {
|
||||
return prometheus.Labels{"event_type": f.EventType, "source": f.Source}
|
||||
}
|
||||
|
||||
func ExampleNewCounterVecT_fast_safe_labels_provider() {
|
||||
// It's possible to use pointer to labels struct
|
||||
myReg := prometheus.NewRegistry()
|
||||
|
||||
counterOpts := prometheus.CounterOpts{
|
||||
Name: "items_counted_fast",
|
||||
}
|
||||
|
||||
c := promsafe.WithAuto[FastMyLabels](myReg).NewCounterVecT(counterOpts)
|
||||
|
||||
c.With(FastMyLabels{
|
||||
EventType: "reservation", Source: "source1",
|
||||
}).Inc()
|
||||
|
||||
// Output:
|
||||
}
|
||||
|
||||
func ExampleNewCounterVecT_single_label_manual() {
|
||||
// Manually registering with a single label
|
||||
// Example of usage of shorthand: no structs no generics, but one string only
|
||||
|
|
Loading…
Reference in New Issue