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

exporter: use only counter dump/schema commands for extacting counters #50718

Merged
merged 1 commit into from Mar 29, 2023

Conversation

avanthakkar
Copy link
Contributor

@avanthakkar avanthakkar commented Mar 28, 2023

Fixes: https://tracker.ceph.com/issues/59191
Signed-off-by: Avan Thakkar athakkar@redhat.com

Ceph exporter no more required the output of perf dump/schema, as the counter dump command returns both labeled and unlabeled perf counters which exporter can fetch and export. Removed the exporter_get_labeled_counters config option as exporter will now export all the counters, labeled or unlabeled.
Also the fix includes the support for renaming the metrics name of rgw multi-site and adding labels to it, similar to what is there in prometheus module.

Contribution Guidelines

Checklist

  • Tracker (select at least one)
    • References tracker ticket
    • Very recent bug; references commit where it was introduced
    • New feature (ticket optional)
    • Doc update (no ticket needed)
    • Code cleanup (no ticket needed)
  • Component impact
    • Affects Dashboard, opened tracker ticket
    • Affects Orchestrator, opened tracker ticket
    • No impact that needs to be tracked
  • Documentation (select at least one)
    • Updates relevant documentation
    • No doc update is appropriate
  • Tests (select at least one)
Show available Jenkins commands
  • jenkins retest this please
  • jenkins test classic perf
  • jenkins test crimson perf
  • jenkins test signed
  • jenkins test make check
  • jenkins test make check arm64
  • jenkins test submodules
  • jenkins test dashboard
  • jenkins test dashboard cephadm
  • jenkins test api
  • jenkins test docs
  • jenkins render docs
  • jenkins test ceph-volume all
  • jenkins test ceph-volume tox
  • jenkins test windows

