Sequence/docs

Logging

The SDK provides non-blocking logging that's safe to use on the hot path.


Overview

Logs from your algo are:

  1. Batched locally on the edge
  2. Shipped to Central Coordinator every ~1-2 seconds
  3. 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

MacroLevel
log_debug!Debug
log_info!Info
log_warn!Warn
log_error!Error

Log Levels

LevelWhen to Use
TRACEVery verbose, usually disabled
DEBUGDevelopment debugging
INFONormal operation info
WARNImportant events, potential issues
ERRORErrors 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
);