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

dnsdist: add support for labels on custom metrics #14956

Merged
merged 16 commits into from
Dec 17, 2024

Conversation

esensar
Copy link
Contributor

@esensar esensar commented Dec 12, 2024

Short description

This adds support for prometheus labels on custom metrics. Changes the metrics maps to hold a map of labels to metric values for each metric. Metrics without labels have an empty string label combination value.

Adds an optional options table as the last parameter of incMetric, decMetric, setMetric and getMetric, which can be used to set labels by using the label key or to set the previously used parameter (either step or value).

Closes: #13359

Checklist

I have:

  • read the CONTRIBUTING.md document
  • compiled this code
  • tested this code
  • included documentation (including possible behaviour changes)
  • documented the code
  • added or modified regression test(s)
  • added or modified unit test(s)

This adds support for prometheus labels on custom metrics. Changes the
metrics maps to hold a map of labels to metric values for each metric.
Metrics without labels have an empty string label combination value.

Adds an optional options table as the last parameter of `incMetric`,
`decMetric`, `setMetric` and `getMetric`, which can be used to set
labels by using the `label` key or to set the previously used parameter
(either `step` or `value`).

Closes: PowerDNS#13359
@coveralls
Copy link

coveralls commented Dec 12, 2024

Pull Request Test Coverage Report for Build 12356677632

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 137 of 179 (76.54%) changed or added relevant lines in 7 files are covered.
  • 7286 unchanged lines in 144 files lost coverage.
  • Overall coverage increased (+8.4%) to 63.958%

Changes Missing Coverage Covered Lines Changed/Added Lines %
pdns/dnsdistdist/dnsdist-carbon.cc 1 3 33.33%
pdns/dnsdistdist/dnsdist-lua-ffi.cc 3 10 30.0%
pdns/dnsdistdist/dnsdist-lua-ffi.hh 13 21 61.9%
pdns/dnsdistdist/dnsdist-metrics.cc 65 75 86.67%
pdns/dnsdistdist/dnsdist-lua.cc 43 58 74.14%
Files with Coverage Reduction New Missed Lines %
pdns/auth-catalogzone.hh 1 66.67%
pdns/dnsdistdist/test-dnsdistrules_cc.cc 1 95.15%
pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc 1 85.12%
pdns/recursordist/nod.hh 1 92.59%
pdns/test-dnsrecords_cc.cc 2 95.97%
pdns/dnsdistdist/test-dnsdist-lua-ffi.cc 2 99.59%
pdns/dnsdistdist/dnsdist-lua-ffi.hh 2 72.22%
pdns/epollmplexer.cc 2 85.0%
pdns/dnssecinfra.cc 2 76.3%
pdns/snmp-agent.hh 2 75.0%
Totals Coverage Status
Change from base Build 12305519461: 8.4%
Covered Lines: 85317
Relevant Lines: 110706

💛 - Coveralls

pdns/dnsdistdist/dnsdist-lua.cc Fixed Show fixed Hide fixed
pdns/dnsdistdist/dnsdist-lua.cc Fixed Show fixed Hide fixed
Copy link
Member

@rgacogne rgacogne left a comment

Choose a reason for hiding this comment

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

I made a few comments, and I think we need to exclude metrics with labels from both Carbon export and dumpStats(), but I'm quite happy with the general concept, and the code itself is good as well.

pdns/dnsdistdist/dnsdist-metrics.cc Show resolved Hide resolved
Comment on lines 249 to 256
auto combinationOfLabels = generateCombinationOfLabels(labels);
auto metricEntry = metric->second.find(combinationOfLabels);
if (metricEntry == metric->second.end()) {
metricEntry = metric->second.emplace(combinationOfLabels, MutableCounter()).first;
g_stats.entries.write_lock()->emplace_back(Stats::EntryTriple{std::string(name), combinationOfLabels, &metricEntry->second.d_value});
}
metricEntry->second.d_value -= step;
return metricEntry->second.d_value.load();
Copy link
Member

Choose a reason for hiding this comment

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

Just a nit but it looks like we could get rid of a bit of code duplication by turning this into a (templated to handle both counters and gauges?) function.

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 makes sense, I will try to clean it up. My C++ skills are not good, so expect a messy first attempt 😄

