diff --git a/products/feature_flags/backend/tasks.py b/products/feature_flags/backend/tasks.py index 9440181e4dae..34fafa034707 100644 --- a/products/feature_flags/backend/tasks.py +++ b/products/feature_flags/backend/tasks.py @@ -16,7 +16,10 @@ from posthog.api.capture import capture_batch_internal from posthog.models.team import Team from posthog.scoping_audit import skip_team_scope_audit -from posthog.storage.hypercache_manager import HYPERCACHE_SIGNAL_UPDATE_COUNTER +from posthog.storage.hypercache_manager import ( + HYPERCACHE_SIGNAL_UPDATE_COUNTER, + get_cache_stats as get_cache_stats_generic, +) from posthog.tasks.utils import CeleryQueue, PushGatewayTask from products.feature_flags.backend.canary import run_local_eval_canary @@ -489,11 +492,18 @@ def refresh_expiring_flag_definitions_cache_entries(self: PushGatewayTask) -> No successful_gauge.set(counts.successful) failed_gauge.set(counts.failed) + # Scan after refresh for metrics (pushes to Pushgateway via get_cache_stats) + stats_after = get_cache_stats_generic(FLAG_DEFINITIONS_HYPERCACHE_MANAGEMENT_CONFIG) + duration = time.time() - start_time logger.info( "Completed flag definitions cache refresh", successful_refreshes=counts.successful, failed_refreshes=counts.failed, + total_cached=stats_after.get("total_cached", 0), + total_teams=stats_after.get("total_teams", 0), + cache_coverage=stats_after.get("cache_coverage", "unknown"), + ttl_distribution=stats_after.get("ttl_distribution", {}), duration_seconds=duration, ) diff --git a/products/feature_flags/backend/test/test_flag_definitions_cache_tasks.py b/products/feature_flags/backend/test/test_flag_definitions_cache_tasks.py index 3785384ecebb..1b06a512cfbb 100644 --- a/products/feature_flags/backend/test/test_flag_definitions_cache_tasks.py +++ b/products/feature_flags/backend/test/test_flag_definitions_cache_tasks.py @@ -5,6 +5,7 @@ from posthog.storage.cache_expiry_manager import CacheRefreshCounts from posthog.tasks.test.utils import PushGatewayTaskTestMixin +from products.feature_flags.backend.local_evaluation import FLAG_DEFINITIONS_HYPERCACHE_MANAGEMENT_CONFIG from products.feature_flags.backend.tasks import ( cleanup_stale_flag_definitions_expiry_tracking_task, refresh_expiring_flag_definitions_cache_entries, @@ -12,8 +13,9 @@ class TestRefreshExpiringFlagDefinitionsCacheEntries(PushGatewayTaskTestMixin, TestCase): + @patch("products.feature_flags.backend.tasks.get_cache_stats_generic", return_value={}) @patch("posthog.storage.cache_expiry_manager.refresh_expiring_caches") - def test_refreshes_cache(self, mock_refresh: MagicMock) -> None: + def test_refreshes_cache(self, mock_refresh: MagicMock, mock_stats: MagicMock) -> None: mock_refresh.return_value = CacheRefreshCounts(successful=5, failed=0) refresh_expiring_flag_definitions_cache_entries() @@ -21,6 +23,7 @@ def test_refreshes_cache(self, mock_refresh: MagicMock) -> None: mock_refresh.assert_called_once() assert self.registry.get_sample_value("posthog_flag_definitions_cache_refresh_successful_count") == 5 assert self.registry.get_sample_value("posthog_flag_definitions_cache_refresh_failed_count") == 0 + mock_stats.assert_called_once_with(FLAG_DEFINITIONS_HYPERCACHE_MANAGEMENT_CONFIG) @patch("posthog.storage.cache_expiry_manager.refresh_expiring_caches") def test_propagates_error(self, mock_refresh: MagicMock) -> None: