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

name composer: fast and slow (reflect-based) implementations #79

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

amberpixels
Copy link

@amberpixels amberpixels commented Sep 23, 2024

Context && Motivation

To create a new metric we have to manually write the full metric name (+ stringified labels) e.g. foo{bar="baz",aaa="b"} That can be tricky and overwhelming when doing it manually: raw strings always give a chance to make a typo (invalid syntax, wrong name, wrong type, missing/extra labels, etc)

Solution

Provide a helper function "NameCompose" that will let us to compose full metric name with given metric_name and labels. To avoid using raw maps (that still can lead to typos and issues explained above), let's do the type-safe solution, using structs.

Two possible solutions are available here:

1. Fast solution (but manual declaring helper for each labels set)

type MyLabelsSet struct {
   Foo string
   Bar int
   Flag bool
}

func (s MyLabelsSet) ToLabelsString() string {
  return `{foo="`+s.Foo+`",bar="`+fmt.Sprintf("%d", s.Bar)+`",flag="`+fmt.Sprintf("%t", s.Flag)+`"}`
}

GetOrCreateCounter(NameCompose("my_counter", MyLabelsSet{
  Foo: "foo1", Bar: 3, Flag: true
 }).Inc()
// -> my_counter{foo:"foo1",bar:"3",flag:"true"}

2. Auto-compose solution (but slow, reflect is involved)

// + No need to declare a custom method to a struct
// + Type can be defined on-the-fly inside a function

func SomeFunc() {
  type MyLabelsAuto struct {
    AutoLabelComposer // making this labels set to let it automatically generate labels string
    Foo string
    Bar int
    Flag bool
  }

  GetOrCreateCounter(NameComposeAuto("my_counter", MyLabelsAuto{
     Foo: "foo1", Bar: 3, Flag: true
  }).Inc()
  // -> my_counter{foo:"foo1",bar:"3",flag:"true"}

Notes:

  • Reflect is involved but optional. You can always declare your own ToLabelsString() method to your labels struct and use it.
  • Reflect as a dependency by itself doesn't harm the "lightweight" factor of the library.

What do you think about such a feature?

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.

1 participant