Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,30 @@ jobs:
- name: Build release
run: cargo build --release

no-logs-in-release:
name: No Logging in Release Binary
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Ensure release binary contains no tracing callsite metadata
run: |
cargo build --release --bin saorsa-node
BINARY=target/release/saorsa-node
# When cfg(debug_assertions)-gated logging is working correctly, no tracing
# callsite metadata (module paths with "event <file>:<line>" patterns) should
# survive in the release binary. We check for the "event <path>:<line>" pattern
# that tracing embeds at each callsite.
MATCHES=$(strings "$BINARY" | grep -cE '^event (src/|/home/).*\.rs:[0-9]+' || true)
if [ "$MATCHES" -gt 0 ]; then
echo "FAIL: release binary contains $MATCHES tracing callsite(s):"
strings "$BINARY" | grep -E '^event (src/|/home/).*\.rs:[0-9]+'
Comment thread
jacderida marked this conversation as resolved.
exit 1
Comment thread
jacderida marked this conversation as resolved.
fi
echo "PASS: release binary contains no tracing callsite metadata"

security:
name: Security Audit
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions src/bin/saorsa-cli/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Cli {
#[arg(long)]
pub allow_loopback: bool,

#[cfg(debug_assertions)]
/// Log level.
#[arg(long, default_value = "info")]
pub log_level: String,
Expand Down
22 changes: 13 additions & 9 deletions src/bin/saorsa-cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ use saorsa_node::client::self_encrypt::{
use saorsa_node::client::{QuantumClient, QuantumConfig, XorName};
use saorsa_node::devnet::DevnetManifest;
use saorsa_node::error::Error;
use saorsa_node::info;
use std::io::{Read as _, Write as _};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tracing::info;
#[cfg(debug_assertions)]
use tracing_subscriber::{fmt, prelude::*, EnvFilter};

/// Length of an `XorName` address in bytes.
Expand All @@ -31,13 +32,16 @@ async fn main() -> color_eyre::Result<()> {

let cli = Cli::parse();

let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&cli.log_level));
#[cfg(debug_assertions)]
{
let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&cli.log_level));

tracing_subscriber::registry()
.with(fmt::layer().with_writer(std::io::stderr))
.with(filter)
.init();
tracing_subscriber::registry()
.with(fmt::layer().with_writer(std::io::stderr))
.with(filter)
.init();
}

info!("saorsa-cli v{}", env!("CARGO_PKG_VERSION"));

Expand Down Expand Up @@ -185,8 +189,8 @@ async fn handle_download(
));
};

let chunk_count = data_map.chunk_identifiers.len();
info!("DataMap loaded: {chunk_count} chunk(s)");
let _chunk_count = data_map.chunk_identifiers.len();
info!("DataMap loaded: {_chunk_count} chunk(s)");

// Determine output path
let output_path = output.map_or_else(
Expand Down
1 change: 1 addition & 0 deletions src/bin/saorsa-devnet/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct Cli {
#[arg(long)]
pub manifest: Option<PathBuf>,

#[cfg(debug_assertions)]
/// Log level for devnet process.
#[arg(long, default_value = "info")]
pub log_level: String,
Expand Down
18 changes: 11 additions & 7 deletions src/bin/saorsa-devnet/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ mod cli;
use clap::Parser;
use cli::Cli;
use saorsa_node::devnet::{Devnet, DevnetConfig, DevnetEvmInfo, DevnetManifest};
use tracing::info;
use saorsa_node::info;
#[cfg(debug_assertions)]
use tracing_subscriber::{fmt, prelude::*, EnvFilter};

#[tokio::main]
Expand All @@ -14,13 +15,16 @@ async fn main() -> color_eyre::Result<()> {

let cli = Cli::parse();

let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&cli.log_level));
#[cfg(debug_assertions)]
{
let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&cli.log_level));

tracing_subscriber::registry()
.with(fmt::layer())
.with(filter)
.init();
tracing_subscriber::registry()
.with(fmt::layer())
.with(filter)
.init();
}

