From e1c918fd5e866fc01a3e29683b99f204b786cb32 Mon Sep 17 00:00:00 2001 From: jspspike Date: Tue, 13 Jul 2021 15:35:21 -0500 Subject: [PATCH 1/4] Fixed issue with tail not deserailzing event properly --- Cargo.lock | 29 ++++++++++++-- Cargo.toml | 3 +- src/commands/dev/socket.rs | 6 ++- src/tail/log_server.rs | 78 ++++++++++++++++++-------------------- src/terminal/json.rs | 20 ++++++++++ src/terminal/mod.rs | 2 + 6 files changed, 90 insertions(+), 48 deletions(-) create mode 100644 src/terminal/json.rs diff --git a/Cargo.lock b/Cargo.lock index 138839444..8557261f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "anyhow" version = "1.0.40" @@ -306,9 +315,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrome-devtools-rs" -version = "0.0.0-alpha.1" +version = "0.0.0-alpha.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d1ada6e226ee1c5a69bfe5b16a494f036151d16461904afd22edeccb93061b" +checksum = "26a79dc4759f70819397d2e4281c8bc2991f9207d6abcbdb9f2279a512bf78e4" dependencies = [ "console 0.11.3", "log 0.4.14", @@ -337,7 +346,7 @@ version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ - "ansi_term", + "ansi_term 0.11.0", "atty", "bitflags", "strsim 0.8.0", @@ -383,6 +392,19 @@ dependencies = [ "uuid", ] +[[package]] +name = "colored_json" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd32eb54d016e203b7c2600e3a7802c75843a92e38ccc4869aefeca21771a64" +dependencies = [ + "ansi_term 0.12.1", + "atty", + "libc", + "serde 1.0.126", + "serde_json", +] + [[package]] name = "combine" version = "3.8.1" @@ -3288,6 +3310,7 @@ dependencies = [ "chrono", "clap", "cloudflare", + "colored_json", "config", "console 0.14.1", "dirs 3.0.2", diff --git a/Cargo.toml b/Cargo.toml index 9d373e1b6..66f8675bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,10 +17,11 @@ backtrace = { version = "0.3.58" } base64 = "0.13.0" billboard = "0.1.0" binary-install = "0.0.3-alpha.1" -chrome-devtools-rs = { version = "=0.0.0-alpha.1", features = ["color"] } +chrome-devtools-rs = { version = "0.0.0-alpha.2", features = ["color"] } chrono = "0.4.19" clap = "2.33.3" cloudflare = "0.8.3" +colored_json = "2.1.0" config = "0.11.0" console = "0.14.1" dirs = "3.0.1" diff --git a/src/commands/dev/socket.rs b/src/commands/dev/socket.rs index 7d300e7cb..031c97c90 100644 --- a/src/commands/dev/socket.rs +++ b/src/commands/dev/socket.rs @@ -7,6 +7,7 @@ use futures_util::sink::SinkExt; use futures_util::stream::{SplitStream, StreamExt}; use tokio_stream::wrappers::UnboundedReceiverStream; +use crate::terminal::colored_json_string; use crate::terminal::message::{Message, StdErr, StdOut}; use tokio::net::TcpStream; use tokio::sync::mpsc; @@ -107,14 +108,15 @@ async fn print_ws_messages( log::info!("{}", &message_text); let parsed_message: Result = serde_json::from_str(&message_text) - .map_err(|e| anyhow!("this event could not be parsed:\n{}", e)); + .map_err(|e| anyhow!("Failed to parse event:\n{}", e)); if let Ok(protocol::Runtime::Event(event)) = parsed_message { // Try to parse json to pretty print, otherwise just print string let json_parse: Result = serde_json::from_str(&*event.to_string()); + if let Ok(json) = json_parse { - if let Ok(json_str) = serde_json::to_string_pretty(&json) { + if let Ok(json_str) = colored_json_string(&json) { println!("{}", json_str); } else { StdOut::message(&format!("{:?}", event.to_string())); diff --git a/src/tail/log_server.rs b/src/tail/log_server.rs index 3f3e394c6..d7f404a42 100644 --- a/src/tail/log_server.rs +++ b/src/tail/log_server.rs @@ -1,4 +1,4 @@ -use crate::terminal::{emoji, styles}; +use crate::terminal::{colored_json_string, emoji, styles}; use anyhow::Result; use hyper::server::conn::AddrIncoming; use hyper::server::Builder; @@ -31,54 +31,43 @@ impl LogServer { } pub async fn run(self) -> Result<()> { - // this is so bad - // but i also am so bad at types - // TODO: make this less terrible - match self.format.as_str() { - "json" => { - let service = make_service_fn(|_| async { - Ok::<_, hyper::Error>(service_fn(print_logs_json)) - }); - - let server = self.server.serve(service); - - // The shutdown receiver listens for a one shot message from our sigint handler as a signal - // to gracefully shut down the hyper server. - let shutdown_rx = self.shutdown_rx; - - let graceful = server.with_graceful_shutdown(async { - shutdown_rx.await.ok(); - }); - - graceful.await?; - - Ok(()) + let format = self.format.clone(); // Having to clone this so much is a little gross TODO + + let service = make_service_fn(move |_| { + let format = format.clone(); + async move { + let format = format.clone(); + Ok::<_, hyper::Error>(service_fn(move |req| { + let format = format.clone(); + async move { + let format = format.clone(); + match format.as_str() { + "pretty" => print_logs_pretty(req).await, + "json" => print_logs_json(req).await, + _ => unreachable!(), + } + } + })) } - "pretty" => { - let service = make_service_fn(|_| async { - Ok::<_, hyper::Error>(service_fn(print_logs_pretty)) - }); + }); - let server = self.server.serve(service); + let server = self.server.serve(service); - // The shutdown receiver listens for a one shot message from our sigint handler as a signal - // to gracefully shut down the hyper server. - let shutdown_rx = self.shutdown_rx; + // The shutdown receiver listens for a one shot message from our sigint handler as a signal + // to gracefully shut down the hyper server. + let shutdown_rx = self.shutdown_rx; - let graceful = server.with_graceful_shutdown(async { - shutdown_rx.await.ok(); - }); + let graceful = server.with_graceful_shutdown(async { + shutdown_rx.await.ok(); + }); - graceful.await?; + graceful.await?; - Ok(()) - } - _ => unreachable!(), - } + Ok(()) } } -async fn print_logs_json(req: Request) -> Result, hyper::Error> { +async fn print_logs_json(req: Request) -> Result> { match (req.method(), req.uri().path()) { (&Method::POST, "/") => { let whole_body = hyper::body::to_bytes(req.into_body()).await?; @@ -137,7 +126,12 @@ async fn print_logs_pretty(req: Request) -> Result> { if !parsed.logs.is_empty() { println!(" Logs:"); parsed.logs.iter().for_each(|log| { - let messages = log.message.join(" "); + let message = colored_json_string(&log.message); + let messages = if let Ok(m) = message { + m + } else { + "Error: Failed to convert encoded message to string".to_string() + }; let output = match log.level.as_str() { "assert" | "error" => format!("{} {}", emoji::X, styles::warning(messages)), @@ -183,7 +177,7 @@ struct LogException { #[derive(Debug, Serialize, Deserialize)] struct LogMessage { - message: Vec, + message: serde_json::Value, level: String, timestamp: usize, } diff --git a/src/terminal/json.rs b/src/terminal/json.rs new file mode 100644 index 000000000..f0d04c956 --- /dev/null +++ b/src/terminal/json.rs @@ -0,0 +1,20 @@ +use colored_json::{Color, ColoredFormatter, PrettyFormatter, Styler}; +use serde_json::Value; + +pub fn colored_json_string(value: &Value) -> Result { + let formatter = ColoredFormatter::with_styler( + PrettyFormatter::new(), + Styler { + key: Color::Green.normal(), + string_value: Color::Blue.bold(), + integer_value: Color::Purple.bold(), + float_value: Color::Purple.italic(), + object_brackets: Color::Yellow.bold(), + array_brackets: Color::Cyan.bold(), + bool_value: Color::Red.bold(), + ..Default::default() + }, + ); + + formatter.to_colored_json_auto(&value) +} diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index a4187af9e..1b3caddd8 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -1,6 +1,8 @@ mod browser; pub mod emoji; pub mod interactive; +mod json; pub mod message; pub mod styles; pub use browser::open_browser; +pub use json::colored_json_string; From 7d636855e89f8f6533a7d5bf0fc5a5e1311bc4d2 Mon Sep 17 00:00:00 2001 From: jspspike Date: Tue, 13 Jul 2021 15:40:12 -0500 Subject: [PATCH 2/4] Fixed chrome-devtools-rs version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 66f8675bf..3b9a339a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ backtrace = { version = "0.3.58" } base64 = "0.13.0" billboard = "0.1.0" binary-install = "0.0.3-alpha.1" -chrome-devtools-rs = { version = "0.0.0-alpha.2", features = ["color"] } +chrome-devtools-rs = { version = "=0.0.0-alpha.2", features = ["color"] } chrono = "0.4.19" clap = "2.33.3" cloudflare = "0.8.3" From d1cda9c9a5efe99ae8e8f1b7aeea2d6864887e08 Mon Sep 17 00:00:00 2001 From: jspspike Date: Wed, 14 Jul 2021 14:29:03 -0500 Subject: [PATCH 3/4] Added logging for exception event --- src/commands/dev/socket.rs | 52 ++++++++++++++++++++++++++++---------- src/terminal/json.rs | 3 +-- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/commands/dev/socket.rs b/src/commands/dev/socket.rs index 031c97c90..6575f10b1 100644 --- a/src/commands/dev/socket.rs +++ b/src/commands/dev/socket.rs @@ -9,6 +9,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream; use crate::terminal::colored_json_string; use crate::terminal::message::{Message, StdErr, StdOut}; +use protocol::domain::runtime::event::Event::ExceptionThrown; use tokio::net::TcpStream; use tokio::sync::mpsc; use tokio::time::sleep; @@ -98,6 +99,18 @@ async fn connect_retry(socket_url: &Url) -> WebSocketStream, fallback: String) { + if let Ok(json) = value { + if let Ok(json_str) = colored_json_string(&json) { + println!("{}", json_str); + } else { + StdOut::message(fallback.as_str()); + } + } else { + println!("{}", fallback); + } +} + async fn print_ws_messages( mut read: SplitStream>>, ) -> Result<()> { @@ -110,20 +123,33 @@ async fn print_ws_messages( let parsed_message: Result = serde_json::from_str(&message_text) .map_err(|e| anyhow!("Failed to parse event:\n{}", e)); - if let Ok(protocol::Runtime::Event(event)) = parsed_message { - // Try to parse json to pretty print, otherwise just print string - let json_parse: Result = - serde_json::from_str(&*event.to_string()); - - if let Ok(json) = json_parse { - if let Ok(json_str) = colored_json_string(&json) { - println!("{}", json_str); - } else { - StdOut::message(&format!("{:?}", event.to_string())); - } - } else { - println!("{}", event); + match parsed_message { + Ok(protocol::Runtime::Event(ExceptionThrown(params))) => { + let default_description = "N/A".to_string(); + let description = params + .exception_details + .exception + .description + .as_ref() + .unwrap_or(&default_description); + + StdOut::message(&format!( + "{} at line {:?}, col {:?}", + description, + params.exception_details.line_number, + params.exception_details.column_number, + )); + + let json_parse = serde_json::to_value(params.clone()); + print_json(json_parse, format!("{:?}", params)); + } + Ok(protocol::Runtime::Event(event)) => { + // Try to parse json to pretty print, otherwise just print string + let json_parse: Result = + serde_json::from_str(&*event.to_string()); + print_json(json_parse, event.to_string()); } + _ => {} } } Err(error) => return Err(error.into()), diff --git a/src/terminal/json.rs b/src/terminal/json.rs index f0d04c956..62c1a2130 100644 --- a/src/terminal/json.rs +++ b/src/terminal/json.rs @@ -1,7 +1,6 @@ use colored_json::{Color, ColoredFormatter, PrettyFormatter, Styler}; -use serde_json::Value; -pub fn colored_json_string(value: &Value) -> Result { +pub fn colored_json_string(value: &serde_json::Value) -> Result { let formatter = ColoredFormatter::with_styler( PrettyFormatter::new(), Styler { From 6cc57fd7e8d898a0b2b1415992b1e42324d154d7 Mon Sep 17 00:00:00 2001 From: jspspike Date: Thu, 15 Jul 2021 11:35:09 -0500 Subject: [PATCH 4/4] Updated chrome-devtools-rs version and improved log_server service closure --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/tail/log_server.rs | 32 +++++++++++++++++--------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8557261f2..688c6e2f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,9 +315,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrome-devtools-rs" -version = "0.0.0-alpha.2" +version = "0.0.0-alpha.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a79dc4759f70819397d2e4281c8bc2991f9207d6abcbdb9f2279a512bf78e4" +checksum = "a20571a8098aabf6fd6c83b896c3ebccd428c85d5a7e2a59ccb50f6c2ec33816" dependencies = [ "console 0.11.3", "log 0.4.14", diff --git a/Cargo.toml b/Cargo.toml index 3b9a339a4..836642b70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ backtrace = { version = "0.3.58" } base64 = "0.13.0" billboard = "0.1.0" binary-install = "0.0.3-alpha.1" -chrome-devtools-rs = { version = "=0.0.0-alpha.2", features = ["color"] } +chrome-devtools-rs = { version = "0.0.0-alpha.3", features = ["color"] } chrono = "0.4.19" clap = "2.33.3" cloudflare = "0.8.3" diff --git a/src/tail/log_server.rs b/src/tail/log_server.rs index d7f404a42..c79c52777 100644 --- a/src/tail/log_server.rs +++ b/src/tail/log_server.rs @@ -31,24 +31,18 @@ impl LogServer { } pub async fn run(self) -> Result<()> { - let format = self.format.clone(); // Having to clone this so much is a little gross TODO + let format = self.format; + + let server_fn_gen = |format: String| { + service_fn(move |req: Request| { + let format = format.clone(); + print_logs(req, format) + }) + }; let service = make_service_fn(move |_| { let format = format.clone(); - async move { - let format = format.clone(); - Ok::<_, hyper::Error>(service_fn(move |req| { - let format = format.clone(); - async move { - let format = format.clone(); - match format.as_str() { - "pretty" => print_logs_pretty(req).await, - "json" => print_logs_json(req).await, - _ => unreachable!(), - } - } - })) - } + async move { Ok::<_, hyper::Error>(server_fn_gen(format)) } }); let server = self.server.serve(service); @@ -67,6 +61,14 @@ impl LogServer { } } +async fn print_logs(req: Request, format: String) -> Result> { + match format.as_str() { + "pretty" => print_logs_pretty(req).await, + "json" => print_logs_json(req).await, + _ => unreachable!(), + } +} + async fn print_logs_json(req: Request) -> Result> { match (req.method(), req.uri().path()) { (&Method::POST, "/") => {