feat(rome_cli): Add server logs to `rage` command
MODIFY
crates/rome_cli/src/commands/daemon.rs
crates/rome_cli/src/commands/daemon.rs
-use std::env;
-
use rome_console::{markup, ConsoleExt};
use rome_lsp::ServerFactory;
use rome_service::{workspace::WorkspaceClient, RomeError, TransportError};
+use std::env;
+use std::path::PathBuf;
+use std::{fs, io};
use tokio::runtime::Runtime;
+use tracing::subscriber::Interest;
use tracing::{debug_span, metadata::LevelFilter, Instrument, Metadata};
use tracing_subscriber::{
layer::{Context, Filter},
@@ -89,6 +91,35 @@ pub(crate) fn print_socket() -> Result<(), Termination> {
Ok(())
}
+const fn log_file_name_prefix() -> &'static str {
+ "server.log"
+}
+
+pub(crate) fn read_most_recent_log_file() -> io::Result<Option<String>> {
+ let logs_dir = rome_log_dir();
+
+ let most_recent = fs::read_dir(logs_dir)?
+ .into_iter()
+ .flatten()
+ .filter(|file| file.file_type().map_or(false, |ty| ty.is_file()))
+ .filter_map(|file| {
+ match file
+ .file_name()
+ .to_str()?
+ .split_once(log_file_name_prefix())
+ {
+ Some((_, date_part)) if date_part.split('-').count() == 4 => Some(file.path()),
+ _ => None,
+ }
+ })
+ .max();
+
+ match most_recent {
+ Some(file) => Ok(Some(fs::read_to_string(file)?)),
+ None => Ok(None),
+ }
+}
+
/// Setup the [tracing]-based logging system for the server
/// The events received by the subscriber are filtered at the `info` level,
/// then printed using the [HierarchicalLayer] layer, and the resulting text
@@ -96,8 +127,7 @@ pub(crate) fn print_socket() -> Result<(), Termination> {
/// `rome-logs/server.log.yyyy-MM-dd-HH` files inside the system temporary
/// directory)
fn setup_tracing_subscriber() {
- let logs_dir = env::temp_dir().join("rome-logs");
- let file_appender = tracing_appender::rolling::hourly(logs_dir, "server.log");
+ let file_appender = tracing_appender::rolling::hourly(rome_log_dir(), log_file_name_prefix());
registry()
.with(
@@ -113,13 +143,20 @@ fn setup_tracing_subscriber() {
.init();
}
+pub(super) fn rome_log_dir() -> PathBuf {
+ match env::var_os("ROME_LOG_DIR") {
+ Some(directory) => PathBuf::from(directory),
+ None => env::temp_dir().join("rome-logs"),
+ }
+}
+
/// Tracing filter enabling:
/// - All spans and events at level info or higher
/// - All spans and events at level debug in crates whose name starts with `rome`
struct LoggingFilter;
-impl<S> Filter<S> for LoggingFilter {
- fn enabled(&self, meta: &Metadata<'_>, _cx: &Context<'_, S>) -> bool {
+impl LoggingFilter {
+ fn is_enabled(&self, meta: &Metadata<'_>) -> bool {
let filter = if meta.target().starts_with("rome") {
LevelFilter::DEBUG
} else {
@@ -128,6 +165,20 @@ impl<S> Filter<S> for LoggingFilter {
meta.level() <= &filter
}
+}
+
+impl<S> Filter<S> for LoggingFilter {
+ fn enabled(&self, meta: &Metadata<'_>, _cx: &Context<'_, S>) -> bool {
+ self.is_enabled(meta)
+ }
+
+ fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
+ if self.is_enabled(meta) {
+ Interest::always()
+ } else {
+ Interest::never()
+ }
+ }
fn max_level_hint(&self) -> Option<LevelFilter> {
Some(LevelFilter::DEBUG)

MODIFY
crates/rome_cli/src/commands/rage.rs
crates/rome_cli/src/commands/rage.rs
@@ -8,6 +8,7 @@ use rome_service::{load_config, DynRef, Workspace};
use std::{env, io, ops::Deref};
use tokio::runtime::Runtime;
+use crate::commands::daemon::read_most_recent_log_file;
use crate::{service, CliSession, Termination, VERSION};
/// Handler for the `rage` command
@@ -25,11 +26,13 @@ pub(crate) fn rage(mut session: CliSession) -> Result<(), Termination> {
{KeyValuePair("OS", markup!({std::env::consts::OS}))}
{Section("Environment")}
+ {EnvVarOs("ROME_LOG_DIR")}
{EnvVarOs("NO_COLOR")}
{EnvVarOs("TERM")}
{RageConfiguration(&session.app.fs)}
{WorkspaceRage(session.app.workspace.deref())}
+ {ConnectedClientServerLog(session.app.workspace.deref())}
));
if session.app.workspace.server_info().is_none() {
@@ -86,11 +89,11 @@ impl Display for RunningRomeServer {
match service::open_transport(runtime) {
Ok(None) => {
- markup!(
+ return markup!(
{Section("Server")}
{KeyValuePair("Status", markup!(<Dim>"stopped"</Dim>))}
)
- .fmt(f)?;
+ .fmt(f);
}
Ok(Some(transport)) => {
markup!("\n"<Emphasis>"Running Rome Server:"</Emphasis>" "{HorizontalLine::new(78)}"
@@ -113,7 +116,7 @@ impl Display for RunningRomeServer {
}
};
- Ok(())
+ RomeServerLog.fmt(f)
}
}
@@ -193,3 +196,36 @@ impl Display for KeyValuePair<'_> {
fmt.write_str("\n")
}
}
+
+struct RomeServerLog;
+
+impl Display for RomeServerLog {
+ fn fmt(&self, fmt: &mut Formatter) -> io::Result<()> {
+ if let Ok(Some(log)) = read_most_recent_log_file() {
+ markup!("\n"<Emphasis><Underline>"Rome Server Log:"</Underline></Emphasis>"
+
+"<Warn>"\u{26a0} Please review the content of the log file before sharing it publicly as it may contain sensitive information:
+ * Path names that may reveal your name, a project name, or the name of your employer.
+ * Source code
+"</Warn>)
+ .fmt(fmt)?;
+
+ write!(fmt, "\n{log}")?;
+ }
+
+ Ok(())
+ }
+}
+
+/// Prints the server logs but only if the client is connected to a rome server.
+struct ConnectedClientServerLog<'a>(&'a dyn Workspace);
+
+impl Display for ConnectedClientServerLog<'_> {
+ fn fmt(&self, fmt: &mut Formatter) -> io::Result<()> {
+ if self.0.server_info().is_some() {
+ RomeServerLog.fmt(fmt)
+ } else {
+ Ok(())
+ }
+ }
+}

MODIFY
crates/rome_cli/tests/snapshots/main_commands_rage/rage_ok.snap
crates/rome_cli/tests/snapshots/main_commands_rage/rage_ok.snap
@@ -14,6 +14,7 @@ Platform:
OS: **PLACEHOLDER**
Environment:
+ ROME_LOG_DIR: **PLACEHOLDER**
NO_COLOR: **PLACEHOLDER**
TERM: **PLACEHOLDER**

MODIFY
crates/rome_cli/tests/snapshots/main_commands_rage/with_configuration.snap
crates/rome_cli/tests/snapshots/main_commands_rage/with_configuration.snap
@@ -24,6 +24,7 @@ Platform:
OS: **PLACEHOLDER**
Environment:
+ ROME_LOG_DIR: **PLACEHOLDER**
NO_COLOR: **PLACEHOLDER**
TERM: **PLACEHOLDER**

MODIFY
crates/rome_cli/tests/snapshots/main_commands_rage/with_malformed_configuration.snap
crates/rome_cli/tests/snapshots/main_commands_rage/with_malformed_configuration.snap
@@ -24,6 +24,7 @@ Platform:
OS: **PLACEHOLDER**
Environment:
+ ROME_LOG_DIR: **PLACEHOLDER**
NO_COLOR: **PLACEHOLDER**
TERM: **PLACEHOLDER**

feat(rome_cli): Add server logs to `rage` command (#3441)