From 40d7583906643fe21829fb0ce99de05b335b0f23 Mon Sep 17 00:00:00 2001 From: "Alex Chi Z." <4198311+skyzh@users.noreply.github.com> Date: Tue, 10 Jun 2025 15:10:41 +0800 Subject: [PATCH] feat(pageserver): use hostname as feature flag resolver property (#12141) ## Problem part of https://github.com/neondatabase/neon/issues/11813 ## Summary of changes Collect pageserver hostname property so that we can use it in the PostHog UI. Not sure if this is the best way to do that -- open to suggestions. --------- Signed-off-by: Alex Chi Z --- libs/remote_storage/src/s3_bucket.rs | 1 + pageserver/src/feature_resolver.rs | 31 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/libs/remote_storage/src/s3_bucket.rs b/libs/remote_storage/src/s3_bucket.rs index d98ff552ee..004aad447e 100644 --- a/libs/remote_storage/src/s3_bucket.rs +++ b/libs/remote_storage/src/s3_bucket.rs @@ -1022,6 +1022,7 @@ impl RemoteStorage for S3Bucket { let Version { key, .. } = &vd; let version_id = vd.version_id().map(|v| v.0.as_str()); if version_id == Some("null") { + // TODO: check the behavior of using the SDK on a non-versioned container return Err(TimeTravelError::Other(anyhow!( "Received ListVersions response for key={key} with version_id='null', \ indicating either disabled versioning, or legacy objects with null version id values" diff --git a/pageserver/src/feature_resolver.rs b/pageserver/src/feature_resolver.rs index 50de3b691c..84edd68011 100644 --- a/pageserver/src/feature_resolver.rs +++ b/pageserver/src/feature_resolver.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; +use pageserver_api::config::NodeMetadata; use posthog_client_lite::{ CaptureEvent, FeatureResolverBackgroundLoop, PostHogClientConfig, PostHogEvaluationError, PostHogFlagFilterPropertyValue, @@ -86,7 +87,35 @@ impl FeatureResolver { } } } - // TODO: add pageserver URL. + // TODO: move this to a background task so that we don't block startup in case of slow disk + let metadata_path = conf.metadata_path(); + match std::fs::read_to_string(&metadata_path) { + Ok(metadata_str) => match serde_json::from_str::(&metadata_str) { + Ok(metadata) => { + properties.insert( + "hostname".to_string(), + PostHogFlagFilterPropertyValue::String(metadata.http_host), + ); + if let Some(cplane_region) = metadata.other.get("region_id") { + if let Some(cplane_region) = cplane_region.as_str() { + // This region contains the cell number + properties.insert( + "neon_region".to_string(), + PostHogFlagFilterPropertyValue::String( + cplane_region.to_string(), + ), + ); + } + } + } + Err(e) => { + tracing::warn!("Failed to parse metadata.json: {}", e); + } + }, + Err(e) => { + tracing::warn!("Failed to read metadata.json: {}", e); + } + } Arc::new(properties) }; let fake_tenants = {