Excessive Console Logs in Production Builds
Console logs left in production code can cause several problems including performance degradation, exposed sensitive information, and a poor user experience. Here’s how to properly handle logging in React applications.
Problems with Production Console Logs
- Performance impact – Console I/O operations slow down your app
- Security risks – May expose sensitive data in browser logs
- Professionalism – Makes your app appear unpolished to users
- Debugging noise – Obscures real issues in production logs
Proper Logging Strategies
1. Remove Logs in Production Builds (Create React App)
// Conditional logging helper
const logger = {
log: (...args) => {
if (process.env.NODE_ENV !== 'production') {
console.log(...args);
}
},
error: (...args) => {
if (process.env.NODE_ENV !== 'production') {
console.error(...args);
}
}
// Add other console methods as needed
};
// Usage
logger.log('Debug message'); // Only shows in development
2. Webpack Plugin to Strip Logs
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // Remove all console.*
// OR for specific methods:
pure_funcs: ['console.log', 'console.debug'] // Remove only these
}
}
})
]
}
};
3. Advanced Logging Library
// logger.js
import { env } from './config'; // Your env config
const logLevels = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3
};
const currentLevel = env.LOG_LEVEL || 'WARN';
export default {
debug: (...args) => {
if (logLevels[currentLevel] <= logLevels.DEBUG) {
console.debug('[DEBUG]', ...args);
}
},
error: (...args) => {
if (logLevels[currentLevel] <= logLevels.ERROR) {
console.error('[ERROR]', ...args);
}
}
// Add other levels as needed
};
Best Practices
- Use a wrapper around console methods for better control
- Implement log levels (debug, info, warn, error)
- Strip logs from production builds automatically
- Keep error logs in production (but sanitize sensitive data)
- Consider server-side logging for production monitoring
Migration Strategy
- Find all console statements:
grep -r "console." src/
- Replace with your logger:
// Before
console.log('User data:', user);
// After
logger.debug('User data:', user);
- Add ESLint rule to prevent future issues:
// .eslintrc.js
module.exports = {
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn'
}
};
Production-Grade Solutions
1. Error Tracking Service Integration
// logger.js
import * as Sentry from '@sentry/react';
export const logger = {
error: (error, context = {}) => {
console.error(error);
Sentry.captureException(error, { extra: context });
},
warn: (message, context) => {
console.warn(message);
Sentry.captureMessage(message, { level: 'warning', extra: context });
}
};
2. Runtime Log Level Control
// Enable debug logging by setting logLevel=debug in localStorage
const getLogLevel = () => {
if (typeof window !== 'undefined') {
return localStorage.getItem('logLevel') ||
(process.env.NODE_ENV === 'development' ? 'debug' : 'error');
}
return 'error';
};
By implementing these patterns, you maintain the ability to debug in development while keeping your production builds clean and performant. Remember to:
- Keep essential error logging in production
- Remove all debug logging from production builds
- Never log sensitive user data
- Consider implementing a proper logging service for production monitoring