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.
|
// 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.
|
// 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.
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if clp, ok := labelProvider.(CustomLabelsProvider); ok {
|
||||||
|
return clp.ToPrometheusLabels()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: let's handle defaults as well, why not?
|
// TODO: let's handle defaults as well, why not?
|
||||||
|
|
||||||
// Here, then, it can be only a struct, that is a parent of StructLabelProvider
|
// 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)
|
// 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 {
|
func extractLabelNames(labelProvider labelsProviderMarker) []string {
|
||||||
if any(labelProvider) == nil {
|
if any(labelProvider) == nil {
|
||||||
return 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
|
// Here, then, it can be only a struct, that is a parent of StructLabelProvider
|
||||||
labels := extractLabelFromStruct(labelProvider)
|
|
||||||
labelNames := make([]string, 0, len(labels))
|
labelNames := make([]string, 0, len(labels))
|
||||||
for k := range labels {
|
for k := range labels {
|
||||||
labelNames = append(labelNames, k)
|
labelNames = append(labelNames, k)
|
||||||
|
|
|
@ -21,6 +21,10 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus/promsafe"
|
"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() {
|
func ExampleNewCounterVecT_multiple_labels_manual() {
|
||||||
// Manually registering with multiple labels
|
// Manually registering with multiple labels
|
||||||
|
|
||||||
|
@ -140,6 +144,35 @@ func ExampleNewCounterVecT_pointer_to_labels_promauto() {
|
||||||
// Output:
|
// 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() {
|
func ExampleNewCounterVecT_single_label_manual() {
|
||||||
// Manually registering with a single label
|
// Manually registering with a single label
|
||||||
// Example of usage of shorthand: no structs no generics, but one string only
|
// Example of usage of shorthand: no structs no generics, but one string only
|
||||||
|
|
Loading…
Reference in New Issue