From 3af03c3971ec7e94c4fe04193d3055c58057d3f3 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Tue, 27 Jun 2023 00:35:07 -0300 Subject: [PATCH] print a Zebra logo and some text if stderr is terminal (#6945) * print a Zebra logo and some text in progress bar mode * add network to printed line, add heart to logo * print logo and message regardless of progress-bar; document how logo was generated --- zebrad/src/application.rs | 5 ++- zebrad/src/components/tracing.rs | 6 +++ zebrad/src/components/tracing/component.rs | 43 +++++++++++++++++++--- zebrad/src/components/tracing/zebra.utf8 | 20 ++++++++++ 4 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 zebrad/src/components/tracing/zebra.utf8 diff --git a/zebrad/src/application.rs b/zebrad/src/application.rs index d7fb3356..47f324a2 100644 --- a/zebrad/src/application.rs +++ b/zebrad/src/application.rs @@ -419,7 +419,10 @@ impl Application for ZebradApp { tracing_config.filter = Some(default_filter.to_owned()); tracing_config.flamegraph = None; } - components.push(Box::new(Tracing::new(tracing_config)?)); + components.push(Box::new(Tracing::new( + config.network.network, + tracing_config, + )?)); // Log git metadata and platform info when zebrad starts up if is_server { diff --git a/zebrad/src/components/tracing.rs b/zebrad/src/components/tracing.rs index d12491f8..439c5052 100644 --- a/zebrad/src/components/tracing.rs +++ b/zebrad/src/components/tracing.rs @@ -138,6 +138,12 @@ impl Config { self.force_use_color || (self.use_color && atty::is(atty::Stream::Stdout)) } + /// Returns `true` if standard error should use color escapes. + /// Automatically checks if Zebra is running in a terminal. + pub fn use_color_stderr(&self) -> bool { + self.force_use_color || (self.use_color && atty::is(atty::Stream::Stderr)) + } + /// Returns `true` if output that could go to standard output or standard error /// should use color escapes. Automatically checks if Zebra is running in a terminal. pub fn use_color_stdout_and_stderr(&self) -> bool { diff --git a/zebrad/src/components/tracing/component.rs b/zebrad/src/components/tracing/component.rs index 4a3a4560..4498b1a1 100644 --- a/zebrad/src/components/tracing/component.rs +++ b/zebrad/src/components/tracing/component.rs @@ -15,12 +15,26 @@ use tracing_subscriber::{ util::SubscriberInitExt, EnvFilter, }; +use zebra_chain::parameters::Network; use crate::{application::build_version, components::tracing::Config}; #[cfg(feature = "flamegraph")] use super::flame; +// Art generated with these two images. +// Zebra logo: book/theme/favicon.png +// Heart image: https://commons.wikimedia.org/wiki/File:Heart_coraz%C3%B3n.svg +// (License: CC BY-SA 3.0) +// +// How to render +// +// Convert heart image to PNG (2000px) and run: +// img2txt -W 40 -H 20 -f utf8 -d none Heart_corazón.svg.png > heart.utf8 +// img2txt -W 40 -H 20 -f utf8 -d none favicon.png > logo.utf8 +// paste favicon.utf8 heart.utf8 > zebra.utf8 +static ZEBRA_ART: [u8; include_bytes!("zebra.utf8").len()] = *include_bytes!("zebra.utf8"); + /// A type-erased boxed writer that can be sent between threads safely. pub type BoxWrite = Box; @@ -52,15 +66,36 @@ pub struct Tracing { impl Tracing { /// Try to create a new [`Tracing`] component with the given `filter`. - #[allow(clippy::print_stdout, clippy::print_stderr)] - pub fn new(config: Config) -> Result { + #[allow(clippy::print_stdout, clippy::print_stderr, clippy::unwrap_in_result)] + pub fn new(network: Network, config: Config) -> Result { // Only use color if tracing output is being sent to a terminal or if it was explicitly // forced to. let use_color = config.use_color_stdout(); + let use_color_stderr = config.use_color_stderr(); let filter = config.filter.unwrap_or_default(); let flame_root = &config.flamegraph; + // If it's a terminal and color escaping is enabled: clear screen and + // print Zebra logo (here `use_color` is being interpreted as + // "use escape codes") + if use_color_stderr { + // Clear screen + eprint!("\x1B[2J"); + eprintln!( + "{}", + std::str::from_utf8(&ZEBRA_ART) + .expect("should always work on a UTF-8 encoded constant") + ); + } + + eprintln!( + "Thank you for running a {} zebrad {} node!", + network.lowercase_name(), + build_version() + ); + eprintln!("You're helping to strengthen the network and contributing to a social good :)"); + let writer = if let Some(log_file) = config.log_file.as_ref() { println!("running zebra"); @@ -263,10 +298,6 @@ impl Tracing { howudoin::init(terminal_consumer); info!("activated progress bar"); - - if config.log_file.is_some() { - eprintln!("waiting for initial progress reports..."); - } } Ok(Self { diff --git a/zebrad/src/components/tracing/zebra.utf8 b/zebrad/src/components/tracing/zebra.utf8 new file mode 100644 index 00000000..bf620dde --- /dev/null +++ b/zebrad/src/components/tracing/zebra.utf8 @@ -0,0 +1,20 @@ + X@8:::::::@X + @::X:;SX;%8S8@@:X::8 + @:;@8@.S8 ;;t;. XX.;@@;:@ 8; %X X% ;8 + 8:@88 .%@.S@.XS: 888:8 X :: .: X + :;SX XS8;::@X@8::;8t8: 8;;:@ % SS % + @::@ 88:::8 8::88::::::X@ 8::8 S X + @:XS8 ;::::::8.88%8@S88::::8: 8S8:8 X S + ::;8 t8S8::::@St 88SX @SS@8:8S;8S @@:: 8 8 +8:XX %%@@::X% 8: X@ t:8t X ..%t8 ;8:8   +::8t: tX:X8tS 8: :@ ;.8@.X tt888: @8:: @ X +::8S: @:8Xtt% 8: S 8 8S.   .8;::. 88:: 8 8 +::X8 S@8 8:8.@8@8Xt S  .%8;S %8:: : : + ::@8 S .  @:::::::X;@ 8.88S8 @8;:X :: :; + 8:X8X .@:X88:::::::::888 @;:X %88:: t t + @::S 888@8:::::::::8X; 8 8::8 8 8 + X:;S@ tXX8;::::::::S::@8 8;S:8 X. .X + ::8S@ :S88XX@8X: @XX:: :: :: + 8:;%X8.:S t; X8%S:8X tt + X8::8SS8SX8@@X@8;8S:8X + X@8:::::::@XS