solana_program_runtime/stable_log.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
//! Stable program log messages
//!
//! The format of these log messages should not be modified to avoid breaking downstream consumers
//! of program logging
use {
base64::{prelude::BASE64_STANDARD, Engine},
itertools::Itertools,
solana_log_collector::{ic_logger_msg, LogCollector},
solana_sdk::pubkey::Pubkey,
std::{cell::RefCell, rc::Rc},
};
/// Log a program invoke.
///
/// The general form is:
///
/// ```notrust
/// "Program <address> invoke [<depth>]"
/// ```
pub fn program_invoke(
log_collector: &Option<Rc<RefCell<LogCollector>>>,
program_id: &Pubkey,
invoke_depth: usize,
) {
ic_logger_msg!(
log_collector,
"Program {} invoke [{}]",
program_id,
invoke_depth
);
}
/// Log a message from the program itself.
///
/// The general form is:
///
/// ```notrust
/// "Program log: <program-generated output>"
/// ```
///
/// That is, any program-generated output is guaranteed to be prefixed by "Program log: "
pub fn program_log(log_collector: &Option<Rc<RefCell<LogCollector>>>, message: &str) {
ic_logger_msg!(log_collector, "Program log: {}", message);
}
/// Emit a program data.
///
/// The general form is:
///
/// ```notrust
/// "Program data: <binary-data-in-base64>*"
/// ```
///
/// That is, any program-generated output is guaranteed to be prefixed by "Program data: "
pub fn program_data(log_collector: &Option<Rc<RefCell<LogCollector>>>, data: &[&[u8]]) {
ic_logger_msg!(
log_collector,
"Program data: {}",
data.iter().map(|v| BASE64_STANDARD.encode(v)).join(" ")
);
}
/// Log return data as from the program itself. This line will not be present if no return
/// data was set, or if the return data was set to zero length.
///
/// The general form is:
///
/// ```notrust
/// "Program return: <program-id> <program-generated-data-in-base64>"
/// ```
///
/// That is, any program-generated output is guaranteed to be prefixed by "Program return: "
pub fn program_return(
log_collector: &Option<Rc<RefCell<LogCollector>>>,
program_id: &Pubkey,
data: &[u8],
) {
ic_logger_msg!(
log_collector,
"Program return: {} {}",
program_id,
BASE64_STANDARD.encode(data)
);
}
/// Log successful program execution.
///
/// The general form is:
///
/// ```notrust
/// "Program <address> success"
/// ```
pub fn program_success(log_collector: &Option<Rc<RefCell<LogCollector>>>, program_id: &Pubkey) {
ic_logger_msg!(log_collector, "Program {} success", program_id);
}
/// Log program execution failure
///
/// The general form is:
///
/// ```notrust
/// "Program <address> failed: <program error details>"
/// ```
pub fn program_failure<E: std::fmt::Display>(
log_collector: &Option<Rc<RefCell<LogCollector>>>,
program_id: &Pubkey,
err: &E,
) {
ic_logger_msg!(log_collector, "Program {} failed: {}", program_id, err);
}