-
Notifications
You must be signed in to change notification settings - Fork 1
[SVLS-9015] Use consts and instance resolution logic from libdd-common #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2b238f4
aea46d5
3f1029b
dd18630
2f0fb8c
3515b51
56f6df1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,51 +8,11 @@ | |
|
|
||
| use dogstatsd::aggregator::AggregatorHandle; | ||
| use dogstatsd::metric::{Metric, MetricValue, SortedTags}; | ||
| use std::env; | ||
| use libdd_common::azure_app_services; | ||
| use tracing::{error, warn}; | ||
|
|
||
| const INSTANCE_METRIC: &str = "azure.functions.enhanced.instance"; | ||
|
|
||
| /// Resolves the instance ID from explicit values (used by tests). | ||
| /// | ||
| /// Picks the env var that matches the Azure integration metric's `instance` | ||
| /// tag for the current hosting plan with fallback logic | ||
| /// if the preferred source is empty. | ||
| fn resolve_instance_id_from( | ||
| website_sku: Option<&str>, | ||
| container_name: Option<&str>, | ||
| website_pod_name: Option<&str>, | ||
| computer_name: Option<&str>, | ||
| ) -> Option<String> { | ||
| fn non_empty(s: Option<&str>) -> Option<&str> { | ||
| s.filter(|v| !v.is_empty()) | ||
| } | ||
|
|
||
| let sku_preferred = match website_sku { | ||
| Some("FlexConsumption") | Some("Dynamic") => { | ||
| non_empty(container_name).or(non_empty(website_pod_name)) | ||
| } | ||
| Some(_) => non_empty(computer_name), | ||
| None => None, | ||
| }; | ||
|
|
||
| sku_preferred | ||
| .or_else(|| non_empty(container_name)) | ||
| .or_else(|| non_empty(website_pod_name)) | ||
| .or_else(|| non_empty(computer_name)) | ||
| .map(|s| s.to_lowercase()) | ||
| } | ||
|
|
||
| /// Resolves the instance ID from environment variables. | ||
| fn resolve_instance_id() -> Option<String> { | ||
| resolve_instance_id_from( | ||
| env::var("WEBSITE_SKU").ok().as_deref(), | ||
| env::var("CONTAINER_NAME").ok().as_deref(), | ||
| env::var("WEBSITE_POD_NAME").ok().as_deref(), | ||
| env::var("COMPUTERNAME").ok().as_deref(), | ||
| ) | ||
| } | ||
|
|
||
| pub struct InstanceMetricsCollector { | ||
| aggregator: AggregatorHandle, | ||
| tags: Option<SortedTags>, | ||
|
|
@@ -61,8 +21,12 @@ pub struct InstanceMetricsCollector { | |
| impl InstanceMetricsCollector { | ||
| /// Creates a new collector, returning `None` if no instance ID is found. | ||
| pub fn new(aggregator: AggregatorHandle, tags: Option<SortedTags>) -> Option<Self> { | ||
| let instance_id = resolve_instance_id(); | ||
| let Some(instance_id) = instance_id else { | ||
| let instance_name = azure_app_services::AAS_METADATA_FUNCTION | ||
| .as_ref() | ||
| .map(|m| m.get_instance_name().to_lowercase()) | ||
| .filter(|n| n != azure_app_services::UNKNOWN_VALUE); | ||
|
|
||
|
Comment on lines
+24
to
+28
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| let Some(instance_id) = instance_name else { | ||
| warn!("No instance ID found, instance metric will not be submitted"); | ||
| return None; | ||
|
Comment on lines
21
to
31
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like unit tests would be redundant since we have tests for the instance name resolution in libdatadog but happy to add if we feel they're needed! |
||
| }; | ||
|
|
@@ -95,82 +59,3 @@ impl InstanceMetricsCollector { | |
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn test_flex_consumption_uses_container_name() { | ||
| let id = resolve_instance_id_from( | ||
| Some("FlexConsumption"), | ||
| Some("0--abc-DEF"), | ||
| Some("0--abc-DEF"), | ||
| None, | ||
| ); | ||
| assert_eq!(id, Some("0--abc-def".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_flex_consumption_falls_back_to_pod_name_if_container_missing() { | ||
| let id = resolve_instance_id_from(Some("FlexConsumption"), None, Some("pod-XYZ"), None); | ||
| assert_eq!(id, Some("pod-xyz".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_consumption_uses_container_name() { | ||
| let id = resolve_instance_id_from( | ||
| Some("Dynamic"), | ||
| Some("ABCD1234-111122223333444455"), | ||
| None, | ||
| None, | ||
| ); | ||
| assert_eq!(id, Some("abcd1234-111122223333444455".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_elastic_premium_uses_computer_name() { | ||
| let id = | ||
| resolve_instance_id_from(Some("ElasticPremium"), None, None, Some("ep0fakewk0000A1")); | ||
| assert_eq!(id, Some("ep0fakewk0000a1".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_dedicated_uses_computer_name() { | ||
| let id = resolve_instance_id_from(Some("PremiumV3"), None, None, Some("p3fakewk0000B2")); | ||
| assert_eq!(id, Some("p3fakewk0000b2".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_empty_string_is_treated_as_missing() { | ||
| let id = | ||
| resolve_instance_id_from(Some("ElasticPremium"), Some(""), Some(""), Some("worker-1")); | ||
| assert_eq!(id, Some("worker-1".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_unknown_sku_falls_back_to_search_order() { | ||
| let id = resolve_instance_id_from(Some("SomeNewSku"), Some("container-1"), None, None); | ||
| assert_eq!(id, Some("container-1".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_missing_sku_falls_back_to_search_order() { | ||
| let id = resolve_instance_id_from(None, Some("container-1"), None, Some("worker-1")); | ||
| assert_eq!(id, Some("container-1".to_string())); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_no_env_vars_returns_none() { | ||
| let id = resolve_instance_id_from(None, None, None, None); | ||
| assert_eq!(id, None); | ||
| } | ||
|
|
||
| // On Windows Consumption we've observed CONTAINER_NAME and WEBSITE_POD_NAME | ||
| // unset but COMPUTERNAME set | ||
| #[test] | ||
| fn test_windows_consumption_falls_through_to_computer_name() { | ||
| let id = resolve_instance_id_from(Some("Dynamic"), None, None, Some("10-20-30-40")); | ||
| assert_eq!(id, Some("10-20-30-40".to_string())); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In
FlexConsumption/DynamicAzure Functions where Azure also exposesCOMPUTERNAME, this now takes the instance name from the pinnedlibdd-commonmetadata resolver, which prioritizesCOMPUTERNAMEbeforeWEBSITE_POD_NAME/CONTAINER_NAME. The previous implementation deliberately used the container/pod values for those SKUs so theazure.functions.enhanced.instancetag matched the Azure integration'sinstancedimension; usingCOMPUTERNAMEin that scenario causes the enhanced instance metric to be attributed under a different instance tag.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In
FlexConsumption/DynamicAzure Functions,COMPUTERNAMEis unset. My investigation to identify what env vars should be used for each hosting plan can be found here