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:
JavaScript
// 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);// 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:
JavaScript
// 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'
}
});// 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
JavaScript
// 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
}
});// 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
JavaScript
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' });
}
});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
JavaScript
const startTime = Date.now();
// ... operation ...
Log.info('Operation completed', {
metadata: {
duration: Date.now() - startTime,
operationType: 'database_query',
recordsProcessed: 150
}
});const startTime = Date.now();
// ... operation ...
Log.info('Operation completed', {
metadata: {
duration: Date.now() - startTime,
operationType: 'database_query',
recordsProcessed: 150
}
});Error Context
JavaScript
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);
}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
JavaScript
Log.info('Product purchased', {
context: {
customerId: customer.id,
sessionId: session.id
},
metadata: {
productId: product.id,
price: product.price,
category: product.category,
discountApplied: discount.amount
}
});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