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 default tags only for a specific group #19

Merged
merged 5 commits into from
May 7, 2021

Conversation

liaden
Copy link
Contributor

@liaden liaden commented Mar 15, 2021

This would fix #16

@@ -9,6 +9,10 @@ class Group

param :name

def default_tags
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably should be a different name since this doesn't include the default_tags of the global scope?

if group
Yabeda::Tags.tag_group(group)[name] = value
else
Yabeda.default_tags[name] = value
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I considered updating Yabeda.default_tags itself to be a hash of hashes and let nil be the key that accessed top level tags.

@Envek
Copy link
Member

Envek commented Mar 15, 2021

Hi! Thank you very much for the pull request!

While I'm generally like the idea and want this feature to be in Yabeda, I will probably will leave some notes about API and implementation, but not today. I will take more thorough look in a few days.

@liaden
Copy link
Contributor Author

liaden commented Mar 15, 2021

No rush on this one. I do like the idea of this functionality, but API is important.

One thought I had was if groups can be nested. If so, the storage of the default tags for a given group seems more appropriate on the group. It seems like in that case then default_tags at the global scope is just a group with no name specified.

Additionally:

Yabeda.configure do
  group :something do
    # should probably have `group :something` implied here
    default_tag :key, value
  end
end

Some of these things made the idea a lot more complex, so I just opted to KISS with this PR. I don't mind expanding the scope and doing more changes if that is better though.

@Envek
Copy link
Member

Envek commented Mar 15, 2021

I like nested default_tag calls, inside groups. If feels more natural. And it should be easy to implement as in DSL current group is available as @group:

def group(group_name)
@group = group_name
return unless block_given?
yield
@group = nil
end

However, not nested calls looks useful too. For example if someone would like to add some tags to all sidekiq-related metrics from yabeda-sidekiq in their application.

@@ -58,8 +58,12 @@ def histogram(*args, **kwargs, &block)
#
# @param name [Symbol] Name of default tag
# @param value [String] Value of default tag
def default_tag(name, value)
::Yabeda.default_tags[name] = value
def default_tag(name, value, group: nil)
Copy link
Member

Choose a reason for hiding this comment

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

You can use this and it will work 😃

Suggested change
def default_tag(name, value, group: nil)
def default_tag(name, value, group: @group)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've pushed up a new commit (to maybe make reviewing easier). I'll squash prior to merge if it all looks good.

Some thoughts as I was working onit:

  1. I created a group object with a name of nil to account for the global group.
  2. with_tags can nest with_tags
  3. Named group's continue to be a child of the global group. Current code doesn't support deeper nesting, and Yabeda.group1.group2.some_gauge.set({}, 5) feels verbose/complicated (and probably not needed).
  4. I got into some weird states on testing when trying to remove methods so I tried to make Yabeda.reset! a bit more resilient and comprehensive (so a bad test doesn't break every subsequent test).
  5. I got the feeling that a group instance could be the evaluation context for the DSL. A group having default_tags and having metrics already feels very similar to the Yabeda module. If this was done, then arbitrary nesting of groups becomes easier.
  6. The two register calls for groups and metrics was a bit confusing since they both call each other.

@@ -7,7 +7,7 @@ class Histogram < Metric
option :buckets

def measure(tags, value)
all_tags = ::Yabeda::Tags.build(tags)
all_tags = ::Yabeda::Tags.build(tags, group)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it be worth extracting this to Metric since all three metrics have this? I don't have a good name for it since we already have tags for just the keys.

@@ -17,15 +17,15 @@ class Metric

# Returns the value for the given label set
def get(labels = {})
values[::Yabeda::Tags.build(labels)]
values[::Yabeda::Tags.build(labels, group)]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ran into some confusion at first that I thought group would be an instance of Group as opposed to a symbol.

@liaden
Copy link
Contributor Author

liaden commented Apr 7, 2021

@Envek Any feedback or other thoughts?

@Envek
Copy link
Member

Envek commented Apr 7, 2021

Sorry, couldn't get to it. I definitely want this feature to be in Yabeda. Hopefully will be able to review it later this week.

Comment on lines 19 to 23
if name
Yabeda.groups[nil].default_tags.merge!(@default_tags)
else
@default_tags.dup
end
Copy link
Member

Choose a reason for hiding this comment

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

While concept of implicit global group looks reasonable, such places to distinguish global tags from group-local ones are looking very weird.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure what you mean by 'such places?'

@liaden
Copy link
Contributor Author

liaden commented Apr 16, 2021

Looking back at this again, I think the handling of groups leaves room for user error/confusion.

Given the curerent implementation of

      def group(group_name)
        @group = group_name
        return unless block_given?

        yield
        @group = nil
      end

We can configure sibling groups

Yabeda.configure do
  group :g1
  # config
  group :g2
  # config
  end

or attempt to have nested groups

Yabeda.configure do
  group :g1 do
    # config
    group :g2 do
      # config
    end
    # more g1 config 
  end 

The nested groups are really the same as the first situation where we create two siblings. Both default_tags and looking up metrics would be handled the same in both cases with an additional surprise that the 'more g1 config'j would apply to the global scope.

I think that it would be good to raise an exception or at least warn when someone attempts to nest two groups to prevent the issue until there is a need for deeper nesting?

@Envek
Copy link
Member

Envek commented Apr 16, 2021

Yeah, groups are somewhat messy, but it is apparently outside of scope for this pull request. Let's discuss it in #20

@Envek
Copy link
Member

Envek commented Apr 16, 2021

I pushed one more commit right into this pull request (yep, “allow edits from maintainers” checkbox allows to do such things) which effectively removes global group usage (but it is still there). Do you like these edits? Let's discuss!

@liaden
Copy link
Contributor Author

liaden commented Apr 29, 2021

Yeah, this looks good to me.

@Envek Envek merged commit d15c7c5 into yabeda-rb:master May 7, 2021
@Envek
Copy link
Member

Envek commented May 7, 2021

Released in 0.9.0. Thank you!

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.

No apply default_tags to all metrics
2 participants