Log Levels
Understanding and using the right log level is crucial for effective monitoring and debugging. Logstyx provides four standard log levels plus support for custom levels, each serving a specific purpose in your logging strategy.
Standard Log Levels
Info
Purpose: Normal operational events and state changes
When to use:
- Successful operations
- State transitions
- Important milestones
- User actions
- Application lifecycle events
Examples:
// User authentication
logger.info({
message: 'User logged in',
userId: '12345',
method: 'oauth2'
});
// Successful operations
logger.info({
message: 'Payment processed',
orderId: 'ord_789',
amount: 99.99
});
// Application events
logger.info({
message: 'Server started',
port: 3000,
environment: 'production'
});
// State changes
logger.info({
message: 'Feature flag toggled',
flag: 'new_checkout',
enabled: true
});Warning
Purpose: Potentially problematic situations that don't prevent operation
When to use:
- Deprecated features being used
- Configuration issues that have fallbacks
- Resource usage approaching limits
- Retryable errors
- Non-critical failures
Examples:
// Resource warnings
logger.warning({
message: 'High memory usage',
usage: 85,
threshold: 80,
unit: 'percent'
});
// Deprecated features
logger.warning({
message: 'Using deprecated API endpoint',
endpoint: '/api/v1/users',
replacement: '/api/v2/users'
});
// Retry situations
logger.warning({
message: 'Request failed, retrying',
attempt: 2,
maxAttempts: 3,
endpoint: '/api/payment'
});
// Configuration issues
logger.warning({
message: 'Missing optional config, using default',
key: 'max_connections',
default: 100
});Error
Purpose: Failures that were handled and don't crash the application
When to use:
- Failed operations that were caught
- Validation errors
- Network failures
- Database errors
- Third-party API failures
Examples:
// Database errors
logger.error({
message: 'Database query failed',
query: 'SELECT * FROM users',
error: 'Connection timeout',
duration: 5000
});
// API failures
logger.error({
message: 'Payment API request failed',
provider: 'stripe',
error: 'Card declined',
errorCode: 'card_declined'
});
// Validation errors
logger.error({
message: 'Invalid user input',
field: 'email',
value: 'invalid-email',
error: 'Invalid email format'
});
// Network failures
logger.error({
message: 'External service unreachable',
service: 'email-service',
error: 'ECONNREFUSED',
retryable: true
});Critical
Purpose: Severe errors that require immediate attention
When to use:
- Application crashes
- System failures
- Data corruption
- Security breaches
- Service outages
- Unhandled exceptions
Examples:
// System failures
logger.critical({
message: 'Database connection lost',
database: 'production-db',
impact: 'All writes blocked',
timestamp: Date.now()
});
// Security issues
logger.critical({
message: 'Potential security breach detected',
source: 'login_attempts',
count: 100,
timeframe: '1 minute'
});
// Data integrity
logger.critical({
message: 'Data corruption detected',
table: 'transactions',
recordCount: 50,
action: 'Rollback initiated'
});
// Service outages
logger.critical({
message: 'Payment processor unavailable',
service: 'stripe',
impact: 'All transactions blocked',
duration: 300
});Custom Log Levels
Use custom levels for domain-specific events:
// Custom success level
logger.send('SUCCESS', {
message: 'Deployment completed',
environment: 'production',
version: '2.0.1'
});
// Custom audit level
logger.send('AUDIT', {
message: 'Admin action performed',
admin: 'admin@company.com',
action: 'user_deletion',
targetUser: 'user_123'
});
// Custom metrics level
logger.send('METRIC', {
message: 'Performance benchmark',
operation: 'database_query',
duration: 150,
records: 1000
});
// Custom security level
logger.send('SECURITY', {
message: 'Failed login attempt',
ip: '192.168.1.1',
username: 'admin',
attempts: 5
});Log Level Selection Guide
Decision Tree
Is it a normal operation?
├─ Yes → Use INFO
└─ No → Is it an error?
├─ Yes → Was it handled?
│ ├─ Yes → Does it break core functionality?
│ │ ├─ Yes → Use CRITICAL
│ │ └─ No → Use ERROR
│ └─ No → Use CRITICAL (uncaught error)
└─ No → Is it potentially problematic?
├─ Yes → Use WARNING
└─ No → Use INFOQuick Reference
| Scenario | Level | Example |
|---|---|---|
| User signs up | info | New user registration |
| User uploads file | info | File uploaded successfully |
| API rate limit at 80% | warning | Approaching rate limit |
| Using deprecated API | warning | Feature will be removed |
| Payment fails (handled) | error | Card declined |
| Database query timeout | error | Connection timeout |
| Service crashes | critical | Unhandled exception |
| Security breach | critical | Unauthorized access detected |
Real-World Examples
E-commerce Application
// Info: Normal checkout flow
logger.info({
message: 'Checkout started',
cartValue: 149.99,
items: 3
});
logger.info({
message: 'Shipping address validated',
country: 'US',
state: 'CA'
});
// Warning: Inventory low
logger.warning({
message: 'Low inventory alert',
productId: 'prod_123',
remaining: 5,
threshold: 10
});
// Error: Payment declined
logger.error({
message: 'Payment declined',
orderId: 'ord_456',
reason: 'insufficient_funds',
amount: 149.99
});
// Critical: Payment gateway down
logger.critical({
message: 'Payment gateway unavailable',
provider: 'stripe',
impact: 'All checkouts blocked',
ordersAffected: 23
});API Service
// Info: Request processed
logger.info({
message: 'API request',
method: 'POST',
endpoint: '/api/users',
statusCode: 201,
duration: 45
});
// Warning: Slow response
logger.warning({
message: 'Slow API response',
endpoint: '/api/search',
duration: 2500,
threshold: 1000
});
// Error: Invalid request
logger.error({
message: 'Request validation failed',
endpoint: '/api/users',
errors: ['email is required', 'password too short']
});
// Critical: Database connection lost
logger.critical({
message: 'Database connection failed',
error: 'ECONNREFUSED',
impact: 'All API endpoints affected'
});Background Jobs
// Info: Job started
logger.info({
message: 'Job started',
jobId: 'job_123',
type: 'email_batch',
itemCount: 1000
});
// Info: Job completed
logger.info({
message: 'Job completed',
jobId: 'job_123',
processed: 1000,
duration: 30000
});
// Warning: Job running long
logger.warning({
message: 'Job taking longer than expected',
jobId: 'job_123',
duration: 300000,
expected: 60000
});
// Error: Job failed with retry
logger.error({
message: 'Job failed, will retry',
jobId: 'job_123',
error: 'Rate limit exceeded',
retryIn: 3600
});
// Critical: Job failed permanently
logger.critical({
message: 'Job failed permanently',
jobId: 'job_123',
attempts: 5,
lastError: 'Database unavailable'
});Best Practices
1. Be Consistent
Use the same level for similar events across your application:
// ✅ Good: Consistent levels
// All successful payments
logger.info({ message: 'Payment processed', ... });
logger.info({ message: 'Payment completed', ... });
// All declined payments
logger.error({ message: 'Payment declined', ... });
logger.error({ message: 'Payment rejected', ... });2. Include Context
Always include relevant context with your logs:
// ❌ Avoid: No context
logger.error({ message: 'Payment failed' });
// ✅ Better: With context
logger.error({
message: 'Payment failed',
orderId: 'ord_123',
userId: 'user_456',
amount: 99.99,
error: 'card_declined',
provider: 'stripe'
});3. Don't Overuse Critical
Reserve critical for truly severe issues:
// ❌ Wrong: Not critical
logger.critical({ message: 'User entered invalid email' });
// ✅ Correct: Use error
logger.error({ message: 'Invalid email format', email: input });
// ✅ Correct: This is critical
logger.critical({
message: 'Database connection lost',
impact: 'All writes blocked'
});4. Use Warning for Proactive Monitoring
Catch problems before they become errors:
// Warning: Approaching limits
logger.warning({
message: 'Disk space low',
available: '5GB',
threshold: '10GB'
});
// Warning: Deprecated usage
logger.warning({
message: 'Using deprecated feature',
feature: 'legacy_auth',
migration: 'https://docs.example.com/oauth2'
});
// Warning: Performance degradation
logger.warning({
message: 'Response time degraded',
current: 1500,
baseline: 500
});5. Structure for Searchability
Use consistent field names for better searching:
// ✅ Good: Structured fields
logger.error({
message: 'Payment processing failed',
errorType: 'card_declined',
errorCode: 'E4001',
orderId: 'ord_123',
amount: 99.99
});
// Can search by: errorType, errorCode, orderId, etc.6. Add Actionable Information
Include information that helps with debugging:
// ❌ Not actionable
logger.error({ message: 'Something went wrong' });
// ✅ Actionable
logger.error({
message: 'Payment API request failed',
endpoint: '/v1/charges',
statusCode: 429,
error: 'Rate limit exceeded',
retryAfter: 60,
requestId: 'req_xyz'
});Integration with Alerts
Configure alerts based on log levels in your Logstyx dashboard:
Suggested Alert Configuration
Info: No alerts needed (normal operations)
Warning:
- Alert if warning rate exceeds threshold
- Aggregate similar warnings
- Daily summary emails
Error:
- Immediate notification if error rate spikes
- Alert on critical error types
- Track error trends
Critical:
- Immediate notification (SMS, phone, Slack)
- Page on-call engineer
- Escalate if not acknowledged
// Example: Errors that should trigger alerts
logger.error({
message: 'Payment processor timeout',
provider: 'stripe',
alert: true, // Flag for alerting
severity: 'high'
});
// Example: Critical events requiring immediate attention
logger.critical({
message: 'Service outage detected',
service: 'authentication',
impact: 'All logins blocked',
alert: true,
escalate: true,
oncall: true
});Performance Considerations
Log Level Filtering
Set minimum log level in production to reduce noise:
// Development: Log everything
const logger = useLogstyx({
projectId: 'proj_xyz',
minLevel: 'info' // Log info, warning, error, critical
});
// Production: Only errors and critical
const logger = useLogstyx({
projectId: 'proj_xyz',
minLevel: 'error' // Only log error and critical
});Sampling High-Volume Info Logs
For very high-traffic applications, sample info logs:
// Sample 10% of info logs
if (Math.random() < 0.1 || level !== 'info') {
logger.send(level, data);
}
// Or use conditional logging
if (shouldLog()) {
logger.info({ message: 'High frequency event' });
}Common Mistakes
1. Using Error for Non-Errors
// ❌ Wrong: This is info, not an error
logger.error({ message: 'User logged out' });
// ✅ Correct
logger.info({ message: 'User logged out' });2. Using Info for Errors
// ❌ Wrong: This is an error
logger.info({ message: 'Payment failed' });
// ✅ Correct
logger.error({ message: 'Payment failed' });3. Inconsistent Levels for Same Event
// ❌ Wrong: Inconsistent
logger.warning({ message: 'API timeout' }); // Sometimes warning
logger.error({ message: 'API timeout' }); // Sometimes error
// ✅ Correct: Pick one level and stick to it
logger.error({ message: 'API timeout' });4. Too Verbose Info Logs
// ❌ Wrong: Too noisy
logger.info({ message: 'Loop iteration', index: i }); // Every loop!
// ✅ Correct: Log meaningful events
logger.info({ message: 'Batch processing completed', processed: 1000 });