Logging
The SDK provides non-blocking logging that's safe to use on the hot path.
Overview
Logs from your algo are:
- Batched locally on the edge
- Shipped to Central Coordinator every ~1-2 seconds
- Viewable in the dashboard and via API
Note
Logging is non-blocking and takes ~100 nanoseconds per call. Safe to use in on_book.
Log Functions
rust
use algo_sdk::log;
// Simple string logs
log::trace("Detailed trace info");
log::debug("Debug message");
log::info("Important info");
log::warn("Warning!");
log::error("Error occurred");Formatted Logging
Use the macros for formatted output:
rust
use algo_sdk::*;
fn on_book(&mut self, book: &L2Book, state: &AlgoState, _features: &OnlineFeatures, actions: &mut Actions) {
let mid = book.mid_px_1e9();
let spread = book.spread_bps();
log_info!("mid={} spread={}bps", mid, spread);
if spread < 5 {
log_warn!("spread too tight: {}bps", spread);
}
}Available Macros
| Macro | Level |
|---|---|
log_debug! | Debug |
log_info! | Info |
log_warn! | Warn |
log_error! | Error |
Log Levels
| Level | When to Use |
|---|---|
TRACE | Very verbose, usually disabled |
DEBUG | Development debugging |
INFO | Normal operation info |
WARN | Important events, potential issues |
ERROR | Errors that need attention |
Tip
Use WARN for fills and important events - they show up highlighted in the dashboard.
Example: Speed Test Logging
rust
impl Algo for SpeedTest {
fn on_book(&mut self, book: &L2Book, state: &AlgoState, _features: &OnlineFeatures, actions: &mut Actions) {
log_info!("INIT: bid=${:.3} ask=${:.3} spread={}bps",
book.bids[0].px_1e9 as f64 / 1e9,
book.asks[0].px_1e9 as f64 / 1e9,
book.spread_bps()
);
self.next_id += 1;
actions.buy(self.next_id, self.size, book.asks[0].px_1e9);
log_info!("BUY: trip={} order={} @${:.3}",
self.current_trip + 1,
self.next_id,
book.asks[0].px_1e9 as f64 / 1e9
);
}
fn on_fill(&mut self, fill: &Fill, _state: &AlgoState) {
let latency_ms = (self.last_order_time.elapsed().as_millis()) as u64;
log_warn!("FILL: order={} qty={} @${:.3} latency={}ms",
fill.order_id,
fill.qty_1e8,
fill.px_1e9 as f64 / 1e9,
latency_ms
);
}
}Viewing Logs
Dashboard
Go to Algo Studio → Select your algo → Logs panel shows real-time output.
API
bash
curl https://api.sequencemkts.com/v1/algos/XRP%2FUSD/logs \
-H "Authorization: Bearer YOUR_API_KEY"
# Edge-scoped logs
curl "https://api.sequencemkts.com/v1/algos/XRP%2FUSD/logs?edge_id=venue-edge-kraken" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
json
{
"symbol": "XRP/USD",
"logs": [
{ "ts": "19:37:05", "level": "INFO", "message": "INIT: bid=$1.800 ask=$1.801" },
{ "ts": "19:37:05", "level": "INFO", "message": "BUY: trip=1 order=5001 @$1.801" },
{ "ts": "19:37:05", "level": "WARN", "message": "FILL: order=5001 latency=19ms" }
]
}Performance Tips
Warning
Avoid logging on every book update in production - it adds overhead and fills up the log buffer.
rust
// BAD: Logs on every tick
fn on_book(&mut self, book: &L2Book, state: &AlgoState, _features: &OnlineFeatures, actions: &mut Actions) {
log_debug!("tick: mid={}", book.mid_px_1e9()); // Too frequent!
}
// GOOD: Log only on significant events
fn on_book(&mut self, book: &L2Book, state: &AlgoState, _features: &OnlineFeatures, actions: &mut Actions) {
if self.should_trade(book) {
log_info!("placing order at {}", book.asks[0].px_1e9);
// ...
}
}
fn on_fill(&mut self, fill: &Fill, _state: &AlgoState) {
log_warn!("FILL: {} @ {}", fill.qty_1e8, fill.px_1e9); // Always log fills
}Log Buffer
Logs are stored in a ring buffer:
- 10,000 total entries across all algos
- Oldest entries are evicted when full
- Cleared when algo is undeployed
- Per-entry message payload is capped at 255 bytes (longer messages are truncated)
Structured Logging Pattern
For machine-parseable logs, use a consistent format:
rust
// Key=value format for easy parsing
log_info!("ORDER id={} side={} qty={} px={}",
order_id,
if side > 0 { "BUY" } else { "SELL" },
qty_1e8,
px_1e9
);
log_warn!("FILL id={} latency_ms={} slippage_bps={}",
fill.order_id,
latency_ms,
slippage
);
// Stats format for dashboards
log_info!("STATS[{}]: trips={} avg_rt={}ms min={}ms max={}ms",
self.tick_count,
self.trips_completed,
self.avg_latency,
self.min_latency,
self.max_latency
);