Logging
SpacetimeDB provides logging capabilities for debugging and monitoring your modules. Log messages are private to the database owner and are not visible to clients.
Writing Logs
- Rust
- C#
- TypeScript
Use the log crate to write logs from your reducers:
use spacetimedb::{reducer, ReducerContext};
#[reducer]
pub fn process_data(ctx: &ReducerContext, value: u32) -> Result<(), String> {
log::info!("Processing data with value: {}", value);
if value > 100 {
log::warn!("Value {} exceeds threshold", value);
}
if value == 0 {
log::error!("Invalid value: 0");
return Err("Value cannot be zero".to_string());
}
log::debug!("Debug information: ctx.sender = {:?}", ctx.sender);
Ok(())
}Available log levels:
log::error!()- Error messageslog::warn!()- Warning messageslog::info!()- Informational messageslog::debug!()- Debug messageslog::trace!()- Trace messages
Use the SpacetimeDB.Log class to write logs from your reducers:
using SpacetimeDB;
public static partial class Module
{
[SpacetimeDB.Reducer]
public static void ProcessData(ReducerContext ctx, uint value)
{
Log.Info($"Processing data with value: {value}");
if (value > 100)
{
Log.Warn($"Value {value} exceeds threshold");
}
if (value == 0)
{
Log.Error("Invalid value: 0");
throw new ArgumentException("Value cannot be zero");
}
Log.Debug($"Debug information: ctx.Sender = {ctx.Sender}");
}
}Available log methods:
Log.Error()- Error messagesLog.Warn()- Warning messagesLog.Info()- Informational messagesLog.Debug()- Debug messagesLog.Trace()- Trace messages
Use the standard console API to write logs from your reducers:
import { spacetimedb } from 'spacetimedb/server';
spacetimedb.reducer('process_data', { value: t.u32() }, (ctx, { value }) => {
console.log(`Processing data with value: ${value}`);
if (value > 100) {
console.warn(`Value ${value} exceeds threshold`);
}
if (value === 0) {
console.error('Invalid value: 0');
throw new Error('Value cannot be zero');
}
console.debug(`Debug information: ctx.sender = ${ctx.sender}`);
});Available console methods:
console.error()- Error messagesconsole.warn()- Warning messagesconsole.log()- Informational messagesconsole.debug()- Debug messages
SpacetimeDB automatically routes these standard console calls through its internal logging system.
Viewing Logs
To view logs from your database, use the spacetime logs command:
spacetime logs <DATABASE_NAME>
Following Logs in Real-Time
To stream logs as they're generated (similar to tail -f):
spacetime logs --follow <DATABASE_NAME>
Filtering Logs
You can filter logs by various criteria:
# Show only errors
spacetime logs --level error <DATABASE_NAME>
# Show warnings and errors
spacetime logs --level warn <DATABASE_NAME>
# Show logs from a specific time range
spacetime logs --since "2023-01-01 00:00:00" <DATABASE_NAME>
For all log viewing options, see the spacetime logs CLI reference.
Best Practices
Log Levels
Use appropriate log levels for different types of messages:
- Error: Use for actual errors that prevent operations from completing
- Warn: Use for potentially problematic situations that don't prevent execution
- Info: Use for important application events (user actions, state changes)
- Debug: Use for detailed diagnostic information useful during development
- Trace: Use for very detailed diagnostic information (typically disabled in production)
Performance Considerations
- Logging has minimal overhead, but excessive logging can impact performance
- Avoid logging in tight loops or high-frequency operations
- Consider using debug/trace logs for verbose output that can be filtered in production
Privacy and Security
- Logs are only visible to the database owner, not to clients
- Avoid logging sensitive information like passwords or authentication tokens
- Be mindful of personally identifiable information (PII) in logs
Structured Logging
- Rust
- C#
- TypeScript
Use structured logging with key-value pairs for better log analysis:
use spacetimedb::log;
#[reducer]
pub fn transfer_credits(ctx: &ReducerContext, to_user: u64, amount: u32) -> Result<(), String> {
log::info!(
"Credit transfer: from={:?}, to={}, amount={}",
ctx.sender,
to_user,
amount
);
// ... transfer logic
Ok(())
}Include relevant context in your log messages:
[SpacetimeDB.Reducer]
public static void TransferCredits(ReducerContext ctx, ulong toUser, uint amount)
{
Log.Info($"Credit transfer: from={ctx.Sender}, to={toUser}, amount={amount}");
// ... transfer logic
}Include relevant context in your log messages:
spacetimedb.reducer('transfer_credits',
{ to_user: t.u64(), amount: t.u32() },
(ctx, { to_user, amount }) => {
console.log(`Credit transfer: from=${ctx.sender}, to=${to_user}, amount=${amount}`);
// ... transfer logic
}
);Next Steps
- Learn about Error Handling in reducers
- Explore the CLI Reference for more logging options
- Set up monitoring and alerting for your production databases