telegraf
telegraf copied to clipboard
feat(serializers.prometheus): allow serializing metrics without HELP and TYPE metadata
Required for all PRs:
- [x] Updated associated README.md.
- [x] Wrote appropriate unit tests.
- [x] Pull request title or commits are in conventional commit format
resolves #11390
Added prometheus_compact_encoding
option, false
by default. It's basically another Prometheus encoder which is mostly a copy of the standard lib implementation:
https://github.com/prometheus/common/blob/main/expfmt/text_create.go
with the only difference in HELP and TYPE comments handling that are just skipped here.
Download PR build artifacts for linux_amd64.tar.gz, darwin_amd64.tar.gz, and windows_amd64.zip. Downloads for additional architectures and packages are available below.
:relaxed: This pull request doesn't significantly change the Telegraf binary size (less than 1%)
:package: Click here to get additional PR build artifacts
Artifact URLs
Hmmm, this seems a lot of code to just leave out two fields... This being said, the HELP
part can already be left-out with the upstream encoder by not setting mf.Help
(see encoder). The easiest way would be to pass your new option to collection.GetProto()
and conditionally set the Help
field there.
For the TYPE
, you should rather add similar code as for HELP
in the upstream encoder to not "fork" that part of the code...
What do you think?
@srebhan thanks for checking it out. The thing is I want to make the network footprint as small as possible. I'm trying to use the serializer with Kafka output and each message is like this:
# HELP node_cpu_seconds_total Telegraf collected metric
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="1",host="vagrant",mode="steal",url="http://localhost:9100/metrics"} 0 1657211085018
It's 206 bytes long. Without HELP
and TYPE
it's 112 bytes.
a quick test
I've done a more real-world example with real-time streaming to Kafka using zstd compression. It's 20 instances of Prometheus node-exporters scraped every 5sec by Telegraf:

So in my test it's 25% more efficient with prometheus_compact_encoding = true
than without it.
implementation
You're right I could easily remove HELP
but that'd be a half-measure I think. So I decided to remove TYPE
as well.
I agree it'd be perfect to have the TYPE
field optional in the upstream code but I came across an issue where Prometheus maintainers wanted to keep their library, which is actually an internal library, stable without having many ways of metrics encoding: https://github.com/prometheus/common/issues/269
Eventually, I couldn't come up with a better solution than a custom encoder that just removes both HELP
and TYPE
metadata from the original Prometheus implementation.
@vpedosyuk I see your point and agree that it would be nice to remove the noise if that's still conforming to the spec, but I do not agree with your way of achieving it. :-) Bluntly copying large chunks of internal prometheus code to Telegraf will make us maintain that encoder and I'm pretty sure you are not going to sync back bug-fixes etc from prometheus to Telegraf, are you?
This being said, the HELP
part can already be removed as I pointed out earlier, by conditionally omitting the Help
field setting here. This can be done now in a PR and will reduce your payload size by 57 bytes (~25%)!
For the TYPE
field, I suggest you try to submit a pull-request against prometheus/common that omits serializing nil
Type
fields just as they do with Help
. I don't think prometheus/common#269 says they are not going to take that change, it just says they are not taking custom encoders. Please link the PR here to follow the process. If it gets merged, we can skip setting that field as described in the HELP
part.
In case the PR is rejected, I would rather like to remove the TYPE
information from the serialized text instead of copying the encoder. This can be done by a regexp or line filtering or similar...
Hello! I am closing this issue due to inactivity. I hope you were able to resolve your problem, if not please try posting this question in our Community Slack or Community Page. Thank you!