Skip to main content

Troubleshooting

Common issues and solutions for MCAP logging in Cerulion Core.

”Failed to create MCAP file”

Problem

Recorder creation fails with a file creation error:
Error: Failed to create MCAP file: Permission denied

Causes

  • File path is invalid
  • Insufficient permissions to write to directory
  • Directory doesn’t exist
  • Disk full

Solutions

Use Absolute Paths

// ✅ Good: Use absolute path
let recorder = McapRecorder::create("/absolute/path/log.mcap", None, None)?;

Check Directory Exists

// ✅ Good: Ensure directory exists
use std::fs;
fs::create_dir_all("logs")?;
let recorder = McapRecorder::create("logs/log.mcap", None, None)?;

Check Permissions

# Verify write permissions
ls -la logs/
# Create directory with correct permissions
mkdir -p logs && chmod 755 logs

Handle Errors Gracefully

// ✅ Good: Continue without logging on error
match McapRecorder::create("log.mcap", None, None) {
    Ok(recorder) => {
        publisher.enable_mcap_logging(Arc::new(recorder));
    }
    Err(e) => {
        eprintln!("Warning: Failed to create MCAP recorder: {}", e);
        eprintln!("Continuing without logging...");
    }
}

”MCAP file is empty”

Problem

MCAP file is created but contains no messages:
$ mcap info log.mcap
No channels found

Causes

  • Recorder dropped before messages were sent
  • No messages actually sent
  • Recorder not properly shared with Arc

Solutions

Keep Recorder in Scope

// ✅ Good: Keep recorder alive
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let recorder = Arc::new(McapRecorder::create("log.mcap", None, None)?);
    
    let mut publisher = Publisher::<SensorData>::create("sensors/data")?;
    publisher.enable_mcap_logging(recorder.clone());
    
    // Send messages
    publisher.send(data)?;
    
    // Recorder closes when dropped at end of scope
    Ok(())
}
// ❌ Bad: Recorder dropped too early
{
    let recorder = Arc::new(McapRecorder::create("log.mcap", None, None)?);
    publisher.enable_mcap_logging(recorder.clone());
}  // Recorder dropped here - no messages logged!

publisher.send(data)?;  // Not logged

Verify Messages are Sent

// ✅ Good: Verify sends
for i in 0..10 {
    publisher.send(data)?;
    println!("Sent message {}", i);
}
println!("All messages sent");

”High CPU usage during logging”

Problem

High CPU usage when MCAP logging is enabled, especially with high-frequency messages.

Causes

  • Compression is too slow for message rate
  • Too many topics logged simultaneously
  • Large message sizes with Zstandard compression

Solutions

Use Faster Compression

// ✅ Good: Use LZ4 or no compression for high-frequency data
let recorder = Arc::new(
    McapRecorder::create("log.mcap", Some(Compression::Lz4), None)?
);

// Or disable compression entirely
let recorder = Arc::new(
    McapRecorder::create("log.mcap", None, None)?
);

Reduce Logging Frequency

// ✅ Good: Log every Nth message
let mut count = 0;
loop {
    let data = get_sensor_data();
    publisher.send(data)?;
    
    // Only log every 10th message
    if count % 10 == 0 {
        logged_publisher.send(data)?;
    }
    count += 1;
}

Log Selectively

// ✅ Good: Log only important topics
important_publisher.enable_mcap_logging(recorder.clone());
// Don't log high-frequency debug topics

Performance Comparison

Message RateCompressionCPU UsageRecommendation
1-10 HzAny< 1%Use any compression
10-100 HzZstandard5-10%Use LZ4 instead
10-100 HzLZ41-3%Good balance
100+ HzZstandard15-25%Disable compression
100+ HzLZ43-8%Consider disabling
100+ HzNone< 1%Best for high frequency

”MCAP file is very large”

Problem

MCAP files are larger than expected, consuming excessive disk space.

Solutions

Enable Compression

// ✅ Good: Use Zstandard for best compression
let recorder = Arc::new(
    McapRecorder::create("log.mcap", Some(Compression::Zstandard), None)?
);

Log Selectively

// ✅ Good: Don't log everything
// Only log important topics
important_publisher.enable_mcap_logging(recorder.clone());

Reduce Message Rate

// ✅ Good: Downsample high-frequency data
let mut count = 0;
if count % 10 == 0 {  // Log 1 out of every 10 messages
    publisher.send(data)?;
}
count += 1;

File Size Estimates

For sensor data (100 Hz, 100 bytes per message, 1 hour):
CompressionFile SizeDisk Usage
None~360 MBHigh
LZ4~120 MBMedium
Zstandard~72 MBLow

”Messages out of order”

Problem

Messages appear out of order when reading MCAP file.

Causes

  • Multiple publishers/subscribers with different timestamps
  • Clock synchronization issues
  • Network delays

Solutions

Ensure Consistent Timestamps

// ✅ Good: Use consistent clock source
use std::time::SystemTime;

let timestamp = SystemTime::now()
    .duration_since(SystemTime::UNIX_EPOCH)?
    .as_nanos() as u64;

let data = SensorData {
    value: 42.0,
    timestamp,
};

Sort on Playback

# Sort messages by timestamp when reading
mcap extract log.mcap | jq 'sort_by(.timestamp)'

”Permission denied” on File Read

Problem

Cannot read MCAP file after creation:
$ mcap info log.mcap
Error: Permission denied

Solutions

# Fix file permissions
chmod 644 log.mcap

# Fix directory permissions
chmod 755 logs/

Debugging Logging Issues

Verify Recorder is Created

match McapRecorder::create("log.mcap", None, None) {
    Ok(recorder) => println!("✓ Recorder created"),
    Err(e) => eprintln!("✗ Failed: {}", e),
}

Verify Logging is Enabled

publisher.enable_mcap_logging(recorder.clone());
println!("✓ Logging enabled on publisher");

Verify Messages are Sent

for i in 0..10 {
    match publisher.send(data) {
        Ok(_) => println!("✓ Sent message {}", i),
        Err(e) => eprintln!("✗ Failed to send: {}", e),
    }
}

Check File Exists

# Verify file was created
ls -lh log.mcap

# Check file size (should be > 0)
du -h log.mcap

# Inspect file contents
mcap info log.mcap

Getting Help

If you’re still experiencing issues:
  1. Check file permissions: Ensure you can write to the target directory
  2. Verify disk space: Ensure sufficient disk space is available
  3. Test with simple example: Try the quickstart example first
  4. Check compression settings: Try without compression first
  5. Review error messages: Pay attention to specific error details
For additional help, check the Cerulion documentation or reach out to the Cerulion community.

Next Steps