feat(#223): map logical usageMetrics names to catalog metrics so models price from the catalog - #228
Merged
Merged
Conversation
…ls price from the catalog
Models author usageMetrics with logical names (e.g. "natHours", "keysCount");
the pricing catalog is keyed by usage_metric names ("NAT-Gateway-Hour",
"KMS-Key-Month"). The engine queried the catalog with the raw logical key, which
never matched, so every node silently fell back to embedded pricingRates and the
catalog (live Infracost + seed) was effectively unreachable — contradicting
Principle 13.
- Add a per-handler `catalog_metrics` map (logical -> catalog usage_metric) on
the resource types that correspond to catalog rows: NAT Gateway, VPC Endpoint,
Elastic IP, CloudWatch Logs + Metrics/Alarms, KMS, Secrets Manager, ECR,
Route53, and Data Transfer. Keyed per handler (not per service) because
resources of the same service reuse a logical name for a different catalog
metric (dataProcessedGb -> NAT-Gateway-DataProcessed vs VPC-Endpoint-DataProcessed;
storedGb -> ECR-Storage vs CloudWatch-Log-Storage).
- ResourceRegistry.resolve_catalog_metric(address, logical) resolves via the
owning handler.
- The engine (flat + tiered cost paths) now retries the catalog query with the
mapped name when the raw name misses, before falling back to pricingRates.
Fully backward compatible: raw name tried first; unmapped names and non-handler
addresses keep using pricingRates.
Tests: per-handler resolution incl. shared-logical-name disambiguation; an
end-to-end aggregate where a NAT node authored with "natHours" prices from the
catalog ($32.85 = 730 x $0.045); unmapped-metric pricingRates fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #223. Connects the pricing catalog to DAG models. Previously the catalog (live Infracost + seed) was unreachable from real models: nodes author
usageMetricswith logical names (natHours,keysCount), but the catalog is keyed byusage_metricnames (NAT-Gateway-Hour,KMS-Key-Month). The engine queried the catalog with the raw logical key → always missed → silently fell back to embeddedpricingRates, contradicting Principle 13.Changes
catalog_metricsmap (logical → catalogusage_metric) on the resource types that correspond to catalog rows: NAT Gateway, VPC Endpoint, Elastic IP, CloudWatch Logs + Metrics/Alarms, KMS, Secrets Manager, ECR, Route53, Data Transfer. Derived directly from each handler's_*_costfunction so the names are exact.dataProcessedGb→NAT-Gateway-DataProcessedvsVPC-Endpoint-DataProcessed;storedGb→ECR-StoragevsCloudWatch-Log-Storage.ResourceRegistry.resolve_catalog_metric(address, logical)resolves via the handler that owns the node'sresourceAddress.pricingRatesfallback.Backward compatibility
Fully preserved: the raw metric name is tried first (nodes already using catalog names keep working), and unmapped logical names / non-handler addresses fall back to
pricingRatesexactly as before.Test plan
resolve_catalog_metric: per-handler resolution incl. shared-logical-name disambiguation (NAT vs VPCdataProcessedGb), unknown address / unmapped name →None.CostAggregator: a NAT node authored withnatHoursprices from the catalog ($32.85 = 730 × $0.045), reachable only if the mapping resolved.pricingRatesfallback still applies.Note: handlers whose example models use ad-hoc metric names not equal to their
valid_metrics(e.g. ALBlcus, Lambdagb_seconds) are not mapped here — those names are ambiguous and can be aligned/added incrementally. This PR establishes the mechanism and covers the handlers with unambiguous catalog metrics.