holochain 0.7.0-dev.20

Holochain, a framework for distributed applications
Documentation
use holo_hash::DnaHash;
use opentelemetry::{global::meter, metrics, KeyValue};
use std::sync::{Arc, OnceLock};

pub(crate) struct Histogram {
    histogram: metrics::Histogram<f64>,
    attributes: Vec<KeyValue>,
}

impl Histogram {
    pub fn record(&self, value: f64) {
        self.histogram.record(value, &self.attributes);
    }
}

pub(crate) type WorkflowDurationMetric = Histogram;

pub(crate) fn create_workflow_duration_metric(
    workflow_name: String,
    dna_hash: Arc<DnaHash>,
) -> WorkflowDurationMetric {
    let attributes = vec![
        KeyValue::new("workflow", workflow_name),
        KeyValue::new("dna_hash", dna_hash.to_string()),
    ];

    let histogram = meter("hc.conductor")
        .f64_histogram("hc.conductor.workflow.duration")
        .with_unit("s")
        .with_description("The time spent running a workflow")
        .build();

    Histogram {
        histogram,
        attributes,
    }
}

pub(crate) type IntegratedOpMetric = metrics::Counter<u64>;

static INTEGRATED_OP_METRIC: OnceLock<IntegratedOpMetric> = OnceLock::new();

pub(crate) fn workflow_integrated_op_metric() -> &'static IntegratedOpMetric {
    INTEGRATED_OP_METRIC.get_or_init(|| {
        meter("hc.conductor")
            .u64_counter("hc.conductor.workflow.integrated_ops")
            .with_description("The number of integrated operations.")
            .build()
    })
}

pub(crate) type OpIntegrationDelayMetric = metrics::Histogram<f64>;

static OP_INTEGRATION_DELAY_METRIC: OnceLock<OpIntegrationDelayMetric> = OnceLock::new();

pub(crate) fn op_integration_delay_metric() -> &'static OpIntegrationDelayMetric {
    OP_INTEGRATION_DELAY_METRIC.get_or_init(|| {
        meter("hc.conductor")
            .f64_histogram("hc.conductor.workflow.integration_delay")
            .with_unit("s")
            .with_description("Time between an op being stored and it being integrated.")
            .build()
    })
}

pub(crate) type OpValidationAttemptsMetric = metrics::Histogram<u64>;

static OP_VALIDATION_ATTEMPTS_METRIC: OnceLock<OpValidationAttemptsMetric> = OnceLock::new();

pub(crate) fn op_validation_attempts_metric() -> &'static OpValidationAttemptsMetric {
    OP_VALIDATION_ATTEMPTS_METRIC.get_or_init(|| {
        meter("hc.conductor")
            .u64_histogram("hc.conductor.workflow.validation_attempts")
            .with_description("Number of validation attempts required to integrate an op.")
            .build()
    })
}

pub(crate) type WasmUsageMetric = metrics::Counter<u64>;

static WASM_USAGE_METRIC: OnceLock<WasmUsageMetric> = OnceLock::new();

pub(crate) fn ribosome_wasm_usage_metric() -> &'static WasmUsageMetric {
    WASM_USAGE_METRIC.get_or_init(|| {
        meter("hc.ribosome.wasm")
            .u64_counter("hc.ribosome.wasm.usage")
            .with_description("The metered usage of a wasm ribosome.")
            .build()
    })
}

pub(crate) type WasmCallDurationMetric = metrics::Histogram<f64>;

static WASM_CALL_DURATION_METRIC: OnceLock<WasmCallDurationMetric> = OnceLock::new();

pub(crate) fn ribosome_wasm_call_duration_metric() -> &'static WasmCallDurationMetric {
    WASM_CALL_DURATION_METRIC.get_or_init(|| {
        meter("hc.ribosome.wasm")
            .f64_histogram("hc.ribosome.wasm_call.duration")
            .with_unit("s")
            .with_description("The time spent running a wasm call.")
            .build()
    })
}

pub(crate) type ZomeCallDurationMetric = metrics::Histogram<f64>;

static ZOME_CALL_DURATION_METRIC: OnceLock<ZomeCallDurationMetric> = OnceLock::new();

pub(crate) fn ribosome_zome_call_duration_metric() -> &'static ZomeCallDurationMetric {
    ZOME_CALL_DURATION_METRIC.get_or_init(|| {
        meter("hc.ribosome.wasm")
            .f64_histogram("hc.ribosome.zome_call.duration")
            .with_unit("s")
            .with_description("The time spent running a zome call.")
            .build()
    })
}

pub(crate) type HostFnCallDurationMetric = metrics::Histogram<f64>;

static HOST_FN_CALL_DURATION_METRIC: OnceLock<HostFnCallDurationMetric> = OnceLock::new();

pub(crate) fn host_fn_call_duration_metric() -> &'static HostFnCallDurationMetric {
    HOST_FN_CALL_DURATION_METRIC.get_or_init(|| {
        meter("hc.ribosome")
            .f64_histogram("hc.ribosome.host_fn_call.duration")
            .with_unit("s")
            .with_description("The time spent executing a host function call.")
            .build()
    })
}

pub(crate) type EmitSignalMetric = metrics::Counter<u64>;

static EMIT_SIGNAL_METRIC: OnceLock<EmitSignalMetric> = OnceLock::new();

pub(crate) fn emit_signal_metric() -> &'static EmitSignalMetric {
    EMIT_SIGNAL_METRIC.get_or_init(|| {
        meter("hc.ribosome")
            .u64_counter("hc.ribosome.host_fn.emit_signal.count")
            .with_description("The number of local signals emitted.")
            .build()
    })
}

pub(crate) type SendRemoteSignalMetric = metrics::Counter<u64>;

static SEND_REMOTE_SIGNAL_METRIC: OnceLock<SendRemoteSignalMetric> = OnceLock::new();

pub(crate) fn send_remote_signal_metric() -> &'static SendRemoteSignalMetric {
    SEND_REMOTE_SIGNAL_METRIC.get_or_init(|| {
        meter("hc.ribosome")
            .u64_counter("hc.ribosome.host_fn.send_remote_signal")
            .with_description("The number of remote signals sent.")
            .build()
    })
}