feat: add etcd gRPC latency Grafana dashboard - #6643
feat: add etcd gRPC latency Grafana dashboard#6643Shaheen Sayyed (shaheen0b111) wants to merge 5 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: shaheen0b111 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Pull request overview
Adds a Grafana dashboard for monitoring HCP etcd gRPC latency across fleets and clusters.
Changes:
- Adds P95/P99 latency panels and SLO violation tables.
- Adds raw histogram and gRPC service/method/type breakdowns.
- Adds datasource, cluster, and namespace filtering variables.
Suppressed comments (9)
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1575
- This request-rate query sums a counter from every HA Prometheus replica. Managed Prometheus can expose the same scrape with different
prometheus_replicalabels, so the panel will report inflated req/s (often 2x) when multiple replicas are selected. Collapse that label before the outer aggregation, as done by other dashboards such asbackend/backend.json:209.
"expr": "sum by (grpc_service, grpc_method) (\n rate(grpc_server_handling_seconds_count{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n)",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:163
- This write-latency tile has the same multi-datasource issue:
lastNotNullreduces each regional response independently, so it does not produce one fleet-wide worst value when$datasourceis All. Merge the Mixed frames and reduce withmax, matching the fleet-stat pattern used byetcd-availability.json.
"reduceOptions": {
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:233
- This P95 read tile also reduces the per-workspace Mixed results with
lastNotNull, so it cannot reliably display the worst value across all regional datasources selected by default. Merge the frames and reduce withmaxbefore displaying the stat.
"reduceOptions": {
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:303
- This P95 write tile has the same problem:
lastNotNullis applied to separate regional Mixed responses, not to one merged fleet result. Merge the datasource frames and reduce withmaxso the tile matches its fleet-wide description.
"reduceOptions": {
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:953
- The write SLO table has the same multi-datasource problem: it only organizes each Mixed response and does not merge the regional frames, so it cannot reliably show all fleet violations together. Add a
mergetransformation beforeorganize, as with the existing etcd fleet tables.
"transformations": [
{
"id": "organize",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1287
- With Datasource=All, this breakdown is evaluated independently in each regional workspace. The same
grpc_serviceis therefore returned once per workspace, but the legend contains onlygrpc_service, producing duplicate unlabeled service series instead of an unambiguous fleet view. Include a region/data-source identity in the series or scope the panel to one datasource; apply the same treatment to the method/type/rate breakdowns.
"expr": "histogram_quantile(0.99,\n sum by (grpc_service, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"legendFormat": "{{ grpc_service }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1387
- With Datasource=All, this breakdown is evaluated independently in each regional workspace. The same
grpc_methodis therefore returned once per workspace, but the legend contains onlygrpc_method, producing duplicate unlabeled method series instead of an unambiguous fleet view. Include a region/data-source identity in the series or scope the panel to one datasource.
"expr": "histogram_quantile(0.99,\n sum by (grpc_method, le) (\n rate(grpc_server_handling_seconds_bucket{\n grpc_service=\"etcdserverpb.KV\",\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"legendFormat": "{{ grpc_method }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1576
- With Datasource=All, this request-rate breakdown is evaluated independently in each regional workspace. The legend contains only service and method, so identical operations from different workspaces appear as duplicate unlabeled series rather than an unambiguous fleet view. Include a region/data-source identity in the series or scope the panel to one datasource.
"expr": "sum by (grpc_service, grpc_method) (\n rate(grpc_server_handling_seconds_count{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n)",
"legendFormat": "{{ grpc_service }}/{{ grpc_method }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1482
- With Datasource=All, this breakdown is evaluated independently in each regional workspace. The same
grpc_typeis therefore returned once per workspace, but the legend contains onlygrpc_type, producing duplicate unlabeled type series instead of an unambiguous fleet view. Include a region/data-source identity in the series or scope the panel to one datasource.
"expr": "histogram_quantile(0.99,\n sum by (grpc_type, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"legendFormat": "{{ grpc_type }}",
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| @@ -0,0 +1,1790 @@ | |||
| { | |||
| "reduceOptions": { | ||
| "calcs": [ | ||
| "lastNotNull" | ||
| ], |
| "transformations": [ | ||
| { | ||
| "id": "organize", | ||
| "options": { | ||
| "excludeByName": { | ||
| "Time": true, | ||
| "__name__": true | ||
| }, | ||
| "indexByName": {}, | ||
| "renameByName": { | ||
| "Value": "P99 Latency", | ||
| "cluster": "Management Cluster", | ||
| "namespace": "Namespace" | ||
| } | ||
| } | ||
| } | ||
| ], |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (10)
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:93
- Because
$datasourceis a multi-select variable, thismax(...)is evaluated independently in each regional Prometheus workspace. The stat'slastNotNullreduction does not compute the maximum across those returned series, so the tile can show one workspace's value instead of the fleet worst value despite its title. Make this an instant query and add a cross-datasourcemaxreduction, following the aggregation pattern inetcd-availability.json.
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:163
- Because
$datasourceis a multi-select variable, thismax(...)is evaluated independently in each regional Prometheus workspace. The stat'slastNotNullreduction does not compute the maximum across those returned series, so the tile can show one workspace's value instead of the fleet worst value despite its title. Make this an instant query and add a cross-datasourcemaxreduction, following the aggregation pattern inetcd-availability.json.
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:233
- Because
$datasourceis a multi-select variable, thismax(...)is evaluated independently in each regional Prometheus workspace. The stat'slastNotNullreduction does not compute the maximum across those returned series, so the tile can show one workspace's value instead of the fleet worst value despite its title. Make this an instant query and add a cross-datasourcemaxreduction, following the aggregation pattern inetcd-availability.json.
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:303
- Because
$datasourceis a multi-select variable, thismax(...)is evaluated independently in each regional Prometheus workspace. The stat'slastNotNullreduction does not compute the maximum across those returned series, so the tile can show one workspace's value instead of the fleet worst value despite its title. Make this an instant query and add a cross-datasourcemaxreduction, following the aggregation pattern inetcd-availability.json.
"calcs": [
"lastNotNull"
],
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1
- The repository PR standard requires screenshots for dashboard/metrics visualization changes (CONTRIBUTING.md:95-98), but the PR description currently has no rendered dashboard screenshot and all validation steps remain unchecked. Please import the dashboard, complete the verification, and attach the required Grafana screenshot(s) before treating this PR as ready.
{
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:954
- The write violations table has the same multi-datasource issue as the read table: with
datasource=All, the instant query produces regional frames, but this chain has nomerge, so the displayed table may not contain all regions' violating clusters. Addmergebeforeorganize, as in the existing etcd fleet dashboard.
"transformations": [
{
"id": "organize",
"options": {
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1739
- The datasource variable is multi-valued and defaults to
All, but the dependentclusterandnamespacevariables below issue Prometheuslabel_values(...)queries through$datasource. Grafana variable queries require a single datasource; when$datasourceexpands to multiple sources/Mixed, these dropdown queries cannot be evaluated reliably, so the default dashboard will have empty/erroring filters and the cascade will not work. Keep the variable datasource single-select or redesign how cluster/namespace options are collected across regions.
"includeAll": true,
"name": "datasource",
"options": [],
"query": "prometheus",
"refresh": 1,
"regex": "^Managed_Prometheus_hcps-.*$",
"type": "datasource",
"multi": true
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:38
- The info panel presents
Compactas a KV gRPC method and maintenance operation, but the etcd protobuf RPC label used by the method breakdown isCompactiononetcdserverpb.KV(the Go client method isCompact). Operators will not find aCompactseries in the rawgrpc_methodbreakdown, so this reference is misleading; use the actual RPC name and service/category.
"content": "### HCP etcd gRPC Latency \u2014 Fleet Summary\n\nThis dashboard tracks **etcd gRPC request latency** (P99/P95) for HCP clusters across all regional Prometheus workspaces.\n\n- **SLO threshold**: 500ms P99 latency (gives 500ms headroom before KAS 1s SLO boundary)\n- **Metric source**: `grpc_server_handling_seconds` histogram (requires `ETCD_METRICS=extensive`)\n- **Alerts**: `userJourneyEtcdReadLatencyP99*` / `userJourneyEtcdWriteLatencyP99*` (MWMBR, RP lane)\n\n#### etcd gRPC Services\n\n| Service | Description |\n|---|---|\n| `etcdserverpb.KV` | Key-value store operations \u2014 primary data path for KAS reads/writes |\n| `etcdserverpb.Watch` | Watch streams for key change notifications (used by KAS informers) |\n| `etcdserverpb.Lease` | Lease management for TTL-based key expiration (leader election, endpoints) |\n| `etcdserverpb.Cluster` | Cluster membership operations (member add/remove/list) |\n| `etcdserverpb.Maintenance` | Maintenance operations (defrag, snapshot, alarm) |\n| `etcdserverpb.Auth` | Authentication and authorization (user/role management) |\n\n#### KV Methods (etcdserverpb.KV)\n\n| Method | Type | Description |\n|---|---|---|\n| `Range` | Read | Primary KAS read path \u2014 fetches keys/ranges from etcd store |\n| `Txn` | Write | Primary KAS write path \u2014 atomic compare-and-swap transactions |\n| `Put` | Write | Direct key-value writes (less common from KAS, used internally) |\n| `DeleteRange` | Write | Delete keys by range (garbage collection, resource deletion) |\n| `Compact` | Maintenance | History compaction \u2014 reclaims storage from old revisions |",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1299
- This panel description names
Compact, but thegrpc_methodlabel for the etcd KV protobuf RPC isCompaction; the current text therefore refers to a method that will not appear in this breakdown. Update the description to use the actual RPC name.
"description": "P99 latency broken down by gRPC method within etcdserverpb.KV (Range, Txn, Compact, etc.).",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:631
- When
datasource=All, this instant table query returns one frame per regional Prometheus datasource. Unlike the existing fleet SLO tables inetcd-availability.json, this transformation chain has nomerge, so regional rows are not reliably combined into one complete violations table. Add amergetransformation beforeorganize.
This issue also appears on line 951 of the same file.
"transformations": [
{
"id": "organize",
"options": {
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (8)
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1871
- Repository PR standards require screenshots for dashboard and metrics changes (CONTRIBUTING.md:95-98), but this PR description does not include a rendered dashboard screenshot. Please import the dashboard and attach the required before/after evidence (or explain why a before state is unavailable for this new dashboard) before approval.
"title": "HCP etcd gRPC Latency",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:106
- These primary summary, timeseries, and SLO panels depend entirely on the
etcd:grpc_server_handling:*recording rules introduced by #6351, but that dependency is currently still open/blocked. If this dashboard is imported before those rules are deployed, the main SLO views will be blank while only the raw-histogram section can render. Please gate the dashboard rollout on #6351 or provide a raw-metric fallback.
"expr": "max(etcd:grpc_server_handling:read_latency_p99:rate5m{cluster=~\"$cluster\",namespace=~\"$namespace\"})",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1766
- The P50/P99 table has the same multi-datasource ambiguity: both instant queries group only by service/method, and the following
mergehas no cluster, namespace, or datasource key to distinguish identical rows returned by different regional workspaces. With the defaultAllselection, rows can be duplicated or combined without identifying their source. Preserve those dimensions in the result, or restrict/document this table as a single-workspace view.
"expr": "histogram_quantile(0.99,\n sum by (grpc_service, grpc_method, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:106
- This stat target does not set
instant/range: false, so Grafana requests the full dashboard time range. Because the following transformations reduce withmax, this tile reports the highest latency observed during the selected window rather than the current worst cluster. Make the target instant (as inetcd-availability.json:212-215) so the reduction only combines the selected workspaces.
"expr": "max(etcd:grpc_server_handling:read_latency_p99:rate5m{cluster=~\"$cluster\",namespace=~\"$namespace\"})",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:195
- This stat target does not set
instant/range: false, so Grafana requests the full dashboard time range. Because the following transformations reduce withmax, this tile reports the highest latency observed during the selected window rather than the current worst cluster. Make the target instant (as inetcd-availability.json:212-215) so the reduction only combines the selected workspaces.
"expr": "max(etcd:grpc_server_handling:write_latency_p99:rate5m{cluster=~\"$cluster\",namespace=~\"$namespace\"})",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:284
- This stat target does not set
instant/range: false, so Grafana requests the full dashboard time range. Because the following transformations reduce withmax, this tile reports the highest latency observed during the selected window rather than the current worst cluster. Make the target instant (as inetcd-availability.json:212-215) so the reduction only combines the selected workspaces.
"expr": "max(etcd:grpc_server_handling:read_latency_p95:rate5m{cluster=~\"$cluster\",namespace=~\"$namespace\"})",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:373
- This stat target does not set
instant/range: false, so Grafana requests the full dashboard time range. Because the following transformations reduce withmax, this tile reports the highest latency observed during the selected window rather than the current worst cluster. Make the target instant (as inetcd-availability.json:212-215) so the reduction only combines the selected workspaces.
"expr": "max(etcd:grpc_server_handling:write_latency_p95:rate5m{cluster=~\"$cluster\",namespace=~\"$namespace\"})",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1370
- With the default
datasource=All, this target is evaluated independently in each regional Prometheus workspace. Because the aggregation and legend retain onlygrpc_service, identical service series from different workspaces are rendered with the same name rather than as one fleet aggregate or source-qualified series. The method/type/rate and P50/P99 panels use the same pattern; please either add source identity to these views or constrain them to one datasource.
"expr": "histogram_quantile(0.99,\n sum by (grpc_service, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1393
- This description also claims that the KV-method panel covers
Compact, but the query at line 1480 filtersgrpc_service="etcdserverpb.KV", soCompactcan never appear in this panel. RemoveCompactfrom the description or add a separate Maintenance-service panel.
"description": "P99 latency broken down by gRPC method within etcdserverpb.KV (Range, Txn, Compact, etc.).",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:38
- Please add the required rendered dashboard screenshot(s) to the PR description before approval. CONTRIBUTING.md requires screenshots for dashboard/metrics visualization changes; this new dashboard currently has no screenshot demonstrating the panels and variable behavior.
"content": "### HCP etcd gRPC Latency — Fleet Summary\n\nThis dashboard tracks **etcd gRPC request latency** (P99/P95) for HCP clusters across all regional Prometheus workspaces.\n\n- **SLO threshold**: 500ms P99 latency (gives 500ms headroom before KAS 1s SLO boundary)\n- **Metric source**: `grpc_server_handling_seconds` histogram (requires `ETCD_METRICS=extensive`)\n- **Alerts**: `userJourneyEtcdReadLatencyP99*` / `userJourneyEtcdWriteLatencyP99*` (MWMBR, RP lane)\n\n#### etcd gRPC Services\n\n| Service | Description |\n|---|---|\n| `etcdserverpb.KV` | Key-value store operations — primary data path for KAS reads/writes |\n| `etcdserverpb.Watch` | Watch streams for key change notifications (used by KAS informers) |\n| `etcdserverpb.Lease` | Lease management for TTL-based key expiration (leader election, endpoints) |\n| `etcdserverpb.Cluster` | Cluster membership operations (member add/remove/list) |\n| `etcdserverpb.Maintenance` | Maintenance operations (defrag, snapshot, alarm) |\n| `etcdserverpb.Auth` | Authentication and authorization (user/role management) |\n\n#### KV Methods (etcdserverpb.KV)\n\n| Method | Type | Description |\n|---|---|---|\n| `Range` | Read | Primary KAS read path — fetches keys/ranges from etcd store |\n| `Txn` | Write | Primary KAS write path — atomic compare-and-swap transactions |\n| `Put` | Write | Direct key-value writes (less common from KAS, used internally) |\n| `DeleteRange` | Write | Delete keys by range (garbage collection, resource deletion) |\n| `Compact` | Maintenance | History compaction — reclaims storage from old revisions |",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1844
- The
datasourcevariable is multi-valued and defaults toAll(line 1833), but Grafana's multi-datasource support is implemented for panel queries through MixedDataSource; a query variable'sdatasourcefield still cannot query every selected datasource. Referencing$datasourcehere therefore cannot populateclusterwhen multiple workspaces are selected, and the dependentnamespacevariable has the same problem below, so the promised cascading dropdowns will be empty or error by default. Use a single datasource for variable queries or redesign how these values are aggregated.
"datasource": {
"type": "prometheus",
"uid": "$datasource"
},
"definition": "label_values(grpc_server_handling_seconds_bucket{namespace=~\"ocm-.*\"},cluster)",
|
/retest-required |
|
/test image-updater-images |
1 similar comment
|
/test image-updater-images |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1380
- When
$datasourceis left at its defaultAll, Grafana executes this query independently in each regional workspace.sum by (grpc_service, le)removes cluster/namespace identity and the legend contains onlygrpc_service, so the panel shows indistinguishable same-named regional series rather than a clearly identified fleet result. Preserve a workspace/cluster identity in the output or explicitly label/document this as a per-region breakdown.
"expr": "histogram_quantile(0.99,\n sum by (grpc_service, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1
- Before this PR is marked ready, please attach a screenshot of the imported dashboard and complete the unchecked Grafana verification in the test plan.
CONTRIBUTING.md:95-98requires screenshots for dashboard/metrics changes, andCONTRIBUTING.md:105-108requires non-Tide checks to be green before review.
{
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:38
Compactis not anetcdserverpb.KVRPC; it belongs to the Maintenance service. The method panel below filters togrpc_service="etcdserverpb.KV", so this entry is documented under a table where it can never appear. Move it to a Maintenance-method reference or remove it from the KV table.
"content": "### HCP etcd gRPC Latency — Fleet Summary\n\nThis dashboard tracks **etcd gRPC request latency** (P99/P95) for HCP clusters across all regional Prometheus workspaces.\n\n- **SLO threshold**: 500ms P99 latency (gives 500ms headroom before KAS 1s SLO boundary)\n- **Metric source**: `grpc_server_handling_seconds` histogram (requires `ETCD_METRICS=extensive`)\n- **Alerts**: `userJourneyEtcdReadLatencyP99*` / `userJourneyEtcdWriteLatencyP99*` (MWMBR, RP lane)\n\n#### etcd gRPC Services\n\n| Service | Description |\n|---|---|\n| `etcdserverpb.KV` | Key-value store operations — primary data path for KAS reads/writes |\n| `etcdserverpb.Watch` | Watch streams for key change notifications (used by KAS informers) |\n| `etcdserverpb.Lease` | Lease management for TTL-based key expiration (leader election, endpoints) |\n| `etcdserverpb.Cluster` | Cluster membership operations (member add/remove/list) |\n| `etcdserverpb.Maintenance` | Maintenance operations (defrag, snapshot, alarm) |\n| `etcdserverpb.Auth` | Authentication and authorization (user/role management) |\n\n#### KV Methods (etcdserverpb.KV)\n\n| Method | Type | Description |\n|---|---|---|\n| `Range` | Read | Primary KAS read path — fetches keys/ranges from etcd store |\n| `Txn` | Write | Primary KAS write path — atomic compare-and-swap transactions |\n| `Put` | Write | Direct key-value writes (less common from KAS, used internally) |\n| `DeleteRange` | Write | Delete keys by range (garbage collection, resource deletion) |\n| `Compact` | Maintenance | History compaction — reclaims storage from old revisions |",
|
/test e2e-parallel |
Add a new Grafana dashboard for monitoring etcd gRPC request latency (P99/P95) across HCP clusters. Includes fleet summary stat tiles, per-cluster timeseries, SLO violation tables, raw histogram panels, and breakdown by gRPC service/method/type with cluster and namespace template variable filters. ARO-26896
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- Add seriesToRows/merge/reduce transformations on stat tiles to correctly compute fleet-wide max across multi-datasource results - Add merge transformation before organize on SLO violation tables to concatenate results from multiple regional Prometheus workspaces
Set instant: true / range: false on stat tile and SLO violation table targets, matching the etcd-availability.json pattern. Without this, stat tile max reduction picks the highest value across the entire dashboard time range instead of the current point-in-time.
4cf6086 to
ec049a8
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Suppressed comments (9)
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1381
- With the default datasource selection set to
All, this query runs once per regional Prometheus datasource. Grouping only bygrpc_serviceand using that alone as the legend discards cluster/namespace (and datasource) context, so the panel renders duplicate same-named lines representing separate regional P99s rather than a distinguishable fleet view. Preserve cluster/namespace in the grouping and legend, or explicitly reduce/document one series per region.
"expr": "histogram_quantile(0.99,\n sum by (grpc_service, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"legendFormat": "{{ grpc_service }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1481
- This method breakdown has the same cross-datasource ambiguity: when
datasource=All, each workspace returns a P99 per method, butcluster/namespaceare removed before the legend is rendered. The resulting duplicategrpc_methodseries cannot be tied to a region or HCP. Keep the cluster/namespace labels in the aggregation and legend, or restrict this panel to one datasource.
"expr": "histogram_quantile(0.99,\n sum by (grpc_method, le) (\n rate(grpc_server_handling_seconds_bucket{\n grpc_service=\"etcdserverpb.KV\",\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"legendFormat": "{{ grpc_method }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1576
- When all regional datasources are selected, this type breakdown also produces one
grpc_typeseries per workspace while discarding the labels that distinguish those workspaces. Grafana will show same-named lines with different regional P99s, making the breakdown misleading. Include cluster/namespace in both the aggregation and legend, or make the panel single-datasource.
"expr": "histogram_quantile(0.99,\n sum by (grpc_type, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"legendFormat": "{{ grpc_type }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1670
- With
datasource=All, this request-rate query fans out across workspaces, but its grouping and legend omit cluster/namespace. The chart therefore overlays separate regional rates under identical service/method names instead of providing distinguishable fleet data. Include the cluster/namespace dimensions in the grouping and legend, or explicitly select a single datasource.
"expr": "sum by (grpc_service, grpc_method) (\n rate(grpc_server_handling_seconds_count{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n)",
"legendFormat": "{{ grpc_service }}/{{ grpc_method }}",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1769
- The P50 and P99 targets in this table likewise aggregate away
cluster/namespace. Under the default multi-datasourceAllselection, the merged table contains duplicate service/method rows from different regional workspaces without any source context, so the displayed comparison is ambiguous. Preserve those dimensions and expose them in the table, or make this panel single-datasource.
"expr": "histogram_quantile(0.5,\n sum by (grpc_service, grpc_method, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
"format": "table",
"instant": true,
"legendFormat": "",
"refId": "P50"
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1
CONTRIBUTING.mdrequires before/after screenshots for dashboard, graph, and metrics changes, but the PR description includes none. Add the required annotated Grafana screenshot(s) showing the imported dashboard before requesting approval.
{
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1380
- This aggregation includes streaming RPCs in a panel labeled as request latency.
grpc_server_handling_secondsmeasures the full handling duration, soWatch/Leasebidi streams can dominate the P99 with connection lifetimes rather than request latency. Filter this query togrpc_type="unary", or separate/relabel the streaming-duration view.
"expr": "histogram_quantile(0.99,\n sum by (grpc_service, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1669
grpc_server_handling_seconds_countcounts completed handling observations; forWatch/Leasebidi streams it increments when a stream closes, not once per request. With nogrpc_typefilter, this panel can report stream-completion rate as request rate. Filter to unary RPCs or rename the panel to describe completed stream/handling rate.
"expr": "sum by (grpc_service, grpc_method) (\n rate(grpc_server_handling_seconds_count{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n)",
observability/grafana-dashboards/sre/user-journey/hcp-etcd-grpc-latency.json:1765
- The P50/P99 table also aggregates all service/method histograms without a
grpc_typefilter, soWatch/Leaserows represent stream lifetimes alongside unary method latency and can distort tail-latency diagnosis. Addgrpc_type="unary"to both targets, or label this table as handling/stream duration rather than request latency.
"expr": "histogram_quantile(0.5,\n sum by (grpc_service, grpc_method, le) (\n rate(grpc_server_handling_seconds_bucket{\n namespace=~\"$namespace\",\n cluster=~\"$cluster\"\n }[$__rate_interval])\n )\n)",
| "refresh": 1, | ||
| "regex": "^Managed_Prometheus_hcps-.*$", | ||
| "type": "datasource", | ||
| "multi": true |
There was a problem hiding this comment.
This is the established pattern used in the existing etcd-availability.json dashboard (same multi-value datasource with includeAll: true, same regex). The label_values() query runs against whichever datasource Grafana resolves first — this is a known Grafana limitation, not a bug in this dashboard. The panel targets use -- Mixed -- datasource which correctly fans out queries to all selected workspaces. The template variables serve as convenience filters; the data completeness comes from the mixed-datasource panel queries, not from the variable dropdown. No change needed.
Summary
hcp-etcd-grpc-latency.jsonfor monitoring etcd gRPC request latency (P99/P95) across HCP clustersetcd:grpc_server_handling:*) and rawgrpc_server_handling_secondshistogram with$__rate_intervalDepends on
ARO-26896
Test plan
Managed_Prometheus_hcps-*sourcesETCD_METRICS=extensive$__rate_intervalgrafanactl verify dashboards— passes