Make the cache stats count what is cached, fetched and transcoded (closes #56) #144

Merged
clawbot merged 6 commits from issue-56-stats-counters into next 2026-09-29 05:25:11 +02:00
3 changed files with 24 additions and 18 deletions
Showing only changes of commit 31ed20ec9e - Show all commits
+8 -6
View File
@@ -46,12 +46,14 @@ exhaustion
counts the cached source images and processed variants (`source_content` counts the cached source images and processed variants (`source_content`
plus `variant_content`) and takes their size from `Cache.UsageBytes`, plus `variant_content`) and takes their size from `Cache.UsageBytes`,
instead of reading `request_cache` and `output_content`, which nothing instead of reading `request_cache` and `output_content`, which nothing
writes; those two tables are left in the schema. A miss is counted after writes; those two tables are left in the schema; a disabled disk cache
it is served or fails, even when the request context has ended by then, reports no items and no size. A hit is counted even when the request
with the bytes it read from upstream, so `upstream_fetch_count` and context has ended. A miss is counted after it is served or fails, also
`upstream_fetch_bytes` move, including for an upstream body that fails when the request context has ended by then, with the bytes it read from
partway or a fetched source that then fails the magic byte check; upstream, so `upstream_fetch_count` and `upstream_fetch_bytes` move,
`transform_count` counts each image the image processor transcodes. including for an upstream body that fails partway or a fetched source
that then fails the magic byte check; `transform_count` counts each image
the image processor transcodes.
- 2026-09-28 strip metadata from processed images (closes #82): every output is - 2026-09-28 strip metadata from processed images (closes #82): every output is
exported with govips' `StripMetadata`, so it carries no EXIF, XMP, IPTC or ICC exported with govips' `StripMetadata`, so it carries no EXIF, XMP, IPTC or ICC
profile; the image is first turned upright with `AutoRotate` (before sizes are profile; the image is first turned upright with `AutoRotate` (before sizes are
+14 -11
View File
@@ -419,18 +419,21 @@ func (c *Cache) Stats(ctx context.Context) (*CacheStats, error) {
return nil, fmt.Errorf("failed to get cache stats: %w", err) return nil, fmt.Errorf("failed to get cache stats: %w", err)
} }
// Count and size the cached source images and processed variants // Count and size the cached source images and processed variants. A
err = c.db.QueryRowContext(ctx, ` // disabled cache holds none, whatever rows an earlier run left.
SELECT (SELECT COUNT(*) FROM source_content) if !c.disabled {
+ (SELECT COUNT(*) FROM variant_content) err = c.db.QueryRowContext(ctx, `
`).Scan(&stats.TotalItems) SELECT (SELECT COUNT(*) FROM source_content)
if err != nil { + (SELECT COUNT(*) FROM variant_content)
c.log.Warn("failed to count cache items for stats", "error", err) `).Scan(&stats.TotalItems)
} if err != nil {
c.log.Warn("failed to count cache items for stats", "error", err)
}
stats.TotalSizeBytes, err = c.UsageBytes(ctx) stats.TotalSizeBytes, err = c.UsageBytes(ctx)
if err != nil { if err != nil {
c.log.Warn("failed to sum cache size for stats", "error", err) c.log.Warn("failed to sum cache size for stats", "error", err)
}
} }
// Compute hit rate as a ratio // Compute hit rate as a ratio
+2 -1
View File
@@ -143,7 +143,8 @@ func (s *Service) Get(ctx context.Context, req *ImageRequest) (*ImageResponse, e
s.log.Error("failed to get cached variant", "key", result.CacheKey, "error", err) s.log.Error("failed to get cached variant", "key", result.CacheKey, "error", err)
// Fall through to re-process // Fall through to re-process
} else { } else {
s.cache.IncrementStats(ctx, true, 0) // Counted also when the request context has ended meanwhile
s.cache.IncrementStats(context.WithoutCancel(ctx), true, 0)
return &ImageResponse{ return &ImageResponse{
Content: reader, Content: reader,