src/exporter/DaemonMetricCollector.cc Show resolved Hide resolved
Comment on lines +298 to +308
else if (daemon_name.find("rbd-mirror") != std::string::npos) {
std::regex re(
"^rbd_mirror_image_([^/]+)/(?:(?:([^/]+)/"
")?)(.*)\\.(replay(?:_bytes|_latency)?)$");
std::smatch match;
if (std::regex_search(daemon_name, match, re) == true) {
new_metric_name = "ceph_rbd_mirror_image_" + match.str(4);
labels["pool"] = quote(match.str(1));
labels["namespace"] = quote(match.str(2));
labels["image"] = quote(match.str(3));
Copy link
Member

Choose a reason for hiding this comment

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

Are we also dropping this from the mgr/prometheus? Otherwise, they'll be duplicate entries, won't it?

Additionally, rather than introducing this transformation code in the ceph-exporter, I'd expect this to be provided by the daemons themselves. If not, we're trading a language (Python) which is super-friendly for data processing with bare C++ (tbh, this code is not complicate at all, but since we are introducing labeled perf-counters, why not go all the way?).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are we also dropping this from the mgr/prometheus? Otherwise, they'll be duplicate entries, won't it?

They're already removed.

Additionally, rather than introducing this transformation code in the ceph-exporter, I'd expect this to be provided by the daemons themselves. If not, we're trading a language (Python) which is super-friendly for data processing with bare C++ (tbh, this code is not complicate at all, but since we are introducing labeled perf-counters, why not go all the way?).

Comment on lines +313 to +318
// Add fixed name metrics from existing ones that have details in their names
// that should be in labels (not in name). For backward compatibility,
// a new fixed name metric is created (instead of replacing)and details are put
// in new labels. Intended for RGW sync perf. counters but extendable as required.
// See: https://tracker.ceph.com/issues/45311
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the comment! It's really helpful.

Comment on lines +324 to +331
std::regex re("^data_sync_from_(.*)\\.");
std::smatch match;
if (std::regex_search(metric_name, match, re) == true) {
new_metric_name = std::regex_replace(metric_name, re, "from_([^.]*)', 'from_zone");
labels["source_zone"] = quote(match.str(1));
return {labels, new_metric_name};
}
Copy link
Member

Choose a reason for hiding this comment

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

Same thing here: why not providing the labeled perf-counter right from the rgw daemon?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well basically this is just addressing this #49248 (comment). To have support for renaming the rgw multi-site metrics and adding labels. And well other daemons can make use of it as well for e.g. any rbd metrics which requires renaming metrics name and adding them as label. So for now it's just rgw in future there maybe other daemons which may need this functionality.

Fixes: https://tracker.ceph.com/issues/59191
Signed-off-by: Avan Thakkar <athakkar@redhat.com>

Ceph exporter no more required the output of perf dump/schema, as the ``counter dump`` command
returns both labeled and unlabeled perf counters which exporter can fetch and export.
Removed the ``exporter_get_labeled_counters`` confiug option as exporter will now export
all the counters, labeled or unlabeled.
Also the fix includes the support for renaming the metrics name of rgw multi-site and
adding labels to it, similar to what is there in prometheus module.
@avanthakkar avanthakkar merged commit ef6b9ae into ceph:main Mar 29, 2023
11 of 12 checks passed
@avanthakkar avanthakkar deleted the use-only-counter-dump-schema branch March 29, 2023 08:52
Copy link
Contributor

@idryomov idryomov left a comment

Choose a reason for hiding this comment

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

The PR is closed but I'm commenting anyway since I had some comments pending -- if you are tagging people for review, give them at least a couple of days to review before merging.

else if (daemon_name.find("rbd-mirror") != std::string::npos) {
std::regex re(
"^rbd_mirror_image_([^/]+)/(?:(?:([^/]+)/"
")?)(.*)\\.(replay(?:_bytes|_latency)?)$");
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is dead code -- rbd-mirror daemon doesn't report any non-labeled per-image counters anymore (starting in reef).

if (daemon_name.find("radosgw") != std::string::npos) {
std::size_t pos = daemon_name.find_last_of('.');
std::string tmp = daemon_name.substr(pos+1);
labels["instance_id"] = quote(tmp);
Copy link
Contributor

Choose a reason for hiding this comment

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

I know nothing about why both "rgw" and "radosgw" branches are needed but this seems wrong to me. Given radosgw.<instance_id>.asok string, wouldn't the above three lines always produce asok string for the value of the label?

json_object labeled_perf_group_object = labeled_perf.value().as_object();
auto counters = labeled_perf_group_object["counters"].as_object();
auto counters_labels = labeled_perf_group_object["labels"].as_object();
auto labeled_perf_group_counters = counter_dump[labeled_perf_group].as_object()["counters"].as_object();
Copy link
Contributor

Choose a reason for hiding this comment

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

All these variable names that start with "labeled" are confusing because counter dump includes both labeled and unlabeled counters. I would remove this prefix throughout.

json_object counter_schema = boost::json::parse(counter_schema_response).as_object();

for (auto &labeled_perf : counter_schema) {
std::string labeled_perf_group = {labeled_perf.key().begin(), labeled_perf.key().end()};
Copy link
Contributor

Choose a reason for hiding this comment

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

This and a few other lines here are over 80 columns.


for(auto &label: counters_labels) {
std::string label_key = {label.key().begin(), label.key().end()};
labels[label_key] = quote(label.value().as_string().c_str());
Copy link
Contributor

Choose a reason for hiding this comment

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

Is c_str needed given that quote takes std::string?

new_metric_name = metric_name;

std::regex re("^data_sync_from_(.*)\\.");
std::smatch match;
Copy link
Contributor

Choose a reason for hiding this comment

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

indentation

@szinn
Copy link

szinn commented Apr 11, 2023

@avanthakkar

This PR might have introduced a bug in 17.2.6

Just upgraded from 17.2.5 to 17.2.6 and prometheus is complaining about an ‘invalid metric type “counter”’ from one of the exporters. Grabbed the metrics file and ran it through promtool check metrics and it pointed to

# HELP ceph_mds_mem_cap+ Capabilities added               
# TYPE ceph_mds_mem_cap+ counter            
ceph_mds_mem_cap+{ceph_daemon="ceph-mds.ceph-filesystem-a"} 3   
ceph_mds_mem_cap+{ceph_daemon="ceph-mds.ceph-filesystem-b"} 0

with the message
error while linting: text format parsing error in line 762: invalid metric name in comment
It would appear that a metric name cannot have a ‘+’ in it

@idryomov
Copy link
Contributor

@szinn This PR is only merged in main, it hasn't been backported anywhere.

@szinn
Copy link

szinn commented Apr 11, 2023

@idryomov Right - the issue appears in 17.2.6 now. exporter is generating a metric with a '+' in it which is invalid and causes prometheus to mark the exporter pod with TargetDown.

This may not be the PR that caused the bug, but the issue is with 17.2.6

@idryomov
Copy link
Contributor

idryomov commented Apr 11, 2023

Understood. I don't think anything changed around mds_mem_cap+ counter -- it has been there with a plus in its name for years. So I'm guessing that either it wasn't surfaced in 17.2.5 but now is (e.g. due to a difference in prio settings) or something changed with regards to how perf counter names are massaged. @jmolmo @epuertat PTAL!

@szinn
Copy link

szinn commented Apr 11, 2023

Looking at my prometheus data, I see ceph_mds_mem_cap, ceph_mds_mem_cap_plus and ceph_mds_mem_cap_minus so perhaps it is just getting surfaced in .6 as you mentioned

@idryomov
Copy link
Contributor

Are you seeing both mds_mem_cap+ and ceph_mds_mem_cap_plus in your dump on 17.2.6?

@szinn
Copy link

szinn commented Apr 11, 2023

Here's what I see on 17.2.6

# HELP ceph_mds_mem_cap Capabilities
# TYPE ceph_mds_mem_cap gauge
ceph_mds_mem_cap{ceph_daemon="ceph-mds.ceph-filesystem-a"} 1
ceph_mds_mem_cap{ceph_daemon="ceph-mds.ceph-filesystem-b"} 0
# HELP ceph_mds_mem_cap+ Capabilities added
# TYPE ceph_mds_mem_cap+ counter
ceph_mds_mem_cap+{ceph_daemon="ceph-mds.ceph-filesystem-a"} 3
ceph_mds_mem_cap+{ceph_daemon="ceph-mds.ceph-filesystem-b"} 0
# HELP ceph_mds_mem_cap_ Capabilities removed
# TYPE ceph_mds_mem_cap_ counter
ceph_mds_mem_cap_{ceph_daemon="ceph-mds.ceph-filesystem-a"} 2
ceph_mds_mem_cap_{ceph_daemon="ceph-mds.ceph-filesystem-b"} 0

It would appear that _minus now shows as _ and _plus now shows as +

The _plus and _minus were perhaps from 17.2.5. I just did a search in the prometheus graph for the prefix.

@epuertat
Copy link
Member

@szinn this specific PR is not backported to 17.2.6, but the new ceph-exporter is there (I'd assume that disabled by default).

I see that the sanitizing code in the mgr/prometheus is still in 17.2.6:

def promethize(path: str) -> str:
''' replace illegal metric name characters '''
result = re.sub(r'[./\s]|::', '_', path).replace('+', '_plus')
# Hyphens usually turn into underscores, unless they are
# trailing
if result.endswith("-"):
result = result[0:-1] + "_minus"
else:
result = result.replace("-", "_")

But there's no such code in the ceph-exporter daemon. The only explanation would be that these metrics are coming from the ceph-exporter instead of from the mgr/prometheus exporter.

@avanthakkar, @pereman2: could you plz confirm what's the status of ceph-exporter in Quincy/17.2.6?

@szinn
Copy link

szinn commented Apr 11, 2023

@avanthakkar @pereman2 @epuertat Thanks for looking into this - even though it doesn't appear to impact functionality, it does mean that metrics aren't being pulled from one exporter which would stop any kind of alerting of issues off of that exporter. That would be a serious issue

@idryomov
Copy link
Contributor

idryomov commented Apr 11, 2023

this specific PR is not backported to 17.2.6, but the new ceph-exporter is there (I'd assume that disabled by default).

@epuertat What do you mean by the new ceph-exporter? ceph-exporter was there in 17.2.5 and not much changed under src/exporter between 17.2.5 and 17.2.6:

The only explanation would be that these metrics are coming from the ceph-exporter instead of from the mgr/prometheus exporter.

Agreed... ceph_mds_mem_cap_ data point confirms this because the actual counter name is cap-. ceph-exporter would prepend ceph_ and substitute _ for - here:

std::string name = "ceph_" + perf_group + "_" + perf_name;
std::replace_if(name.begin(), name.end(), is_hyphen, '_');

@jmolmo
Copy link
Member

jmolmo commented Apr 12, 2023

Probably the right thing to do is to produce the perf counter with the right name in each daemon.

Obviously, we can fix the problem in Ceph exporter, (and continue making different assumptions about how to replace each invalid character in the perf counter name), but if we were fixed the problem in the mds daemon the first time the problem arose, now we will not find this problem again.

In the case of mds, (what i find taking a look to the offensive counter) we have four counters with the same problem:

mdm_plb.add_u64_counter(l_mdm_inoa, "ino+", "Inodes opened");

In fact the use of the signs "+" or "-" in the counters has different meaning depending of the counter.
"+" = "opened" or "added"
"-" = "closed" or "removed"

@vshankar Do you think that to change the name of these counters is possible (any possible regression), or should we continue doing the "syntactic" replacement in the new ceph exporter?

@idryomov
Copy link
Contributor

idryomov commented Apr 12, 2023

@jmolmo Putting aside the choice between carrying over massaging code from mgr/prometheus module to the exporter daemon and changing the perf counters themselves (which are many years old!), can you link the PR that actually caused the regression in 17.2.6? A few comments above @epuertat said that

the new ceph-exporter is there (I'd assume that disabled by default).

What is new about ceph-exporter or how metrics are surfaced in 17.2.6? And, whatever it is, it doesn't appear to be disabled by default?

@avanthakkar avanthakkar changed the title exporter: user only counter dump/schema commands for extacting counters exporter: use only counter dump/schema commands for extacting counters Apr 12, 2023
@vshankar
Copy link
Contributor

@vshankar Do you think that to change the name of these counters is possible (any possible regression), or should we continue doing the "syntactic" replacement in the new ceph exporter?

I need to check. Will get back asap.

@epuertat
Copy link
Member

@jmolmo Prometheus is only one way to expose perf-counters, but Ceph supports others: InfluxDB/Telegraf/Zabbix. Each one could have different requirements for metrics names, so I don't think that each Ceph daemon individually should deal with that. IMHO it corresponds to the adaptation layer (ceph-exporter) to sanitize each perf-counter name to make it suitable for each monitoring framework.

Different question is doing complicate metric renamings, like the one here. I think that those transformations should be provided by the daemons themselves.

@epuertat
Copy link
Member

epuertat commented Apr 12, 2023

@szinn we have discussed this topic in today's CLT meeting:

Cause

The specific PRs that introduced this issue were:

Those PR allowed Cephadm/Rook to deploy the new (17.2.5) ceph-exporter, which was meant (among other things) to resolve scalability/performance issues with the existing centralized mgr/prometheus exporter. However, this new service should have never been enabled by default in Quincy, as it was meant to only be (experimentally) used by those deployments with scalability issues.

Impact

  • Cephadm: As per our preliminary analysis it should only affect new deployments, not upgrades on existing ones, since services are only automatically deployed during cephadm bootstrap stage.

  • Rook: in this case it affects both new and existing deployments.

The impact would be:

  • Ceph metrics could be duplicated: from the existing centralized mgr/prometheus exporter (legacy approach), and from the new ceph-exporter, which is deployed as a side-car container on each node and reports Ceph metrics for all colocated services in that node.
  • In a few cases (e.g.: ceph_mds_mem_cap+), where those metrics contain characters not supported by Prometheus (e.g.: +), Prometheus would complain about malformed metric names (however those metrics will still be properly reported via mgr/prometheus as ceph_mds_mem_cap_plus).
  • In a few cases (e.g.: ceph_mds_mem_cap_minus), with metrics ending in -, they would have different names in Prometheus (e.g.: ceph_mds_mem_cap_minus when coming from mgr/prometheus and ceph_mds_mem_cap_ when coming from ceph-exporter).

Workaround

  • Cephadm:
    • For upgrades on existing deployments no impact is expected, hence no workaround would be required.
    • For fresh installs with cephadm bootstrap (Rook-based deployments are unaffected), the --skip-monitoring-stack flag could be enabled not to install this new ceph-exporter service. This will also skip the installation of the rest of monitoring services (prometheus, grafana, node-exporter, alertmanager), which should be manually deployed after the bootstrap stage.
    • For upgrades already facing this issue: ceph orch rm ceph-exporter should be enough to prune this service.
  • Rook:
    • Remove the ceph-exporter service: kubectl delete -f exporter-service-monitor.yaml (reported not to work by @szinn; waiting for @travisn for a workaround).

Next Actions

Retrospective

  • Review the existing integration tests for monitoring.
  • Tighten up the backport screening process (suggestion to consider adopting best-practices as Conventional Commits).

CC: @adk3798 @avanthakkar @idryomov @jmolmo @nizamial09 @yuriw

@jmolmo
Copy link
Member

jmolmo commented Apr 12, 2023

Thanks @epuertat for the detailed clarifications.

@szinn
Copy link

szinn commented Apr 12, 2023

Thanks for the writeup as well - This did show up when I upgraded to 17.2.6 from 17.2.5 via rook-ceph. I didl try the ceph orch command and it indicated there was no orchestrator configured.

@epuertat
Copy link
Member

Thanks for the writeup as well - This did show up when I upgraded to 17.2.6 from 17.2.5 via rook-ceph. I will try the ceph orch command. If I understand you correctly, the ceph prometheus metrics will still be available via the previous mechanism.

Thanks for the heads up, @szinn. I completely ignored that Rook was already deploying this service. I'll update the notes above. Thanks again!

The ceph orch command is not likely to work on Rook deployments. I guess you'll have to run a kubectl delete -f <...>. @travisn: could you please help here? Thanks!

@szinn
Copy link

szinn commented Apr 12, 2023

Yes, as of 17.2.6, rook is deploying Ceph-exporter and the service monitor instance to go with it. Unfortunately deleting the service monitor and Ceph-exporter won't work since the rook-operator will just put them back again. Will likely have to wait for either a fix from @travisn or wait until Ceph-exporter is corrected to sanitize all metric names before I can upgrade.

avanthakkar added a commit to avanthakkar/rook that referenced this pull request Apr 12, 2023
The expected ceph version for exporter is changed temporarily because some regression was detected in
Ceph version 17.2.6 which is summarised here ceph/ceph#50718 (comment).
Thus, disabling ceph-exporter for now until all the regression are fixed.
Signed-off-by: avanthakkar <avanjohn@gmail.com>
avanthakkar added a commit to avanthakkar/rook that referenced this pull request Apr 12, 2023
The expected ceph version for exporter is changed temporarily because some regression was detected in
Ceph version 17.2.6 which is summarised here ceph/ceph#50718 (comment).
Thus, disabling ceph-exporter for now until all the regression are fixed.

Signed-off-by: avanthakkar <avanjohn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants