Skip to content

Commit 11c14a3

Browse files
feat: No longer launch Go-based agent for compatibility/OTLP/AAP config (#788)
https://datadoghq.atlassian.net/browse/SVLS-7398 - As part of coming release, bottlecap agent no longer launches Go-based agent when compatibility/AAP/OTLP features are active - Emit the same metric when detecting any of above configuration - Update corresponding unit tests Manifests: - [Test lambda function](https://us-east-1.console.aws.amazon.com/lambda/home?region=us-east-1#/functions/ltn1-fullinstrument-bn-cold-python310-lambda?code=&subtab=envVars&tab=testing) with [logs](https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logsV2:log-groups/log-group/$252Faws$252Flambda$252Fltn1-fullinstrument-bn-cold-python310-lambda/log-events/2025$252F08$252F21$252F$255B$2524LATEST$255Df3788d359677452dad162488ff15456f$3FfilterPattern$3Dotel) showing compatibility/AAP/OTPL are enabled <img width="2260" height="454" alt="image" src="https://github.com/user-attachments/assets/5dfd4954-5191-4390-83f5-a8eb3bffb9d3" /> - [Logging](https://app.datadoghq.com/logs/livetail?query=functionname%3Altn1-fullinstrument-bn-cold-python310-lambda%20Metric&agg_m=count&agg_m_source=base&agg_t=count&cols=host%2Cservice&fromUser=true&messageDisplay=inline&refresh_mode=paused&storage=driveline&stream_sort=desc&viz=stream&from_ts=1755787655569&to_ts=1755787689060&live=false) <img width="1058" height="911" alt="image" src="https://github.com/user-attachments/assets/629f75d1-e115-4478-afac-ad16d9369fa7" /> - [Metric](https://app.datadoghq.com/screen/integration/aws_lambda_enhanced_metrics?fromUser=false&fullscreen_end_ts=1755788220000&fullscreen_paused=true&fullscreen_refresh_mode=paused&fullscreen_section=overview&fullscreen_start_ts=1755787200000&fullscreen_widget=2&graph-explorer__tile_def=N4IgbglgXiBcIBcD2AHANhAzgkAaEAxgK7ZIC2A%2BhgHYDWmcA2gLr4BOApgI5EfYOxGoTphRJqmDhQBmSNmQCGOeJgIK0CtnhA8ObCHyagAJkoUVMSImwIc4IMhwT6CDfNQWP7utgE8AjNo%2BvvaYRGSwpggKxkgA5gB0kmxgemh8mAkcAB4IHBIQ4gnSChBoSKlswAAkCgDumBQKBARW1Ai41ZxxhdSd0kTUBAi9AL4ABABGvuPAA0Mj4h6OowkKja2DCAAUAJTaCnFx3UpyoeEgo6wgsvJEGgJCN3Jk9wrevH6BV-iWbMqgTbtOAAJgADPg5MY9BRpkZEL4UHZ4LdXhptBBqNDsnAISAoXp7NDVJdmKMfiBsL50nBgOSgA&refresh_mode=sliding&from_ts=1755783890661&to_ts=1755787490661&live=true) <img width="1227" height="1196" alt="image" src="https://github.com/user-attachments/assets/2922eb54-9853-4512-a902-dfa97916b643" />
1 parent 5294bd6 commit 11c14a3

File tree

5 files changed

+187
-104
lines changed

5 files changed

+187
-104
lines changed

bottlecap/src/bin/bottlecap/main.rs

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use bottlecap::{
3737
},
3838
logger,
3939
logs::{agent::LogsAgent, flusher::LogsFlusher},
40+
metrics::enhanced::lambda::Lambda as enhanced_metrics,
4041
otlp::{agent::Agent as OtlpAgent, should_enable_otlp_agent},
4142
proxy::{interceptor, should_start_proxy},
4243
secrets::decrypt,
@@ -85,9 +86,7 @@ use std::{
8586
collections::{HashMap, hash_map},
8687
env,
8788
io::{Error, Result},
88-
os::unix::process::CommandExt,
8989
path::Path,
90-
process::Command,
9190
sync::Arc,
9291
time::{Duration, Instant},
9392
};
@@ -403,14 +402,7 @@ fn load_configs(start_time: Instant) -> (AwsConfig, AwsCredentials, Arc<Config>)
403402
let aws_credentials = AwsCredentials::from_env();
404403
let lambda_directory: String =
405404
env::var("LAMBDA_TASK_ROOT").unwrap_or_else(|_| "/var/task".to_string());
406-
let config = match config::get_config(Path::new(&lambda_directory)) {
407-
Ok(config) => Arc::new(config),
408-
Err(_e) => {
409-
let err = Command::new("/opt/datadog-agent-go").exec();
410-
panic!("Error starting the extension: {err:?}");
411-
}
412-
};
413-
405+
let config = Arc::new(config::get_config(Path::new(&lambda_directory)));
414406
(aws_config, aws_credentials, config)
415407
}
416408

@@ -509,11 +501,22 @@ async fn extension_loop_active(
509501
);
510502
start_dogstatsd_aggregator(metrics_aggr_service);
511503

