diff --git a/engine/Cargo.lock b/engine/Cargo.lock index 3f8f27ad0..6dabfb12b 100644 --- a/engine/Cargo.lock +++ b/engine/Cargo.lock @@ -895,6 +895,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tracing-subscriber", ] [[package]] @@ -1060,6 +1061,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tracing-subscriber", ] [[package]] @@ -4010,6 +4012,7 @@ dependencies = [ "serde_json", "serde_magnus", "tokio", + "tracing-subscriber", ] [[package]] diff --git a/engine/language_client_python/Cargo.toml b/engine/language_client_python/Cargo.toml index 0c2a13268..622f32b83 100644 --- a/engine/language_client_python/Cargo.toml +++ b/engine/language_client_python/Cargo.toml @@ -46,6 +46,7 @@ regex.workspace = true serde.workspace = true serde_json.workspace = true tokio = { version = "1", features = ["full"] } +tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter","valuable"] } [build-dependencies] pyo3-build-config = "0.21.2" diff --git a/engine/language_client_python/src/lib.rs b/engine/language_client_python/src/lib.rs index 299b1e237..dbf693d47 100644 --- a/engine/language_client_python/src/lib.rs +++ b/engine/language_client_python/src/lib.rs @@ -5,6 +5,7 @@ mod types; use pyo3::prelude::{pyfunction, pymodule, PyAnyMethods, PyModule, PyResult}; use pyo3::{wrap_pyfunction, Bound, Python}; +use tracing_subscriber::{self, EnvFilter}; #[pyfunction] fn invoke_runtime_cli(py: Python) -> PyResult<()> { @@ -21,14 +22,36 @@ fn invoke_runtime_cli(py: Python) -> PyResult<()> { #[pymodule] fn baml_py(m: Bound<'_, PyModule>) -> PyResult<()> { - if let Err(e) = env_logger::try_init_from_env( - env_logger::Env::new() - .filter("BAML_LOG") - .write_style("BAML_LOG_STYLE"), - ) { - eprintln!("Failed to initialize BAML logger: {:#}", e); + let use_json = match std::env::var("BAML_LOG_JSON") { + Ok(val) => val.trim().eq_ignore_ascii_case("true") || val.trim() == "1", + Err(_) => false, }; + if use_json { + // JSON formatting + tracing_subscriber::fmt() + .with_target(false) + .with_file(false) + .with_line_number(false) + .json() + .with_env_filter( + EnvFilter::try_from_env("BAML_LOG").unwrap_or_else(|_| EnvFilter::new("info")), + ) + .flatten_event(true) + .with_current_span(false) + .with_span_list(false) + .init(); + } else { + // Regular formatting + if let Err(e) = env_logger::try_init_from_env( + env_logger::Env::new() + .filter("BAML_LOG") + .write_style("BAML_LOG_STYLE"), + ) { + eprintln!("Failed to initialize BAML logger: {:#}", e); + } + } + m.add_class::()?; m.add_class::()?; diff --git a/engine/language_client_ruby/ext/ruby_ffi/Cargo.toml b/engine/language_client_ruby/ext/ruby_ffi/Cargo.toml index 83a05013d..7899cfa80 100644 --- a/engine/language_client_ruby/ext/ruby_ffi/Cargo.toml +++ b/engine/language_client_ruby/ext/ruby_ffi/Cargo.toml @@ -31,6 +31,7 @@ serde.workspace = true serde_json.workspace = true serde_magnus = { git = "https://github.com/BoundaryML/serde-magnus.git", branch = "sam/magnus-0.7.1" } tokio = { version = "1", features = ["full"] } +tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter","valuable"] } [dev-dependencies.magnus] version = "0.7.1" diff --git a/engine/language_client_ruby/ext/ruby_ffi/src/lib.rs b/engine/language_client_ruby/ext/ruby_ffi/src/lib.rs index 3338fe7ea..7286a2487 100644 --- a/engine/language_client_ruby/ext/ruby_ffi/src/lib.rs +++ b/engine/language_client_ruby/ext/ruby_ffi/src/lib.rs @@ -4,6 +4,7 @@ use magnus::{class, function, method, prelude::*, Error, RHash, Ruby}; use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; +use tracing_subscriber::EnvFilter; use function_result::FunctionResult; use function_result_stream::FunctionResultStream; @@ -201,14 +202,36 @@ fn invoke_runtime_cli(ruby: &Ruby, argv0: String, argv: Vec) -> Result<( #[magnus::init(name = "ruby_ffi")] fn init(ruby: &Ruby) -> Result<()> { - if let Err(e) = env_logger::try_init_from_env( - env_logger::Env::new() - .filter("BAML_LOG") - .write_style("BAML_LOG_STYLE"), - ) { - eprintln!("Failed to initialize BAML logger: {:#}", e); + let use_json = match std::env::var("BAML_LOG_JSON") { + Ok(val) => val.trim().eq_ignore_ascii_case("true") || val.trim() == "1", + Err(_) => false, }; + if use_json { + // JSON formatting + tracing_subscriber::fmt() + .with_target(false) + .with_file(false) + .with_line_number(false) + .json() + .with_env_filter( + EnvFilter::try_from_env("BAML_LOG").unwrap_or_else(|_| EnvFilter::new("info")), + ) + .flatten_event(true) + .with_current_span(false) + .with_span_list(false) + .init(); + } else { + // Regular formatting + if let Err(e) = env_logger::try_init_from_env( + env_logger::Env::new() + .filter("BAML_LOG") + .write_style("BAML_LOG_STYLE"), + ) { + eprintln!("Failed to initialize BAML logger: {:#}", e); + } + } + let module = ruby.define_module("Baml")?.define_module("Ffi")?; module.define_module_function("invoke_runtime_cli", function!(invoke_runtime_cli, 2))?; diff --git a/engine/language_client_typescript/Cargo.toml b/engine/language_client_typescript/Cargo.toml index 59172ff8b..39de4ab86 100644 --- a/engine/language_client_typescript/Cargo.toml +++ b/engine/language_client_typescript/Cargo.toml @@ -33,6 +33,7 @@ napi-derive = "2" serde.workspace = true serde_json.workspace = true tokio = { version = "1", features = ["full"] } +tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter","valuable"] } [build-dependencies] napi-build = "2.1.3" diff --git a/engine/language_client_typescript/src/lib.rs b/engine/language_client_typescript/src/lib.rs index f1388a4cf..5d5ab78c2 100644 --- a/engine/language_client_typescript/src/lib.rs +++ b/engine/language_client_typescript/src/lib.rs @@ -7,6 +7,7 @@ mod runtime; mod types; pub(crate) use runtime::BamlRuntime; +use tracing_subscriber::{self, EnvFilter}; #[napi(js_name = "invoke_runtime_cli")] pub fn run_cli(env: Env, params: Vec) -> napi::Result { @@ -21,11 +22,34 @@ pub fn run_cli(env: Env, params: Vec) -> napi::Result { #[napi::module_init] fn module_init() { - if let Err(e) = env_logger::try_init_from_env( - env_logger::Env::new() - .filter("BAML_LOG") - .write_style("BAML_LOG_STYLE"), - ) { - eprintln!("Failed to initialize BAML logger: {:#}", e); + // Check if JSON logging is enabled + let use_json = match std::env::var("BAML_LOG_JSON") { + Ok(val) => val.trim().eq_ignore_ascii_case("true") || val.trim() == "1", + Err(_) => false, }; + + if use_json { + // JSON formatting + tracing_subscriber::fmt() + .with_target(false) + .with_file(false) + .with_line_number(false) + .json() + .with_env_filter( + EnvFilter::try_from_env("BAML_LOG").unwrap_or_else(|_| EnvFilter::new("info")), + ) + .flatten_event(true) + .with_current_span(false) + .with_span_list(false) + .init(); + } else { + // Regular formatting + if let Err(e) = env_logger::try_init_from_env( + env_logger::Env::new() + .filter("BAML_LOG") + .write_style("BAML_LOG_STYLE"), + ) { + eprintln!("Failed to initialize BAML logger: {:#}", e); + } + } }