Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a tracing subscriber for LSP logging #93

Merged
merged 15 commits into from
Dec 13, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Check AIR_LOG envvar on startup
  • Loading branch information
DavisVaughan committed Dec 11, 2024
commit f6e203e500ebcaf4c67edb15af45a9651444f72d
2 changes: 1 addition & 1 deletion crates/lsp/src/handlers_state.rs
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ pub(crate) fn initialize(
) -> anyhow::Result<InitializeResult> {
// TODO: Get default log level from `params.initialization_options`
// and `AIR_LOG` env var.
let log_level = logging::LogLevel::Trace;
let log_level = None;

logging::init_logging(log_tx, log_level, params.client_info.as_ref());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initializing logging in the initialize() handler is as early as I think we can initialize it. We are going to require information from the Client to correctly set up our logging infrastructure, so we can't do this any earlier.


26 changes: 23 additions & 3 deletions crates/lsp/src/logging.rs
Original file line number Diff line number Diff line change
@@ -37,8 +37,8 @@ use tracing_subscriber::{
// TODO:
// - Add `air.server.log` as a VS Code extension option that sets the log level,
// and pass it through the arbitrary `initializationOptions` field of `InitializeParams`.
// - Add `AIR_LOG` environment variable that sets the log level as well, and prefer this
// over the extension option as its the "harder" thing to set.

const LOG_ENV_KEY: &str = "AIR_LOG";

pub(crate) struct LogMessage {
contents: String,
@@ -130,9 +130,11 @@ impl<'a> MakeWriter<'a> for LogWriterMaker {

pub(crate) fn init_logging(
log_tx: LogMessageSender,
log_level: LogLevel,
log_level: Option<LogLevel>,
client_info: Option<&ClientInfo>,
) {
let log_level = resolve_log_level(log_level);

let writer = if client_info.is_some_and(|client_info| {
client_info.name.starts_with("Zed") || client_info.name.starts_with("Visual Studio Code")
}) {
@@ -182,6 +184,24 @@ fn is_test_client(client_info: Option<&ClientInfo>) -> bool {
client_info.map_or(false, |client_info| client_info.name == "AirTestClient")
}

fn resolve_log_level(log_level: Option<LogLevel>) -> LogLevel {
// Check log environment variable, this overrides any Client options
if let Some(log_level) = std::env::var(LOG_ENV_KEY)
.ok()
.and_then(|level| serde_json::from_value(serde_json::Value::String(level)).ok())
{
return log_level;
}

// Client specified log level through initialization parameters
if let Some(log_level) = log_level {
return log_level;
}

// Fallback
LogLevel::default()
}

#[derive(Clone, Copy, Debug, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub(crate) enum LogLevel {