504+
let metrics_intake_url = create_metrics_intake_url_prefix(config);
512505
let metrics_flushers = Arc::new(TokioMutex::new(start_metrics_flushers(
513506
Arc::clone(&api_key_factory),
514507
&metrics_aggr_handle,
508+
&metrics_intake_url,
515509
config,
516510
)));
511+
512+
// Create lambda enhanced metrics instance once
513+
let lambda_enhanced_metrics =
514+
enhanced_metrics::new(metrics_aggr_handle.clone(), Arc::clone(config));
515+
516+
// Send config issue metrics
517+
let config_issues = config::fallback(config);
518+
send_config_issue_metric(&config_issues, &lambda_enhanced_metrics);
519+
517520
// Lifecycle Invocation Processor
518521
let invocation_processor = Arc::new(TokioMutex::new(InvocationProcessor::new(
519522
Arc::clone(&tags_provider),
@@ -1012,33 +1015,33 @@ fn start_logs_agent(
10121015
(logs_agent_channel, logs_flusher)
10131016
}
10141017

1015-
fn start_metrics_flushers(
1016-
api_key_factory: Arc<ApiKeyFactory>,
1017-
metrics_aggr_handle: &MetricsAggregatorHandle,
1018-
config: &Arc<Config>,
1019-
) -> Vec<MetricsFlusher> {
1020-
let mut flushers = Vec::new();
1021-
1022-
let metrics_intake_url = if !config.dd_url.is_empty() {
1018+
fn create_metrics_intake_url_prefix(config: &Config) -> MetricsIntakeUrlPrefix {
1019+
if !config.dd_url.is_empty() {
10231020
let dd_dd_url = DdDdUrl::new(config.dd_url.clone()).expect("can't parse DD_DD_URL");
1024-
10251021
let prefix_override = MetricsIntakeUrlPrefixOverride::maybe_new(None, Some(dd_dd_url));
1026-
MetricsIntakeUrlPrefix::new(None, prefix_override)
1022+
MetricsIntakeUrlPrefix::new(None, prefix_override).expect("can't parse DD_DD_URL prefix")
10271023
} else if !config.url.is_empty() {
10281024
let dd_url = DdUrl::new(config.url.clone()).expect("can't parse DD_URL");
1029-
10301025
let prefix_override = MetricsIntakeUrlPrefixOverride::maybe_new(Some(dd_url), None);
1031-
MetricsIntakeUrlPrefix::new(None, prefix_override)
1026+
MetricsIntakeUrlPrefix::new(None, prefix_override).expect("can't parse DD_URL prefix")
10321027
} else {
1033-
// use site
10341028
let metrics_site = MetricsSite::new(config.site.clone()).expect("can't parse site");
1035-
MetricsIntakeUrlPrefix::new(Some(metrics_site), None)
1036-
};
1029+
MetricsIntakeUrlPrefix::new(Some(metrics_site), None).expect("can't parse site prefix")
1030+
}
1031+
}
1032+
1033+
fn start_metrics_flushers(
1034+
api_key_factory: Arc<ApiKeyFactory>,
1035+
metrics_aggr_handle: &MetricsAggregatorHandle,
1036+
metrics_intake_url: &MetricsIntakeUrlPrefix,
1037+
config: &Arc<Config>,
1038+
) -> Vec<MetricsFlusher> {
1039+
let mut flushers = Vec::new();
10371040

10381041
let flusher_config = MetricsFlusherConfig {
10391042
api_key_factory,
10401043
aggregator_handle: metrics_aggr_handle.clone(),
1041-
metrics_intake_url_prefix: metrics_intake_url.expect("can't parse site or override"),
1044+
metrics_intake_url_prefix: metrics_intake_url.clone(),
10421045
https_proxy: config.proxy_https.clone(),
10431046
timeout: Duration::from_secs(config.flush_timeout),
10441047
retry_strategy: DsdRetryStrategy::Immediate(3),
@@ -1163,6 +1166,28 @@ fn start_trace_agent(
11631166
)
11641167
}
11651168

1169+
/// Sends metrics indicating issue with configuration.
1170+
///
1171+
/// # Arguments
1172+
/// * `issue_reasons` - Vector of messages describing the issue with the configurations
1173+
/// * `lambda_enhanced_metrics` - The lambda enhanced metrics instance
1174+
fn send_config_issue_metric(issue_reasons: &[String], lambda_enhanced_metrics: &enhanced_metrics) {
1175+
if issue_reasons.is_empty() {
1176+
return;
1177+
}
1178+
let now = std::time::UNIX_EPOCH
1179+
.elapsed()
1180+
.expect("can't poll clock")
1181+
.as_secs()
1182+
.try_into()
1183+
.unwrap_or_default();
1184+
1185+
// Setup a separate metric for each config issue reason
1186+
for issue_reason in issue_reasons {
1187+
lambda_enhanced_metrics.set_config_load_issue_metric(now, issue_reason);
1188+
}
1189+
}
1190+
11661191
fn start_dogstatsd_aggregator(aggr_service: MetricsAggregatorService) {
11671192
tokio::spawn(async move {
11681193
aggr_service.run().await;

0 commit comments

Comments
 (0)