Skip to content

Commit

Permalink
Add graphql query complexity histogram metric (#2349)
Browse files Browse the repository at this point in the history
## Linked Issues/PRs
Closes #2274

## Checklist
- [x] Breaking changes are clearly marked as such in the PR description
and changelog
- [x] New behavior is reflected in tests
- [x] [The specification](https://github.com/FuelLabs/fuel-specs/)
matches the implemented behavior (link update PR if changes are needed)

### Before requesting review
- [x] I have reviewed the code myself
- [x] I have created follow-up issues caused by this PR and linked them
here

Co-authored-by: Green Baneling <[email protected]>
  • Loading branch information
AurelienFT and xgreenx authored Oct 14, 2024
1 parent 7528047 commit aba4d36
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- [2335](https://github.com/FuelLabs/fuel-core/pull/2335): Added CLI arguments for configuring GraphQL query costs.

### Added
- [2347](https://github.com/FuelLabs/fuel-core/pull/2347): Add GraphQL complexity histogram

## [Version 0.39.0]

### Added
Expand Down
13 changes: 13 additions & 0 deletions crates/fuel-core/src/graphql_api/metrics_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ use async_graphql::{
NextParseQuery,
NextRequest,
NextResolve,
NextValidation,
ResolveInfo,
},
parser::types::ExecutableDocument,
Response,
ServerError,
ServerResult,
ValidationResult,
Value,
Variables,
};
Expand Down Expand Up @@ -118,4 +121,14 @@ impl Extension for MetricsExtInner {

res
}

async fn validation(
&self,
ctx: &ExtensionContext<'_>,
next: NextValidation<'_>,
) -> Result<ValidationResult, Vec<ServerError>> {
let result = next.run(ctx).await?;
graphql_metrics().graphql_complexity_observe(result.complexity as f64);
Ok(result)
}
}
29 changes: 29 additions & 0 deletions crates/metrics/src/graphql_metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ pub struct GraphqlMetrics {
// using gauges in case blocks are rolled back for any reason
pub total_txs_count: Gauge,
requests: Family<Label, Histogram>,
queries_complexity: Histogram,
}

impl GraphqlMetrics {
fn new() -> Self {
let tx_count_gauge = Gauge::default();
let queries_complexity = Histogram::new(buckets_complexity());
let requests = Family::<Label, Histogram>::new_with_constructor(|| {
Histogram::new(timing_buckets().iter().cloned())
});
let mut registry = global_registry().registry.lock();
registry.register("graphql_request_duration_seconds", "", requests.clone());
registry.register(
"graphql_query_complexity",
"The complexity of all queries received",
queries_complexity.clone(),
);

registry.register(
"importer_tx_count",
Expand All @@ -41,6 +48,7 @@ impl GraphqlMetrics {

Self {
total_txs_count: tx_count_gauge,
queries_complexity,
requests,
}
}
Expand All @@ -51,9 +59,30 @@ impl GraphqlMetrics {
});
histogram.observe(time);
}

pub fn graphql_complexity_observe(&self, complexity: f64) {
self.queries_complexity.observe(complexity);
}
}

static GRAPHQL_METRICS: OnceLock<GraphqlMetrics> = OnceLock::new();
pub fn graphql_metrics() -> &'static GraphqlMetrics {
GRAPHQL_METRICS.get_or_init(GraphqlMetrics::new)
}

fn buckets_complexity() -> impl Iterator<Item = f64> {
[
1_000.0,
5_000.0,
10_000.0,
20_000.0,
50_000.0,
100_000.0,
250_000.0,
500_000.0,
1_000_000.0,
5_000_000.0,
10_000_000.0,
]
.into_iter()
}

0 comments on commit aba4d36

Please sign in to comment.