defect_cli/
observability.rs1use std::time::Duration;
11
12use defect_config::LangfuseConfig;
13use defect_obs::LangfuseObserver;
14use defect_obs::langfuse::{
15 DEFAULT_FLUSH_INTERVAL, DEFAULT_HOST, DEFAULT_MAX_BATCH, LangfuseSetup, build_observer,
16};
17
18pub fn build_langfuse_observer(
31 config: Option<&LangfuseConfig>,
32 http_stack_config: defect_http::HttpStackConfig,
33) -> anyhow::Result<Option<LangfuseObserver>> {
34 let Some(cfg) = config.filter(|c| c.enabled) else {
35 return Ok(None);
36 };
37
38 let (Some(public_key), Some(secret_key)) = (cfg.public_key.clone(), cfg.secret_key.clone())
39 else {
40 tracing::warn!(
41 "tracing.langfuse.enabled = true but public_key / secret_key missing; \
42 langfuse reporting disabled"
43 );
44 return Ok(None);
45 };
46
47 let http = defect_http::build_http_stack(http_stack_config)
48 .map_err(|e| anyhow::anyhow!("langfuse http stack init failed: {e}"))?;
49
50 let setup = LangfuseSetup {
51 host: cfg.host.clone().unwrap_or_else(|| DEFAULT_HOST.to_string()),
52 public_key,
53 secret_key,
54 flush_interval: cfg
55 .flush_interval_ms
56 .map_or(DEFAULT_FLUSH_INTERVAL, Duration::from_millis),
57 max_batch: cfg.max_batch.unwrap_or(DEFAULT_MAX_BATCH),
58 };
59
60 Ok(Some(build_observer(setup, http)))
61}