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

Protobuf support #47

Closed
wants to merge 77 commits into from
Closed

Conversation

ackintosh
Copy link
Contributor

@ackintosh ackintosh commented Feb 24, 2022

Closes #46

This PR adds protobuf support to the client, which provides functionality to encode metrics to an instance of the OpenMetrics protobuf format.

        let mut registry = Registry::default();

        // ...

        // Encode metrics to an instance of the OpenMetrics protobuf format.
        let metric_set: openmetrics_data_model::MetricSet = encode(&registry);

        for family in metric_set.metric_families {
            println!(family.name);

            for metric in family.metrics {
                // ...
            }
        }

📝 Todos

FYI: I'm working to use this Protobuf support, in sigp/gossipsub-testground#4, in order to record metrics whose gossipsub-libp2p to InfluxDB.


(Edit: Resolved) How to manage the dependencies of .proto files

This PR introduces a openmetrics_data_model.proto file dependency. We can get the file from here.

For now, I've copied the .proto file manually and added it to git. However, I think that is not good as it could happen operational errors. So we need to consider how to manage the .proto file.

  1. Using Buf
  1. Download the proto file via build.rs

I couldn't find another way, I think 2. Download the proto file via build.rs is good.

Edit: I changed my mind, manually coping is suitable: #47 (comment)

@ackintosh

This comment was marked as resolved.

@mxinden
Copy link
Member

mxinden commented Feb 28, 2022

@mxinden I would appreciate it if you could give me some advice. bow

ackintosh#1 should fix your issue @ackintosh. Let me know if that works for you.

@ackintosh
Copy link
Contributor Author

ackintosh commented Mar 7, 2022

It works, thank you @mxinden !

@mxinden
Copy link
Member

mxinden commented Mar 14, 2022

Please ping me once this is ready for a first review @ackintosh. Thanks for the help!

@ackintosh
Copy link
Contributor Author

Most of what I need to implement are finished, there are small (maybe) TODO tasks though.

@mxinden

@mxinden
Copy link
Member

mxinden commented Apr 8, 2022

This is great news @ackintosh. Unfortunately I will be offline for a bit, thus I will likely not get to it next week :/

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.

Thanks for the work @ackintosh! I have a couple of high-level comments. I will take a more in-depth look.

Cargo.toml Outdated Show resolved Hide resolved
src/encoding/proto.rs Outdated Show resolved Hide resolved
src/encoding/proto.rs Outdated Show resolved Hide resolved
src/encoding/proto.rs Outdated Show resolved Hide resolved
@mxinden
Copy link
Member

mxinden commented Apr 16, 2022

I couldn't find another way, I think 2. Download the proto file via build.rs is good. memo

I would like the prometheus crate to be able to build offline, i.e. once one downloaded all dependencies from crates.io to not require internet access. Downloading the file on each build would thus not work.

@mxinden
Copy link
Member

mxinden commented Apr 16, 2022

Using Buf

This is an interesting suggestion. What do you think of moving it to https://github.com/OpenObservability/OpenMetrics/ as it concerns the whole project?

@mxinden
Copy link
Member

mxinden commented Apr 16, 2022

For now, I've copied the .proto file manually and added into git.

I don't expect any breaking changes to the .proto file, and thus think this is a valid option.

@ackintosh
Copy link
Contributor Author

Using Buf

This is an interesting suggestion. What do you think of moving it to https://github.com/OpenObservability/OpenMetrics/ as it concerns the whole project?

💡 I posted an issue to OpenMetrics just now: prometheus/OpenMetrics#253

@ackintosh
Copy link
Contributor Author

I couldn't find another way, I think 2. Download the proto file via build.rs is good. memo

I would like the prometheus crate to be able to build offline, i.e. once one downloaded all dependencies from crates.io to not require internet access. Downloading the file on each build would thus not work.

Ahh, that makes sense. 💡

@ackintosh
Copy link
Contributor Author

FYI: I'm planning that use the Protobuf support, in gossipsub-testground, in order to record metrics whose gossipsub-libp2p to InfluxDB.

@ackintosh

This comment was marked as resolved.

@ackintosh

This comment was marked as outdated.

@ackintosh

This comment was marked as resolved.

@ackintosh

This comment was marked as resolved.

@mxinden
Copy link
Member

mxinden commented Aug 20, 2022

I took another look. What do you think of ackintosh#6?

  • It does not require an associated type.
  • It does not force any allocations, not even on the implementation of Family.
  • It significantly reduces the type signatures, both on the implementor and the consumer side.
  • Tests all pass.

