Use ctx.logger in agents and c.var.logger in routes for structured logging. Logs are automatically tied to session IDs for debugging.
Log Levels
import { createAgent } from '@agentuity/runtime';
const agent = createAgent('LoggingExample', {
handler: async (ctx, input) => {
ctx.logger.trace('Verbose debugging info');
ctx.logger.debug('Debug-level details');
ctx.logger.info('General information');
ctx.logger.warn('Warning: potential issue');
ctx.logger.error('Error occurred', error);
return { success: true };
},
});Levels from most to least verbose: trace → debug → info → warn → error. The default minimum level is info.
Structured Logging
Pass context as a second argument for searchable metadata:
const agent = createAgent('ProductSearch', {
handler: async (ctx, input) => {
const startTime = Date.now();
const results = await searchProducts(input.query);
ctx.logger.info('Search completed', {
query: input.query,
resultCount: results.length,
userId: input.userId,
durationMs: Date.now() - startTime,
});
return { results };
},
});This creates structured log entries you can filter and search in the Agentuity App or the CLI.
Child Loggers
Create component-scoped loggers that inherit parent context:
const agent = createAgent('ChildLoggerExample', {
handler: async (ctx, input) => {
// Child logger adds context to all its messages
const dbLogger = ctx.logger.child({
component: 'database',
requestId: ctx.sessionId,
});
dbLogger.debug('Connecting to database');
dbLogger.info('Query executed', { duration: 45, rows: 10 });
// Another child logger for a different component
const embeddingsLogger = ctx.logger.child({
component: 'embeddings',
documentId: input.documentId,
});
embeddingsLogger.info('Generating embeddings', { chunkCount: 12 });
return { success: true };
},
});Child loggers are useful for tracing operations through different parts of your code.
Logging in Routes
Routes access the logger via c.var.logger:
import { createRouter } from '@agentuity/runtime';
import paymentHandler from '@agent/payment-handler';
const router = createRouter();
router.post('/webhooks/payments', async (c) => {
const eventType = c.req.header('x-webhook-event');
c.var.logger.info('Webhook received', {
provider: 'stripe',
eventType,
});
const payload = await c.req.json();
const result = await paymentHandler.run({
event: eventType,
customerId: payload.customer,
amount: payload.amount,
});
c.var.logger.info('Webhook processed', {
eventType,
customerId: payload.customer,
success: result.success,
});
return c.json({ received: true });
});
export default router;Configuration
Set the minimum log level with the AGENTUITY_LOG_LEVEL environment variable:
# In .env
AGENTUITY_LOG_LEVEL=debug # Show debug and above| Level | Shows |
|---|---|
trace | trace, debug, info, warn, error |
debug | debug, info, warn, error |
info | info, warn, error (default) |
warn | warn, error |
error | error only |
Viewing Logs
View logs for a specific session using the CLI:
# List recent sessions
agentuity cloud session list
# View logs for a session
agentuity cloud session logs sess_abc123xyzLogs are also visible in the Agentuity App session timeline. See CLI Reference for more log viewing options.
Best Practices
- Use
ctx.logger: Always usectx.loggerorc.var.loggerinstead ofconsole.logfor proper log collection - Add context: Include IDs, counts, and timing in structured fields
- Use appropriate levels:
infofor normal flow,warnfor recoverable issues,errorfor failures - Create child loggers: For complex operations, create component-specific loggers
Next Steps
- Tracing: Track timing and debug performance with OpenTelemetry spans
- Sessions & Debugging: Use session IDs to trace issues across logs and spans