fn collect_process_metrics(
        logger: ReplicaLogger,
        backends: Arc<Mutex<HashMap<CanisterId, SandboxProcess>>>,
        metrics: Arc<SandboxedExecutionMetrics>,
    ) {
        loop {
            // Collect pids while having list of backend processes locked, but
            // ensure that we only hold the lock long enough for the collection
            // to finish. This ensures that metrics collection does not unduly
            // lock out normal operation, at the risk that metrics may be
            // temporarily stale (but that is something to be expected anyways).
            let pids = {
                let mut pids = Vec::<u32>::new();
                for sandbox_process in backends.lock().unwrap().values() {
                    pids.push(sandbox_process.pid);
                }
                pids
            };

            let mut total_anon_rss: u64 = 0;

            // For all processes requested, get their memory usage and report
            // it keyed by pid. Ignore processes failures to get
            for pid in &pids {
                if let Ok(kib) = process_os_metrics::get_nonshared_rss(*pid) {
                    total_anon_rss += kib;
                } else {
                    warn!(logger, "Unable to get process information for pid {}", *pid);
                }
            }

            metrics
                .sandboxed_execution_subprocess_anon_rss_total
                .set(total_anon_rss.try_into().unwrap());

            // Collect metrics sufficiently infrequently that it does not use
            // excessive compute resources. It might be sensible to scale this
            // based on the time measured to perform the collection and e.g.
            // ensure that we are 99% idle instead of using a static duration
            // here.
            std::thread::sleep(std::time::Duration::from_secs(5));
        }
    }
// Walk through all our backend processes and fetch information about them
// from kernel. Publish these as metrics.
Walk through all our backend processes and fetch information about them
from kernel. Publish these as metrics.
Walk through all our backend processes and fetch information about them from kernel . Publish these as metrics .
fn collect_process_metrics(
        logger: ReplicaLogger,
        backends: Arc<Mutex<HashMap<CanisterId, SandboxProcess>>>,
        metrics: Arc<SandboxedExecutionMetrics>,
    ) {
        loop {
            // Collect pids while having list of backend processes locked, but
            // ensure that we only hold the lock long enough for the collection
            // to finish. This ensures that metrics collection does not unduly
            // lock out normal operation, at the risk that metrics may be
            // temporarily stale (but that is something to be expected anyways).
            let pids = {
                let mut pids = Vec::<u32>::new();
                for sandbox_process in backends.lock().unwrap().values() {
                    pids.push(sandbox_process.pid);
                }
                pids
            };
            let mut total_anon_rss: u64 = 0;
            // For all processes requested, get their memory usage and report
            // it keyed by pid. Ignore processes failures to get
            for pid in &pids {
                if let Ok(kib) = process_os_metrics::get_nonshared_rss(*pid) {
                    total_anon_rss += kib;
                } else {
                    warn!(logger, "Unable to get process information for pid {}", *pid);
                }
            }
            metrics
                .sandboxed_execution_subprocess_anon_rss_total
                .set(total_anon_rss.try_into().unwrap());
            // Collect metrics sufficiently infrequently that it does not use
            // excessive compute resources. It might be sensible to scale this
            // based on the time measured to perform the collection and e.g.
            // ensure that we are 99% idle instead of using a static duration
            // here.
            std::thread::sleep(std::time::Duration::from_secs(5));
        }
    }
fn collect_process_metrics ( logger : ReplicaLogger , backends : Arc < Mutex < HashMap < CanisterId , SandboxProcess > > > , metrics : Arc < SandboxedExecutionMetrics > , ) { loop { // Collect pids while having list of backend processes locked, but // ensure that we only hold the lock long enough for the collection // to finish. This ensures that metrics collection does not unduly // lock out normal operation, at the risk that metrics may be // temporarily stale (but that is something to be expected anyways). let pids = { let mut pids = Vec :: < u32 > :: new ( ) ; for sandbox_process in backends . lock ( ) . unwrap ( ) . values ( ) { pids . push ( sandbox_process . pid ) ; } pids } ; let mut total_anon_rss : u64 = 0 ; // For all processes requested, get their memory usage and report // it keyed by pid. Ignore processes failures to get for pid in & pids { if let Ok ( kib ) = process_os_metrics :: get_nonshared_rss ( * pid ) { total_anon_rss += kib ; } else { warn ! ( logger " " pid ) ; } } metrics . sandboxed_execution_subprocess_anon_rss_total . set ( total_anon_rss . try_into ( ) . unwrap ( ) ) ; // Collect metrics sufficiently infrequently that it does not use // excessive compute resources. It might be sensible to scale this // based on the time measured to perform the collection and e.g. // ensure that we are 99% idle instead of using a static duration // here. std :: thread :: sleep ( std :: time :: Duration :: from_secs ( 5 ) ) ; } }
Walk through all our backend processes and fetch information about them
from kernel.
Walk through all our backend processes and fetch information about them from kernel .
logger
ReplicaLogger
backends
Arc<Mutex<HashMap<CanisterId, SandboxProcess>>>
metrics
Arc<SandboxedExecutionMetrics>
logger
ReplicaLogger
backends
Arc<Mutex<HashMap<CanisterId, SandboxProcess>>>
metrics
Arc<SandboxedExecutionMetrics>