88
99use dogstatsd:: aggregator:: AggregatorHandle ;
1010use dogstatsd:: metric:: { Metric , MetricValue , SortedTags } ;
11- use std :: env ;
11+ use libdd_common :: azure_app_services ;
1212use tracing:: { error, warn} ;
1313
1414const INSTANCE_METRIC : & str = "azure.functions.enhanced.instance" ;
1515
16- /// Resolves the instance ID from explicit values (used by tests).
17- ///
18- /// Picks the env var that matches the Azure integration metric's `instance`
19- /// tag for the current hosting plan with fallback logic
20- /// if the preferred source is empty.
21- fn resolve_instance_id_from (
22- website_sku : Option < & str > ,
23- container_name : Option < & str > ,
24- website_pod_name : Option < & str > ,
25- computer_name : Option < & str > ,
26- ) -> Option < String > {
27- fn non_empty ( s : Option < & str > ) -> Option < & str > {
28- s. filter ( |v| !v. is_empty ( ) )
29- }
30-
31- let sku_preferred = match website_sku {
32- Some ( "FlexConsumption" ) | Some ( "Dynamic" ) => {
33- non_empty ( container_name) . or ( non_empty ( website_pod_name) )
34- }
35- Some ( _) => non_empty ( computer_name) ,
36- None => None ,
37- } ;
38-
39- sku_preferred
40- . or_else ( || non_empty ( container_name) )
41- . or_else ( || non_empty ( website_pod_name) )
42- . or_else ( || non_empty ( computer_name) )
43- . map ( |s| s. to_lowercase ( ) )
44- }
45-
46- /// Resolves the instance ID from environment variables.
47- fn resolve_instance_id ( ) -> Option < String > {
48- resolve_instance_id_from (
49- env:: var ( "WEBSITE_SKU" ) . ok ( ) . as_deref ( ) ,
50- env:: var ( "CONTAINER_NAME" ) . ok ( ) . as_deref ( ) ,
51- env:: var ( "WEBSITE_POD_NAME" ) . ok ( ) . as_deref ( ) ,
52- env:: var ( "COMPUTERNAME" ) . ok ( ) . as_deref ( ) ,
53- )
54- }
55-
5616pub struct InstanceMetricsCollector {
5717 aggregator : AggregatorHandle ,
5818 tags : Option < SortedTags > ,
@@ -61,8 +21,12 @@ pub struct InstanceMetricsCollector {
6121impl InstanceMetricsCollector {
6222 /// Creates a new collector, returning `None` if no instance ID is found.
6323 pub fn new ( aggregator : AggregatorHandle , tags : Option < SortedTags > ) -> Option < Self > {
64- let instance_id = resolve_instance_id ( ) ;
65- let Some ( instance_id) = instance_id else {
24+ let instance_name = azure_app_services:: AAS_METADATA_FUNCTION
25+ . as_ref ( )
26+ . map ( |m| m. get_instance_name ( ) . to_lowercase ( ) )
27+ . filter ( |n| n != azure_app_services:: UNKNOWN_VALUE ) ;
28+
29+ let Some ( instance_id) = instance_name else {
6630 warn ! ( "No instance ID found, instance metric will not be submitted" ) ;
6731 return None ;
6832 } ;
@@ -95,82 +59,3 @@ impl InstanceMetricsCollector {
9559 }
9660 }
9761}
98-
99- #[ cfg( test) ]
100- mod tests {
101- use super :: * ;
102-
103- #[ test]
104- fn test_flex_consumption_uses_container_name ( ) {
105- let id = resolve_instance_id_from (
106- Some ( "FlexConsumption" ) ,
107- Some ( "0--abc-DEF" ) ,
108- Some ( "0--abc-DEF" ) ,
109- None ,
110- ) ;
111- assert_eq ! ( id, Some ( "0--abc-def" . to_string( ) ) ) ;
112- }
113-
114- #[ test]
115- fn test_flex_consumption_falls_back_to_pod_name_if_container_missing ( ) {
116- let id = resolve_instance_id_from ( Some ( "FlexConsumption" ) , None , Some ( "pod-XYZ" ) , None ) ;
117- assert_eq ! ( id, Some ( "pod-xyz" . to_string( ) ) ) ;
118- }
119-
120- #[ test]
121- fn test_consumption_uses_container_name ( ) {
122- let id = resolve_instance_id_from (
123- Some ( "Dynamic" ) ,
124- Some ( "ABCD1234-111122223333444455" ) ,
125- None ,
126- None ,
127- ) ;
128- assert_eq ! ( id, Some ( "abcd1234-111122223333444455" . to_string( ) ) ) ;
129- }
130-
131- #[ test]
132- fn test_elastic_premium_uses_computer_name ( ) {
133- let id =
134- resolve_instance_id_from ( Some ( "ElasticPremium" ) , None , None , Some ( "ep0fakewk0000A1" ) ) ;
135- assert_eq ! ( id, Some ( "ep0fakewk0000a1" . to_string( ) ) ) ;
136- }
137-
138- #[ test]
139- fn test_dedicated_uses_computer_name ( ) {
140- let id = resolve_instance_id_from ( Some ( "PremiumV3" ) , None , None , Some ( "p3fakewk0000B2" ) ) ;
141- assert_eq ! ( id, Some ( "p3fakewk0000b2" . to_string( ) ) ) ;
142- }
143-
144- #[ test]
145- fn test_empty_string_is_treated_as_missing ( ) {
146- let id =
147- resolve_instance_id_from ( Some ( "ElasticPremium" ) , Some ( "" ) , Some ( "" ) , Some ( "worker-1" ) ) ;
148- assert_eq ! ( id, Some ( "worker-1" . to_string( ) ) ) ;
149- }
150-
151- #[ test]
152- fn test_unknown_sku_falls_back_to_search_order ( ) {
153- let id = resolve_instance_id_from ( Some ( "SomeNewSku" ) , Some ( "container-1" ) , None , None ) ;
154- assert_eq ! ( id, Some ( "container-1" . to_string( ) ) ) ;
155- }
156-
157- #[ test]
158- fn test_missing_sku_falls_back_to_search_order ( ) {
159- let id = resolve_instance_id_from ( None , Some ( "container-1" ) , None , Some ( "worker-1" ) ) ;
160- assert_eq ! ( id, Some ( "container-1" . to_string( ) ) ) ;
161- }
162-
163- #[ test]
164- fn test_no_env_vars_returns_none ( ) {
165- let id = resolve_instance_id_from ( None , None , None , None ) ;
166- assert_eq ! ( id, None ) ;
167- }
168-
169- // On Windows Consumption we've observed CONTAINER_NAME and WEBSITE_POD_NAME
170- // unset but COMPUTERNAME set
171- #[ test]
172- fn test_windows_consumption_falls_through_to_computer_name ( ) {
173- let id = resolve_instance_id_from ( Some ( "Dynamic" ) , None , None , Some ( "10-20-30-40" ) ) ;
174- assert_eq ! ( id, Some ( "10-20-30-40" . to_string( ) ) ) ;
175- }
176- }
0 commit comments