mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 09:16:00 +00:00
Merge branch 'unstable' into vc-fallback
This commit is contained in:
@@ -10,6 +10,7 @@ pub const DEFAULT_NETWORK_DIR: &str = "network";
|
||||
pub const DEFAULT_VALIDATOR_DIR: &str = "validators";
|
||||
pub const DEFAULT_SECRET_DIR: &str = "secrets";
|
||||
pub const DEFAULT_WALLET_DIR: &str = "wallets";
|
||||
pub const DEFAULT_TRACING_DIR: &str = "tracing";
|
||||
|
||||
/// Base directory name for unnamed testnets passed through the --testnet-dir flag
|
||||
pub const CUSTOM_TESTNET_DIR: &str = "custom";
|
||||
|
||||
@@ -37,7 +37,7 @@ derivative = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
psutil = { version = "3.2.2", optional = true }
|
||||
psutil = { version = "3.3.0", optional = true }
|
||||
procfs = { version = "0.15.1", optional = true }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -47,6 +47,9 @@ pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinde
|
||||
pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value";
|
||||
pub const CONSENSUS_BLOCK_VALUE_HEADER: &str = "Eth-Consensus-Block-Value";
|
||||
|
||||
pub const CONTENT_TYPE_HEADER: &str = "Content-Type";
|
||||
pub const SSZ_CONTENT_TYPE_HEADER: &str = "application/octet-stream";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// The `reqwest` client raised an error.
|
||||
@@ -1832,6 +1835,7 @@ impl BeaconNodeHttpClient {
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
builder_booster_factor: Option<u64>,
|
||||
) -> Result<Url, Error> {
|
||||
let mut path = self.eth_path(V3)?;
|
||||
|
||||
@@ -1854,6 +1858,11 @@ impl BeaconNodeHttpClient {
|
||||
.append_pair("skip_randao_verification", "");
|
||||
}
|
||||
|
||||
if let Some(builder_booster_factor) = builder_booster_factor {
|
||||
path.query_pairs_mut()
|
||||
.append_pair("builder_boost_factor", &builder_booster_factor.to_string());
|
||||
}
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
@@ -1863,12 +1872,14 @@ impl BeaconNodeHttpClient {
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
builder_booster_factor: Option<u64>,
|
||||
) -> Result<(JsonProduceBlockV3Response<T>, ProduceBlockV3Metadata), Error> {
|
||||
self.get_validator_blocks_v3_modular(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
SkipRandaoVerification::No,
|
||||
builder_booster_factor,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -1880,9 +1891,16 @@ impl BeaconNodeHttpClient {
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
builder_booster_factor: Option<u64>,
|
||||
) -> Result<(JsonProduceBlockV3Response<T>, ProduceBlockV3Metadata), Error> {
|
||||
let path = self
|
||||
.get_validator_blocks_v3_path(slot, randao_reveal, graffiti, skip_randao_verification)
|
||||
.get_validator_blocks_v3_path(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
skip_randao_verification,
|
||||
builder_booster_factor,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let opt_result = self
|
||||
@@ -1923,12 +1941,14 @@ impl BeaconNodeHttpClient {
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
builder_booster_factor: Option<u64>,
|
||||
) -> Result<(ProduceBlockV3Response<T>, ProduceBlockV3Metadata), Error> {
|
||||
self.get_validator_blocks_v3_modular_ssz::<T>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
SkipRandaoVerification::No,
|
||||
builder_booster_factor,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -1940,9 +1960,16 @@ impl BeaconNodeHttpClient {
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
builder_booster_factor: Option<u64>,
|
||||
) -> Result<(ProduceBlockV3Response<T>, ProduceBlockV3Metadata), Error> {
|
||||
let path = self
|
||||
.get_validator_blocks_v3_path(slot, randao_reveal, graffiti, skip_randao_verification)
|
||||
.get_validator_blocks_v3_path(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
skip_randao_verification,
|
||||
builder_booster_factor,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let opt_response = self
|
||||
|
||||
@@ -243,6 +243,8 @@ pub struct ProcessHealth {
|
||||
pub pid_mem_resident_set_size: u64,
|
||||
/// The total virtual memory used by this pid.
|
||||
pub pid_mem_virtual_memory_size: u64,
|
||||
/// The total shared memory used by this pid.
|
||||
pub pid_mem_shared_memory_size: u64,
|
||||
/// Number of cpu seconds consumed by this pid.
|
||||
pub pid_process_seconds_total: u64,
|
||||
}
|
||||
@@ -277,6 +279,7 @@ impl ProcessHealth {
|
||||
pid_num_threads: stat.num_threads,
|
||||
pid_mem_resident_set_size: process_mem.rss(),
|
||||
pid_mem_virtual_memory_size: process_mem.vms(),
|
||||
pid_mem_shared_memory_size: process_mem.shared(),
|
||||
pid_process_seconds_total: process_times.busy().as_secs()
|
||||
+ process_times.children_system().as_secs()
|
||||
+ process_times.children_system().as_secs(),
|
||||
|
||||
@@ -729,6 +729,7 @@ pub struct ValidatorBlocksQuery {
|
||||
pub randao_reveal: SignatureBytes,
|
||||
pub graffiti: Option<Graffiti>,
|
||||
pub skip_randao_verification: SkipRandaoVerification,
|
||||
pub builder_boost_factor: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize)]
|
||||
@@ -1553,9 +1554,10 @@ pub struct ProduceBlockV3Metadata {
|
||||
)]
|
||||
pub consensus_version: ForkName,
|
||||
pub execution_payload_blinded: bool,
|
||||
#[serde(with = "serde_utils::u256_dec")]
|
||||
pub execution_payload_value: Uint256,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub consensus_block_value: u64,
|
||||
#[serde(with = "serde_utils::u256_dec")]
|
||||
pub consensus_block_value: Uint256,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> FullBlockContents<T> {
|
||||
@@ -1706,7 +1708,7 @@ impl TryFrom<&HeaderMap> for ProduceBlockV3Metadata {
|
||||
})?;
|
||||
let consensus_block_value =
|
||||
parse_required_header(headers, CONSENSUS_BLOCK_VALUE_HEADER, |s| {
|
||||
s.parse::<u64>()
|
||||
s.parse::<Uint256>()
|
||||
.map_err(|e| format!("invalid {CONSENSUS_BLOCK_VALUE_HEADER}: {e:?}"))
|
||||
})?;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
- enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg
|
||||
- enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg
|
||||
# Teku team (Consensys)
|
||||
- enr:-KG4QMOEswP62yzDjSwWS4YEjtTZ5PO6r65CPqYBkgTTkrpaedQ8uEUo1uMALtJIvb2w_WWEVmg5yt1UAuK1ftxUU7QDhGV0aDKQu6TalgMAAAD__________4JpZIJ2NIJpcIQEnfA2iXNlY3AyNTZrMaEDfol8oLr6XJ7FsdAYE7lpJhKMls4G_v6qQOGKJUWGb_uDdGNwgiMog3VkcIIjKA
|
||||
- enr:-KG4QNTx85fjxABbSq_Rta9wy56nQ1fHK0PewJbGjLm1M4bMGx5-3Qq4ZX2-iFJ0pys_O90sVXNNOxp2E7afBsGsBrgDhGV0aDKQu6TalgMAAAD__________4JpZIJ2NIJpcIQEnfA2iXNlY3AyNTZrMaECGXWQ-rQ2KZKRH1aOW4IlPDBkY4XDphxg9pxKytFCkayDdGNwgiMog3VkcIIjKA
|
||||
- enr:-KG4QF4B5WrlFcRhUU6dZETwY5ZzAXnA0vGC__L1Kdw602nDZwXSTs5RFXFIFUnbQJmhNGVU6OIX7KVrCSTODsz1tK4DhGV0aDKQu6TalgMAAAD__________4JpZIJ2NIJpcIQExNYEiXNlY3AyNTZrMaECQmM9vp7KhaXhI-nqL_R0ovULLCFSFTa9CPPSdb1zPX6DdGNwgiMog3VkcIIjKA
|
||||
# Prysm team (Prysmatic Labs)
|
||||
- enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
# Prater config
|
||||
|
||||
# Extends the mainnet preset
|
||||
CONFIG_NAME: 'prater'
|
||||
PRESET_BASE: 'mainnet'
|
||||
|
||||
CONFIG_NAME: 'prater'
|
||||
|
||||
# Transition
|
||||
# ---------------------------------------------------------------
|
||||
# Expected August 10, 2022
|
||||
TERMINAL_TOTAL_DIFFICULTY: 10790000
|
||||
# By default, don't use these params
|
||||
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615
|
||||
|
||||
|
||||
# Genesis
|
||||
# ---------------------------------------------------------------
|
||||
# `2**14` (= 16,384)
|
||||
@@ -32,19 +35,15 @@ GENESIS_DELAY: 1919188
|
||||
# Altair
|
||||
ALTAIR_FORK_VERSION: 0x01001020
|
||||
ALTAIR_FORK_EPOCH: 36660
|
||||
# Merge
|
||||
# Bellatrix
|
||||
BELLATRIX_FORK_VERSION: 0x02001020
|
||||
BELLATRIX_FORK_EPOCH: 112260
|
||||
# Capella
|
||||
CAPELLA_FORK_VERSION: 0x03001020
|
||||
CAPELLA_FORK_EPOCH: 162304
|
||||
# Sharding
|
||||
SHARDING_FORK_VERSION: 0x04001020
|
||||
SHARDING_FORK_EPOCH: 18446744073709551615
|
||||
|
||||
# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D.
|
||||
TRANSITION_TOTAL_DIFFICULTY: 4294967296
|
||||
|
||||
# DENEB
|
||||
DENEB_FORK_VERSION: 0x04001020
|
||||
DENEB_FORK_EPOCH: 231680
|
||||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
@@ -70,11 +69,10 @@ INACTIVITY_SCORE_RECOVERY_RATE: 16
|
||||
EJECTION_BALANCE: 16000000000
|
||||
# 2**2 (= 4)
|
||||
MIN_PER_EPOCH_CHURN_LIMIT: 4
|
||||
# 2**3 (= 8)
|
||||
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
|
||||
# 2**16 (= 65,536)
|
||||
CHURN_LIMIT_QUOTIENT: 65536
|
||||
|
||||
# [New in Deneb:EIP7514] 2**3 (= 8)
|
||||
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
|
||||
|
||||
# Fork choice
|
||||
# ---------------------------------------------------------------
|
||||
@@ -89,16 +87,41 @@ DEPOSIT_NETWORK_ID: 5
|
||||
# Prater test deposit contract on Goerli Testnet
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b
|
||||
|
||||
# Network
|
||||
# Networking
|
||||
# ---------------------------------------------------------------
|
||||
SUBNETS_PER_NODE: 2
|
||||
# `10 * 2**20` (= 10485760, 10 MiB)
|
||||
GOSSIP_MAX_SIZE: 10485760
|
||||
# `2**10` (= 1024)
|
||||
MAX_REQUEST_BLOCKS: 1024
|
||||
# `2**8` (= 256)
|
||||
EPOCHS_PER_SUBNET_SUBSCRIPTION: 256
|
||||
# `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months)
|
||||
MIN_EPOCHS_FOR_BLOCK_REQUESTS: 33024
|
||||
# `10 * 2**20` (=10485760, 10 MiB)
|
||||
MAX_CHUNK_SIZE: 10485760
|
||||
# 5s
|
||||
TTFB_TIMEOUT: 5
|
||||
# 10s
|
||||
RESP_TIMEOUT: 10
|
||||
ATTESTATION_PROPAGATION_SLOT_RANGE: 32
|
||||
# 500ms
|
||||
MAXIMUM_GOSSIP_CLOCK_DISPARITY: 500
|
||||
MESSAGE_DOMAIN_INVALID_SNAPPY: 0x00000000
|
||||
MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
|
||||
# 2 subnets per node
|
||||
SUBNETS_PER_NODE: 2
|
||||
# 2**8 (= 64)
|
||||
ATTESTATION_SUBNET_COUNT: 64
|
||||
ATTESTATION_SUBNET_EXTRA_BITS: 0
|
||||
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
|
||||
ATTESTATION_SUBNET_PREFIX_BITS: 6
|
||||
|
||||
# Deneb
|
||||
# `2**7` (=128)
|
||||
MAX_REQUEST_BLOCKS_DENEB: 128
|
||||
# MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
|
||||
MAX_REQUEST_BLOB_SIDECARS: 768
|
||||
# `2**12` (= 4096 epochs, ~18 days)
|
||||
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096
|
||||
# `6`
|
||||
BLOB_SIDECAR_SUBNET_COUNT: 6
|
||||
|
||||
@@ -17,8 +17,8 @@ pub const VERSION: &str = git_version!(
|
||||
// NOTE: using --match instead of --exclude for compatibility with old Git
|
||||
"--match=thiswillnevermatchlol"
|
||||
],
|
||||
prefix = "Lighthouse/v4.5.0-",
|
||||
fallback = "Lighthouse/v4.5.0"
|
||||
prefix = "Lighthouse/v4.6.0-rc.0-",
|
||||
fallback = "Lighthouse/v4.6.0-rc.0"
|
||||
);
|
||||
|
||||
/// Returns `VERSION`, but with platform information appended to the end.
|
||||
|
||||
@@ -8,15 +8,20 @@ edition = { workspace = true }
|
||||
test_logger = [] # Print log output to stderr when running tests instead of dropping it
|
||||
|
||||
[dependencies]
|
||||
slog = { workspace = true }
|
||||
slog-term = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
lighthouse_metrics = { workspace = true }
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
||||
lazy_static = { workspace = true }
|
||||
sloggers = { workspace = true }
|
||||
slog-async = { workspace = true }
|
||||
take_mut = "0.2.2"
|
||||
lighthouse_metrics = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
||||
slog = { workspace = true }
|
||||
slog-async = { workspace = true }
|
||||
slog-term = { workspace = true }
|
||||
sloggers = { workspace = true }
|
||||
take_mut = "0.2.2"
|
||||
tokio = { workspace = true, features = [ "time" ] }
|
||||
tracing = "0.1"
|
||||
tracing-core = { workspace = true }
|
||||
tracing-log = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
tracing-appender = { workspace = true }
|
||||
|
||||
@@ -7,13 +7,22 @@ use lighthouse_metrics::{
|
||||
use slog::Logger;
|
||||
use slog_term::Decorator;
|
||||
use std::io::{Result, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::time::{Duration, Instant};
|
||||
use tracing_appender::non_blocking::NonBlocking;
|
||||
use tracing_logging_layer::LoggingLayer;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
pub const MAX_MESSAGE_WIDTH: usize = 40;
|
||||
|
||||
pub mod async_record;
|
||||
mod sse_logging_components;
|
||||
mod tracing_logging_layer;
|
||||
mod tracing_metrics_layer;
|
||||
|
||||
pub use sse_logging_components::SSELoggingComponents;
|
||||
pub use tracing_logging_layer::cleanup_logging_task;
|
||||
pub use tracing_metrics_layer::MetricsLayer;
|
||||
|
||||
/// The minimum interval between log messages indicating that a queue is full.
|
||||
const LOG_DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);
|
||||
@@ -214,6 +223,48 @@ impl TimeLatch {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_tracing_layer(base_tracing_log_path: PathBuf, turn_on_terminal_logs: bool) {
|
||||
let filter_layer = match tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
.or_else(|_| tracing_subscriber::EnvFilter::try_new("warn"))
|
||||
{
|
||||
Ok(filter) => filter,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to initialize dependency logging {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let libp2p_writer =
|
||||
tracing_appender::rolling::daily(base_tracing_log_path.clone(), "libp2p.log");
|
||||
let discv5_writer =
|
||||
tracing_appender::rolling::daily(base_tracing_log_path.clone(), "discv5.log");
|
||||
|
||||
let (libp2p_non_blocking_writer, libp2p_guard) = NonBlocking::new(libp2p_writer);
|
||||
let (discv5_non_blocking_writer, discv5_guard) = NonBlocking::new(discv5_writer);
|
||||
|
||||
let custom_layer = LoggingLayer {
|
||||
libp2p_non_blocking_writer,
|
||||
libp2p_guard,
|
||||
discv5_non_blocking_writer,
|
||||
discv5_guard,
|
||||
};
|
||||
|
||||
if let Err(e) = tracing_subscriber::fmt()
|
||||
.with_env_filter(filter_layer)
|
||||
.with_writer(move || {
|
||||
tracing_subscriber::fmt::writer::OptionalWriter::<std::io::Stdout>::from(
|
||||
turn_on_terminal_logs.then(std::io::stdout),
|
||||
)
|
||||
})
|
||||
.finish()
|
||||
.with(MetricsLayer)
|
||||
.with(custom_layer)
|
||||
.try_init()
|
||||
{
|
||||
eprintln!("Failed to initialize dependency logging {e}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a logger suitable for test usage.
|
||||
///
|
||||
/// By default no logs will be printed, but they can be enabled via
|
||||
|
||||
115
common/logging/src/tracing_logging_layer.rs
Normal file
115
common/logging/src/tracing_logging_layer.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
use chrono::{naive::Days, prelude::*};
|
||||
use slog::{debug, warn};
|
||||
use std::io::Write;
|
||||
use tracing::Subscriber;
|
||||
use tracing_appender::non_blocking::{NonBlocking, WorkerGuard};
|
||||
use tracing_subscriber::layer::Context;
|
||||
use tracing_subscriber::Layer;
|
||||
|
||||
pub struct LoggingLayer {
|
||||
pub libp2p_non_blocking_writer: NonBlocking,
|
||||
pub libp2p_guard: WorkerGuard,
|
||||
pub discv5_non_blocking_writer: NonBlocking,
|
||||
pub discv5_guard: WorkerGuard,
|
||||
}
|
||||
|
||||
impl<S> Layer<S> for LoggingLayer
|
||||
where
|
||||
S: Subscriber,
|
||||
{
|
||||
fn on_event(&self, event: &tracing::Event<'_>, _ctx: Context<S>) {
|
||||
let meta = event.metadata();
|
||||
let log_level = meta.level();
|
||||
let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
||||
|
||||
let target = match meta.target().split_once("::") {
|
||||
Some((crate_name, _)) => crate_name,
|
||||
None => "unknown",
|
||||
};
|
||||
|
||||
let mut writer = match target {
|
||||
"libp2p_gossipsub" => self.libp2p_non_blocking_writer.clone(),
|
||||
"discv5" => self.discv5_non_blocking_writer.clone(),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let mut visitor = LogMessageExtractor {
|
||||
message: String::default(),
|
||||
};
|
||||
|
||||
event.record(&mut visitor);
|
||||
let message = format!("{} {} {}\n", timestamp, log_level, visitor.message);
|
||||
|
||||
if let Err(e) = writer.write_all(message.as_bytes()) {
|
||||
eprintln!("Failed to write log: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LogMessageExtractor {
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl tracing_core::field::Visit for LogMessageExtractor {
|
||||
fn record_debug(&mut self, _: &tracing_core::Field, value: &dyn std::fmt::Debug) {
|
||||
self.message = format!("{} {:?}", self.message, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a long lived async task that routinely deletes old tracing log files
|
||||
pub async fn cleanup_logging_task(path: std::path::PathBuf, log: slog::Logger) {
|
||||
loop {
|
||||
// Delay for 1 day and then prune old logs
|
||||
tokio::time::sleep(std::time::Duration::from_secs(60 * 60 * 24)).await;
|
||||
|
||||
let Some(yesterday_date) = chrono::prelude::Local::now()
|
||||
.naive_local()
|
||||
.checked_sub_days(Days::new(1))
|
||||
else {
|
||||
warn!(log, "Could not calculate the current date");
|
||||
return;
|
||||
};
|
||||
|
||||
// Search for old log files
|
||||
let dir = path.as_path();
|
||||
|
||||
if dir.is_dir() {
|
||||
let Ok(files) = std::fs::read_dir(dir) else {
|
||||
warn!(log, "Could not read log directory contents"; "path" => ?dir);
|
||||
break;
|
||||
};
|
||||
|
||||
for file in files {
|
||||
let Ok(dir_entry) = file else {
|
||||
warn!(log, "Could not read file");
|
||||
continue;
|
||||
};
|
||||
|
||||
let Ok(file_name) = dir_entry.file_name().into_string() else {
|
||||
warn!(log, "Could not read file"; "file" => ?dir_entry);
|
||||
continue;
|
||||
};
|
||||
|
||||
if file_name.starts_with("libp2p.log") | file_name.starts_with("discv5.log") {
|
||||
let log_file_date = file_name.split('.').collect::<Vec<_>>();
|
||||
if log_file_date.len() == 3 {
|
||||
let Ok(log_file_date_type) =
|
||||
NaiveDate::parse_from_str(log_file_date[2], "%Y-%m-%d")
|
||||
else {
|
||||
warn!(log, "Could not parse log file date"; "file" => file_name);
|
||||
continue;
|
||||
};
|
||||
|
||||
if log_file_date_type < yesterday_date.into() {
|
||||
// Delete the file, its too old
|
||||
debug!(log, "Removing old log file"; "file" => &file_name);
|
||||
if let Err(e) = std::fs::remove_file(dir_entry.path()) {
|
||||
warn!(log, "Failed to remove log file"; "file" => file_name, "error" => %e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
common/logging/src/tracing_metrics_layer.rs
Normal file
63
common/logging/src/tracing_metrics_layer.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
//! Exposes [`MetricsLayer`]: A tracing layer that registers metrics of logging events.
|
||||
|
||||
use lighthouse_metrics as metrics;
|
||||
use tracing_log::NormalizeEvent;
|
||||
|
||||
lazy_static! {
|
||||
/// Count of `INFO` logs registered per enabled dependency.
|
||||
pub static ref DEP_INFOS_TOTAL: metrics::Result<metrics::IntCounterVec> =
|
||||
metrics::try_create_int_counter_vec(
|
||||
"dep_info_total",
|
||||
"Count of infos logged per enabled dependency",
|
||||
&["target"]
|
||||
);
|
||||
/// Count of `WARN` logs registered per enabled dependency.
|
||||
pub static ref DEP_WARNS_TOTAL: metrics::Result<metrics::IntCounterVec> =
|
||||
metrics::try_create_int_counter_vec(
|
||||
"dep_warn_total",
|
||||
"Count of warns logged per enabled dependency",
|
||||
&["target"]
|
||||
);
|
||||
/// Count of `ERROR` logs registered per enabled dependency.
|
||||
pub static ref DEP_ERRORS_TOTAL: metrics::Result<metrics::IntCounterVec> =
|
||||
metrics::try_create_int_counter_vec(
|
||||
"dep_error_total",
|
||||
"Count of errors logged per enabled dependency",
|
||||
&["target"]
|
||||
);
|
||||
}
|
||||
|
||||
/// Layer that registers Prometheus metrics for `INFO`, `WARN` and `ERROR` logs emitted per dependency.
|
||||
/// Dependencies are enabled via the `RUST_LOG` env flag.
|
||||
pub struct MetricsLayer;
|
||||
|
||||
impl<S: tracing_core::Subscriber> tracing_subscriber::layer::Layer<S> for MetricsLayer {
|
||||
fn on_event(
|
||||
&self,
|
||||
event: &tracing_core::Event<'_>,
|
||||
_ctx: tracing_subscriber::layer::Context<'_, S>,
|
||||
) {
|
||||
// get the event's normalized metadata
|
||||
// this is necessary to get the correct module path for libp2p events
|
||||
let normalized_meta = event.normalized_metadata();
|
||||
let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata());
|
||||
|
||||
if !meta.is_event() {
|
||||
// ignore tracing span events
|
||||
return;
|
||||
}
|
||||
|
||||
let full_target = meta.module_path().unwrap_or_else(|| meta.target());
|
||||
let target = full_target
|
||||
.split_once("::")
|
||||
.map(|(name, _rest)| name)
|
||||
.unwrap_or(full_target);
|
||||
let target = &[target];
|
||||
match *meta.level() {
|
||||
tracing_core::Level::INFO => metrics::inc_counter_vec(&DEP_INFOS_TOTAL, target),
|
||||
tracing_core::Level::WARN => metrics::inc_counter_vec(&DEP_WARNS_TOTAL, target),
|
||||
tracing_core::Level::ERROR => metrics::inc_counter_vec(&DEP_ERRORS_TOTAL, target),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
//! Due to `jemalloc` requiring configuration at compile time or immediately upon runtime
|
||||
//! initialisation it is configured via a Cargo config file in `.cargo/config.toml`.
|
||||
//!
|
||||
//! The `jemalloc` tuning can be overriden by:
|
||||
//! The `jemalloc` tuning can be overridden by:
|
||||
//!
|
||||
//! A) `JEMALLOC_SYS_WITH_MALLOC_CONF` at compile-time.
|
||||
//! B) `_RJEM_MALLOC_CONF` at runtime.
|
||||
|
||||
@@ -14,6 +14,10 @@ lazy_static::lazy_static! {
|
||||
"process_virtual_memory_bytes",
|
||||
"Virtual memory used by the current process"
|
||||
);
|
||||
pub static ref PROCESS_SHR_MEM: Result<IntGauge> = try_create_int_gauge(
|
||||
"process_shared_memory_bytes",
|
||||
"Shared memory used by the current process"
|
||||
);
|
||||
pub static ref PROCESS_SECONDS: Result<IntGauge> = try_create_int_gauge(
|
||||
"process_cpu_seconds_total",
|
||||
"Total cpu time taken by the current process"
|
||||
@@ -90,6 +94,7 @@ pub fn scrape_process_health_metrics() {
|
||||
set_gauge(&PROCESS_NUM_THREADS, health.pid_num_threads);
|
||||
set_gauge(&PROCESS_RES_MEM, health.pid_mem_resident_set_size as i64);
|
||||
set_gauge(&PROCESS_VIRT_MEM, health.pid_mem_virtual_memory_size as i64);
|
||||
set_gauge(&PROCESS_SHR_MEM, health.pid_mem_shared_memory_size as i64);
|
||||
set_gauge(&PROCESS_SECONDS, health.pid_process_seconds_total as i64);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user