Skip to content

Commit 201bb52

Browse files
committed
up
1 parent b6bd3b4 commit 201bb52

File tree

2 files changed

+74
-71
lines changed

2 files changed

+74
-71
lines changed

prometheus/promsafe/safe.go

+72-69
Original file line numberDiff line numberDiff line change
@@ -21,75 +21,78 @@
2121
// The following example demonstrates how to create and use a CounterVec with
2222
// type-safe labels (compared to how it's done in a regular way):
2323
//
24-
// package main
25-
//
26-
// import (
27-
// "strconv"
28-
//
29-
// "github.com/prometheus/client_golang/prometheus"
30-
// "github.com/prometheus/client_golang/prometheus/promsafe"
31-
// )
32-
//
33-
// // Original unsafe way (no type safety)
34-
// func originalUnsafeWay() {
35-
// counterVec := prometheus.NewCounterVec(
36-
// prometheus.CounterOpts{
37-
// Name: "http_requests_total",
38-
// Help: "Total number of HTTP requests by status code and method.",
39-
// },
40-
// []string{"code", "method"}, / / Labels defined as raw strings
41-
// )
42-
//
43-
// // No compile-time checks; label order and types must be correct
44-
// // You have to know which and how many labels are expected (in proper order)
45-
// counterVec.WithLabelValues("200", "GET").Inc()
46-
//
47-
// // or you can use map, that is even more fragile
48-
// counterVect.WithLabels(prometheus.Labels{"code": "200", "method": "GET"}).Inc()
49-
// }
50-
//
51-
// // Safe way (Quick implementation, reflect-based under-the-hood)
52-
// type Labels1 struct {
53-
// promsafe.StructLabelProvider
54-
// Code int
55-
// Method string
56-
// }
57-
//
58-
// func safeReflectWay() {
59-
// counterVec := promsafe.NewCounterVec[Labels1](prometheus.CounterOpts{
60-
// Name: "http_requests_total_reflection",
61-
// Help: "Total number of HTTP requests by status code and method (reflection-based).",
62-
// })
63-
//
64-
// // Compile-time safe and readable; Will be converted into properly ordered list: "200", "GET"
65-
// counterVec.With(Labels1{Method: "GET", Code: 200}).Inc()
66-
// }
67-
//
68-
// // Safe way with manual implementation (no reflection overhead, as fast as original)
69-
// type Labels2 struct {
70-
// promsafe.StructLabelProvider
71-
// Code int
72-
// Method string
73-
// }
74-
//
75-
// func (c Labels2) ToPrometheusLabels() prometheus.Labels {
76-
// return prometheus.Labels{
77-
// "code": strconv.Itoa(c.Code), // Convert int to string
78-
// "method": c.Method,
79-
// }
80-
// }
81-
//
82-
// func (c Labels2) ToLabelNames() []string {
83-
// return []string{"code", "method"}
84-
// }
85-
//
86-
// func safeManualWay() {
87-
// counterVec := promsafe.NewCounterVec[Labels2](prometheus.CounterOpts{
88-
// Name: "http_requests_total_custom",
89-
// Help: "Total number of HTTP requests by status code and method (manual implementation).",
90-
// })
91-
// counterVec.With(Labels2{Code: 404, Method: "POST"}).Inc()
92-
// }
24+
// package main
25+
//
26+
// import (
27+
// "strconv"
28+
//
29+
// "github.com/prometheus/client_golang/prometheus"
30+
// "github.com/prometheus/client_golang/prometheus/promsafe"
31+
// )
32+
//
33+
// // Original unsafe way (no type safety)
34+
//
35+
// func originalUnsafeWay() {
36+
// counterVec := prometheus.NewCounterVec(
37+
// prometheus.CounterOpts{
38+
// Name: "http_requests_total",
39+
// Help: "Total number of HTTP requests by status code and method.",
40+
// },
41+
// []string{"code", "method"}, // Labels defined as raw strings
42+
// )
43+
//
44+
// // No compile-time checks; label order and types must be correct
45+
// // You have to know which and how many labels are expected (in proper order)
46+
// counterVec.WithLabelValues("200", "GET").Inc()
47+
//
48+
// // or you can use map, that is even more fragile
49+
// counterVec.With(prometheus.Labels{"code": "200", "method": "GET"}).Inc()
50+
// }
51+
//
52+
// // Safe way (Quick implementation, reflect-based under-the-hood)
53+
//
54+
// type Labels1 struct {
55+
// promsafe.StructLabelProvider
56+
// Code int
57+
// Method string
58+
// }
59+
//
60+
// func safeReflectWay() {
61+
// counterVec := promsafe.NewCounterVec[Labels1](prometheus.CounterOpts{
62+
// Name: "http_requests_total_reflection",
63+
// Help: "Total number of HTTP requests by status code and method (reflection-based).",
64+
// })
65+
//
66+
// // Compile-time safe and readable; Will be converted into properly ordered list: "200", "GET"
67+
// counterVec.With(Labels1{Method: "GET", Code: 200}).Inc()
68+
// }
69+
//
70+
// // Safe way with manual implementation (no reflection overhead, as fast as original)
71+
//
72+
// type Labels2 struct {
73+
// promsafe.StructLabelProvider
74+
// Code int
75+
// Method string
76+
// }
77+
//
78+
// func (c Labels2) ToPrometheusLabels() prometheus.Labels {
79+
// return prometheus.Labels{
80+
// "code": strconv.Itoa(c.Code), // Convert int to string
81+
// "method": c.Method,
82+
// }
83+
// }
84+
//
85+
// func (c Labels2) ToLabelNames() []string {
86+
// return []string{"code", "method"}
87+
// }
88+
//
89+
// func safeManualWay() {
90+
// counterVec := promsafe.NewCounterVec[Labels2](prometheus.CounterOpts{
91+
// Name: "http_requests_total_custom",
92+
// Help: "Total number of HTTP requests by status code and method (manual implementation).",
93+
// })
94+
// counterVec.With(Labels2{Code: 404, Method: "POST"}).Inc()
95+
// }
9396
//
9497
// Package promsafe also provides compatibility adapter for integration with Prometheus's
9598
// `promauto` package, ensuring seamless adoption while preserving type-safety.

prometheus/promsafe/safe_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525

2626
// These are Examples that can be treated as basic smoke tests
2727

28-
func ExampleNewCounterVecT_multiple_labels_manual() {
28+
func ExampleNewCounterVec_multiple_labels_manual() {
2929
// Manually registering with multiple labels
3030

3131
type MyCounterLabels struct {
@@ -72,7 +72,7 @@ func (f FastMyLabels) ToLabelNames() []string {
7272
return []string{"event_type", "source"}
7373
}
7474

75-
func ExampleNewCounterVecT_fast_safe_labels_provider() {
75+
func ExampleNewCounterVec_fast_safe_labels_provider() {
7676
// Note: fast labels provider has a drawback: they can't be declared as inline structs
7777
// as we need methods
7878

0 commit comments

Comments
 (0)