linera_sdk/
log.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::{
5    panic::{self, PanicHookInfo},
6    sync::Once,
7};
8
9use log::{LevelFilter, Log, Metadata, Record};
10
11use crate::{
12    contract::wit::base_runtime_api as contract_wit, service::wit::base_runtime_api as service_wit,
13};
14
15static CONTRACT_LOGGER: ContractLogger = ContractLogger;
16static SERVICE_LOGGER: ServiceLogger = ServiceLogger;
17
18static INSTALL_LOGGER: Once = Once::new();
19
20/// A logger that uses the system API for contracts.
21#[derive(Clone, Copy, Debug)]
22pub struct ContractLogger;
23
24impl ContractLogger {
25    /// Configures [`log`] to use the log system API for contracts.
26    pub fn install() {
27        INSTALL_LOGGER.call_once(|| {
28            log::set_logger(&CONTRACT_LOGGER).expect("Failed to initialize contract logger");
29            log::set_max_level(LevelFilter::Trace);
30            panic::set_hook(Box::new(log_panic));
31        });
32    }
33}
34
35impl Log for ContractLogger {
36    fn enabled(&self, _: &Metadata) -> bool {
37        true
38    }
39
40    fn log(&self, record: &Record) {
41        contract_wit::log(&record.args().to_string(), record.level().into());
42    }
43
44    fn flush(&self) {}
45}
46
47/// A logger that uses the system API for services.
48#[derive(Clone, Copy, Debug)]
49pub struct ServiceLogger;
50
51impl ServiceLogger {
52    /// Configures [`log`] to use the log system API for services.
53    pub fn install() {
54        INSTALL_LOGGER.call_once(|| {
55            log::set_logger(&SERVICE_LOGGER).expect("Failed to initialize service logger");
56            log::set_max_level(LevelFilter::Trace);
57            panic::set_hook(Box::new(log_panic));
58        });
59    }
60}
61
62impl Log for ServiceLogger {
63    fn enabled(&self, _: &Metadata) -> bool {
64        true
65    }
66
67    fn log(&self, record: &Record) {
68        service_wit::log(&record.args().to_string(), record.level().into());
69    }
70
71    fn flush(&self) {}
72}
73
74/// Logs a panic using the [`log`] API.
75fn log_panic(info: &PanicHookInfo<'_>) {
76    log::error!("{info}");
77}