137 lines
4.5 KiB
Markdown
137 lines
4.5 KiB
Markdown
# ADR-052: Granular Debug Logging Strategy
|
|
|
|
**Date**: 2026-01-11
|
|
|
|
**Status**: Accepted (Fully Implemented)
|
|
|
|
**Related**: [ADR-004](0004-standardized-application-wide-structured-logging.md)
|
|
|
|
## Context
|
|
|
|
Global log levels (INFO vs DEBUG) are too coarse. Developers need to inspect detailed debug information for specific subsystems (e.g., `ai-service`, `db-pool`) without being flooded by logs from the entire application.
|
|
|
|
## Decision
|
|
|
|
We will adopt a namespace-based debug filter pattern, similar to the `debug` npm package, but integrated into our Pino logger.
|
|
|
|
1. **Logger Namespaces**: Every service/module logger must be initialized with a `module` property (e.g., `logger.child({ module: 'ai-service' })`).
|
|
2. **Environment Filter**: We will support a `DEBUG_MODULES` environment variable that overrides the log level for matching modules.
|
|
|
|
## Implementation
|
|
|
|
### Core Implementation (Completed 2026-01-11)
|
|
|
|
Implemented in [src/services/logger.server.ts:140-150](src/services/logger.server.ts#L140-L150):
|
|
|
|
```typescript
|
|
const debugModules = (process.env.DEBUG_MODULES || '').split(',').map((s) => s.trim());
|
|
|
|
export const createScopedLogger = (moduleName: string) => {
|
|
// If DEBUG_MODULES contains "ai-service" or "*", force level to 'debug'
|
|
const isDebugEnabled = debugModules.includes('*') || debugModules.includes(moduleName);
|
|
|
|
return logger.child({
|
|
module: moduleName,
|
|
level: isDebugEnabled ? 'debug' : logger.level,
|
|
});
|
|
};
|
|
```
|
|
|
|
### Adopted Services (Completed 2026-01-26)
|
|
|
|
Services currently using `createScopedLogger`:
|
|
|
|
- `ai-service` - AI/Gemini integration ([src/services/aiService.server.ts:1020](src/services/aiService.server.ts#L1020))
|
|
- `flyer-processing-service` - Flyer upload and processing ([src/services/flyerProcessingService.server.ts:20](src/services/flyerProcessingService.server.ts#L20))
|
|
|
|
## Usage
|
|
|
|
### Enable Debug Logging for Specific Modules
|
|
|
|
To debug only AI and flyer processing:
|
|
|
|
```bash
|
|
DEBUG_MODULES=ai-service,flyer-processing-service npm run dev
|
|
```
|
|
|
|
### Enable All Debug Logging
|
|
|
|
Use wildcard to enable debug logging for all modules:
|
|
|
|
```bash
|
|
DEBUG_MODULES=* npm run dev
|
|
```
|
|
|
|
### Common Module Names
|
|
|
|
| Module Name | Purpose | File |
|
|
| -------------------------- | ---------------------------------------- | ----------------------------------------------- |
|
|
| `ai-service` | AI/Gemini API interactions | `src/services/aiService.server.ts` |
|
|
| `flyer-processing-service` | Flyer upload, validation, and processing | `src/services/flyerProcessingService.server.ts` |
|
|
|
|
## Best Practices
|
|
|
|
1. **Use Scoped Loggers for Long-Running Services**: Services with complex workflows or external API calls should use `createScopedLogger` to allow targeted debugging.
|
|
|
|
2. **Use Child Loggers for Contextual Data**: Even within scoped loggers, create child loggers with job/request-specific context:
|
|
|
|
```typescript
|
|
const logger = createScopedLogger('my-service');
|
|
|
|
async function processJob(job: Job) {
|
|
const jobLogger = logger.child({ jobId: job.id, jobName: job.name });
|
|
jobLogger.debug('Starting job processing');
|
|
}
|
|
```
|
|
|
|
3. **Module Naming Convention**: Use kebab-case suffixed with `-service` or `-worker` (e.g., `ai-service`, `email-worker`).
|
|
|
|
4. **Production Usage**: `DEBUG_MODULES` can be set in production for temporary debugging, but should not be used continuously due to increased log volume.
|
|
|
|
## Examples
|
|
|
|
### Development Debugging
|
|
|
|
Debug AI service issues during development:
|
|
|
|
```bash
|
|
# Dev container
|
|
DEBUG_MODULES=ai-service npm run dev
|
|
|
|
# Or via PM2
|
|
DEBUG_MODULES=ai-service pm2 restart flyer-crawler-api-dev
|
|
```
|
|
|
|
### Production Troubleshooting
|
|
|
|
Temporarily enable debug logging for a specific subsystem:
|
|
|
|
```bash
|
|
# SSH into production server
|
|
ssh root@projectium.com
|
|
|
|
# Set environment variable and restart
|
|
DEBUG_MODULES=ai-service pm2 restart flyer-crawler-api
|
|
|
|
# View logs
|
|
pm2 logs flyer-crawler-api --lines 100
|
|
|
|
# Disable debug logging
|
|
pm2 unset DEBUG_MODULES flyer-crawler-api
|
|
pm2 restart flyer-crawler-api
|
|
```
|
|
|
|
## Consequences
|
|
|
|
**Positive**:
|
|
|
|
- Developers can inspect detailed logs for specific subsystems without log flooding
|
|
- Production debugging becomes more targeted and efficient
|
|
- No performance impact when debug logging is disabled
|
|
- Compatible with existing Pino logging infrastructure
|
|
|
|
**Negative**:
|
|
|
|
- Requires developers to know module names (mitigated by documentation above)
|
|
- Not all services have adopted scoped loggers yet (gradual migration)
|