mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-11 12:56:46 +00:00
Finish basic logging setup with tracing
This commit is contained in:
parent
bdb562ebf2
commit
0da3a45312
3 changed files with 40 additions and 80 deletions
|
@ -36,19 +36,23 @@ fn main() -> Result<()> {
|
|||
)?;
|
||||
|
||||
// Split the right pane horizontally for server logs (50/50 split)
|
||||
// Updated to handle dated log files properly
|
||||
writeln!(
|
||||
stdin,
|
||||
"split-window -t djls-debug:0.1 -v -p 50 'tail -f /tmp/djls.log'"
|
||||
r#"split-window -t djls-debug:0.1 -v -p 50 'bash -c "log=\$(ls -t /tmp/djls.log.* 2>/dev/null | head -1); if [ -z \"\$log\" ]; then echo \"Waiting for server logs...\"; while [ -z \"\$log\" ]; do sleep 1; log=\$(ls -t /tmp/djls.log.* 2>/dev/null | head -1); done; fi; echo \"Tailing \$log\"; tail -F \"\$log\""'"#
|
||||
)?;
|
||||
|
||||
// Set pane titles
|
||||
writeln!(stdin, "select-pane -t djls-debug:0.0 -T 'Editor'")?;
|
||||
writeln!(stdin, "select-pane -t djls-debug:0.1 -T 'LSP DevTools'")?;
|
||||
writeln!(stdin, "select-pane -t djls-debug:0.1 -T 'LSP Messages'")?;
|
||||
writeln!(stdin, "select-pane -t djls-debug:0.2 -T 'Server Logs'")?;
|
||||
|
||||
// Enable pane borders with titles at the top
|
||||
writeln!(stdin, "set -t djls-debug pane-border-status top")?;
|
||||
|
||||
// Enable mouse support for scrolling and pane interaction
|
||||
writeln!(stdin, "set -t djls-debug mouse on")?;
|
||||
|
||||
// Add custom keybind to kill session (capital K)
|
||||
writeln!(stdin, "bind-key K kill-session")?;
|
||||
|
||||
|
@ -64,9 +68,9 @@ fn main() -> Result<()> {
|
|||
writeln!(stdin, "set -t djls-debug status-left '[#S] '")?;
|
||||
writeln!(stdin, "set -t djls-debug status-left-length 20")?;
|
||||
|
||||
// Right side: keybind hints
|
||||
writeln!(stdin, "set -t djls-debug status-right ' C-b d: detach | C-b K: kill session | C-b x: kill pane | C-b z: zoom | C-b ?: help '")?;
|
||||
writeln!(stdin, "set -t djls-debug status-right-length 90")?;
|
||||
// Right side: keybind hints - updated to include mouse info
|
||||
writeln!(stdin, "set -t djls-debug status-right ' Mouse: scroll/click | C-b d: detach | C-b K: kill | C-b x: kill pane | C-b z: zoom | C-b ?: help '")?;
|
||||
writeln!(stdin, "set -t djls-debug status-right-length 120")?;
|
||||
|
||||
// Center: window name
|
||||
writeln!(stdin, "set -t djls-debug status-justify centre")?;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Logging infrastructure bridging tracing events to LSP client messages.
|
||||
//! Logging infrastructure for forwarding tracing events to LSP client messages.
|
||||
//!
|
||||
//! This module provides both temporary dual-dispatch macros and the permanent
|
||||
//! `LspLayer` implementation for forwarding tracing events to the LSP client.
|
||||
//! This module provides the `LspLayer` implementation for forwarding tracing
|
||||
//! events to the LSP client through the tracing infrastructure.
|
||||
//!
|
||||
//! ## `LspLayer`
|
||||
//!
|
||||
|
@ -10,34 +10,25 @@
|
|||
//! - ERROR, WARN, INFO, DEBUG → forwarded to LSP client
|
||||
//! - TRACE → kept server-side only (for performance)
|
||||
//!
|
||||
//! ## Temporary Macros
|
||||
//! ## Usage
|
||||
//!
|
||||
//! These macros bridge the gap during our migration from `client::log_message`
|
||||
//! to the tracing infrastructure. They ensure messages are sent to both systems
|
||||
//! so we maintain LSP client visibility while building out tracing support.
|
||||
//! Use standard tracing macros throughout the codebase:
|
||||
//!
|
||||
//! Each macro supports two invocation patterns to handle the different APIs:
|
||||
//!
|
||||
//! 1. String literal:
|
||||
//! ```rust,ignore
|
||||
//! log_info!("Server initialized");
|
||||
//! log_warn!("Configuration not found");
|
||||
//! log_error!("Failed to parse document");
|
||||
//! tracing::info!("Server initialized");
|
||||
//! tracing::warn!("Configuration not found");
|
||||
//! tracing::error!("Failed to parse document");
|
||||
//! ```
|
||||
//!
|
||||
//! 2. Format string with arguments:
|
||||
//! For formatted messages:
|
||||
//! ```rust,ignore
|
||||
//! log_info!("Processing {} documents", count);
|
||||
//! log_warn!("Timeout after {}ms for {}", ms, path);
|
||||
//! log_error!("Failed to open {}: {}", file, err);
|
||||
//! tracing::info!("Processing {} documents", count);
|
||||
//! tracing::warn!("Timeout after {}ms for {}", ms, path);
|
||||
//! tracing::error!("Failed to open {}: {}", file, err);
|
||||
//! ```
|
||||
//!
|
||||
//! The difference in the macro arms exists because of how each system works:
|
||||
//!
|
||||
//! - `client::log_message` expects a single string value
|
||||
//! - `tracing` macros can handle format strings natively for structured logging
|
||||
//! - For format strings, we format once for the client but pass the original
|
||||
//! format string and args to tracing to preserve structured data
|
||||
//! The `LspLayer` automatically handles forwarding appropriate log levels
|
||||
//! to the LSP client while preserving structured logging data for file output.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -163,38 +154,4 @@ where
|
|||
guard
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! log_info {
|
||||
($msg:literal) => {
|
||||
$crate::client::log_message(tower_lsp_server::lsp_types::MessageType::INFO, $msg);
|
||||
tracing::info!($msg);
|
||||
};
|
||||
($fmt:literal, $($arg:tt)*) => {
|
||||
$crate::client::log_message(tower_lsp_server::lsp_types::MessageType::INFO, format!($fmt, $($arg)*));
|
||||
tracing::info!($fmt, $($arg)*);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! log_warn {
|
||||
($msg:literal) => {
|
||||
$crate::client::log_message(tower_lsp_server::lsp_types::MessageType::WARNING, $msg);
|
||||
tracing::warn!($msg);
|
||||
};
|
||||
($fmt:literal, $($arg:tt)*) => {
|
||||
$crate::client::log_message(tower_lsp_server::lsp_types::MessageType::WARNING, format!($fmt, $($arg)*));
|
||||
tracing::warn!($fmt, $($arg)*);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! log_error {
|
||||
($msg:literal) => {
|
||||
$crate::client::log_message(tower_lsp_server::lsp_types::MessageType::ERROR, $msg);
|
||||
tracing::error!($msg);
|
||||
};
|
||||
($fmt:literal, $($arg:tt)*) => {
|
||||
$crate::client::log_message(tower_lsp_server::lsp_types::MessageType::ERROR, format!($fmt, $($arg)*));
|
||||
tracing::error!($fmt, $($arg)*);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -25,8 +25,7 @@ use tower_lsp_server::lsp_types::WorkspaceServerCapabilities;
|
|||
use tower_lsp_server::LanguageServer;
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
|
||||
use crate::log_error;
|
||||
use crate::log_info;
|
||||
|
||||
use crate::queue::Queue;
|
||||
use crate::session::Session;
|
||||
|
||||
|
@ -58,7 +57,7 @@ impl DjangoLanguageServer {
|
|||
if let Some(s) = &*session {
|
||||
f(s)
|
||||
} else {
|
||||
log_error!("Attempted to access session before initialization");
|
||||
tracing::error!("Attempted to access session before initialization");
|
||||
R::default()
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +71,7 @@ impl DjangoLanguageServer {
|
|||
if let Some(s) = &mut *session {
|
||||
f(s)
|
||||
} else {
|
||||
log_error!("Attempted to access session before initialization");
|
||||
tracing::error!("Attempted to access session before initialization");
|
||||
R::default()
|
||||
}
|
||||
}
|
||||
|
@ -85,16 +84,16 @@ impl DjangoLanguageServer {
|
|||
let session_arc = Arc::clone(&self.session);
|
||||
|
||||
if let Err(e) = self.queue.submit(async move { f(session_arc).await }).await {
|
||||
log_error!("Failed to submit task: {}", e);
|
||||
tracing::error!("Failed to submit task: {}", e);
|
||||
} else {
|
||||
log_info!("Task submitted successfully");
|
||||
tracing::info!("Task submitted successfully");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LanguageServer for DjangoLanguageServer {
|
||||
async fn initialize(&self, params: InitializeParams) -> LspResult<InitializeResult> {
|
||||
log_info!("Initializing server...");
|
||||
tracing::info!("Initializing server...");
|
||||
|
||||
let session = Session::new(¶ms);
|
||||
|
||||
|
@ -142,7 +141,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
async fn initialized(&self, _params: InitializedParams) {
|
||||
log_info!("Server received initialized notification.");
|
||||
tracing::info!("Server received initialized notification.");
|
||||
|
||||
self.with_session_task(|session_arc| async move {
|
||||
let project_path_and_venv = {
|
||||
|
@ -162,13 +161,13 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
};
|
||||
|
||||
if let Some((path_display, venv_path)) = project_path_and_venv {
|
||||
log_info!(
|
||||
tracing::info!(
|
||||
"Task: Starting initialization for project at: {}",
|
||||
path_display
|
||||
);
|
||||
|
||||
if let Some(ref path) = venv_path {
|
||||
log_info!("Using virtual environment from config: {}", path);
|
||||
tracing::info!("Using virtual environment from config: {}", path);
|
||||
}
|
||||
|
||||
let init_result = {
|
||||
|
@ -188,10 +187,10 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
|
||||
match init_result {
|
||||
Ok(()) => {
|
||||
log_info!("Task: Successfully initialized project: {}", path_display);
|
||||
tracing::info!("Task: Successfully initialized project: {}", path_display);
|
||||
}
|
||||
Err(e) => {
|
||||
log_error!(
|
||||
tracing::error!(
|
||||
"Task: Failed to initialize Django project at {}: {}",
|
||||
path_display,
|
||||
e
|
||||
|
@ -205,7 +204,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
log_info!("Task: No project instance found to initialize.");
|
||||
tracing::info!("Task: No project instance found to initialize.");
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -217,7 +216,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
}
|
||||
|
||||
async fn did_open(&self, params: DidOpenTextDocumentParams) {
|
||||
log_info!("Opened document: {:?}", params.text_document.uri);
|
||||
tracing::info!("Opened document: {:?}", params.text_document.uri);
|
||||
|
||||
self.with_session_mut(|session| {
|
||||
let db = session.db();
|
||||
|
@ -227,7 +226,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
}
|
||||
|
||||
async fn did_change(&self, params: DidChangeTextDocumentParams) {
|
||||
log_info!("Changed document: {:?}", params.text_document.uri);
|
||||
tracing::info!("Changed document: {:?}", params.text_document.uri);
|
||||
|
||||
self.with_session_mut(|session| {
|
||||
let db = session.db();
|
||||
|
@ -237,7 +236,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
}
|
||||
|
||||
async fn did_close(&self, params: DidCloseTextDocumentParams) {
|
||||
log_info!("Closed document: {:?}", params.text_document.uri);
|
||||
tracing::info!("Closed document: {:?}", params.text_document.uri);
|
||||
|
||||
self.with_session_mut(|session| {
|
||||
session.documents_mut().handle_did_close(¶ms);
|
||||
|
@ -265,7 +264,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
}
|
||||
|
||||
async fn did_change_configuration(&self, _params: DidChangeConfigurationParams) {
|
||||
log_info!("Configuration change detected. Reloading settings...");
|
||||
tracing::info!("Configuration change detected. Reloading settings...");
|
||||
|
||||
let project_path = self
|
||||
.with_session(|session| session.project().map(|p| p.path().to_path_buf()))
|
||||
|
@ -277,7 +276,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
session.set_settings(new_settings);
|
||||
}
|
||||
Err(e) => {
|
||||
log_error!("Error loading settings: {}", e);
|
||||
tracing::error!("Error loading settings: {}", e);
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue