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

Derive macro to register struct of metrics #218

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

Hackzzila
Copy link

Resolves #140
cc @mxinden

Here is a rough implementation. It does not have docs yet

Example:

#[derive(Register, Default)]
struct Metrics {
    /// This is my counter
    my_counter: Counter,
    nested: NestedMetrics,
    #[register(skip)]
    skipped: Counter,
    #[register(unit = "bytes")]
    custom_unit: Counter,
    #[register(name = "my_custom_name")]
    custom_name: Counter,
    /// This will get ignored
    #[register(help = "my custom help")]
    custom_help: Counter,
}

#[derive(Register, Default)]
struct NestedMetrics {
    /// This is my gauge
    my_gauge: Gauge,
}
// Only if Metrics implements default
let metrics = Metrics::register_default(&mut registry);

let metrics = Metrics::default();
metrics.register(&mut registry);

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Solid work. Thank you!

I left a couple of questions.

Once we covered those, there is a bit of polishing (mostly docs as you said above).

Overall this looks good. I expect this to safe a lot of folks a lot of typing.

@@ -389,3 +391,51 @@ pub trait Metric: crate::encoding::EncodeMetric + Send + Sync + std::fmt::Debug

impl<T> Metric for T where T: crate::encoding::EncodeMetric + Send + Sync + std::fmt::Debug + 'static
{}

pub trait Register {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
pub trait Register {
pub trait Registrant {

I guess something to be registered would be a registrant. What do you think? Is that more or less intuitive? I am not a native speaker.

@@ -15,13 +15,14 @@ default = []
protobuf = ["dep:prost", "dep:prost-types", "dep:prost-build"]

[workspace]
members = ["derive-encode"]
members = ["derive-encode", "derive-register"]
Copy link
Member

Choose a reason for hiding this comment

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

I guess we could as well do both encode and register in one derive crate? I am undecided. What is your rational for two crates?

Copy link
Author

Choose a reason for hiding this comment

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

I just went off of the existing naming. I would be fine with one crate, but then I think it should be named just prometheus-client-derive. Also, should this be behind a feature so people don't have to compile syn if they don't need to?

Copy link
Member

Choose a reason for hiding this comment

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

  • I am in favor of one crate only.
  • The rename to prometheus-client-derive sounds good.
  • Moving prometheus-client-derive behind a feature sounds good to me.
  • I suggest making it a default feature.

Comment on lines +399 to +412
pub trait RegisterDefault {
fn register_default(registry: &mut Registry) -> Self;
}

impl<T> RegisterDefault for T
where
T: Register + Default,
{
fn register_default(registry: &mut Registry) -> Self {
let this = Self::default();
this.register(registry);
this
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Neat!

edition = "2021"

[dependencies]
darling = "0.20.10"
Copy link
Member

Choose a reason for hiding this comment

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

I would like to keep prometheus-client's dependency tree as lean as possible.

For users:

  • Better compile time.
  • Less crates to audit.

For maintainers:

  • Less maintenance work (depending on how much we need to re-invent the wheel.)

It is not only darling as a dependency, but also the dependencies of darling.

How much work do you think would it be to implement this feature without darling?

Copy link
Author

Choose a reason for hiding this comment

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

Probably only an hour or two? It doesn't seem too difficult

Copy link
Member

Choose a reason for hiding this comment

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

Great. Would you mind removing darling from this pull request?

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.

feat: derive register logic on struct of metrics
2 participants