Copy link
Member

Choose a reason for hiding this comment

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

No problem, and please feel free to ask for help if needed, or even to just leave the cleanup to me when you are done, that's completely fine!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you! I will take a shot and let you know if I get stuck

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 have added a template function for this. Let me know if it looks okay or if it needs some work.

@esensar
Copy link
Contributor Author

esensar commented Dec 12, 2024

By the way, an unrelated question:
I have tried to fix formatting in files I have touched, using the provided script (./build-scripts/format-code...). Doing that has produced wrong results, which failed on CI. On further inspection I saw that the script expects clang-format-11, while I had clang-format-17 installed. After installing 11, it worked as expected. Is there a reason that clang-format-11 is still used?

@omoerbeek
Copy link
Member

By the way, an unrelated question: I have tried to fix formatting in files I have touched, using the provided script (./build-scripts/format-code...). Doing that has produced wrong results, which failed on CI. On further inspection I saw that the script expects clang-format-11, while I had clang-format-17 installed. After installing 11, it worked as expected. Is there a reason that clang-format-11 is still used?

Version 11 was the one that was available in our CI when we started enforcing formatting. Later we noticed differences with newer clang-format versions, so we fixated the version. It mights be time to move to a newer version...

@esensar esensar requested a review from rgacogne December 12, 2024 18:37
@esensar
Copy link
Contributor Author

esensar commented Dec 12, 2024

I think everything is covered now. I still need to update documentation though.

Copy link
Member

@rgacogne rgacogne left a comment

Choose a reason for hiding this comment

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

Looks good to me, I suggested a few changes to appease the static analyzer. A new regression test would be nice, and of course as you already mentioned this needs to be documented :)

pdns/dnsdistdist/dnsdist-lua-ffi.cc Show resolved Hide resolved
pdns/dnsdistdist/dnsdist-lua-ffi.cc Show resolved Hide resolved
pdns/dnsdistdist/dnsdist-lua.cc Show resolved Hide resolved
pdns/dnsdistdist/dnsdist-lua.cc Show resolved Hide resolved
@esensar esensar marked this pull request as ready for review December 16, 2024 10:32
@esensar esensar requested a review from rgacogne December 16, 2024 10:32
@esensar
Copy link
Contributor Author

esensar commented Dec 16, 2024

I have added the documentation. I was not sure what to set as versionAdded. Also, should I have added variants with options as separate functions (in case of incMetric, decMetric and declareMetric) and deprecate old variants, or is this way of documenting parameters with different variants okay?

Copy link
Member

@rgacogne rgacogne left a comment

Choose a reason for hiding this comment

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

A couple nits but the documentation looks OK and the tests are quite nice, thanks!

pdns/dnsdistdist/docs/reference/custommetrics.rst Outdated Show resolved Hide resolved
pdns/dnsdistdist/docs/reference/custommetrics.rst Outdated Show resolved Hide resolved
pdns/dnsdistdist/docs/reference/custommetrics.rst Outdated Show resolved Hide resolved
@esensar
Copy link
Contributor Author

esensar commented Dec 16, 2024

A couple nits but the documentation looks OK and the tests are quite nice, thanks!

Thank you! I think for 2.0.0 (if breaking changes are allowed between major versions), we could just leave opts for incMetric, decMetric and declareMetric, instead of allowing previous optional parameter for these, but I guess that can be done in a separate PR for easier backporting.

@esensar esensar requested a review from rgacogne December 16, 2024 16:54
@rgacogne
Copy link
Member

I think for 2.0.0 (if breaking changes are allowed between major versions), we could just leave opts for incMetric, decMetric and declareMetric, instead of allowing previous optional parameter for these, but I guess that can be done in a separate PR for easier backporting.

Breaking changes in major versions are of course OK when they are needed or particularly useful, but my feeling is that it's neither in this case. The solution you came with is backward-compatible and quite clean 👍.

@rgacogne rgacogne merged commit 34ede92 into PowerDNS:master Dec 17, 2024
77 checks passed
@esensar esensar deleted the feat/metric-labels branch December 17, 2024 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Prometheus metric labels on custom metrics
4 participants