Motia Icon
Development Guide

Observability

See what's happening in your Motia app with logging, tracing, and debugging

Your app is running. But what's actually happening inside?

  • Is that API getting hit?
  • Did the event emit?
  • Why did that Step fail?
  • Which user triggered this flow?

Motia gives you everything you need to answer these questions.


Logging

Every Step has a logger in the context. Use it to see what's happening.

Log Levels

LevelWhen to use it
infoNormal stuff - "User created", "Order processed"
warnSomething's weird but not broken - "High API usage", "Slow response"
errorThings broke - Failed API calls, exceptions, crashes
debugDeep debugging - Raw data, internal state, timing info

How to Log

export const handler: Handlers['ProcessOrder'] = async (input, { logger }) => {
  // Simple message
  logger.info('Processing order')
 
  // With context data
  logger.info('Order created', {
    orderId: input.id,
    total: input.total
  })
 
  // Errors
  try {
    await chargeCard(input.paymentMethod)
  } catch (error) {
    logger.error('Payment failed', {
      error: error.message,
      orderId: input.id
    })
  }
 
  // Warnings for unusual situations
  if (input.total > 1000) {
    logger.warn('Large order', {
      total: input.total,
      threshold: 1000
    })
  }
 
  // Debug info (only shows with --debug flag)
  logger.debug('Raw input', { input })
}

👉 Always add context data to your logs. { orderId: '123' } is way more useful than just a message.


Where to See Logs

Start your app:

npm run dev

Logs appear in two places:

1. Your Terminal

See logs right where you ran npm run dev:

[INFO] Processing order { orderId: '123', total: 99.99 }
[INFO] Order created { orderId: '123' }
[INFO] Payment successful

2. Workbench

Open http://localhost:3000 and click on your flow. Logs show up in real-time with:

  • Timestamps
  • Which Step logged it
  • The trace ID (to follow a request through the entire flow)
  • Full context data

Workbench Logs


Tracing

Every request gets a unique traceId. This lets you follow a single request through your entire flow.

export const handler: Handlers['CreateOrder'] = async (req, { logger, traceId }) => {
  logger.info('Order started', { traceId })
  
  // traceId stays the same across all Steps in this flow
  await emit({ 
    topic: 'process.payment', 
    data: { orderId: '123' } 
  })
  
  return { status: 200, body: { traceId } }
}

In Workbench:

  • Click any log entry
  • See all logs with the same traceId
  • Follow the request from start to finish

Debug Mode

Want more detailed logs?

npm run dev -- --debug

This enables debug level logs. You'll see everything - raw inputs, internal state, timing info.

In production: Don't use debug mode (it's slow and logs everything).


Tips for Better Logs

Use Objects, Not Strings

Good:

logger.info('Payment processed', {
  paymentId: '123',
  amount: 100,
  status: 'success'
})

Bad:

logger.info(`Payment 123 processed: amount=100`)

Why? Objects are searchable, filterable, and easier to parse.

Track Performance

export const handler: Handlers['ProcessOrder'] = async (input, { logger }) => {
  const start = performance.now()
 
  await processOrder(input)
 
  logger.info('Order processed', {
    duration: performance.now() - start,
    orderId: input.id
  })
}

Log Errors Properly

try {
  await riskyOperation()
} catch (error) {
  logger.error('Operation failed', {
    error: error.message,
    stack: error.stack,
    input: input.id  // Don't log sensitive data!
  })
  throw error  // Re-throw so Motia can retry
}

Debugging Workflows

Problem: Something's not working, but where?

Steps to debug:

  1. Check terminal logs - See which Steps ran
  2. Open Workbench at http://localhost:3000
  3. Click your flow - See the visual diagram
  4. Expand logs panel - See all logs in chronological order
  5. Click a log - Filter by that traceId to follow the request
  6. Check each Step - See where it failed

Common Issues

API not responding?

  • Check if the Step ran: Look for logs with your Step's name
  • Check the response: Look for status: 200 in logs

Event not firing?

  • Check if emit() was called: Search logs for "emit"
  • Check the topic name: Make sure it matches subscribes: ['topic']

Step not running?

  • Check if it's discovered: Look for [CREATED] Step in startup logs
  • Check the file name: Must contain .step. or _step

Remember

  • Log everything important - But not everything (no sensitive data!)
  • Use traceId - Follow requests through your entire flow
  • Check Workbench - Visual debugging is easier
  • Use objects - Don't log strings, log objects
  • Debug mode - Only for development, never in production

Need help? See our Community Resources for questions, examples, and discussions.

On this page