info!("saorsa-devnet v{}", env!("CARGO_PKG_VERSION"));

Expand Down
9 changes: 8 additions & 1 deletion src/bin/saorsa-node/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,24 @@ pub struct Cli {
#[arg(long, default_value = "9100", env = "SAORSA_METRICS_PORT")]
pub metrics_port: u16,

#[cfg(debug_assertions)]
/// Log level.
#[arg(long, value_enum, default_value = "info", env = "RUST_LOG")]
pub log_level: CliLogLevel,

#[cfg(debug_assertions)]
/// Log output format.
#[arg(long, value_enum, default_value = "text", env = "SAORSA_LOG_FORMAT")]
pub log_format: CliLogFormat,

#[cfg(debug_assertions)]
/// Directory for log file output.
/// When set, logs are written to files in this directory instead of stdout.
/// Files rotate daily and are named saorsa-node.YYYY-MM-DD.log.
#[arg(long, env = "SAORSA_LOG_DIR")]
pub log_dir: Option<PathBuf>,

#[cfg(debug_assertions)]
/// Maximum number of rotated log files to retain (only used with --log-dir).
/// Oldest files are deleted when this limit is reached. Rotation is daily.
#[arg(long, default_value = "7", env = "SAORSA_LOG_MAX_FILES")]
Expand Down Expand Up @@ -208,7 +212,10 @@ impl Cli {
config.port = self.port;
config.ip_version = self.ip_version.into();
config.bootstrap = self.bootstrap;
config.log_level = self.log_level.into();
#[cfg(debug_assertions)]
{
config.log_level = self.log_level.into();
}
config.network_mode = self.network_mode.into();

// Upgrade config
Expand Down
118 changes: 63 additions & 55 deletions src/bin/saorsa-node/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
mod cli;

use clap::Parser;
use cli::{Cli, CliLogFormat};
use cli::Cli;
#[cfg(debug_assertions)]
use cli::CliLogFormat;
use saorsa_node::info;
use saorsa_node::NodeBuilder;
use tracing::info;
#[cfg(debug_assertions)]
use tracing_subscriber::prelude::*;
#[cfg(debug_assertions)]
use tracing_subscriber::{fmt, EnvFilter, Layer};

#[tokio::main]
Expand All @@ -17,63 +21,67 @@ async fn main() -> color_eyre::Result<()> {
// Parse CLI arguments
let cli = Cli::parse();

// Extract logging options before consuming the CLI struct
let log_format = cli.log_format;
let log_dir = cli.log_dir.clone();
let log_max_files = cli.log_max_files;
#[cfg(debug_assertions)]
{
// Extract logging options before consuming the CLI struct
let log_format = cli.log_format;
let log_dir = cli.log_dir.clone();
let log_max_files = cli.log_max_files;

// Initialize tracing
let log_level: String = cli.log_level.into();
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&log_level));
// Initialize tracing
let log_level: String = cli.log_level.into();
let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&log_level));

// _guard must live for the duration of main() to ensure log flushing.
// The guard's Drop impl flushes buffered logs — it is intentionally held, not read.
#[allow(clippy::collection_is_never_read)]
let _guard: Option<tracing_appender::non_blocking::WorkerGuard>;
// _guard must live for the duration of main() to ensure log flushing.
// The guard's Drop impl flushes buffered logs — it is intentionally held, not read.
#[allow(clippy::collection_is_never_read)]
let _guard: Option<tracing_appender::non_blocking::WorkerGuard>;

