mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 19:49:28 +00:00
This commit is contained in:
parent
86bbf55954
commit
fd4a1746b1
12 changed files with 235 additions and 31 deletions
67
Cargo.lock
generated
67
Cargo.lock
generated
|
@ -1082,6 +1082,7 @@ dependencies = [
|
|||
"toml",
|
||||
"tower 0.5.1 (git+https://github.com/Cuprate/tower.git?rev=6c7faf0)",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
|
@ -1144,6 +1145,15 @@ dependencies = [
|
|||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
|
@ -1987,6 +1997,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
@ -2149,6 +2165,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
|
@ -2889,6 +2911,37 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a693d0c8cf16973fac5a93fbe47b8c6452e7097d4fcac49f3d7a18e39c76e62e"
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.8.0"
|
||||
|
@ -2978,6 +3031,8 @@ dependencies = [
|
|||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hashbrown 0.14.5",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
"tokio",
|
||||
|
@ -3084,6 +3139,18 @@ dependencies = [
|
|||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
|
|
|
@ -122,6 +122,7 @@ tokio-stream = { version = "0.1", default-features = false }
|
|||
tokio = { version = "1", default-features = false }
|
||||
tower = { git = "https://github.com/Cuprate/tower.git", rev = "6c7faf0", default-features = false } # <https://github.com/tower-rs/tower/pull/796>
|
||||
toml = { version = "0.8", default-features = false }
|
||||
tracing-appender = { version = "0.2", default-features = false }
|
||||
tracing-subscriber = { version = "0.3", default-features = false }
|
||||
tracing = { version = "0.1", default-features = false }
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
network = "Mainnet"
|
||||
|
||||
## Tracing config.
|
||||
[tracing]
|
||||
[tracing.stdout]
|
||||
## The minimum level for log events to be displayed.
|
||||
level = "info"
|
||||
|
||||
|
|
|
@ -68,11 +68,12 @@ serde_json = { workspace = true }
|
|||
serde = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
thread_local = { workspace = true }
|
||||
tokio-util = { workspace = true }
|
||||
tokio-util = { workspace = true, features = ["rt"] }
|
||||
tokio-stream = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
toml = { workspace = true, features = ["parse", "display"]}
|
||||
tower = { workspace = true }
|
||||
tracing-appender = { workspace = true }
|
||||
tracing-subscriber = { workspace = true, features = ["std", "fmt", "default"] }
|
||||
tracing = { workspace = true, features = ["default"] }
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::{collections::HashMap, sync::Arc};
|
|||
use futures::StreamExt;
|
||||
use monero_serai::block::Block;
|
||||
use tokio::sync::{mpsc, oneshot, Notify};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tower::{Service, ServiceExt};
|
||||
use tracing::error;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use rayon::prelude::*;
|
|||
use std::ops::ControlFlow;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use tower::{Service, ServiceExt};
|
||||
use tracing::info;
|
||||
use tracing::{info, instrument};
|
||||
|
||||
use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
|
||||
use cuprate_consensus::{
|
||||
|
@ -120,6 +120,7 @@ impl super::BlockchainManager {
|
|||
///
|
||||
/// This function will panic if the batch is empty or if any internal service returns an unexpected
|
||||
/// error that we cannot recover from or if the incoming batch contains no blocks.
|
||||
#[instrument(name = "incoming_block_batch" skip_all, level = "info", fields(start_height = batch.blocks.first().unwrap().0.number().unwrap(), len = batch.blocks.len()))]
|
||||
pub async fn handle_incoming_block_batch(&mut self, batch: BlockBatch) {
|
||||
let (first_block, _) = batch
|
||||
.blocks
|
||||
|
@ -146,10 +147,7 @@ impl super::BlockchainManager {
|
|||
/// This function will panic if any internal service returns an unexpected error that we cannot
|
||||
/// recover from or if the incoming batch contains no blocks.
|
||||
async fn handle_incoming_block_batch_main_chain(&mut self, batch: BlockBatch) {
|
||||
info!(
|
||||
"Handling batch to main chain height: {}",
|
||||
batch.blocks.first().unwrap().0.number().unwrap()
|
||||
);
|
||||
let start_height = batch.blocks.first().unwrap().0.number().unwrap();
|
||||
|
||||
let batch_prep_res = self
|
||||
.block_verifier_service
|
||||
|
@ -192,6 +190,7 @@ impl super::BlockchainManager {
|
|||
|
||||
self.add_valid_block_to_main_chain(verified_block).await;
|
||||
}
|
||||
info!("Successfully added block batch");
|
||||
}
|
||||
|
||||
/// Handles an incoming [`BlockBatch`] that does not follow the main-chain.
|
||||
|
|
|
@ -80,7 +80,7 @@ pub struct Config {
|
|||
/// The storage config.
|
||||
storage: StorageConfig,
|
||||
|
||||
fs: FileSystemConfig,
|
||||
pub fs: FileSystemConfig,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
|
|
@ -2,15 +2,22 @@ use serde::{Deserialize, Serialize};
|
|||
use tracing::level_filters::LevelFilter;
|
||||
|
||||
/// [`tracing`] config.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Default, Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct TracingConfig {
|
||||
pub stdout: StdoutTracingConfig,
|
||||
pub file: FileTracingConfig,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct StdoutTracingConfig {
|
||||
/// The default minimum log level.
|
||||
#[serde(with = "level_filter_serde")]
|
||||
pub level: LevelFilter,
|
||||
}
|
||||
|
||||
impl Default for TracingConfig {
|
||||
impl Default for StdoutTracingConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
level: LevelFilter::INFO,
|
||||
|
@ -18,6 +25,25 @@ impl Default for TracingConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct FileTracingConfig {
|
||||
/// The default minimum log level.
|
||||
#[serde(with = "level_filter_serde")]
|
||||
pub level: LevelFilter,
|
||||
|
||||
pub max_log_files: usize,
|
||||
}
|
||||
|
||||
impl Default for FileTracingConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
level: LevelFilter::DEBUG,
|
||||
max_log_files: 7,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod level_filter_serde {
|
||||
use std::str::FromStr;
|
||||
|
||||
|
|
105
binaries/cuprated/src/logging.rs
Normal file
105
binaries/cuprated/src/logging.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use crate::config::Config;
|
||||
use cuprate_helper::fs::logs_path;
|
||||
use std::mem::forget;
|
||||
use std::sync::OnceLock;
|
||||
use tracing::instrument::WithSubscriber;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing::subscriber::Interest;
|
||||
use tracing::Metadata;
|
||||
use tracing_appender::non_blocking::NonBlocking;
|
||||
use tracing_appender::rolling::Rotation;
|
||||
use tracing_subscriber::filter::Filtered;
|
||||
use tracing_subscriber::fmt::format::{DefaultFields, Format};
|
||||
use tracing_subscriber::layer::{Context, Layered, SubscriberExt};
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
use tracing_subscriber::{
|
||||
fmt::Layer as FmtLayer,
|
||||
layer::Filter,
|
||||
reload::{Handle, Layer as ReloadLayer},
|
||||
Layer,
|
||||
};
|
||||
use tracing_subscriber::{reload, Registry};
|
||||
|
||||
static FILE_WRITER_FILTER_HANDLE: OnceLock<Handle<CupratedTracingFilter, Registry>> =
|
||||
OnceLock::new();
|
||||
|
||||
static STDOUT_FILTER_HANDLE: OnceLock<
|
||||
Handle<
|
||||
CupratedTracingFilter,
|
||||
Layered<
|
||||
Filtered<
|
||||
FmtLayer<Registry, DefaultFields, Format, NonBlocking>,
|
||||
ReloadLayer<CupratedTracingFilter, Registry>,
|
||||
Registry,
|
||||
>,
|
||||
Registry,
|
||||
Registry,
|
||||
>,
|
||||
>,
|
||||
> = OnceLock::new();
|
||||
|
||||
pub struct CupratedTracingFilter {
|
||||
pub level: LevelFilter,
|
||||
}
|
||||
|
||||
impl<S> Filter<S> for CupratedTracingFilter {
|
||||
fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
|
||||
Filter::<S>::enabled(&self.level, meta, cx)
|
||||
}
|
||||
|
||||
fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
|
||||
Filter::<S>::callsite_enabled(&self.level, meta)
|
||||
}
|
||||
|
||||
fn max_level_hint(&self) -> Option<LevelFilter> {
|
||||
Some(self.level)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_logging(config: &Config) {
|
||||
use tracing_subscriber::{fmt, Layer};
|
||||
|
||||
let (stdout_filter, stdout_handle) = reload::Layer::new(CupratedTracingFilter {
|
||||
level: config.tracing.stdout.level,
|
||||
});
|
||||
drop(STDOUT_FILTER_HANDLE.set(stdout_handle));
|
||||
|
||||
let stdout_layer = fmt::Layer::default()
|
||||
.with_target(false)
|
||||
.with_filter(stdout_filter);
|
||||
|
||||
let appender_config = &config.tracing.file;
|
||||
let (appender, guard) = tracing_appender::non_blocking(
|
||||
tracing_appender::rolling::Builder::new()
|
||||
.rotation(Rotation::DAILY)
|
||||
.max_log_files(appender_config.max_log_files)
|
||||
.build(logs_path(&config.fs.data_directory, config.network()))
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
forget(guard);
|
||||
|
||||
let (appender_filter, appender_handle) = reload::Layer::new(CupratedTracingFilter {
|
||||
level: appender_config.level,
|
||||
});
|
||||
drop(FILE_WRITER_FILTER_HANDLE.set(appender_handle));
|
||||
|
||||
let appender_layer = fmt::layer()
|
||||
.with_target(false)
|
||||
.with_ansi(false)
|
||||
.with_writer(appender)
|
||||
.with_filter(appender_filter);
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(appender_layer)
|
||||
.with(stdout_layer)
|
||||
.init();
|
||||
}
|
||||
|
||||
pub fn modify_stdout_output(f: impl FnOnce(&mut CupratedTracingFilter)) {
|
||||
STDOUT_FILTER_HANDLE.get().unwrap().modify(f).unwrap();
|
||||
}
|
||||
|
||||
pub fn modify_file_output(f: impl FnOnce(&mut CupratedTracingFilter)) {
|
||||
FILE_WRITER_FILTER_HANDLE.get().unwrap().modify(f).unwrap();
|
||||
}
|
|
@ -30,6 +30,7 @@ mod blockchain;
|
|||
mod commands;
|
||||
mod config;
|
||||
mod constants;
|
||||
mod logging;
|
||||
mod p2p;
|
||||
mod rpc;
|
||||
mod signals;
|
||||
|
@ -42,7 +43,7 @@ fn main() {
|
|||
|
||||
let config = config::read_config_and_args();
|
||||
|
||||
let log_level_handle = init_logging(&config);
|
||||
logging::init_logging(&config);
|
||||
|
||||
let rt = init_tokio_rt();
|
||||
|
||||
|
@ -98,21 +99,10 @@ fn main() {
|
|||
let (command_tx, command_rx) = mpsc::channel(1);
|
||||
std::thread::spawn(|| commands::command_listener(command_tx));
|
||||
|
||||
io_loop(command_rx, log_level_handle).await;
|
||||
io_loop(command_rx).await;
|
||||
});
|
||||
}
|
||||
|
||||
fn init_logging(config: &Config) -> Handle<LevelFilter, Registry> {
|
||||
let (filter, handle) = tracing_subscriber::reload::Layer::new(config.tracing.level);
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(filter)
|
||||
.with(tracing_subscriber::fmt::Layer::default().with_target(false))
|
||||
.init();
|
||||
|
||||
handle
|
||||
}
|
||||
|
||||
fn init_tokio_rt() -> tokio::runtime::Runtime {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
|
@ -120,16 +110,11 @@ fn init_tokio_rt() -> tokio::runtime::Runtime {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
async fn io_loop(
|
||||
mut incoming_commands: mpsc::Receiver<Command>,
|
||||
tracing_level_handle: Handle<LevelFilter, Registry>,
|
||||
) -> ! {
|
||||
async fn io_loop(mut incoming_commands: mpsc::Receiver<Command>) -> ! {
|
||||
while let Some(command) = incoming_commands.recv().await {
|
||||
match command {
|
||||
Command::SetLog { level } => {
|
||||
tracing_level_handle
|
||||
.modify(|filter| *filter = level)
|
||||
.unwrap();
|
||||
logging::modify_stdout_output(|filter| filter.level = level);
|
||||
|
||||
println!("LOG LEVEL CHANGED: {level}");
|
||||
}
|
||||
|
|
|
@ -200,6 +200,21 @@ pub fn txpool_path(data_dir: &Path, network: Network) -> PathBuf {
|
|||
path_with_network(data_dir, network).join("txpool")
|
||||
}
|
||||
|
||||
/// Cuprate's logs directory.
|
||||
///
|
||||
/// This is the PATH used for all Cuprate log files.
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_helper::{network::Network, fs::{CUPRATE_DATA_DIR, logs_path}};
|
||||
///
|
||||
/// assert_eq!(logs_path(&**CUPRATE_DATA_DIR, Network::Mainnet).as_path(), CUPRATE_DATA_DIR.join("logs"));
|
||||
/// assert_eq!(logs_path(&**CUPRATE_DATA_DIR, Network::Stagenet).as_path(), CUPRATE_DATA_DIR.join(Network::Stagenet.to_string()).join("logs"));
|
||||
/// assert_eq!(logs_path(&**CUPRATE_DATA_DIR, Network::Testnet).as_path(), CUPRATE_DATA_DIR.join(Network::Testnet.to_string()).join("logs"));
|
||||
/// ```
|
||||
pub fn logs_path(data_dir: &Path, network: Network) -> PathBuf {
|
||||
path_with_network(data_dir, network).join("logs")
|
||||
}
|
||||
|
||||
/// Cuprate's address-book directory.
|
||||
///
|
||||
/// This is the PATH used for any Cuprate address-book files.
|
||||
|
|
|
@ -42,7 +42,11 @@ pub(crate) fn save_peers_to_disk<Z: BorshNetworkZone>(
|
|||
let file = cfg
|
||||
.peer_store_directory
|
||||
.join(format!("{}_p2p_state", Z::NAME));
|
||||
spawn_blocking(move || fs::write(&file, &data))
|
||||
|
||||
spawn_blocking(move || {
|
||||
fs::create_dir_all(file.parent().unwrap())?;
|
||||
fs::write(&file, &data)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn read_peers_from_disk<Z: BorshNetworkZone>(
|
||||
|
|
Loading…
Reference in a new issue