docs/versioned_docs/version-1.12.0/00300-resources/00100-how-to/00300-logging.md
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
SpacetimeDB provides logging capabilities for debugging and monitoring your modules. Log messages are private to the database owner and are not visible to clients.
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 messagesSpacetimeDB automatically routes these standard console calls through its internal logging system.
</TabItem> <TabItem value="csharp" label="C#">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 messagesUse 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 messagesTo view logs from your database, use the spacetime logs command:
spacetime logs <DATABASE_NAME>
To stream logs as they're generated (similar to tail -f):
spacetime logs --follow <DATABASE_NAME>
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.
Use appropriate log levels for different types of messages:
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
}
);
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
}
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(())
}