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

feat: derive register logic on struct of metrics #140

Open
mxinden opened this issue May 15, 2023 · 2 comments · May be fixed by #218
Open

feat: derive register logic on struct of metrics #140

mxinden opened this issue May 15, 2023 · 2 comments · May be fixed by #218
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@mxinden
Copy link
Member

mxinden commented May 15, 2023

One oftentimes has a struct of metrics like:

struct Metrics {
    a: Counter,
    b: Gauge,
}

Code to register the metrics in Metrics with a Registry could be generated via a derive macro on Metrics.

  • The metric name would be taken from the field name.
  • The metric help text would be taken from the Rust doc String.
  • The metric unit could be provided via a macro attribute.
#[derive(Register)]
struct Metrics {
    /// My Gauge tracking the number of xxx
    a: Counter,
    /// My Counter, tracking the event xxx
    #[prometheus-unit(Seconds)]
    b: Gauge,
}

Where the Register trait is something along the lines of:

trait Register {
  fn create_and_register(registry: &mut Registry) -> Self;
}
@mxinden mxinden added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers labels May 15, 2023
@Hackzzila
Copy link

I think this is a great idea! I actually implemented this myself for a project before coming across this issue. I implemented it a little differently to allow for nested structs.

pub trait Register {
    fn register(self, registry: &mut Registry);
}

pub trait RegisterField {
    fn register_field(
        self,
        name: impl Into<String>,
        help: impl Into<String>,
        registry: &mut Registry,
    );
}

impl<T: Metric> RegisterField for T {
    fn register_field(
        self,
        name: impl Into<String>,
        help: impl Into<String>,
        registry: &mut Registry,
    ) {
        registry.register(name, help, self);
    }
}

Example:

#[derive(Debug, Clone, Register)]
pub struct Metrics {
    pub foo: FooMetrics,
}

#[derive(Debug, Clone, Default, Register)]
pub struct FooMetrics {
    // This is registered as foo_counter by default
    pub messages: Counter,
}

If this is still wanted, we can decide on specifics and I can make a PR!

@mxinden
Copy link
Member Author

mxinden commented Jul 22, 2024

Cool! Yes, this is still wanted. Can you open a pull request with your current implementation @Hackzzila? Best to discuss with an implementation at hand.

@Hackzzila Hackzzila linked a pull request Jul 22, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants