Impact: MEDIUM (enables production debugging with structured, searchable, context-rich log entries)
Bare console.log("Error:", error) in production gives you a message with no context: no service name, no user ID, no request ID, no error code. When your service handles 10,000 requests per minute and something fails, you need to filter logs by service, correlate errors with specific users, and search by error ID to find the root cause. Scoped loggers attach this context automatically.
Every service and middleware should create a scoped logger with its name, and every log entry should include an errorId following the convention COMPONENT_OPERATION_RESULT.
Incorrect (bare console.log with no context):
// lib/services/RuleService.ts// ❌ No context, no structure, impossible to filter in productionexport class RuleService { async createRule(userId: string, input: CreateRuleInput) { console.log('Creating rule') // ❌ Which service? Which user? Which rule? try { const rule = await this.repo.create(input) console.log('Rule created:', rule.id) // ❌ No userId for correlation return rule } catch (error) { console.log('Error creating rule:', error) // ❌ No errorId, no structured data throw error } } async deleteRule(userId: string, ruleId: string) { console.log('Deleting rule', ruleId) // ❌ Same generic format everywhere const rule = await this.repo.findById(ruleId) if (rule?.userId !== userId) { console.log('Unauthorized delete attempt') // ❌ No userId — who tried? return null } await this.repo.delete(ruleId) console.log('Rule deleted') // ❌ No correlation data }}
// lib/factories/ServiceFactory.ts// ✅ Logger created with service name at factory levelexport class ServiceFactory { static async createRuleService(): Promise<RuleService> { const supabase = await createServerSupabaseClient() const repos = new RepositoryFactory(supabase) return new RuleService( repos.createRuleRepository(), createScopedLogger('RuleService'), // ✅ Scoped to service name ) }}
{"timestamp":"2026-03-03T14:22:01.123Z","level":"error","service":"RuleService","message":"Failed to create rule","errorId":"RULE_CREATE_FAILED","userId":"usr_abc123","ruleName":"My Rule","error":"unique constraint violation"}
Detection hints:
# Find bare console.log in services (should use scoped logger)grep -rn "console\.log\|console\.error\|console\.warn" src/lib/services --include="*.ts"# Find console.log in API routes (should use scoped logger)grep -rn "console\.log" src/app/api --include="*.ts"# Verify scoped loggers are being usedgrep -rn "createScopedLogger" src/lib --include="*.ts"