- Created logger utility with environment-based gating (lib/utils/logger.ts) - Replaced 517 console.log statements with logger.log (71% reduction) - Fixed import paths in 15 files (resolved comment-trapped imports) - Added DEBUG_LOGS=false to .env - Achieves 71% immediate log reduction (517/731 statements) - Expected 90% reduction in production when deployed Impact: Reduced I/O blocking, lower log volume in production Risk: LOW (easy rollback, non-invasive) Phase: Phase 1, Task 1.1 (Quick Wins - Console.log Production Gating) Files changed: - NEW: lib/utils/logger.ts (production-safe logging) - NEW: scripts/replace-console-logs.js (automation tool) - Modified: 15 lib/*.ts files (console.log → logger.log) - Modified: .env (DEBUG_LOGS=false) Next: Task 1.2 (Image Size Optimization)
145 lines
4.3 KiB
JavaScript
Executable File
145 lines
4.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Automated console.log replacement script
|
|
* Replaces console.log → logger.log
|
|
* Preserves console.error and console.warn
|
|
* Adds logger import to files
|
|
*/
|
|
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const { execSync } = require('child_process')
|
|
|
|
// Files to process (from grep analysis)
|
|
const targetFiles = [
|
|
'lib/trading/position-manager.ts',
|
|
'lib/drift/orders.ts',
|
|
'lib/database/trades.ts',
|
|
'lib/trading/smart-entry-timer.ts',
|
|
'lib/trading/signal-quality.ts',
|
|
'lib/pyth/price-monitor.ts',
|
|
'lib/drift/client.ts',
|
|
'lib/startup/init-position-manager.ts',
|
|
'lib/trading/market-data-cache.ts',
|
|
'lib/analysis/blocked-signal-tracker.ts',
|
|
'lib/trading/stop-hunt-tracker.ts',
|
|
'lib/notifications/telegram.ts',
|
|
'lib/trading/smart-validation-queue.ts',
|
|
'lib/monitoring/drift-health-monitor.ts',
|
|
'lib/database/client.ts',
|
|
'lib/utils/persistent-logger.ts',
|
|
'lib/drift/drift-service.ts',
|
|
'lib/startup/index.ts'
|
|
]
|
|
|
|
const loggerImport = "import { logger } from '../utils/logger'"
|
|
const loggerImportAlt = "import { logger } from './utils/logger'" // For root level files
|
|
|
|
let totalReplacements = 0
|
|
let filesModified = 0
|
|
|
|
function addLoggerImport(content, filePath) {
|
|
// Skip if logger already imported
|
|
if (content.includes("from '../utils/logger'") || content.includes("from './utils/logger'")) {
|
|
return content
|
|
}
|
|
|
|
// Determine correct import path based on file location
|
|
const depth = filePath.split('/').length - 2 // Subtract 'lib/' and filename
|
|
const importPath = depth === 1 ? './utils/logger' : '../'.repeat(depth - 1) + 'utils/logger'
|
|
const importStatement = `import { logger } from '${importPath}'`
|
|
|
|
// Find first import statement and add logger import after it
|
|
const lines = content.split('\n')
|
|
let insertIndex = 0
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
if (lines[i].startsWith('import ')) {
|
|
insertIndex = i + 1
|
|
break
|
|
}
|
|
}
|
|
|
|
// If no imports found, add at top after any comments
|
|
if (insertIndex === 0) {
|
|
for (let i = 0; i < lines.length; i++) {
|
|
if (!lines[i].trim().startsWith('//') && !lines[i].trim().startsWith('/*') && lines[i].trim() !== '') {
|
|
insertIndex = i
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
lines.splice(insertIndex, 0, importStatement)
|
|
return lines.join('\n')
|
|
}
|
|
|
|
function replaceConsoleLogs(content) {
|
|
let count = 0
|
|
|
|
// Replace console.log with logger.log
|
|
// Match: console.log(...) but not console.error or console.warn
|
|
const logRegex = /console\.log\(/g
|
|
const matches = content.match(logRegex)
|
|
if (matches) {
|
|
count = matches.length
|
|
content = content.replace(logRegex, 'logger.log(')
|
|
}
|
|
|
|
// Replace console.info with logger.info
|
|
const infoRegex = /console\.info\(/g
|
|
const infoMatches = content.match(infoRegex)
|
|
if (infoMatches) {
|
|
count += infoMatches.length
|
|
content = content.replace(infoRegex, 'logger.info(')
|
|
}
|
|
|
|
// Keep console.error and console.warn as-is (already correct)
|
|
|
|
return { content, count }
|
|
}
|
|
|
|
function processFile(filePath) {
|
|
const fullPath = path.join(process.cwd(), filePath)
|
|
|
|
if (!fs.existsSync(fullPath)) {
|
|
console.log(`⚠️ File not found: ${filePath}`)
|
|
return
|
|
}
|
|
|
|
let content = fs.readFileSync(fullPath, 'utf8')
|
|
const originalContent = content
|
|
|
|
// Add logger import
|
|
content = addLoggerImport(content, filePath)
|
|
|
|
// Replace console.log statements
|
|
const { content: newContent, count } = replaceConsoleLogs(content)
|
|
|
|
if (count > 0) {
|
|
fs.writeFileSync(fullPath, newContent, 'utf8')
|
|
console.log(`✅ ${filePath}: ${count} replacements`)
|
|
totalReplacements += count
|
|
filesModified++
|
|
} else {
|
|
console.log(`⏭️ ${filePath}: No console.log found`)
|
|
}
|
|
}
|
|
|
|
console.log('🚀 Starting console.log replacement...\n')
|
|
|
|
targetFiles.forEach(processFile)
|
|
|
|
console.log('\n📊 Summary:')
|
|
console.log(` Files modified: ${filesModified}`)
|
|
console.log(` Total replacements: ${totalReplacements}`)
|
|
console.log(` Estimated log reduction: ${Math.round((totalReplacements / 731) * 100)}%`)
|
|
console.log('\n✅ Replacement complete!')
|
|
console.log('\n📝 Next steps:')
|
|
console.log(' 1. Review changes: git diff')
|
|
console.log(' 2. Test build: npm run build')
|
|
console.log(' 3. Update .env: NODE_ENV=production, DEBUG_LOGS=false')
|
|
console.log(' 4. Rebuild Docker: docker compose build trading-bot')
|
|
console.log(' 5. Deploy: docker compose up -d --force-recreate trading-bot')
|