diff --git a/.gitignore b/.gitignore index df769d2..0dd34a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /.idea +/.worktrees diff --git a/Cargo.toml b/Cargo.toml index cb438b9..68b902c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ repository = "https://github.com/DataDog/serverless-components" [profile.release] opt-level = "z" -lto = true +lto = "fat" codegen-units = 1 -strip = true +strip = "symbols" +panic = "abort" diff --git a/crates/datadog-trace-agent/src/http_utils.rs b/crates/datadog-trace-agent/src/http_utils.rs index c330cf2..090f58f 100644 --- a/crates/datadog-trace-agent/src/http_utils.rs +++ b/crates/datadog-trace-agent/src/http_utils.rs @@ -114,6 +114,23 @@ pub fn verify_request_content_length( None } +/// Environment variable set by the Lambda runtime to indicate the initialisation type. +/// Lambda Lite (web function / snap-start mode) sets this to `"native-http"`; +/// standard on-demand invocations set it to `"on-demand"`. +const ENV_LAMBDA_INIT_TYPE: &str = "AWS_LAMBDA_INITIALIZATION_TYPE"; + +/// Returns true if the current environment is Lambda Lite (web function / snap start mode). +/// +/// Determined by checking [`ENV_LAMBDA_INIT_TYPE`]` == "native-http"`. This is used to gate +/// behaviour specific to long-running web server deployments on Lambda Lite. +pub fn is_lambda_lite() -> bool { + is_lambda_lite_from_env(std::env::var(ENV_LAMBDA_INIT_TYPE).ok().as_deref()) +} + +fn is_lambda_lite_from_env(val: Option<&str>) -> bool { + val == Some("native-http") +} + /// Builds a reqwest client with optional proxy configuration and timeout. /// Uses rustls TLS by default. FIPS-compliant TLS is available via the fips feature pub fn build_client( @@ -135,8 +152,29 @@ mod tests { use hyper::StatusCode; use libdd_common::hyper_migration; + use super::is_lambda_lite_from_env; use super::verify_request_content_length; + #[test] + fn test_is_lambda_lite_native_http() { + assert!(is_lambda_lite_from_env(Some("native-http"))); + } + + #[test] + fn test_is_lambda_lite_on_demand() { + assert!(!is_lambda_lite_from_env(Some("on-demand"))); + } + + #[test] + fn test_is_lambda_lite_empty_string() { + assert!(!is_lambda_lite_from_env(Some(""))); + } + + #[test] + fn test_is_lambda_lite_unset() { + assert!(!is_lambda_lite_from_env(None)); + } + fn create_test_headers_with_content_length(val: &str) -> HeaderMap { let mut map = HeaderMap::new(); map.insert(header::CONTENT_LENGTH, val.parse().unwrap()); diff --git a/crates/datadog-trace-agent/src/mini_agent.rs b/crates/datadog-trace-agent/src/mini_agent.rs index 6af32b1..4c2ec51 100644 --- a/crates/datadog-trace-agent/src/mini_agent.rs +++ b/crates/datadog-trace-agent/src/mini_agent.rs @@ -31,6 +31,10 @@ const PROFILING_ENDPOINT_PATH: &str = "/profiling/v1/input"; const TRACER_PAYLOAD_CHANNEL_BUFFER_SIZE: usize = 10; const STATS_PAYLOAD_CHANNEL_BUFFER_SIZE: usize = 10; const PROXY_PAYLOAD_CHANNEL_BUFFER_SIZE: usize = 10; +/// Sentinel file written on startup in Lambda Lite mode. +/// dd-trace (Node.js) checks this path via DATADOG_MINI_AGENT_PATH in constants.js +/// to decide whether to switch from LogExporter (stdout) to AgentExporter (HTTP :8126). +const LAMBDA_LITE_SENTINEL_PATH: &str = "/tmp/datadog/mini_agent_ready"; pub struct MiniAgent { pub config: Arc, @@ -147,6 +151,18 @@ impl MiniAgent { now.elapsed().as_millis() ); + // Write a sentinel file so that Node.js dd-trace detects a running agent and + // switches from LogExporter (stdout) to AgentExporter (HTTP :8126). + // Only written for Lambda Lite; standard Lambda invocations use the Lambda + // Extension path (/opt/extensions/datadog-agent) instead. + // /opt is read-only in Lambda Lite, so we use /tmp/datadog/ (created by the + // serverless-compat JS layer before spawning this binary). + if crate::http_utils::is_lambda_lite() { + if let Err(e) = std::fs::write(LAMBDA_LITE_SENTINEL_PATH, b"") { + debug!("Could not write mini agent sentinel file: {}", e); + } + } + if let Some(pipe_name) = pipe_name_opt { // Windows named pipe transport #[cfg(all(windows, feature = "windows-pipes"))]