Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add constrained labels and Constrained variant for all MetricVecs #1151

Merged
merged 2 commits into from
Dec 13, 2022

Conversation

Okhoshi
Copy link
Contributor

@Okhoshi Okhoshi commented Oct 21, 2022

Constrained variants of MetricVec provides a way to restrict the possible values a label can take, to prevent cardinality explosion when the label value comes from a non-trusted source (as a user input or HTTP header).

Extracted from discussions on #1066

@bwplotka @kakkoyun

Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally great! Just some suggestions ideas for simpler API. Thanks!

prometheus/counter.go Outdated Show resolved Hide resolved
prometheus/desc.go Outdated Show resolved Hide resolved
prometheus/desc.go Outdated Show resolved Hide resolved
prometheus/desc.go Outdated Show resolved Hide resolved
@Okhoshi Okhoshi requested a review from bwplotka October 26, 2022 08:46
@bwplotka
Copy link
Member

bwplotka commented Oct 31, 2022

Some alternatives we might have:

func TestConstrained(t *testing.T) {
	constrained := ConstrainedLabels{
		"c": func(s string) string {
			switch s {
			case "value1":
				return s
			default:
				return "unspecified"
			}
		},
	}

	// Option 1: Wrap registry.
	// Cons: We can't validate WithLabelValues(...)
	{
		r := NewRegistry()
		r = WrapRegistererWithConstrained(constrained, r)
		c := NewCounterVec(CounterOpts{Name: "yolo"}, []string{"a"})
		c2 := NewCounter(CounterOpts{Name: "yolo2"})
		r.MustRegister(c, c2)
	}

	// Option 2a: New function
	// Cons: Weird when we want to have metric with only constrained dynamic labels
	{
		r := NewRegistry()
		c := NewConstrainedCounterVec(CounterOpts{Name: "yolo"}, []string{"a"}, constrained)
		c2 := NewConstrainedCounterVec(CounterOpts{Name: "yolo2"}, nil, constrained)
		r.MustRegister(c, c2)
	}
	// Option 2b: New function with mapping (initial idea)
	// Cons: Complex init code, extra TWO functions to each metric type, not easy to configure mapping between dynamic label name and its constraints, weird UX - might be not clear we are mapping values not adding new ones with the set.
	{
		r := NewRegistry()
		c := NewConstrainedCounterVec(CounterOpts{Name: "yolo"}, []string{"a", "c"}, constrained)
		c2 := NewConstrainedCounterVec(CounterOpts{Name: "yolo2"}, []string{"a"}, constrained)
		r.MustRegister(c, c2)
	}

	// Option 3a: WrapCounter (func WrapCounterWithConstrainedLabel(c interface{}, labels ConstrainedLabels) *CounterVec {)
	// Pros: One wrapper per metric type.
	// Cons: Yet another way to define new label
	{
		r := NewRegistry()
		c := WrapCounterWithConstrainedLabels(NewCounterVec(CounterOpts{Name: "yolo"}, []string{"a"}), constrained)
		c2 := WrapCounterWithConstrainedLabel(NewCounter(CounterOpts{Name: "yolo2"}), constrained)
		r.MustRegister(c, c2)
	}
	// Option 3b: WrapCounter with mapping
	// Pros: One wrapper per metric type.
	// Cons: Yet another way to define new label, same as 2b
	{
		r := NewRegistry()
		c := WrapCounterWithConstrainedLabels(NewCounterVec(CounterOpts{Name: "yolo"}, []string{"a", "b"}), constrained)
		c2 := WrapCounterWithConstrainedLabel(NewCounter(CounterOpts{Name: "yolo2"}), []string{"a"}, constrained)
		r.MustRegister(c, c2)
	}

	// Option 4: New function with redefined API - variadic (perhaps in another package).
	{
		r := NewRegistry()
		c := NewCounterVec2(CounterOpts{Name: "yolo"}, WithCounterVecLabels("a", "b"), WithCounterVecConstrainedLabels(constrained))
		c2 := NewCounterVec2(CounterOpts{Name: "yolo2"}, WithCounterVecLabels("a"), WithCounterVecConstrainedLabels(constrained))
		r.MustRegister(c, c2)
	}

	// Option 5: New function with redefined API - struct (perhaps in another package).
	{
		r := NewRegistry()
		c := NewCounterVec3(CounterVecOpts{Name: "yolo", VariableLabels: []string{"a", "b"}, ConstrainedLabels: constrained})
		c2 := NewCounterVec3(CounterVecOpts{Name: "yolo2", VariableLabels: []string{"a"}, ConstrainedLabels: constrained})
		r.MustRegister(c, c2)
	}
}

type ConstrainedLabel func(string) string
type ConstrainedLabels map[string]ConstrainedLabel

type CounterVecOpts struct {
	Namespace string
	Subsystem string
	Name      string

	Help string

	ConstLabels       Labels
	VariableLabels    []string
	ConstrainedLabels ConstrainedLabels
}

