Skip to content
11 changes: 11 additions & 0 deletions bottlecap/src/bin/bottlecap/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ async fn main() -> anyhow::Result<()> {
.map_err(|e| anyhow::anyhow!("Failed to create client: {e:?}"))?;
cold_start_durations.create_extensions_api_client_ms = elapsed_ms(step_start_time);

// Lambda starts the runtime once every extension has registered, and
// tracers probe `/info` early in their init. Bind the trace agent's port
// before registering, so that probe queues instead of being refused.
let trace_listener = bottlecap::traces::trace_agent::TraceAgent::bind_listener(None)
.inspect_err(|e| error!("Error starting trace agent: {e:?}"))
.ok();

let cloned_client = client.clone();
let runtime_api = aws_config.runtime_api.clone();
let managed_instance_mode = aws_config.is_managed_instance_mode();
Expand Down Expand Up @@ -193,6 +200,7 @@ async fn main() -> anyhow::Result<()> {
&r,
Arc::clone(&api_key_factory),
cold_start_durations,
trace_listener,
)
.await
{
Expand Down Expand Up @@ -326,6 +334,7 @@ async fn extension_loop_idle(
}

#[allow(clippy::too_many_lines)]
#[allow(clippy::too_many_arguments)]
async fn extension_loop_active(
aws_config: Arc<AwsConfig>,
config: &Arc<Config>,
Expand All @@ -334,6 +343,7 @@ async fn extension_loop_active(
r: &RegisterResponse,
api_key_factory: Arc<ApiKeyFactory>,
mut cold_start_durations: ColdStartDurations,
trace_listener: Option<tokio::net::TcpListener>,
) -> anyhow::Result<()> {
let (mut event_bus, event_bus_tx) = EventBus::run();

Expand Down Expand Up @@ -462,6 +472,7 @@ async fn extension_loop_active(
appsec_processor.clone(),
&shared_client,
Arc::clone(&proxy_aggregator),
trace_listener,
);

let api_runtime_proxy_shutdown_signal = start_api_runtime_proxy(
Expand Down
31 changes: 19 additions & 12 deletions bottlecap/src/startup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,19 @@ pub fn build_trace_agent(
}

/// Builds the trace-processing pipeline with [`build_trace_agent`] and spawns
/// the [`trace_agent::TraceAgent`] HTTP listener onto the current tokio
/// runtime. Convenience entry point for callers that do not need to
/// the [`trace_agent::TraceAgent`] HTTP server on `listener` onto the current
/// tokio runtime. Convenience entry point for callers that do not need to
/// further configure the `TraceAgent` before spawning it.
///
/// Errors from `TraceAgent::start` (TCP bind failures, router-extension
/// failures, axum serve errors) are logged and discarded; the surrounding
/// pipeline keeps running with a dead trace channel. Callers that need to
/// react to startup errors should use [`build_trace_agent`] and spawn the
/// agent themselves.
/// `listener` comes from [`trace_agent::TraceAgent::bind_listener`], called
/// before the extension registers. `None` means that bind failed (the caller
/// logged it), and no trace agent is served.
///
/// Errors from `TraceAgent::start_with_listener` (router-extension failures,
/// axum serve errors) are logged and discarded; the surrounding pipeline keeps
/// running with a dead trace channel. Callers that need to react to startup
/// errors should use [`build_trace_agent`] and spawn the agent themselves.
#[allow(clippy::too_many_arguments)]
pub fn start_trace_agent(
config: &Arc<Config>,
api_key_factory: &Arc<ApiKeyFactory>,
Expand All @@ -240,6 +244,7 @@ pub fn start_trace_agent(
appsec_processor: Option<Arc<TokioMutex<AppSecProcessor>>>,
client: &reqwest::Client,
proxy_aggregator: Arc<TokioMutex<proxy_aggregator::Aggregator>>,
listener: Option<tokio::net::TcpListener>,
) -> TraceAgentPipeline {
let (trace_agent, pipeline) = build_trace_agent(
config,
Expand All @@ -252,11 +257,13 @@ pub fn start_trace_agent(
None,
);

tokio::spawn(async move {
if let Err(e) = trace_agent.start().await {
error!("Error starting trace agent: {e:?}");
}
});
if let Some(listener) = listener {
tokio::spawn(async move {
if let Err(e) = trace_agent.start_with_listener(listener).await {
error!("Error starting trace agent: {e:?}");
}
});
}

pipeline
}
Expand Down
Loading
Loading