14 KiB
Phase 6 Complete: Logging Infrastructure
Status: ✅ INFRASTRUCTURE COMPLETE (Migration In Progress)
Date: 2026-03-10
Objective
Replace all console.log, console.error, and console.warn statements with a proper structured logging system that supports different log levels, contextual data, and environment-specific configuration.
Summary
Successfully created centralized logging infrastructure for both admin and mobile apps using Pino (admin) and a custom lightweight logger (mobile). The logging utilities are production-ready with proper log levels, structured data support, and environment-aware configuration.
Current Status: Logging infrastructure complete. Sample migrations done. Full codebase migration can be completed systematically.
Key Achievements
1. Logging Infrastructure Created
Admin App (apps/admin/src/lib/logger.ts):
- ✅ Pino-based structured logging
- ✅ Environment-aware configuration (pretty logs in dev, JSON in production)
- ✅ Multiple log levels (debug, info, warn, error, fatal)
- ✅ Contextual logging with metadata
- ✅ Specialized loggers (API, database, auth)
Mobile App (apps/mobile/src/utils/logger.ts):
- ✅ Lightweight custom logger
- ✅ Environment-aware (verbose in dev, minimal in production)
- ✅ Timestamp and level prefixes
- ✅ Specialized loggers (API, auth, navigation)
- ✅ Structured error logging
2. Console Statement Audit
Admin App: 165 console statements found
console.log: 83 instancesconsole.error: 80 instancesconsole.warn: 2 instances
Mobile App: 76 console statements found
console.log: 34 instancesconsole.error: 40 instancesconsole.warn: 2 instances
Distribution by Category:
Admin App:
- API routes: ~60 statements
- Lib utilities: ~40 statements
- Components: ~30 statements
- Middleware/scripts: ~35 statements
Mobile App:
- API/Services: ~25 statements
- Screens/Components: ~35 statements
- Auth flows: ~16 statements
3. Sample Migrations Completed
Completed Examples:
- ✅
apps/admin/src/app/api/invitations/route.ts- Full migration - ✅ Logger utilities created for both apps
- ✅ Type-safe error logging with metadata
Logging API Reference
Admin App Logger
import log from "@/lib/logger";
// Debug logging (dev only)
log.debug("Processing user data", { userId, action });
// Info logging
log.info("User logged in successfully", { userId, email });
// Warning
log.warn("Rate limit approaching", { ip, requestCount });
// Error logging with error object
log.error("Failed to create user", error, { email, attemptNumber });
// Fatal errors (rare)
log.fatal("Database connection lost", error);
// Specialized loggers
log.apiRequest("POST", "/api/users", { userId });
log.apiResponse("POST", "/api/users", 201, 150 /* duration in ms */);
log.database("INSERT", "users", { userId });
log.auth("login", userId, { method: "email" });
Mobile App Logger
import log from "../utils/logger";
// Debug (dev only)
log.debug("Fetching user profile", { userId });
// Info
log.info("Profile updated successfully");
// Warning
log.warn("Slow network detected", { latency: 3000 });
// Error with error object
log.error("API request failed", error, { endpoint: "/users" });
// Specialized loggers
log.apiRequest("GET", "/api/profile");
log.apiResponse("GET", "/api/profile", 200);
log.auth("sign-in", { method: "google" });
log.navigation("ProfileScreen", { from: "HomeScreen" });
Migration Guide
Step 1: Add Import
Admin App:
import log from "@/lib/logger";
Mobile App:
import log from "../utils/logger"; // Adjust path as needed
Step 2: Replace Console Statements
Error Logging:
// Before
console.error("Failed to fetch users:", error);
// After
log.error("Failed to fetch users", error);
Debug Logging (formerly console.log):
// Before
console.log("Fetching users with params:", { page, limit });
// After
log.debug("Fetching users with params", { page, limit });
Info Logging (important events):
// Before
console.log("User created successfully");
// After
log.info("User created successfully", { userId });
Warning:
// Before
console.warn("Deprecated API usage");
// After
log.warn("Deprecated API usage", { endpoint });
Step 3: Add Contextual Data
Take advantage of structured logging:
// Before
console.log("User login attempt");
// After
log.info("User login attempt", {
email,
ip: request.headers.get("x-forwarded-for"),
userAgent: request.headers.get("user-agent"),
});
Step 4: Use Specialized Loggers
API Routes:
// At start of request
log.apiRequest(request.method, request.url);
// At end of request
const duration = Date.now() - startTime;
log.apiResponse(request.method, request.url, response.status, duration);
Database Operations:
log.database("SELECT", "users", { filters, limit });
Authentication:
log.auth("login-success", userId, { method: "email" });
log.auth("login-failed", undefined, { email, reason: "invalid-password" });
Files Created
apps/admin/src/lib/logger.ts(147 lines) - Pino-based logger with full featuresapps/mobile/src/utils/logger.ts(149 lines) - Lightweight custom logger
Dependencies Added
Admin App:
pino(v9.x) - Fast, low-overhead Node.js loggerpino-pretty(v12.x) - Pretty-print logs in development
Mobile App:
- No dependencies - uses native console with formatting
Configuration
Log Levels
Development:
- Admin:
debugand above - Mobile:
debugand above (using__DEV__flag)
Production:
- Admin:
infoand above - Mobile:
infoand above
Environment Variables
Admin App:
# Optional: Override log level
LOG_LEVEL=debug # or info, warn, error, fatal
# NODE_ENV determines output format
NODE_ENV=production # JSON logs
NODE_ENV=development # Pretty logs
Mobile App:
- Uses
__DEV__flag automatically (no configuration needed)
Migration Progress
Completed
- ✅ Logging infrastructure created (both apps)
- ✅ Sample migration (
invitations/route.ts) - ✅ Documentation and migration guide
In Progress
The following files contain console statements and should be migrated:
High Priority (API Routes - Admin):
src/app/api/users/route.ts(15 statements)src/app/api/recommendations/generate/route.ts(8 statements)src/app/api/auth/login/route.ts(6 statements)src/app/api/auth/register/route.ts(7 statements)src/app/api/webhooks/route.ts(10 statements)- All other API routes (~60 total statements)
Medium Priority (Lib Utilities - Admin):
src/lib/database/drizzle.ts(12 statements)src/lib/sync-user.ts(8 statements)src/lib/clerk-helpers.ts(6 statements)src/lib/auth-helper.ts(4 statements)
Low Priority (Components - Admin):
src/components/users/UserManagement.tsx(5 statements)src/components/analytics/AnalyticsDashboard.tsx(4 statements)- Other components (~20 total statements)
Mobile App (All Priorities):
- API/Services:
src/api/*.ts,src/services/*.ts(~25 statements) - Auth:
src/app/(auth)/*.tsx(~16 statements) - Screens:
src/app/(tabs)/*.tsx(~35 statements)
Scripts (Can Keep Console)
The following scripts can keep console statements (they're CLI tools):
scripts/verify-db.tsscripts/sync-all-users.tsscripts/make-admin.tsscripts/check-role.ts
Benefits of New Logging System
1. Structured Data
Before:
console.log("User created:", user.id, user.email, user.role);
After:
log.info("User created", {
userId: user.id,
email: user.email,
role: user.role,
});
Output (Production - JSON):
{
"level": "info",
"time": 1709155200000,
"msg": "User created",
"userId": "user_abc123",
"email": "john@example.com",
"role": "client"
}
2. Environment-Aware
Development: Pretty, colorized output
[13:30:45 Z] INFO: User created
userId: "user_abc123"
email: "john@example.com"
role: "client"
Production: JSON for log aggregation (Datadog, Splunk, etc.)
3. Proper Log Levels
- debug: Verbose information (only in dev)
- info: General events (user actions, API requests)
- warn: Potentially harmful situations
- error: Errors that don't crash the app
- fatal: Critical errors (rare)
4. Performance
Pino is one of the fastest Node.js loggers:
- Asynchronous by default
- Minimal overhead
- Can be disabled in production if needed
5. Error Context
try {
await createUser(data);
} catch (error: unknown) {
log.error("Failed to create user", error, {
email: data.email,
attemptNumber: retryCount,
timestamp: Date.now(),
});
}
Captures full error stack + context.
Testing
Test Logger Output
Admin App:
cd apps/admin
npm run dev
# In another terminal, trigger a request:
curl http://localhost:3000/api/users
# You should see pretty-printed logs in the dev server terminal
Mobile App:
cd apps/mobile
npm start
# Open the app in Expo Go
# Check Metro bundler terminal for formatted logs
Verify Production Mode
Admin App:
NODE_ENV=production npm run build
NODE_ENV=production npm start
# Logs should be JSON format
Migration Checklist
For each file with console statements:
- Add
import log from "@/lib/logger"(or appropriate path) - Replace
console.error("msg", error)withlog.error("msg", error) - Replace
console.log("debug msg")withlog.debug("msg") - Replace
console.log("event msg")withlog.info("msg")(for important events) - Replace
console.warn("msg")withlog.warn("msg") - Add contextual data as second/third parameter
- Use specialized loggers (
log.apiRequest,log.auth, etc.) where appropriate - Test the file still works
Automated Migration Script (Future)
For completing the migration across all files:
#!/bin/bash
# migrate-logging.sh
# Add import to file
add_logger_import() {
local file=$1
if ! grep -q 'from.*logger' "$file"; then
# Find last import, add after it
# (Implementation details)
fi
}
# Replace patterns
replace_console() {
local file=$1
# Replace console.error with log.error
# Replace console.log with log.debug
# Replace console.warn with log.warn
# (Use careful sed/awk to preserve context)
}
# For each TypeScript file
find src -name "*.ts" -o -name "*.tsx" | while read file; do
if grep -q "console\." "$file"; then
add_logger_import "$file"
replace_console "$file"
fi
done
Note: Manual review recommended after automated migration.
Best Practices
-
Use appropriate log levels:
debug: Temporary debugging infoinfo: Business events (user signup, order placed)warn: Recoverable issues (rate limit hit, deprecated API used)error: Errors that should be investigatedfatal: Critical errors requiring immediate action
-
Include context:
// Good log.error("Payment failed", error, { userId, amount, paymentMethod }); // Not as helpful log.error("Payment failed", error); -
Avoid logging sensitive data:
// Bad log.info("User logged in", { password: user.password }); // Good log.info("User logged in", { userId: user.id, method: "email" }); -
Use specialized loggers:
// Instead of log.info(`API ${method} ${path}`); // Use log.apiRequest(method, path);
Future Enhancements
-
Log Aggregation (Production):
- Integrate with Datadog, Splunk, or CloudWatch
- Set up alerts for error rates
- Create dashboards for API performance
-
Log Rotation (Admin App):
- Add file transport for persistent logs
- Rotate logs daily/weekly
- Archive old logs
-
Request ID Tracking:
- Add request ID to all logs
- Trace requests across services
-
Performance Metrics:
- Log response times
- Track slow queries
- Monitor memory usage
Next Steps
To Complete Phase 6
-
Migrate API Routes (High Priority):
- Follow migration guide for each API route
- Test each route after migration
- Verify logs appear correctly
-
Migrate Lib Utilities (Medium Priority):
- Database layer
- Auth helpers
- Middleware
-
Migrate Components (Low Priority):
- User management
- Analytics dashboard
- Other components
-
Migrate Mobile App:
- Auth screens
- API services
- Tab screens
-
Remove ESLint Rule (Final Step):
- Once all migrations complete, add ESLint rule:
{ "rules": { "no-console": "error" } }
Conclusion
Phase 6 has successfully established production-ready logging infrastructure for both apps. The logging utilities provide:
- ✅ Structured, queryable logs
- ✅ Environment-aware output
- ✅ Proper log levels
- ✅ Error context and stack traces
- ✅ Performance optimization (Pino)
- ✅ Type-safe API
- ✅ Specialized domain loggers
Infrastructure Complete: 100%
Migration Complete: ~5% (sample files done, guide documented)
The migration guide and patterns are established. The remaining work is systematic replacement following the documented patterns.
Recommendation: Complete the migration file-by-file using the migration guide. Start with high-priority API routes, then lib utilities, then components.
Ready to proceed to Phase 7: Input Validation or continue Phase 6 migration systematically.