None of the ideas are perfect (: However Option 5 seems to be the cleanest 🤔 arguments for:

Pros:

  • Follow client golang patterns (configuring things via opts)
  • Extensible

We can also do 5b - so where ConstainedLabels could be change to Constrains of existing Labels in VariableLabels, but to me this is more confusing and harder to implement.

WDYT?

@bwplotka
Copy link
Member

Apart from those options I wonder if func(string) string is enough - I wonder if we want another logic to panic/error on certain cardinality. I guess It's fine, error might be handled by implementation of func(string) string through some side effect.

@bwplotka
Copy link
Member

cc @beorn7

@Okhoshi
Copy link
Contributor Author

Okhoshi commented Oct 31, 2022

Apart from those options I wonder if func(string) string is enough - I wonder if we want another logic to panic/error on certain cardinality. I guess It's fine, error might be handled by implementation of func(string) string through some side effect.

For me, the logic to not return error was that we always reduce to some known values. If some values are completely unacceptable, there's still the option to panic inside the func(string) string or to validate the values before passing them to the WithLabels.

@Okhoshi
Copy link
Contributor Author

Okhoshi commented Oct 31, 2022

Some alternatives we might have:

[code stripped for readability]

None of the ideas are perfect (: However Option 5 seems to be the cleanest 🤔 arguments for:

Pros:

  • Follow client golang patterns (configuring things via opts)
  • Extensible

We can also do 5b - so where ConstainedLabels could be change to Constrains of existing Labels in VariableLabels, but to me this is more confusing and harder to implement.

WDYT?

I like Option 4 and 5, for their extensibility and that they are known patterns. The choice between the two is essentially a question of personal taste I guess. We could have them in a separate package until v2 where we could make them default, WDYT ?

I also agree on the better readability if we don't merge variableLabels and constrainedLabels, having them completely separated and panicking if they overlap seems the most predictable and understandable way to manage them.
In that case, we only need to define the behaviour of WithLabelValues since one doesn't the label names, only the values. The most logical way would be to keep the ordering of variableLabels and then the ordering of constrainedLabels.

Just to make sure I'm on the same page as you, constrainedLabels are not applicable to the single Metrics types (Counter, Gauge, ...), are they ?

@bwplotka
Copy link
Member

I like Option 4 and 5, for their extensibility and that they are known patterns. The choice between the two is essentially a question of personal taste I guess. We could have them in a separate package until v2 where we could make them default, WDYT ?

Yea, I think Opt 5 is equally explicit and less verbose perhaps, so probably better?

In that case, we only need to define the behaviour of WithLabelValues since one doesn't the label names, only the values. The most logical way would be to keep the ordering of variableLabels and then the ordering of constrainedLabels.

You are totally right, this might cause confusion... I thought as you proposed, but it's not very explicit (someone might add constainedLabel fields above variable label fields in their definition). This is definitely Pros of your approach of setting constraints to existing variable labels. Another trade-off (:

Just to make sure I'm on the same page as you, constrainedLabels are not applicable to the single Metrics types (Counter, Gauge, ...), are they ?

If we assume non-mapping approach (separate label names to variableLabels) - they are not applicable to non Vectors.

@Okhoshi
Copy link
Contributor Author

Okhoshi commented Nov 1, 2022

Yea, I think Opt 5 is equally explicit and less verbose perhaps, so probably better?

I agree, let's start with Opt5 then 👍

You are totally right, this might cause confusion... I thought as you proposed, but it's not very explicit (someone might add constainedLabel fields above variable label fields in their definition). This is definitely Pros of your approach of setting constraints to existing variable labels. Another trade-off (:

Definitely not an easy task to define this new API 😅
Instead of splitting them completely, we could also merge them completely. And since we opt for Opt5, it gives us some freedom to redefine how we achieve this.

type ConstrainedLabel struct {
  Name         string
  Constraint func(string)string
}

type CounterVecOpts struct {
  CounterOpts
  VariableLabels []ConstrainedLabel
}

// ---

prometheus.V2().NewCounterVec(CounterVecOpts{
  ..., // Usual CounterOpts stuff
  VariableLabels: []ConstrainedLabels{
    {Name: "A"},
    {Name: "B", Constraint: func(v string) string { ... }},
  },
})

Compared to the suggestion I made on Slack, I moved to an array because maps do not preserve key order.

WDYT ?

@Okhoshi Okhoshi force-pushed the constrainedlabels branch 2 times, most recently from 08cbd6f to baed670 Compare November 7, 2022 22:07
@beorn7
Copy link
Member

beorn7 commented Nov 18, 2022

I was too busy to look at this all week. Maybe I'll find time next week. But feel free to move forward without me.

@beorn7
Copy link
Member

beorn7 commented Nov 24, 2022

Finally I had a bit of time to look at it.

I haven't checked correctness (i.e. "is it doing what we expect it to do?"). I assume you are on top of that anyway.

Interesting approach with the V2 variable. Do you know of any other applications of this pattern? It looks intriguing, but it would be even better if this has already been tried elsewhere.

In general, I'm OK with this. I'll elaborate on one more idea in the next comment, but feel free to go ahead as is.

@beorn7
Copy link
Member

beorn7 commented Nov 24, 2022

This whole thing reminds me of ancient thoughts I had about revamping labels. One was about somehow automating the instantiation of all the possible vector elements, which is something that is recommended to do manually right now. Here is an example from the client_golang code itself:

	cnt := prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "promhttp_metric_handler_requests_total",
			Help: "Total number of scrapes by HTTP status code.",
		},
		[]string{"code"},
	)
	// Initialize the most likely HTTP status codes.
	cnt.WithLabelValues("200")
	cnt.WithLabelValues("500")
	cnt.WithLabelValues("503")