What do you think @ackintosh?

(I am sorry for leading you astray suggesting to use an Iterator.)

@ackintosh
Copy link
Contributor Author

Thank you @mxinden! It's awesome. ✨ I have merged ackintosh#6 and made some updates according to the changes in ackintosh#6.

I run benchmark again in the same way, and the result was definitely good.

Benchmark

$ critcmp baseline-vec baseline-max

group     baseline-max                           baseline-vec
-----     ------------                           ------------
encode    1.00      6.1±0.14ms        ? ?/sec    1.05      6.4±0.24ms        ? ?/sec

Allocation count

  • vec: 124114
  • now: 114014

No worries, the experiments to use an Iterator was so exciting and I have learned a lot from them. 😃

@ackintosh ackintosh marked this pull request as ready for review August 23, 2022 07:18
@ackintosh
Copy link
Contributor Author

TODOs on this PR have been done. ✅

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.

Great progress here.

Would you mind bumping the crate version and adding a changelog entry? As far as I can tell, this does not introduce any breaking changes and could thus be released as v0.18.1.


[dependencies]
dtoa = "1.0"
itoa = "1.0"
parking_lot = "0.12"
prometheus-client-derive-proto-encode = { version = "0.1.0", path = "derive-proto-encode", optional = true }
Copy link
Member

Choose a reason for hiding this comment

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

Exploring the thought on whether we could use the same derive macro for both text and protobuf. I guess we can not feature flag the generated protobuf code via #[cfg(feature = "protobuf")] as we would not have access to the flag in the downstream user crate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is cool if we use the same derive macro, I'll do some experiments. 🙂

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 investigated but yeah, I couldn't find a way to do that.

@@ -10,14 +10,21 @@ repository = "https://github.com/prometheus/client_rust"
homepage = "https://github.com/prometheus/client_rust"
documentation = "https://docs.rs/prometheus-client"

[features]
protobuf = ["dep:prost", "dep:prost-types", "dep:prost-build", "dep:prometheus-client-derive-proto-encode", "dep:void"]
Copy link
Member

Choose a reason for hiding this comment

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

I think CI is currently not running with --all-features. Can you add it with this pull request to make sure your feature is being tested?

Copy link
Contributor Author

@ackintosh ackintosh Aug 27, 2022

Choose a reason for hiding this comment

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

Added 33c940a

@ackintosh
Copy link
Contributor Author

https://github.com/prometheus/client_rust/pull/47/checks?check_run_id=8046799148

DCO
There are 49 commits incorrectly signed off. This means that the author(s) of these commits failed to include a Signed-off-by line in their commit message.

I need to rebase this branch to add Signed-off-by lines.

dependabot bot and others added 3 commits August 27, 2022 11:21
* build(deps): update dtoa requirement from 0.4 to 1.0

Updates the requirements on [dtoa](https://github.com/dtolnay/dtoa) to permit the latest version.
- [Release notes](https://github.com/dtolnay/dtoa/releases)
- [Commits](dtolnay/dtoa@0.4.0...1.0.1)

---
updated-dependencies:
- dependency-name: dtoa
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* src/encoding/text: Adjust to breaking changes in dtoa

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
)

Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
mxinden and others added 23 commits August 27, 2022 11:24
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
…s#79)

Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
…eus#78)

Before `proemtheus-client` would use the `owning_ref` crate to map the target
of a `std::sync::RwLockReadGuard`. `owning_ref` has multiple unsoundness
issues, see https://rustsec.org/advisories/RUSTSEC-2022-0040.html. Instead of
replacing `owning_ref` with a similar crate, we switch to locking via
`parking_lot` which supports the above mapping natively.

Signed-off-by: Max Inden <mail@max-inden.de>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
void is used in only encoding/proto.

Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
Signed-off-by: ackintosh <sora.akatsuki@gmail.com>
# Conflicts:
#	.github/workflows/rust.yml
#	CHANGELOG.md
#	Cargo.toml
#	src/metrics/gauge.rs
@ackintosh
Copy link
Contributor Author

@ackintosh
Copy link
Contributor Author

Rebased this branch according to the DCO check #47 (comment)

Hmm, I noticed that the commit history was broken due to the rebasing... sorry.

I'll create another pull request and close this. 🙇

@ackintosh ackintosh mentioned this pull request Aug 30, 2022
@ackintosh
Copy link
Contributor Author

I have created #83

@ackintosh ackintosh closed this Aug 30, 2022
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.

Custom encoder?