let layer: Box<dyn Layer<_> + Send + Sync> = match (log_format, log_dir) {
(CliLogFormat::Text, None) => {
_guard = None;
Box::new(fmt::layer())
}
(CliLogFormat::Json, None) => {
_guard = None;
Box::new(fmt::layer().json().flatten_event(true))
}
(CliLogFormat::Text, Some(dir)) => {
let file_appender = tracing_appender::rolling::Builder::new()
.rotation(tracing_appender::rolling::Rotation::DAILY)
.max_log_files(log_max_files)
.filename_prefix("saorsa-node")
.filename_suffix("log")
.build(dir)?;
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
_guard = Some(guard);
Box::new(fmt::layer().with_writer(non_blocking).with_ansi(false))
}
(CliLogFormat::Json, Some(dir)) => {
let file_appender = tracing_appender::rolling::Builder::new()
.rotation(tracing_appender::rolling::Rotation::DAILY)
.max_log_files(log_max_files)
.filename_prefix("saorsa-node")
.filename_suffix("log")
.build(dir)?;
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
_guard = Some(guard);
Box::new(
fmt::layer()
.json()
.flatten_event(true)
.with_writer(non_blocking)
.with_ansi(false),
)
}
};
let layer: Box<dyn Layer<_> + Send + Sync> = match (log_format, log_dir) {
(CliLogFormat::Text, None) => {
_guard = None;
Box::new(fmt::layer())
}
(CliLogFormat::Json, None) => {
_guard = None;
Box::new(fmt::layer().json().flatten_event(true))
}
(CliLogFormat::Text, Some(dir)) => {
let file_appender = tracing_appender::rolling::Builder::new()
.rotation(tracing_appender::rolling::Rotation::DAILY)
.max_log_files(log_max_files)
.filename_prefix("saorsa-node")
.filename_suffix("log")
.build(dir)?;
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
_guard = Some(guard);
Box::new(fmt::layer().with_writer(non_blocking).with_ansi(false))
}
(CliLogFormat::Json, Some(dir)) => {
let file_appender = tracing_appender::rolling::Builder::new()
.rotation(tracing_appender::rolling::Rotation::DAILY)
.max_log_files(log_max_files)
.filename_prefix("saorsa-node")
.filename_suffix("log")
.build(dir)?;
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
_guard = Some(guard);
Box::new(
fmt::layer()
.json()
.flatten_event(true)
.with_writer(non_blocking)
.with_ansi(false),
)
}
};

tracing_subscriber::registry()
.with(layer)
.with(filter)
.init();
tracing_subscriber::registry()
.with(layer)
.with(filter)
.init();
}

info!(
version = env!("CARGO_PKG_VERSION"),
Expand Down
10 changes: 5 additions & 5 deletions src/client/chunk_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
//! generic function used by both [`super::QuantumClient`] and E2E test helpers.

use crate::ant_protocol::{ChunkMessage, ChunkMessageBody, CHUNK_PROTOCOL_ID};
use crate::{debug, warn};
use saorsa_core::identity::PeerId;
use saorsa_core::{P2PEvent, P2PNode};
use std::time::Duration;
use tokio::sync::broadcast::error::RecvError;
use tokio::time::Instant;
use tracing::{debug, warn};

/// Send a chunk-protocol message to `target_peer` and await a matching response.
///
Expand Down Expand Up @@ -57,8 +57,8 @@ pub async fn send_and_await_chunk_response<T, E>(
})) if topic == CHUNK_PROTOCOL_ID && source == *target_peer => {
let response = match ChunkMessage::decode(&data) {
Ok(r) => r,
Err(e) => {
warn!("Failed to decode chunk message, skipping: {e}");
Err(_e) => {
warn!("Failed to decode chunk message, skipping: {_e}");
continue;
}
};
Expand All @@ -70,8 +70,8 @@ pub async fn send_and_await_chunk_response<T, E>(
}
}
Ok(Ok(_)) => {}
Ok(Err(RecvError::Lagged(skipped))) => {
debug!("Chunk protocol events lagged by {skipped} messages, continuing");
Ok(Err(RecvError::Lagged(_skipped))) => {
debug!("Chunk protocol events lagged by {_skipped} messages, continuing");
}
Ok(Err(RecvError::Closed)) | Err(_) => break,
}
Expand Down
Loading
Loading