Now imagine the code label above being a ConstrainedLabel that normalizes all label values to either 200, 500, 503, or other.

Imagine further that the ConstrainedLabel type looks like this:

type ConstrainedLabel struct {
	Name       string
	Constraint func(string) string
	Values     func() []string
}

If Values returns a non-empty slice, the slice contains all possible label values.

And now we have all the parts in place: If a vector has only constant and constrained labels, of which all have a Values function that returns a non-empty slice, the code can automatically create the cartesian product of all labels and initialize all vector elements.

WDYT?

@Okhoshi
Copy link
Contributor Author

Okhoshi commented Nov 25, 2022

And now we have all the parts in place: If a vector has only constant and constrained labels, of which all have a Values function that returns a non-empty slice, the code can automatically create the cartesian product of all labels and initialize all vector elements.

WDYT?

I really loves the idea ! Instantiating all the possibles combinations always add some boilerplate code we could indeed automate in this case.

However, I'm not really sure to see how we could enforce that Constraint won't ever return something else than an element of Values ?
And is there any reason to make Values a function that returns []string instead of the slice itself ?

Also, there's situation where the Cartesian product of all labels is larger than the actual set of label combinations, because some combinations may be impossible, we couldn't do anything about that though.

@bwplotka
Copy link
Member

bwplotka commented Nov 28, 2022

Hm, I like the idea of reusing some concepts around instantiation, although arguably AFAIK those concepts might go away if we implement _created timestamp in OM. 🙈

On top of that, automation feels like the second step. The first should be to define the API for constraints. I am a bit afraid of putting Values items. Do we really need to force everyone to expose hundreds status code metrics, because constraints allow max 100, when during execution only 200 and 500 codes were seen for weeks, so only 2 metrics could suffice?

@beorn7
Copy link
Member

beorn7 commented Nov 29, 2022

However, I'm not really sure to see how we could enforce that Constraint won't ever return something else than an element of Values ?

That would be the contract of the interface. Go's type system is not powerful enough to let the compiler enforce it, but that shouldn't keep us from using such a contract, should it?

And is there any reason to make Values a function that returns []string instead of the slice itself ?

I guess the reason is that I thought of ConstrainedLabel as an interface, but it is, in fact, a struct. (Maybe it should be an interface? Not sure…) So yes, if ConstrainedLabel remains a struct, with the name as a field (rather than a method), then Values should just be a field, too.

On top of that, automation feels like the second step. The first should be to define the API for constraints.

Sure. But we should design the API now in a way that it allows this kind of automation without a breaking change.
(Which means we might need a boolean to switch the behavior on explicitly if we introduce it later.)

Do we really need to force everyone to expose hundreds status code metrics, because constraints allow max 100, when during execution only 200 and 500 codes were seen for weeks, so only 2 metrics could suffice?

First of all, we could make the auto-initialization an opt-in, see above.

But to think a bit further: In the cleanest Prometheus semantics, you want to initialize all metrics in a vector in advance. Having "rare" status codes only show up when they actually occur is indeed a smell (the "springing into existence with a value of one" problem is not the only problem with that). In practice, we cannot always predict all future label values in advance, so we have to live with the situation. However, with constrained labels in the game, we do know all possible label values in advance, so we can initialize the full metrics vector. I would also argue that the situation where you require the label values to be constrained is likely also a situation where you want clean semantics.

On the other hand, if you want to use a constrained label merely to check if an HTTP status code is "syntactically correct" (three digit number), then you wouldn't populate the Values slice anyway, and the auto-init wouldn't kick in.

If you want to use a constrained label to make sure it only has a very constrained set of label values (e.g. 200, 500, other), then you would populate the Values slice and get the auto-init out of the box.

So maybe we don't need an opt-in flag, if we say you "opt in" by populating the Values slice.

@Okhoshi
Copy link
Contributor Author

Okhoshi commented Dec 4, 2022

I guess the reason is that I thought of ConstrainedLabel as an interface, but it is, in fact, a struct. (Maybe it should be an interface? Not sure…) So yes, if ConstrainedLabel remains a struct, with the name as a field (rather than a method), then Values should just be a field, too.

