Skip to main content

ckb_rpc/module/
debug.rs

1use async_trait::async_trait;
2use ckb_jsonrpc_types::{ExtraLoggerConfig, MainLoggerConfig};
3use ckb_logger_service::Logger;
4use jsonrpc_core::{Error, ErrorCode::InternalError, Result};
5use jsonrpc_utils::rpc;
6use std::time;
7/// RPC Module Debug for internal RPC methods.
8///
9/// **This module is for CKB developers and will not guarantee compatibility.** The methods here
10/// will be changed or removed without advanced notification.
11#[rpc(openrpc)]
12#[async_trait]
13pub trait DebugRpc {
14    /// Dumps jemalloc memory profiling information into a file.
15    ///
16    /// The file is stored in the server running the CKB node.
17    ///
18    /// The RPC returns the path to the dumped file on success or returns an error on failure.
19    #[rpc(name = "jemalloc_profiling_dump")]
20    fn jemalloc_profiling_dump(&self) -> Result<String>;
21    /// Changes main logger config options while CKB is running.
22    #[rpc(name = "update_main_logger")]
23    fn update_main_logger(&self, config: MainLoggerConfig) -> Result<()>;
24    /// Sets logger config options for extra loggers.
25    ///
26    /// CKB nodes allow setting up extra loggers. These loggers will have their own log files and
27    /// they only append logs to their log files.
28    ///
29    /// ## Params
30    ///
31    /// * `name` - Extra logger name
32    /// * `config_opt` - Adds a new logger or update an existing logger when this is not null.
33    /// Removes the logger when this is null.
34    #[rpc(name = "set_extra_logger")]
35    fn set_extra_logger(&self, name: String, config_opt: Option<ExtraLoggerConfig>) -> Result<()>;
36}
37
38#[derive(Clone)]
39pub(crate) struct DebugRpcImpl {}
40
41#[async_trait]
42impl DebugRpc for DebugRpcImpl {
43    fn jemalloc_profiling_dump(&self) -> Result<String> {
44        let timestamp = time::SystemTime::now()
45            .duration_since(time::SystemTime::UNIX_EPOCH)
46            .unwrap()
47            .as_secs();
48        let filename = format!("ckb-jeprof.{timestamp}.heap");
49        match ckb_memory_tracker::jemalloc_profiling_dump(&filename) {
50            Ok(()) => Ok(filename),
51            Err(err) => Err(Error {
52                code: InternalError,
53                message: err,
54                data: None,
55            }),
56        }
57    }
58
59    fn update_main_logger(&self, config: MainLoggerConfig) -> Result<()> {
60        let MainLoggerConfig {
61            filter,
62            to_stdout,
63            to_file,
64            color,
65        } = config;
66        if filter.is_none() && to_stdout.is_none() && to_file.is_none() && color.is_none() {
67            return Ok(());
68        }
69        Logger::update_main_logger(filter, to_stdout, to_file, color).map_err(|err| Error {
70            code: InternalError,
71            message: err,
72            data: None,
73        })
74    }
75
76    fn set_extra_logger(&self, name: String, config_opt: Option<ExtraLoggerConfig>) -> Result<()> {
77        if let Err(err) = Logger::check_extra_logger_name(&name) {
78            return Err(Error {
79                code: InternalError,
80                message: err,
81                data: None,
82            });
83        }
84        if let Some(config) = config_opt {
85            Logger::update_extra_logger(name, config.filter)
86        } else {
87            Logger::remove_extra_logger(name)
88        }
89        .map_err(|err| Error {
90            code: InternalError,
91            message: err,
92            data: None,
93        })
94    }
95}