prometheus / prometheus/client_rust
[IDEA]: Add helper for implementing `EncodeLabelSet` manually
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 606
- Forks
- 113
- Avg merge
- 9h 7m
- Merged PRs (30d)
- 8
Description
Problem
Manually implementing EncodeLabelSet for a struct currently involves a lot of boilerplate:
pub struct MyLabels {
pub method: &'static str, // or String, Cow<'static, str>, etc.
pub status: u16
// many other fields
}
impl EncodeLabelSet for MyLabels {
fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), fmt::Error> {
// label: method = self.method
{
let mut label = encoder.encode_label();
let mut key = label.encode_label_key()?;
// field name -> key string (handle raw-idents manually if you used them)
EncodeLabelKey::encode("method", &mut key)?;
let mut value = key.encode_label_value()?;
EncodeLabelValue::encode(&self.method, &mut value)?;
value.finish()?;
}
// label: status = self.status
{
let mut label = encoder.encode_label();
let mut key = label.encode_label_key()?;
EncodeLabelKey::encode("status", &mut key)?;
let mut value = key.encode_label_value()?;
EncodeLabelValue::encode(&self.status, &mut value)?;
value.finish()?;
}
// repeated for all other fields
Ok(())
}
}
This can become a chore if you have to implement it manually (e.g. because you want conditional encoding).
Solution
A new LabelSetWriter struct that allows you to easily specify (key, value) pairs to encode.
Usage
pub struct MyLabels {
pub status: u16,
pub method: &'static str,
pub optional: Option<&'static str>,
// suppose we want to flatten these (like `#[prometheus(flatten)]`)
pub common: CommonLabels
}
impl EncodeLabelSet for MyLabels {
fn encode(&self, enc: &mut LabelSetEncoder) -> Result<(), fmt::Error> {
let mut writer = LabelSetWriter::new(enc);
.kv("status", &self.status)?
.kv("method", &self.method)?;
// allows for conditional encoding
if let Some(optional) = &self.optional {
writer.kv("optional", optional)?;
}
// allows flattening
writer.flatten(&self.common)?;
Ok(())
}
}
Discussion
I've written the code for LabelSetWriter and it's helpful for me in reducing boilerplate.
Would anyone else find this useful? I'm open to making a PR if so.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing EncodeLabelSet and LabelSetEncoder APIs, then compare the proposed LabelSetWriter usage for key/value encoding, conditional fields, and flattening. Done would require an agreed scope for the helper and validation that the proposed API fits the library's existing label-encoding model.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- observability-sre
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100