Metadata & Context
Metadata and context allow you to add structured information to your logs, making them more informative and easier to analyze.
Context Property
Use the context
property to add structured data to your logs:
// Basic context usage
Log.info('User login successful', {
context: {
userId: 123,
username: 'john.doe',
ipAddress: '192.168.1.1'
}
});
// Context with error logging
Log.error('Database connection failed', {
context: {
database: 'users',
host: 'localhost',
port: 5432,
retryCount: 3
}
}, error);
Metadata Property
Use the metadata
property for additional structured information:
// Metadata with performance data
Log.info('API request completed', {
metadata: {
responseTime: 234,
statusCode: 200,
cacheHit: true
}
});
// Metadata with business context
Log.warn('Order processing delayed', {
metadata: {
orderId: 'ORD-123',
priority: 'high',
estimatedDelay: '5 minutes'
}
});
Combining Context and Metadata
// Using both context and metadata
Log.info('Payment processed', {
context: {
customerId: 456,
orderId: 'ORD-789'
},
metadata: {
amount: 99.99,
currency: 'USD',
paymentMethod: 'credit_card',
processingTime: 1.2
}
});
Express.js Integration
app.use((req, res, next) => {
// Add request context to all logs
req.logContext = {
requestId: req.id,
method: req.method,
url: req.url,
userAgent: req.get('User-Agent')
};
next();
});
app.post('/api/users', async (req, res) => {
Log.info('User creation started', {
context: req.logContext,
metadata: {
email: req.body.email,
role: req.body.role
}
});
try {
const user = await userService.create(req.body);
Log.info('User created successfully', {
context: req.logContext,
metadata: {
userId: user.id,
email: user.email
}
});
res.json(user);
} catch (error) {
Log.error('User creation failed', {
context: req.logContext,
metadata: {
email: req.body.email,
validationErrors: error.validationErrors
}
}, error);
res.status(400).json({ error: 'Failed to create user' });
}
});
Common Usage Patterns
Performance Monitoring
const startTime = Date.now();
// ... operation ...
Log.info('Operation completed', {
metadata: {
duration: Date.now() - startTime,
operationType: 'database_query',
recordsProcessed: 150
}
});
Error Context
try {
await processPayment(paymentData);
} catch (error) {
Log.error('Payment processing failed', {
context: {
customerId: paymentData.customerId,
orderId: paymentData.orderId
},
metadata: {
amount: paymentData.amount,
paymentMethod: paymentData.method,
attemptNumber: 2
}
}, error);
}
Business Events
Log.info('Product purchased', {
context: {
customerId: customer.id,
sessionId: session.id
},
metadata: {
productId: product.id,
price: product.price,
category: product.category,
discountApplied: discount.amount
}
});
Best Practices
Best Practices
- Use context for request/operation data: User IDs, request IDs, session data
- Use metadata for business/technical data: Performance metrics, business values
- Keep objects flat: Avoid deeply nested structures
- Use consistent naming: Stick to camelCase or snake_case throughout your app
- Include relevant data only: Don't log everything, focus on what's useful for debugging
Next Steps
- Global Metadata - Add consistent context to all logs
- Tags - Categorize and organize logs
- Correlation IDs - Track requests across services