refactor(logging): consolidate logging setup into shared helper in goose crate (#8817)
Signed-off-by: Rodolfo Olivieri <rolivier@redhat.com> Signed-off-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -51,7 +51,6 @@ serde_json = { workspace = true, features = ["preserve_order"] }
|
||||
futures = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt", "json", "time"] }
|
||||
tracing-appender = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
|
||||
@@ -1,71 +1,17 @@
|
||||
use anyhow::Result;
|
||||
use tracing_appender::rolling::Rotation;
|
||||
use tracing_subscriber::{
|
||||
filter::LevelFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer,
|
||||
Registry,
|
||||
};
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
|
||||
#[cfg(feature = "otel")]
|
||||
use goose::otel::otlp;
|
||||
use goose::tracing::langfuse_layer;
|
||||
|
||||
/// Sets up the logging infrastructure for the application.
|
||||
/// This includes:
|
||||
/// - File-based logging with JSON formatting (DEBUG level)
|
||||
/// - Console output for development (INFO level)
|
||||
/// - Optional Langfuse integration (DEBUG level)
|
||||
/// Sets up the logging infrastructure for the server.
|
||||
/// Logs go to a JSON file and a pretty console layer on stderr.
|
||||
pub fn setup_logging(name: Option<&str>) -> Result<()> {
|
||||
let log_dir = goose::logging::prepare_log_directory("server", true)?;
|
||||
let timestamp = chrono::Local::now().format("%Y%m%d_%H%M%S").to_string();
|
||||
let log_filename = if let Some(n) = name {
|
||||
format!("{}-{}.log", timestamp, n)
|
||||
} else {
|
||||
format!("{}.log", timestamp)
|
||||
let config = goose::logging::LoggingConfig {
|
||||
component: "server",
|
||||
name,
|
||||
extra_directives: &["goose_server=info", "tower_http=info"],
|
||||
console: true,
|
||||
json: false,
|
||||
};
|
||||
let file_appender =
|
||||
tracing_appender::rolling::RollingFileAppender::new(Rotation::NEVER, log_dir, log_filename);
|
||||
|
||||
// Create JSON file logging layer
|
||||
let file_layer = fmt::layer()
|
||||
.with_target(true)
|
||||
.with_level(true)
|
||||
.with_writer(file_appender)
|
||||
.with_ansi(false)
|
||||
.with_file(true);
|
||||
|
||||
let base_env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
||||
EnvFilter::new("")
|
||||
.add_directive("mcp_client=info".parse().unwrap())
|
||||
.add_directive("goose=info".parse().unwrap())
|
||||
.add_directive("goose_server=info".parse().unwrap())
|
||||
.add_directive("tower_http=info".parse().unwrap())
|
||||
.add_directive(LevelFilter::WARN.into())
|
||||
});
|
||||
|
||||
let console_layer = fmt::layer()
|
||||
.with_writer(std::io::stderr)
|
||||
.with_target(true)
|
||||
.with_level(true)
|
||||
.with_file(true)
|
||||
.with_ansi(false)
|
||||
.with_line_number(true)
|
||||
.pretty();
|
||||
|
||||
let mut layers = vec![
|
||||
file_layer.with_filter(base_env_filter.clone()).boxed(),
|
||||
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() {
|
||||
layers.push(langfuse.with_filter(LevelFilter::DEBUG).boxed());
|
||||
}
|
||||
|
||||
let subscriber = Registry::default().with(layers);
|
||||
|
||||
let subscriber = goose::logging::build_logging_subscriber(&config)?;
|
||||
subscriber.try_init()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user