outlayer_cli/commands/
logs.rs1use anyhow::{Context, Result};
2
3use crate::api::ApiClient;
4use crate::config::{self, NetworkConfig, ProjectConfig};
5
6pub async fn logs(
8 network: &NetworkConfig,
9 project_config: Option<&ProjectConfig>,
10 nonce: Option<u32>,
11 limit: i64,
12) -> Result<()> {
13 let creds = config::load_credentials(network)?;
14 let api = ApiClient::new(network);
15
16 let nonce = nonce
18 .or_else(|| {
19 project_config
20 .and_then(|c| c.run.as_ref())
21 .and_then(|r| r.payment_key_nonce)
22 })
23 .context("No payment key nonce. Use --nonce or set payment_key_nonce in outlayer.toml.")?;
24
25 let resp = api
26 .get_payment_key_usage(&creds.account_id, nonce, limit, 0)
27 .await?;
28
29 if resp.usage.is_empty() {
30 eprintln!("No execution history for key nonce {nonce}.");
31 return Ok(());
32 }
33
34 println!(
35 "{:<38} {:<10} {:>10} {:<25}",
36 "CALL_ID", "STATUS", "COST", "PROJECT"
37 );
38
39 for u in &resp.usage {
40 let cost = format_usd(&u.compute_cost);
41 println!(
42 "{:<38} {:<10} {:>10} {:<25}",
43 u.call_id, u.status, cost, u.project_id
44 );
45 }
46
47 if resp.total > limit {
48 eprintln!(
49 "\nShowing {}/{} entries. Use --limit to see more.",
50 resp.usage.len(),
51 resp.total
52 );
53 }
54
55 Ok(())
56}
57
58fn format_usd(minimal_units: &str) -> String {
59 let units: u64 = minimal_units.parse().unwrap_or(0);
60 let dollars = units as f64 / 1_000_000.0;
61 format!("${:.4}", dollars)
62}