pub fn start<C>(service: &Service<C>, exit: ::exit_future::Exit, handle: TaskExecutor) where
	C: Components,
{
	let network = service.network();
	let client = service.client();
	let txpool = service.transaction_pool();
	let mut last_number = None;
	let mut last_update = time::Instant::now();

	let mut sys = System::new();
	let self_pid = get_current_pid();

	let display_notifications = network.status().for_each(move |sync_status| {

		if let Ok(info) = client.info() {
			let best_number: u64 = info.chain.best_number.as_();
			let best_hash = info.chain.best_hash;
			let num_peers = sync_status.num_peers;
			let speed = move || speed(best_number, last_number, last_update);
			last_update = time::Instant::now();
			let (status, target) = match (sync_status.sync.state, sync_status.sync.best_seen_block) {
				(SyncState::Idle, _) => ("Idle".into(), "".into()),
				(SyncState::Downloading, None) => (format!("Syncing{}", speed()), "".into()),
				(SyncState::Downloading, Some(n)) => (format!("Syncing{}", speed()), format!(", target=#{}", n)),
			};
			last_number = Some(best_number);
			let txpool_status = txpool.status();
			let finalized_number: u64 = info.chain.finalized_number.as_();
			let bandwidth_download = network.average_download_per_sec();
			let bandwidth_upload = network.average_upload_per_sec();
			info!(
				target: "substrate",
				"{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}",
				Colour::White.bold().paint(&status),
				target,
				Colour::White.bold().paint(format!("{}", sync_status.num_peers)),
				Colour::White.paint(format!("{}", best_number)),
				best_hash,
				Colour::White.paint(format!("{}", finalized_number)),
				info.chain.finalized_hash,
				TransferRateFormat(bandwidth_download),
				TransferRateFormat(bandwidth_upload),
			);

			// get cpu usage and memory usage of this process
			let (cpu_usage, memory) = if sys.refresh_process(self_pid) {
				let proc = sys.get_process(self_pid).expect("Above refresh_process succeeds, this should be Some(), qed");
				(proc.cpu_usage(), proc.memory())
			} else { (0.0, 0) };

			let network_state = serde_json::to_string(&network.network_state()).unwrap_or_default();

			telemetry!(
				SUBSTRATE_INFO;
				"system.interval";
				"network_state" => network_state,
				"status" => format!("{}{}", status, target),
				"peers" => num_peers,
				"height" => best_number,
				"best" => ?best_hash,
				"txcount" => txpool_status.ready,
				"cpu" => cpu_usage,
				"memory" => memory,
				"finalized_height" => finalized_number,
				"finalized_hash" => ?info.chain.finalized_hash,
				"bandwidth_download" => bandwidth_download,
				"bandwidth_upload" => bandwidth_upload,
			);
		} else {
			warn!("Error getting best block information");
		}

		Ok(())
	});

	let client = service.client();
	let mut last = match client.info() {
		Ok(info) => Some((info.chain.best_number, info.chain.best_hash)),
		Err(e) => { warn!("Error getting best block information: {:?}", e); None }
	};

	let display_block_import = client.import_notification_stream().for_each(move |n| {
		// detect and log reorganizations.
		if let Some((ref last_num, ref last_hash)) = last {
			if n.header.parent_hash() != last_hash {
				let tree_route = ::client::blockchain::tree_route(
					client.backend().blockchain(),
					BlockId::Hash(last_hash.clone()),
					BlockId::Hash(n.hash),
				);

				match tree_route {
					Ok(ref t) if !t.retracted().is_empty() => info!(
						"Reorg from #{},{} to #{},{}, common ancestor #{},{}",
						last_num, last_hash,
						n.header.number(), n.hash,
						t.common_block().number, t.common_block().hash,
					),
					Ok(_) => {},
					Err(e) => warn!("Error computing tree route: {}", e),
				}
			}
		}

		last = Some((n.header.number().clone(), n.hash.clone()));

		info!(target: "substrate", "Imported #{} ({})", n.header.number(), n.hash);
		Ok(())
	});

	let txpool = service.transaction_pool();
	let display_txpool_import = txpool.import_notification_stream().for_each(move |_| {
		let status = txpool.status();
		telemetry!(SUBSTRATE_INFO; "txpool.import"; "ready" => status.ready, "future" => status.future);
		Ok(())
	});

	let informant_work = display_notifications.join3(display_block_import, display_txpool_import);
	handle.spawn(exit.until(informant_work).map(|_| ()));
}
/// Spawn informant on the event loop
Spawn informant on the event loop
Spawn informant on the event loop
pub fn start<C>(service: &Service<C>, exit: ::exit_future::Exit, handle: TaskExecutor) where
	C: Components,
{
	let network = service.network();
	let client = service.client();
	let txpool = service.transaction_pool();
	let mut last_number = None;
	let mut last_update = time::Instant::now();
	let mut sys = System::new();
	let self_pid = get_current_pid();
	let display_notifications = network.status().for_each(move |sync_status| {
		if let Ok(info) = client.info() {
			let best_number: u64 = info.chain.best_number.as_();
			let best_hash = info.chain.best_hash;
			let num_peers = sync_status.num_peers;
			let speed = move || speed(best_number, last_number, last_update);
			last_update = time::Instant::now();
			let (status, target) = match (sync_status.sync.state, sync_status.sync.best_seen_block) {
				(SyncState::Idle, _) => ("Idle".into(), "".into()),
				(SyncState::Downloading, None) => (format!("Syncing{}", speed()), "".into()),
				(SyncState::Downloading, Some(n)) => (format!("Syncing{}", speed()), format!(", target=#{}", n)),
			};
			last_number = Some(best_number);
			let txpool_status = txpool.status();
			let finalized_number: u64 = info.chain.finalized_number.as_();
			let bandwidth_download = network.average_download_per_sec();
			let bandwidth_upload = network.average_upload_per_sec();
			info!(
				target: "substrate",
				"{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}",
				Colour::White.bold().paint(&status),
				target,
				Colour::White.bold().paint(format!("{}", sync_status.num_peers)),
				Colour::White.paint(format!("{}", best_number)),
				best_hash,
				Colour::White.paint(format!("{}", finalized_number)),
				info.chain.finalized_hash,
				TransferRateFormat(bandwidth_download),
				TransferRateFormat(bandwidth_upload),
			);
			// get cpu usage and memory usage of this process
			let (cpu_usage, memory) = if sys.refresh_process(self_pid) {
				let proc = sys.get_process(self_pid).expect("Above refresh_process succeeds, this should be Some(), qed");
				(proc.cpu_usage(), proc.memory())
			} else { (0.0, 0) };
			let network_state = serde_json::to_string(&network.network_state()).unwrap_or_default();
			telemetry!(
				SUBSTRATE_INFO;
				"system.interval";
				"network_state" => network_state,
				"status" => format!("{}{}", status, target),
				"peers" => num_peers,
				"height" => best_number,
				"best" => ?best_hash,
				"txcount" => txpool_status.ready,
				"cpu" => cpu_usage,
				"memory" => memory,
				"finalized_height" => finalized_number,
				"finalized_hash" => ?info.chain.finalized_hash,
				"bandwidth_download" => bandwidth_download,
				"bandwidth_upload" => bandwidth_upload,
			);
		} else {
			warn!("Error getting best block information");
		}
		Ok(())
	});
	let client = service.client();
	let mut last = match client.info() {
		Ok(info) => Some((info.chain.best_number, info.chain.best_hash)),
		Err(e) => { warn!("Error getting best block information: {:?}", e); None }
	};
	let display_block_import = client.import_notification_stream().for_each(move |n| {
		// detect and log reorganizations.
		if let Some((ref last_num, ref last_hash)) = last {
			if n.header.parent_hash() != last_hash {
				let tree_route = ::client::blockchain::tree_route(
					client.backend().blockchain(),
					BlockId::Hash(last_hash.clone()),
					BlockId::Hash(n.hash),
				);
				match tree_route {
					Ok(ref t) if !t.retracted().is_empty() => info!(
						"Reorg from #{},{} to #{},{}, common ancestor #{},{}",
						last_num, last_hash,
						n.header.number(), n.hash,
						t.common_block().number, t.common_block().hash,
					),
					Ok(_) => {},
					Err(e) => warn!("Error computing tree route: {}", e),
				}
			}
		}
		last = Some((n.header.number().clone(), n.hash.clone()));
		info!(target: "substrate", "Imported #{} ({})", n.header.number(), n.hash);
		Ok(())
	});
	let txpool = service.transaction_pool();
	let display_txpool_import = txpool.import_notification_stream().for_each(move |_| {
		let status = txpool.status();
		telemetry!(SUBSTRATE_INFO; "txpool.import"; "ready" => status.ready, "future" => status.future);
		Ok(())
	});
	let informant_work = display_notifications.join3(display_block_import, display_txpool_import);
	handle.spawn(exit.until(informant_work).map(|_| ()));
}
pub fn start < C > ( service : & Service < C > , exit : :: exit_future :: Exit , handle : TaskExecutor ) where C : Components , { let network = service . network ( ) ; let client = service . client ( ) ; let txpool = service . transaction_pool ( ) ; let mut last_number = None ; let mut last_update = time :: Instant :: now ( ) ; let mut sys = System :: new ( ) ; let self_pid = get_current_pid ( ) ; let display_notifications = network . status ( ) . for_each ( move | sync_status | { if let Ok ( info ) = client . info ( ) { let best_number : u64 = info . chain . best_number . as_ ( ) ; let best_hash = info . chain . best_hash ; let num_peers = sync_status . num_peers ; let speed = move | | speed ( best_number , last_number , last_update ) ; last_update = time :: Instant :: now ( ) ; let ( status , target ) = match ( sync_status . sync . state , sync_status . sync . best_seen_block ) { ( SyncState :: Idle , _ ) => ( " " . into ( ) , " " . into ( ) ) , ( SyncState :: Downloading , None ) => ( format ! ( " " speed ( ) ) , " " . into ( ) ) , ( SyncState :: Downloading , Some ( n ) ) => ( format ! ( " " speed ( ) ) , format ! ( " " n ) ) , } ; last_number = Some ( best_number ) ; let txpool_status = txpool . status ( ) ; let finalized_number : u64 = info . chain . finalized_number . as_ ( ) ; let bandwidth_download = network . average_download_per_sec ( ) ; let bandwidth_upload = network . average_upload_per_sec ( ) ; info ! ( target " " " Colour White bold ( ) paint ( status ) target Colour White bold ( ) paint ( format ( " " sync_status num_peers ) ) Colour White paint ( format ( " " best_number ) ) best_hash Colour White paint ( format ( " " finalized_number ) ) info chain finalized_hash TransferRateFormat ( bandwidth_download ) TransferRateFormat ( bandwidth_upload ) ) ; // get cpu usage and memory usage of this process let ( cpu_usage , memory ) = if sys . refresh_process ( self_pid ) { let proc = sys . get_process ( self_pid ) . expect ( " " ) ; ( proc . cpu_usage ( ) , proc . memory ( ) ) } else { ( 0.0 , 0 ) } ; let network_state = serde_json :: to_string ( & network . network_state ( ) ) . unwrap_or_default ( ) ; telemetry ! ( SUBSTRATE_INFO " " " " network_state " " format ( " " status target ) " " num_peers " " best_number " " best_hash " " txpool_status ready " " cpu_usage " " memory " " finalized_number " " info chain finalized_hash " " bandwidth_download " " bandwidth_upload ) ; } else { warn ! ( " " ) ; } Ok ( ( ) ) } ) ; let client = service . client ( ) ; let mut last = match client . info ( ) { Ok ( info ) => Some ( ( info . chain . best_number , info . chain . best_hash ) ) , Err ( e ) => { warn ! ( " " e ) ; None } } ; let display_block_import = client . import_notification_stream ( ) . for_each ( move | n | { // detect and log reorganizations. if let Some ( ( ref last_num , ref last_hash ) ) = last { if n . header . parent_hash ( ) != last_hash { let tree_route = :: client :: blockchain :: tree_route ( client . backend ( ) . blockchain ( ) , BlockId :: Hash ( last_hash . clone ( ) ) , BlockId :: Hash ( n . hash ) , ) ; match tree_route { Ok ( ref t ) if ! t . retracted ( ) . is_empty ( ) => info ! ( " " last_num last_hash n header number ( ) n hash t common_block ( ) number t common_block ( ) hash ) , Ok ( _ ) => { } , Err ( e ) => warn ! ( " " e ) , } } } last = Some ( ( n . header . number ( ) . clone ( ) , n . hash . clone ( ) ) ) ; info ! ( target " " " " n header number ( ) n hash ) ; Ok ( ( ) ) } ) ; let txpool = service . transaction_pool ( ) ; let display_txpool_import = txpool . import_notification_stream ( ) . for_each ( move | _ | { let status = txpool . status ( ) ; telemetry ! ( SUBSTRATE_INFO " " " " status ready " " status future ) ; Ok ( ( ) ) } ) ; let informant_work = display_notifications . join3 ( display_block_import , display_txpool_import ) ; handle . spawn ( exit . until ( informant_work ) . map ( | _ | ( ) ) ) ; }
Spawn informant on the event loop
Spawn informant on the event loop
service
&Service<C>
exit
::exit_future::Exit
handle
TaskExecutor
service
&Service<C>
exit
::exit_future::Exit
handle
TaskExecutor