Skip to content

Separate artifact and metadata cache metrics on /metrics and the analytics page - #463

Open
abhinavgautam01 wants to merge 3 commits into
git-pkgs:mainfrom
abhinavgautam01:fix/metadata-cache-metrics-416
Open

abhinavgautam01 wants to merge 3 commits into
git-pkgs:mainfrom
abhinavgautam01:fix/metadata-cache-metrics-416

Conversation

@abhinavgautam01

Copy link
Copy Markdown
Contributor

Closes #416

Problem

Metadata cache hits were recorded in proxy_cache_hits_total with only an ecosystem label, so they could not be told apart from artifact hits. Cache size and download totals only covered artifacts. On /ui/analytics the Runtime card's hit rate pooled both kinds while every figure above it described artifacts alone, which is the mismatch in the issue's screenshot.

Changes

Metrics

Metric Change
proxy_cache_hits_total New kind label: artifact or metadata
proxy_cache_misses_total New kind label: artifact or metadata
proxy_metadata_cache_served_bytes_total{ecosystem} New counter: metadata bytes served from the cache
proxy_metadata_cache_size_bytes{ecosystem} New gauge: size of cached metadata documents
proxy_metadata_cache_entries{ecosystem} New gauge: number of cached metadata documents
  • RecordCacheHit and RecordCacheMiss are replaced by one function per kind (RecordArtifactCacheHit, RecordMetadataCacheHit and so on), so a call site cannot pass an arbitrary label value.
  • Every existing call site is classified:
    • artifact: artifact downloads and the Gradle build cache
    • metadata: lookupMetadata and the stored-rewrite fast path in rewrite_cache.go
  • Each request still records exactly one hit or miss, as before.
  • The two gauges are read from the persistent metadata_cache table on the same one-minute tick as the artifact gauges. Aliases such as gem and rubygems share a series and ecosystems that disappear are removed, matching UpdateEcosystemStats.
  • Bytes served is a process counter rather than a database total, because the metadata cache does not record hits per row. Adding that would mean a database write on every metadata request.

Analytics page

  • New Metadata cache card with total documents, total size and a per-ecosystem table. It notes when cache_metadata is off and reports a failed query rather than showing an empty cache.
  • The Runtime card shows artifact and metadata lookups separately, each with its own hit rate, plus metadata bytes served from cache.
  • The headline tile now reads Artifact hit rate, so it describes the same cache as the figures above it.

Docs

The README metrics table is updated. A short section explains the two caches and how to query each kind.

Compatibility

  • Adding a label keeps existing sum(...) queries working. Every query in deploy/grafana/git-pkgs-proxy.json already aggregates with sum, so the dashboard keeps working unchanged.
  • Its hit-ratio panel still covers both kinds. Filtering it to kind="artifact" would match the analytics page and I can add that here if wanted.
  • Queries that select a single series without aggregating, for example proxy_cache_hits_total{ecosystem="npm"}, now return two series.

Tests

  • Metrics: kinds land in separate series, only metadata hits add served bytes, labels are normalized and the gauge updater merges aliases and removes ecosystems that disappear.
  • Database: GetMetadataCacheStats on an empty cache, alias merging and rows with no recorded size.
  • Handler: the metadata TTL test now asserts served bytes and that artifact hits stay unchanged. A new test covers the stored-rewrite hit path. Existing artifact, Gradle and metadata tests assert on the right kind.
  • Server: runtime view split by kind, the metadata cache view and the analytics page with caching on and off.

Recording metadata hits as artifact hits again makes both new metadata hit tests fail.

go build, go vet, golangci-lint (v2.13.1), go test -race ./... and Swagger regeneration all pass locally.

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, the split looks right and every call site is classified correctly. Two things before merging:

internal/server/analytics.go:217 runs GetMetadataCacheStats() (a full GROUP BY over metadata_cache) on every analytics page load, while the ticker in server.go runs the same query separately for the gauges. The artifact figures on the same page come from the s.ecoStats 60-second snapshot, and the README says the page and gauges read the same snapshot. Please put the metadata stats behind that snapshot (or a small one alongside it) and have both the page and updateMetadataCacheStats read from it.

deploy/grafana/git-pkgs-proxy.json: the headline hit-ratio stat (line 368) still pools artifact and metadata, which is the confusion #416 reported. Please filter it to kind="artifact" to match the analytics tile, and change the hit/miss rate panels (lines 984 and 996) to sum by (kind) so the two kinds show as separate series.

@abhinavgautam01

Copy link
Copy Markdown
Contributor Author

Thanks, both addressed:

  • Metadata stats now come from a snapshot alongside s.ecoStats. I made the cache generic (statsCache, with ecosystemStatsCache and metadataStatsCache as aliases), so both keep the same TTL, error retry and last-good behavior. The page reads it with Get and updateMetadataCacheStats refreshes it with Refresh, so page loads no longer query. Added tests for both.
  • Grafana: the hit-ratio stat is filtered to kind="artifact" (now titled "Artifact cache hit ratio") and the hit and miss rate panels use sum by (kind) with per-kind legends.

Also merged main to resolve the conflicts. The new Arch database and signature hits and the Go sumdb tile hit read from the metadata cache, so they are now recorded as metadata hits.

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.

Metadata cache metrics not exposed (or recorded/labeled)

2 participants