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

Prometheus metrics #504

Closed
wants to merge 7 commits into from
Closed

Conversation

thinkharderdev
Copy link
Contributor

@thinkharderdev thinkharderdev commented Nov 8, 2022

Which issue does this PR close?

Closes #427

Rationale for this change

We should expose metrics from the scheduler in a standard format. This PR adds an initial integration with prometheus to expose some basic scheduler metrics

What changes are included in this PR?

  1. Add a new trait SchedulerMetricsCollector which is plugged into the core event loop to capture metrics
  2. Add some additional metadata to the job events so we can track durations of the different parts of the query lifecycle (queued, planning, execution) separately.
  3. Add an implementation of SchedulerMetricsCollector for prometheus
  4. Add an API endpoint /api/metrics which will expose metrics.
  5. Add some baseline metrics

In addition, I did some refactoring to make the core event loop more testable. Currently you can't really test it rigorously at all which is not great since it is a rather critical piece of code. I added a new trait TaskLauncher which can control how the TaskManager which actually launch tasks and various crate-private methods to plug in a custom launcher. I don't imagine this will ever be something exposed through a public API but it is very useful for testing.

Using the TaskLauncher I added some additional utilities to write scheduler test more succinctly.

Are there any user-facing changes?

Users can plug in their own metrics collector if they want.

No

Comment on lines +24 to +42
let execution_time = register_histogram_with_registry!(
"query_time_seconds",
"Histogram of query execution time in seconds",
vec![0.5_f64, 1_f64, 5_f64, 30_f64, 60_f64],
registry
)
.map_err(|e| {
BallistaError::Internal(format!("Error registering metric: {:?}", e))
})?;

let planning_time = register_histogram_with_registry!(
"planning_time_ms",
"Histogram of query planning time in milliseconds",
vec![1.0_f64, 5.0_f64, 25.0_f64, 100.0_f64, 500.0_f64],
registry
)
.map_err(|e| {
BallistaError::Internal(format!("Error registering metric: {:?}", e))
})?;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These histograms are hard to generalize since use cases could vary wildly. We can either:

  1. Make these configurable
  2. Try and choose sensible defaults and if someone needs to customize then they can implement a custom collector

Comment on lines -412 to +486
let value = self.encode_execution_graph(graph.clone())?;

let value = encode_protobuf(&graph.status())?;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

First bug uncovered while testing the event loop proper :) When a job would fail we would save the entire graph into FailedJobs here but in all other scenarios we only save the status

@andygrove
Copy link
Member

This is awesome! Thanks @thinkharderdev. I will make time to try this out later this week.

@thinkharderdev thinkharderdev marked this pull request as ready for review November 8, 2022 19:00
@thinkharderdev
Copy link
Contributor Author

I think this is ready for review. I had to tweak how we do the API routing slightly because the prometheus exporter probably won't send an application/json Accept header and I'm not sure it is guaranteed to send any particular Accept header so changed the routing to look at the path instead. But I was able to verify the metrics are exported.

@andygrove
Copy link
Member

I filed #507 for writing documentation in the user guide for this feature.

@andygrove andygrove added this to the Ballista 0.10.0 milestone Nov 10, 2022
@andygrove
Copy link
Member

I pulled this branch and ran into a build issue:

  = note: /home/andy/miniconda3/envs/dask-sql/bin/../lib/gcc/x86_64-conda-linux-gnu/12.1.0/../../../../x86_64-conda-linux-gnu/bin/ld: /home/andy/git/apache/arrow-ballista/target/release/deps/libprocfs-372835ba76b41348.rlib(procfs-372835ba76b41348.procfs.efebeec9-cgu.3.rcgu.o): in function `procfs::CpuTime::from_str':
          procfs.efebeec9-cgu.3:(.text._ZN6procfs7CpuTime8from_str17hf1b21a01a95d1a1cE+0x7b): undefined reference to `getauxval'

It is building OK in CI though so I am confused. Any ideas @thinkharderdev?

@thinkharderdev
Copy link
Contributor Author

Hmm... I haven't seen this locally but is looks like something when building the prometheus-rs crate. What OS are you using?

@thinkharderdev
Copy link
Contributor Author

I filed #507 for writing documentation in the user guide for this feature.

Awesome. I'll have another PR shortly that will add the pending tasks queue tracking. I can add some initial documentation as part of that PR.

@andygrove
Copy link
Member

Hmm... I haven't seen this locally but is looks like something when building the prometheus-rs crate. What OS are you using?

Ubuntu 20.04.4 LTS

@thinkharderdev
Copy link
Contributor Author

@andygrove This PR is superseded by #511 which has some tweaks to make the plug-ability more useful so if we're good with the other PR we should just merge that one and I can close this one. I'll leave it open for the moment in case it's easier to review them separately.

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.

Provide integration with Grafana / Prometheus
2 participants