I don't really see any reason to make ConstrainedLabel an interface, but would be happy to be proven wrong 👍

But we should design the API now in a way that it allows this kind of automation without a breaking change.

It seems to me that the current design is flexible enough to be extended in the future to support such automation.

Could we go further with this MR as is then ?

@beorn7
Copy link
Member

beorn7 commented Dec 6, 2022

Could we go further with this MR as is then ?

Seems fine to me.

Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks clean! Some comments otherwise LGTM. I asked on Gopher slack about out V2 pattern - maybe we can get some quick feedback.

Thanks 💪🏽

cc @kakkoyun

prometheus/counter_test.go Show resolved Hide resolved
prometheus/labels.go Outdated Show resolved Hide resolved
prometheus/labels.go Outdated Show resolved Hide resolved
prometheus/vnext.go Show resolved Hide resolved
prometheus/labels.go Outdated Show resolved Hide resolved
prometheus/labels.go Outdated Show resolved Hide resolved
prometheus/labels.go Outdated Show resolved Hide resolved
prometheus/labels.go Outdated Show resolved Hide resolved
prometheus/labels.go Show resolved Hide resolved
Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work, thanks!

Important comment about V2 struct is missing, otherwise it's good to merge, thanks!

prometheus/vnext.go Show resolved Hide resolved
prometheus/vnext.go Show resolved Hide resolved
MetricVecOpts exposes options specific to MetricVec initialisation. The
first option exposed by MetricVecOpts are constraints on VariableLabels,
allowing restrictions on the possible values a label can take, to
prevent cardinality explosion when the label value comes from a
non-trusted source (as a user input or HTTP header).

Signed-off-by: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
Signed-off-by: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💪🏽

