feat: gate telemetry behind Cargo feature flags (#8119)

Signed-off-by: Rodolfo Olivieri <rolivier@redhat.com>
Signed-off-by: Douwe Osinga <douwe@squareup.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
Rodolfo Olivieri
2026-03-26 13:33:43 -03:00
committed by GitHub
parent 8c8bb1051d
commit adc0e221fc
20 changed files with 111 additions and 38 deletions
+3 -1
View File
@@ -11,11 +11,13 @@ description.workspace = true
workspace = true
[features]
default = ["code-mode", "local-inference", "aws-providers", "rustls-tls"]
default = ["code-mode", "local-inference", "aws-providers", "telemetry", "otel", "rustls-tls"]
code-mode = ["goose/code-mode"]
local-inference = ["goose/local-inference"]
aws-providers = ["goose/aws-providers"]
cuda = ["goose/cuda", "local-inference"]
telemetry = ["goose/telemetry"]
otel = ["goose/otel"]
rustls-tls = [
"reqwest/rustls",
"tokio-tungstenite/rustls-tls-native-roots",
@@ -119,6 +119,7 @@ pub async fn run() -> Result<()> {
.await?;
}
#[cfg(feature = "otel")]
if goose::otel::otlp::is_otlp_initialized() {
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
goose::otel::otlp::shutdown_otlp();
+2
View File
@@ -5,6 +5,7 @@ use tracing_subscriber::{
Registry,
};
#[cfg(feature = "otel")]
use goose::otel::otlp;
use goose::tracing::langfuse_layer;
@@ -55,6 +56,7 @@ pub fn setup_logging(name: Option<&str>) -> Result<()> {
console_layer.with_filter(base_env_filter).boxed(),
];
#[cfg(feature = "otel")]
layers.extend(otlp::init_otlp_layers(goose::config::Config::global()));
if let Some(langfuse) = langfuse_layer::create_langfuse_observer() {
+6
View File
@@ -197,6 +197,7 @@ async fn start_agent(
State(state): State<Arc<AppState>>,
Json(payload): Json<StartAgentRequest>,
) -> Result<Json<Session>, ErrorResponse> {
#[cfg(feature = "telemetry")]
goose::posthog::set_session_context("desktop", false);
let StartAgentRequest {
@@ -212,6 +213,7 @@ async fn start_agent(
Ok(recipe) => Some(recipe),
Err(err) => {
error!("Failed to decode recipe deeplink: {}", err);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("recipe_deeplink_decode_failed", &err.to_string());
return Err(ErrorResponse {
message: err.to_string(),
@@ -253,6 +255,7 @@ async fn start_agent(
.await
.map_err(|err| {
error!("Failed to create session: {}", err);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("session_create_failed", &err.to_string());
ErrorResponse {
message: format!("Failed to create session: {}", err),
@@ -370,6 +373,7 @@ async fn resume_agent(
State(state): State<Arc<AppState>>,
Json(payload): Json<ResumeAgentRequest>,
) -> Result<Json<ResumeAgentResponse>, ErrorResponse> {
#[cfg(feature = "telemetry")]
goose::posthog::set_session_context("desktop", true);
let session = state
@@ -378,6 +382,7 @@ async fn resume_agent(
.await
.map_err(|err| {
error!("Failed to resume session {}: {}", payload.session_id, err);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("session_resume_failed", &err.to_string());
ErrorResponse {
message: format!("Failed to resume session: {}", err),
@@ -702,6 +707,7 @@ async fn agent_add_extension(
.add_extension(request.config, &request.session_id)
.await
.map_err(|e| {
#[cfg(feature = "telemetry")]
goose::posthog::emit_error(
"extension_add_failed",
&format!("{}: {}", extension_name, e),
+4
View File
@@ -213,6 +213,7 @@ async fn create_recipe(
}
Err(e) => {
tracing::error!("Error details: {:?}", e);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("recipe_create_failed", &e.to_string());
let error_response = CreateRecipeResponse {
recipe: None,
@@ -240,6 +241,7 @@ async fn encode_recipe(
Ok(encoded) => Ok(Json(EncodeRecipeResponse { deeplink: encoded })),
Err(err) => {
tracing::error!("Failed to encode recipe: {}", err);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("recipe_encode_failed", &err.to_string());
Err(StatusCode::BAD_REQUEST)
}
@@ -266,6 +268,7 @@ async fn decode_recipe(
},
Err(err) => {
tracing::error!("Failed to decode deeplink: {}", err);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("recipe_decode_failed", &err.to_string());
Err(StatusCode::BAD_REQUEST)
}
@@ -392,6 +395,7 @@ async fn schedule_recipe(
Ok(_) => Ok(StatusCode::OK),
Err(e) => {
tracing::error!("Failed to schedule recipe: {}", e);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("recipe_schedule_failed", &e.to_string());
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
@@ -403,6 +403,7 @@ async fn fork_session(
.await
.map_err(|e| {
tracing::error!("Failed to get session: {}", e);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("session_get_failed", &e.to_string());
ErrorResponse {
message: if e.to_string().contains("not found") {
@@ -423,6 +424,7 @@ async fn fork_session(
.await
.map_err(|e| {
tracing::error!("Failed to copy session: {}", e);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("session_copy_failed", &e.to_string());
ErrorResponse {
message: format!("Failed to copy session: {}", e),
@@ -441,6 +443,7 @@ async fn fork_session(
.await
.map_err(|e| {
tracing::error!("Failed to truncate conversation: {}", e);
#[cfg(feature = "telemetry")]
goose::posthog::emit_error("session_truncate_failed", &e.to_string());
ErrorResponse {
message: format!("Failed to truncate conversation: {}", e),
@@ -1,4 +1,5 @@
use axum::{extract::State, http::StatusCode, routing::post, Json, Router};
#[cfg(feature = "telemetry")]
use goose::posthog::emit_event;
use serde::Deserialize;
use std::collections::HashMap;
@@ -29,6 +30,7 @@ async fn send_telemetry_event(
let event_name = request.event_name;
let properties = request.properties;
#[cfg(feature = "telemetry")]
tokio::spawn(async move {
if let Err(e) = emit_event(&event_name, properties).await {
tracing::debug!("Failed to send telemetry event: {}", e);