@bwplotka bwplotka merged commit fae2f63 into prometheus:main Dec 13, 2022
@Okhoshi Okhoshi deleted the constrainedlabels branch December 13, 2022 13:09
apricote referenced this pull request in hetznercloud/hcloud-cloud-controller-manager Apr 13, 2023
….0 (#424)

[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[github.com/prometheus/client_golang](https://togithub.com/prometheus/client_golang)
| require | minor | `v1.14.0` -> `v1.15.0` |

---

### Release Notes

<details>
<summary>prometheus/client_golang</summary>

###
[`v1.15.0`](https://togithub.com/prometheus/client_golang/releases/tag/v1.15.0)

[Compare
Source](https://togithub.com/prometheus/client_golang/compare/v1.14.0...v1.15.0)

#### Changed

\[BUGFIX] Fix issue with atomic variables on ppc64le
[#&#8203;1171](https://togithub.com/prometheus/client_golang/issues/1171)
\[BUGFIX] Support for multiple samples within same metric
[#&#8203;1181](https://togithub.com/prometheus/client_golang/issues/1181)
\[BUGFIX] Bump golang.org/x/text to v0.3.8 to mitigate CVE-2022-32149
[#&#8203;1187](https://togithub.com/prometheus/client_golang/issues/1187)
\[ENHANCEMENT] Add exemplars and middleware examples
[#&#8203;1173](https://togithub.com/prometheus/client_golang/issues/1173)
\[ENHANCEMENT] Add more context to "duplicate label names" error to
enable debugging
[#&#8203;1177](https://togithub.com/prometheus/client_golang/issues/1177)
\[ENHANCEMENT] Add constrained labels and constrained variant for all
MetricVecs
[#&#8203;1151](https://togithub.com/prometheus/client_golang/issues/1151)
\[ENHANCEMENT] Moved away from deprecated github.com/golang/protobuf
package
[#&#8203;1183](https://togithub.com/prometheus/client_golang/issues/1183)
\[ENHANCEMENT] Add possibility to dynamically get label values for http
instrumentation
[#&#8203;1066](https://togithub.com/prometheus/client_golang/issues/1066)
\[ENHANCEMENT] Add ability to Pusher to add custom headers
[#&#8203;1218](https://togithub.com/prometheus/client_golang/issues/1218)
\[ENHANCEMENT] api: Extend and improve efficiency of json-iterator usage
[#&#8203;1225](https://togithub.com/prometheus/client_golang/issues/1225)
\[ENHANCEMENT] Added (official) support for go 1.20
[#&#8203;1234](https://togithub.com/prometheus/client_golang/issues/1234)
\[ENHANCEMENT] timer: Added support for exemplars
[#&#8203;1233](https://togithub.com/prometheus/client_golang/issues/1233)
\[ENHANCEMENT] Filter expected metrics as well in CollectAndCompare
[#&#8203;1143](https://togithub.com/prometheus/client_golang/issues/1143)
\[ENHANCEMENT] ⚠️ Only set start/end if time is not Zero. This breaks
compatibility in experimental api package. If you strictly depend on
empty time.Time as actual value, the behavior is now changed
[#&#8203;1238](https://togithub.com/prometheus/client_golang/issues/1238)

<details>
  <summary>All commits</summary>

- Merge release 1.14 to main by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1164](https://togithub.com/prometheus/client_golang/pull/1164)
- Fix typo in doc comment by
[@&#8203;beorn7](https://togithub.com/beorn7) in
[https://github.com/prometheus/client_golang/pull/1166](https://togithub.com/prometheus/client_golang/pull/1166)
- Fix issue with atomic variables on ppc64le by
[@&#8203;beorn7](https://togithub.com/beorn7) in
[https://github.com/prometheus/client_golang/pull/1171](https://togithub.com/prometheus/client_golang/pull/1171)
- examples: Add exemplars and middleware examples by
[@&#8203;jessicalins](https://togithub.com/jessicalins) in
[https://github.com/prometheus/client_golang/pull/1173](https://togithub.com/prometheus/client_golang/pull/1173)
- Add context to "duplicate label names" to enable debugging by
[@&#8203;SpencerMalone](https://togithub.com/SpencerMalone) in
[https://github.com/prometheus/client_golang/pull/1177](https://togithub.com/prometheus/client_golang/pull/1177)
- Add constrained labels and Constrained variant for all MetricVecs by
[@&#8203;Okhoshi](https://togithub.com/Okhoshi) in
[https://github.com/prometheus/client_golang/pull/1151](https://togithub.com/prometheus/client_golang/pull/1151)
- Support for multiple samples within same metric by
[@&#8203;machadovilaca](https://togithub.com/machadovilaca) in
[https://github.com/prometheus/client_golang/pull/1181](https://togithub.com/prometheus/client_golang/pull/1181)
- Replace deprecated github.com/golang/protobuf package by
[@&#8203;zhsj](https://togithub.com/zhsj) in
[https://github.com/prometheus/client_golang/pull/1183](https://togithub.com/prometheus/client_golang/pull/1183)
- Bump golang.org/x/text to v0.3.8 to mitigate CVE-2022-32149 by
[@&#8203;b4bay](https://togithub.com/b4bay) in
[https://github.com/prometheus/client_golang/pull/1187](https://togithub.com/prometheus/client_golang/pull/1187)
- typo fix by
[@&#8203;ibreakthecloud](https://togithub.com/ibreakthecloud) in
[https://github.com/prometheus/client_golang/pull/1178](https://togithub.com/prometheus/client_golang/pull/1178)
- Add possibility to dynamically get label values for http
instrumentation by [@&#8203;Okhoshi](https://togithub.com/Okhoshi) in
[https://github.com/prometheus/client_golang/pull/1066](https://togithub.com/prometheus/client_golang/pull/1066)
- Bump github.com/cespare/xxhash/v2 from 2.1.2 to 2.2.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1199](https://togithub.com/prometheus/client_golang/pull/1199)
- Bump github.com/prometheus/procfs from 0.8.0 to 0.9.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1198](https://togithub.com/prometheus/client_golang/pull/1198)
- Bump golang.org/x/sys from 0.3.0 to 0.4.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1217](https://togithub.com/prometheus/client_golang/pull/1217)
- Synchronize common files from prometheus/prometheus by
[@&#8203;prombot](https://togithub.com/prombot) in
[https://github.com/prometheus/client_golang/pull/1213](https://togithub.com/prometheus/client_golang/pull/1213)
- Bump github.com/prometheus/common from 0.37.0 to 0.39.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1197](https://togithub.com/prometheus/client_golang/pull/1197)
- Add `Header` method to Pusher for custom header by
[@&#8203;songjiayang](https://togithub.com/songjiayang) in
[https://github.com/prometheus/client_golang/pull/1218](https://togithub.com/prometheus/client_golang/pull/1218)
- Synchronize common files from prometheus/prometheus by
[@&#8203;prombot](https://togithub.com/prombot) in
[https://github.com/prometheus/client_golang/pull/1224](https://togithub.com/prometheus/client_golang/pull/1224)
- api: Extend and improve json-iterator usage by
[@&#8203;beorn7](https://togithub.com/beorn7) in
[https://github.com/prometheus/client_golang/pull/1225](https://togithub.com/prometheus/client_golang/pull/1225)
- Indent example in godoc consistently by
[@&#8203;lamida](https://togithub.com/lamida) in
[https://github.com/prometheus/client_golang/pull/1226](https://togithub.com/prometheus/client_golang/pull/1226)
- Remove unnecessary check if label is nil in observeWithExemplar by
[@&#8203;dimonl](https://togithub.com/dimonl) in
[https://github.com/prometheus/client_golang/pull/1235](https://togithub.com/prometheus/client_golang/pull/1235)
- README: Remove not working gocoverage images. by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1236](https://togithub.com/prometheus/client_golang/pull/1236)
- Added support for go 1.20. by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1234](https://togithub.com/prometheus/client_golang/pull/1234)
- timer: Added support for exemplars. by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1233](https://togithub.com/prometheus/client_golang/pull/1233)
- Synchronize common files from prometheus/prometheus by
[@&#8203;prombot](https://togithub.com/prombot) in
[https://github.com/prometheus/client_golang/pull/1237](https://togithub.com/prometheus/client_golang/pull/1237)
- Filter expected metrics as well in CollectAndCompare by
[@&#8203;DariaKunoichi](https://togithub.com/DariaKunoichi) in
[https://github.com/prometheus/client_golang/pull/1143](https://togithub.com/prometheus/client_golang/pull/1143)
- Only set start/end if time is not Zero by
[@&#8203;jacksontj](https://togithub.com/jacksontj) in
[https://github.com/prometheus/client_golang/pull/1238](https://togithub.com/prometheus/client_golang/pull/1238)
- Bump google.golang.org/protobuf from 1.28.1 to 1.30.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1243](https://togithub.com/prometheus/client_golang/pull/1243)
- Bump golang.org/x/sys from 0.5.0 to 0.6.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1246](https://togithub.com/prometheus/client_golang/pull/1246)
- Bump github.com/golang/protobuf from 1.5.2 to 1.5.3 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1245](https://togithub.com/prometheus/client_golang/pull/1245)
- Bump github.com/prometheus/common from 0.41.0 to 0.42.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1244](https://togithub.com/prometheus/client_golang/pull/1244)
- Cut v1.15.0 by [@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1249](https://togithub.com/prometheus/client_golang/pull/1249)

</details>

#### New Contributors
* @&#8203;SpencerMalone made their first
contributi[https://github.com/prometheus/client_golang/pull/1177](https://togithub.com/prometheus/client_golang/pull/1177)l/1177
* @&#8203;Okhoshi made their first
contributi[https://github.com/prometheus/client_golang/pull/1151](https://togithub.com/prometheus/client_golang/pull/1151)l/1151
* @&#8203;machadovilaca made their first
contributi[https://github.com/prometheus/client_golang/pull/1181](https://togithub.com/prometheus/client_golang/pull/1181)l/1181
* @&#8203;b4bay made their first
contributi[https://github.com/prometheus/client_golang/pull/1187](https://togithub.com/prometheus/client_golang/pull/1187)l/1187
* @&#8203;ibreakthecloud made their first
contributi[https://github.com/prometheus/client_golang/pull/1178](https://togithub.com/prometheus/client_golang/pull/1178)l/1178
* @&#8203;songjiayang made their first
contributi[https://github.com/prometheus/client_golang/pull/1218](https://togithub.com/prometheus/client_golang/pull/1218)l/1218
* @&#8203;lamida made their first
contributi[https://github.com/prometheus/client_golang/pull/1226](https://togithub.com/prometheus/client_golang/pull/1226)l/1226
* @&#8203;dimonl made their first
contributi[https://github.com/prometheus/client_golang/pull/1235](https://togithub.com/prometheus/client_golang/pull/1235)l/1235
* @&#8203;DariaKunoichi made their first
contributi[https://github.com/prometheus/client_golang/pull/1143](https://togithub.com/prometheus/client_golang/pull/1143)l/1143

**Full Changelog**:
prometheus/client_golang@v1.14.0...v1.15.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/hetznercloud/hcloud-cloud-controller-manager).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS40MC4wIiwidXBkYXRlZEluVmVyIjoiMzUuNDAuMCJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot referenced this pull request in open-feature/flagd Apr 14, 2023
….0 (#608)

[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[github.com/prometheus/client_golang](https://togithub.com/prometheus/client_golang)
| require | minor | `v1.14.0` -> `v1.15.0` |

---

### Release Notes

<details>
<summary>prometheus/client_golang</summary>

###
[`v1.15.0`](https://togithub.com/prometheus/client_golang/releases/tag/v1.15.0)

[Compare
Source](https://togithub.com/prometheus/client_golang/compare/v1.14.0...v1.15.0)

#### Changed

\[BUGFIX] Fix issue with atomic variables on ppc64le
[#&#8203;1171](https://togithub.com/prometheus/client_golang/issues/1171)
\[BUGFIX] Support for multiple samples within same metric
[#&#8203;1181](https://togithub.com/prometheus/client_golang/issues/1181)
\[BUGFIX] Bump golang.org/x/text to v0.3.8 to mitigate CVE-2022-32149
[#&#8203;1187](https://togithub.com/prometheus/client_golang/issues/1187)
\[ENHANCEMENT] Add exemplars and middleware examples
[#&#8203;1173](https://togithub.com/prometheus/client_golang/issues/1173)
\[ENHANCEMENT] Add more context to "duplicate label names" error to
enable debugging
[#&#8203;1177](https://togithub.com/prometheus/client_golang/issues/1177)
\[ENHANCEMENT] Add constrained labels and constrained variant for all
MetricVecs
[#&#8203;1151](https://togithub.com/prometheus/client_golang/issues/1151)
\[ENHANCEMENT] Moved away from deprecated github.com/golang/protobuf
package
[#&#8203;1183](https://togithub.com/prometheus/client_golang/issues/1183)
\[ENHANCEMENT] Add possibility to dynamically get label values for http
instrumentation
[#&#8203;1066](https://togithub.com/prometheus/client_golang/issues/1066)
\[ENHANCEMENT] Add ability to Pusher to add custom headers
[#&#8203;1218](https://togithub.com/prometheus/client_golang/issues/1218)
\[ENHANCEMENT] api: Extend and improve efficiency of json-iterator usage
[#&#8203;1225](https://togithub.com/prometheus/client_golang/issues/1225)
\[ENHANCEMENT] Added (official) support for go 1.20
[#&#8203;1234](https://togithub.com/prometheus/client_golang/issues/1234)
\[ENHANCEMENT] timer: Added support for exemplars
[#&#8203;1233](https://togithub.com/prometheus/client_golang/issues/1233)
\[ENHANCEMENT] Filter expected metrics as well in CollectAndCompare
[#&#8203;1143](https://togithub.com/prometheus/client_golang/issues/1143)
\[ENHANCEMENT] ⚠️ Only set start/end if time is not Zero. This breaks
compatibility in experimental api package. If you strictly depend on
empty time.Time as actual value, the behavior is now changed
[#&#8203;1238](https://togithub.com/prometheus/client_golang/issues/1238)

<details>
  <summary>All commits</summary>

- Merge release 1.14 to main by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1164](https://togithub.com/prometheus/client_golang/pull/1164)
- Fix typo in doc comment by
[@&#8203;beorn7](https://togithub.com/beorn7) in
[https://github.com/prometheus/client_golang/pull/1166](https://togithub.com/prometheus/client_golang/pull/1166)
- Fix issue with atomic variables on ppc64le by
[@&#8203;beorn7](https://togithub.com/beorn7) in
[https://github.com/prometheus/client_golang/pull/1171](https://togithub.com/prometheus/client_golang/pull/1171)
- examples: Add exemplars and middleware examples by
[@&#8203;jessicalins](https://togithub.com/jessicalins) in
[https://github.com/prometheus/client_golang/pull/1173](https://togithub.com/prometheus/client_golang/pull/1173)
- Add context to "duplicate label names" to enable debugging by
[@&#8203;SpencerMalone](https://togithub.com/SpencerMalone) in
[https://github.com/prometheus/client_golang/pull/1177](https://togithub.com/prometheus/client_golang/pull/1177)
- Add constrained labels and Constrained variant for all MetricVecs by
[@&#8203;Okhoshi](https://togithub.com/Okhoshi) in
[https://github.com/prometheus/client_golang/pull/1151](https://togithub.com/prometheus/client_golang/pull/1151)
- Support for multiple samples within same metric by
[@&#8203;machadovilaca](https://togithub.com/machadovilaca) in
[https://github.com/prometheus/client_golang/pull/1181](https://togithub.com/prometheus/client_golang/pull/1181)
- Replace deprecated github.com/golang/protobuf package by
[@&#8203;zhsj](https://togithub.com/zhsj) in
[https://github.com/prometheus/client_golang/pull/1183](https://togithub.com/prometheus/client_golang/pull/1183)
- Bump golang.org/x/text to v0.3.8 to mitigate CVE-2022-32149 by
[@&#8203;b4bay](https://togithub.com/b4bay) in
[https://github.com/prometheus/client_golang/pull/1187](https://togithub.com/prometheus/client_golang/pull/1187)
- typo fix by
[@&#8203;ibreakthecloud](https://togithub.com/ibreakthecloud) in
[https://github.com/prometheus/client_golang/pull/1178](https://togithub.com/prometheus/client_golang/pull/1178)
- Add possibility to dynamically get label values for http
instrumentation by [@&#8203;Okhoshi](https://togithub.com/Okhoshi) in
[https://github.com/prometheus/client_golang/pull/1066](https://togithub.com/prometheus/client_golang/pull/1066)
- Bump github.com/cespare/xxhash/v2 from 2.1.2 to 2.2.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1199](https://togithub.com/prometheus/client_golang/pull/1199)
- Bump github.com/prometheus/procfs from 0.8.0 to 0.9.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1198](https://togithub.com/prometheus/client_golang/pull/1198)
- Bump golang.org/x/sys from 0.3.0 to 0.4.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1217](https://togithub.com/prometheus/client_golang/pull/1217)
- Synchronize common files from prometheus/prometheus by
[@&#8203;prombot](https://togithub.com/prombot) in
[https://github.com/prometheus/client_golang/pull/1213](https://togithub.com/prometheus/client_golang/pull/1213)
- Bump github.com/prometheus/common from 0.37.0 to 0.39.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1197](https://togithub.com/prometheus/client_golang/pull/1197)
- Add `Header` method to Pusher for custom header by
[@&#8203;songjiayang](https://togithub.com/songjiayang) in
[https://github.com/prometheus/client_golang/pull/1218](https://togithub.com/prometheus/client_golang/pull/1218)
- Synchronize common files from prometheus/prometheus by
[@&#8203;prombot](https://togithub.com/prombot) in
[https://github.com/prometheus/client_golang/pull/1224](https://togithub.com/prometheus/client_golang/pull/1224)
- api: Extend and improve json-iterator usage by
[@&#8203;beorn7](https://togithub.com/beorn7) in
[https://github.com/prometheus/client_golang/pull/1225](https://togithub.com/prometheus/client_golang/pull/1225)
- Indent example in godoc consistently by
[@&#8203;lamida](https://togithub.com/lamida) in
[https://github.com/prometheus/client_golang/pull/1226](https://togithub.com/prometheus/client_golang/pull/1226)
- Remove unnecessary check if label is nil in observeWithExemplar by
[@&#8203;dimonl](https://togithub.com/dimonl) in
[https://github.com/prometheus/client_golang/pull/1235](https://togithub.com/prometheus/client_golang/pull/1235)
- README: Remove not working gocoverage images. by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1236](https://togithub.com/prometheus/client_golang/pull/1236)
- Added support for go 1.20. by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1234](https://togithub.com/prometheus/client_golang/pull/1234)
- timer: Added support for exemplars. by
[@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1233](https://togithub.com/prometheus/client_golang/pull/1233)
- Synchronize common files from prometheus/prometheus by
[@&#8203;prombot](https://togithub.com/prombot) in
[https://github.com/prometheus/client_golang/pull/1237](https://togithub.com/prometheus/client_golang/pull/1237)
- Filter expected metrics as well in CollectAndCompare by
[@&#8203;DariaKunoichi](https://togithub.com/DariaKunoichi) in
[https://github.com/prometheus/client_golang/pull/1143](https://togithub.com/prometheus/client_golang/pull/1143)
- Only set start/end if time is not Zero by
[@&#8203;jacksontj](https://togithub.com/jacksontj) in
[https://github.com/prometheus/client_golang/pull/1238](https://togithub.com/prometheus/client_golang/pull/1238)
- Bump google.golang.org/protobuf from 1.28.1 to 1.30.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1243](https://togithub.com/prometheus/client_golang/pull/1243)
- Bump golang.org/x/sys from 0.5.0 to 0.6.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1246](https://togithub.com/prometheus/client_golang/pull/1246)
- Bump github.com/golang/protobuf from 1.5.2 to 1.5.3 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1245](https://togithub.com/prometheus/client_golang/pull/1245)
- Bump github.com/prometheus/common from 0.41.0 to 0.42.0 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/prometheus/client_golang/pull/1244](https://togithub.com/prometheus/client_golang/pull/1244)
- Cut v1.15.0 by [@&#8203;bwplotka](https://togithub.com/bwplotka) in
[https://github.com/prometheus/client_golang/pull/1249](https://togithub.com/prometheus/client_golang/pull/1249)

</details>

#### New Contributors
* @&#8203;SpencerMalone made their first
contributi[https://github.com/prometheus/client_golang/pull/1177](https://togithub.com/prometheus/client_golang/pull/1177)l/1177
* @&#8203;Okhoshi made their first
contributi[https://github.com/prometheus/client_golang/pull/1151](https://togithub.com/prometheus/client_golang/pull/1151)l/1151
* @&#8203;machadovilaca made their first
contributi[https://github.com/prometheus/client_golang/pull/1181](https://togithub.com/prometheus/client_golang/pull/1181)l/1181
* @&#8203;b4bay made their first
contributi[https://github.com/prometheus/client_golang/pull/1187](https://togithub.com/prometheus/client_golang/pull/1187)l/1187
* @&#8203;ibreakthecloud made their first
contributi[https://github.com/prometheus/client_golang/pull/1178](https://togithub.com/prometheus/client_golang/pull/1178)l/1178
* @&#8203;songjiayang made their first
contributi[https://github.com/prometheus/client_golang/pull/1218](https://togithub.com/prometheus/client_golang/pull/1218)l/1218
* @&#8203;lamida made their first
contributi[https://github.com/prometheus/client_golang/pull/1226](https://togithub.com/prometheus/client_golang/pull/1226)l/1226
* @&#8203;dimonl made their first
contributi[https://github.com/prometheus/client_golang/pull/1235](https://togithub.com/prometheus/client_golang/pull/1235)l/1235
* @&#8203;DariaKunoichi made their first
contributi[https://github.com/prometheus/client_golang/pull/1143](https://togithub.com/prometheus/client_golang/pull/1143)l/1143

**Full Changelog**:
prometheus/client_golang@v1.14.0...v1.15.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/open-feature/flagd).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS40MC4wIiwidXBkYXRlZEluVmVyIjoiMzUuNDAuMCJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants