19 changed files with 505 additions and 121 deletions
@ -0,0 +1,119 @@ |
|||||||
|
# Logging System |
||||||
|
|
||||||
|
This document describes the logging system implemented to reduce console noise and improve performance. |
||||||
|
|
||||||
|
## Overview |
||||||
|
|
||||||
|
The application now uses a centralized logging system that: |
||||||
|
- Reduces console noise in production |
||||||
|
- Provides conditional debug logging |
||||||
|
- Improves performance by removing debug logs in production builds |
||||||
|
- Allows developers to enable debug logging when needed |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
### For Developers |
||||||
|
|
||||||
|
In development mode, you can control logging from the browser console: |
||||||
|
|
||||||
|
```javascript |
||||||
|
// Enable debug logging |
||||||
|
jumbleDebug.enable() |
||||||
|
|
||||||
|
// Disable debug logging |
||||||
|
jumbleDebug.disable() |
||||||
|
|
||||||
|
// Check current status |
||||||
|
jumbleDebug.status() |
||||||
|
|
||||||
|
// Use debug logging directly |
||||||
|
jumbleDebug.log('Debug message', data) |
||||||
|
jumbleDebug.warn('Warning message', data) |
||||||
|
jumbleDebug.error('Error message', data) |
||||||
|
jumbleDebug.perf('Performance message', data) |
||||||
|
``` |
||||||
|
|
||||||
|
### For Code |
||||||
|
|
||||||
|
Use the logger instead of direct console statements: |
||||||
|
|
||||||
|
```typescript |
||||||
|
import logger from '@/lib/logger' |
||||||
|
|
||||||
|
// Debug logging (only shows in dev mode with debug enabled) |
||||||
|
logger.debug('Debug information', data) |
||||||
|
|
||||||
|
// Info logging (always shows) |
||||||
|
logger.info('Important information', data) |
||||||
|
|
||||||
|
// Warning logging (always shows) |
||||||
|
logger.warn('Warning message', data) |
||||||
|
|
||||||
|
// Error logging (always shows) |
||||||
|
logger.error('Error message', data) |
||||||
|
|
||||||
|
// Performance logging (only in dev mode) |
||||||
|
logger.perf('Performance metric', data) |
||||||
|
``` |
||||||
|
|
||||||
|
## Log Levels |
||||||
|
|
||||||
|
- **debug**: Development debugging information (disabled in production) |
||||||
|
- **info**: Important application information (always enabled) |
||||||
|
- **warn**: Warning messages (always enabled) |
||||||
|
- **error**: Error messages (always enabled) |
||||||
|
- **perf**: Performance metrics (development only) |
||||||
|
|
||||||
|
## Configuration |
||||||
|
|
||||||
|
The logger automatically configures itself based on: |
||||||
|
|
||||||
|
1. **Environment**: Debug logging is disabled in production builds |
||||||
|
2. **Local Storage**: `jumble-debug=true` enables debug mode |
||||||
|
3. **Environment Variable**: `VITE_DEBUG=true` enables debug mode |
||||||
|
|
||||||
|
## Performance Impact |
||||||
|
|
||||||
|
- **Production**: Debug logs are completely removed, improving performance |
||||||
|
- **Development**: Debug logs are conditionally enabled, reducing noise |
||||||
|
- **Console Operations**: Reduced console.log calls improve browser performance |
||||||
|
|
||||||
|
## Migration |
||||||
|
|
||||||
|
The following files have been updated to use the new logging system: |
||||||
|
|
||||||
|
- `src/providers/FeedProvider.tsx` - Feed initialization and switching |
||||||
|
- `src/pages/primary/DiscussionsPage/index.tsx` - Vote counting and event fetching |
||||||
|
- `src/services/client.service.ts` - Relay operations and circuit breaker |
||||||
|
- `src/providers/NostrProvider/index.tsx` - Event signing and validation |
||||||
|
- `src/components/Note/index.tsx` - Component rendering |
||||||
|
- `src/PageManager.tsx` - Page rendering |
||||||
|
|
||||||
|
## Benefits |
||||||
|
|
||||||
|
1. **Reduced Console Noise**: Debug logs are hidden by default |
||||||
|
2. **Better Performance**: Fewer console operations in production |
||||||
|
3. **Developer Control**: Easy to enable debug logging when needed |
||||||
|
4. **Consistent Logging**: Centralized logging with consistent format |
||||||
|
5. **Production Ready**: Debug logs are completely removed in production builds |
||||||
|
|
||||||
|
## Debug Mode |
||||||
|
|
||||||
|
To enable debug mode: |
||||||
|
|
||||||
|
1. **In Browser Console** (development only): |
||||||
|
```javascript |
||||||
|
jumbleDebug.enable() |
||||||
|
``` |
||||||
|
|
||||||
|
2. **Via Local Storage**: |
||||||
|
```javascript |
||||||
|
localStorage.setItem('jumble-debug', 'true') |
||||||
|
``` |
||||||
|
|
||||||
|
3. **Via Environment Variable**: |
||||||
|
```bash |
||||||
|
VITE_DEBUG=true npm run dev |
||||||
|
``` |
||||||
|
|
||||||
|
Debug mode will show all debug-level logs with timestamps and log levels. |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
/** |
||||||
|
* Debug utilities for development and troubleshooting |
||||||
|
*
|
||||||
|
* Usage in browser console: |
||||||
|
* - jumbleDebug.enable() - Enable debug logging |
||||||
|
* - jumbleDebug.disable() - Disable debug logging |
||||||
|
* - jumbleDebug.status() - Check current debug status |
||||||
|
*/ |
||||||
|
|
||||||
|
import logger from './logger' |
||||||
|
|
||||||
|
interface DebugUtils { |
||||||
|
enable: () => void |
||||||
|
disable: () => void |
||||||
|
status: () => { enabled: boolean; level: string } |
||||||
|
log: (message: string, ...args: any[]) => void |
||||||
|
warn: (message: string, ...args: any[]) => void |
||||||
|
error: (message: string, ...args: any[]) => void |
||||||
|
perf: (message: string, ...args: any[]) => void |
||||||
|
} |
||||||
|
|
||||||
|
const debugUtils: DebugUtils = { |
||||||
|
enable: () => { |
||||||
|
logger.setDebugMode(true) |
||||||
|
console.log('🔧 Jumble debug logging enabled') |
||||||
|
}, |
||||||
|
|
||||||
|
disable: () => { |
||||||
|
logger.setDebugMode(false) |
||||||
|
console.log('🔧 Jumble debug logging disabled') |
||||||
|
}, |
||||||
|
|
||||||
|
status: () => { |
||||||
|
const enabled = logger.isDebugEnabled() |
||||||
|
console.log(`🔧 Jumble debug status: ${enabled ? 'ENABLED' : 'DISABLED'}`) |
||||||
|
return { enabled, level: enabled ? 'debug' : 'info' } |
||||||
|
}, |
||||||
|
|
||||||
|
log: (message: string, ...args: any[]) => { |
||||||
|
logger.debug(message, ...args) |
||||||
|
}, |
||||||
|
|
||||||
|
warn: (message: string, ...args: any[]) => { |
||||||
|
logger.warn(message, ...args) |
||||||
|
}, |
||||||
|
|
||||||
|
error: (message: string, ...args: any[]) => { |
||||||
|
logger.error(message, ...args) |
||||||
|
}, |
||||||
|
|
||||||
|
perf: (message: string, ...args: any[]) => { |
||||||
|
logger.perf(message, ...args) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Expose debug utilities globally in development
|
||||||
|
if (import.meta.env.DEV) { |
||||||
|
;(window as any).jumbleDebug = debugUtils |
||||||
|
} |
||||||
|
|
||||||
|
export default debugUtils |
||||||
@ -0,0 +1,114 @@ |
|||||||
|
/** |
||||||
|
* Centralized logging utility to reduce console noise and improve performance |
||||||
|
*
|
||||||
|
* Usage: |
||||||
|
* - Use logger.debug() for development debugging (only shows in dev mode) |
||||||
|
* - Use logger.info() for important information (always shows) |
||||||
|
* - Use logger.warn() for warnings (always shows) |
||||||
|
* - Use logger.error() for errors (always shows) |
||||||
|
*
|
||||||
|
* In production builds, debug logs are completely removed to improve performance. |
||||||
|
*/ |
||||||
|
|
||||||
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' |
||||||
|
|
||||||
|
interface LoggerConfig { |
||||||
|
level: LogLevel |
||||||
|
enableDebug: boolean |
||||||
|
enablePerformance: boolean |
||||||
|
} |
||||||
|
|
||||||
|
class Logger { |
||||||
|
private config: LoggerConfig |
||||||
|
|
||||||
|
constructor() { |
||||||
|
// In production, disable debug logging for better performance
|
||||||
|
const isDev = import.meta.env.DEV |
||||||
|
const isDebugEnabled = isDev && (localStorage.getItem('jumble-debug') === 'true' || import.meta.env.VITE_DEBUG === 'true') |
||||||
|
|
||||||
|
this.config = { |
||||||
|
level: isDebugEnabled ? 'debug' : 'info', |
||||||
|
enableDebug: isDebugEnabled, |
||||||
|
enablePerformance: isDev |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private shouldLog(level: LogLevel): boolean { |
||||||
|
const levels = ['debug', 'info', 'warn', 'error'] |
||||||
|
const currentLevelIndex = levels.indexOf(this.config.level) |
||||||
|
const messageLevelIndex = levels.indexOf(level) |
||||||
|
return messageLevelIndex >= currentLevelIndex |
||||||
|
} |
||||||
|
|
||||||
|
private formatMessage(level: LogLevel, message: string, ...args: any[]): [string, ...any[]] { |
||||||
|
const timestamp = new Date().toISOString().substring(11, 23) // HH:mm:ss.SSS
|
||||||
|
const prefix = `[${timestamp}] [${level.toUpperCase()}]` |
||||||
|
return [`${prefix} ${message}`, ...args] |
||||||
|
} |
||||||
|
|
||||||
|
debug(message: string, ...args: any[]): void { |
||||||
|
if (!this.config.enableDebug || !this.shouldLog('debug')) return |
||||||
|
console.log(...this.formatMessage('debug', message, ...args)) |
||||||
|
} |
||||||
|
|
||||||
|
info(message: string, ...args: any[]): void { |
||||||
|
if (!this.shouldLog('info')) return |
||||||
|
console.log(...this.formatMessage('info', message, ...args)) |
||||||
|
} |
||||||
|
|
||||||
|
warn(message: string, ...args: any[]): void { |
||||||
|
if (!this.shouldLog('warn')) return |
||||||
|
console.warn(...this.formatMessage('warn', message, ...args)) |
||||||
|
} |
||||||
|
|
||||||
|
error(message: string, ...args: any[]): void { |
||||||
|
if (!this.shouldLog('error')) return |
||||||
|
console.error(...this.formatMessage('error', message, ...args)) |
||||||
|
} |
||||||
|
|
||||||
|
// Performance logging for development
|
||||||
|
perf(message: string, ...args: any[]): void { |
||||||
|
if (!this.config.enablePerformance) return |
||||||
|
console.log(`[PERF] ${message}`, ...args) |
||||||
|
} |
||||||
|
|
||||||
|
// Group logging for related operations
|
||||||
|
group(label: string, fn: () => void): void { |
||||||
|
if (!this.config.enableDebug) { |
||||||
|
fn() |
||||||
|
return |
||||||
|
} |
||||||
|
console.group(label) |
||||||
|
fn() |
||||||
|
console.groupEnd() |
||||||
|
} |
||||||
|
|
||||||
|
// Conditional logging based on environment
|
||||||
|
dev(message: string, ...args: any[]): void { |
||||||
|
if (import.meta.env.DEV) { |
||||||
|
console.log(message, ...args) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Enable/disable debug mode at runtime
|
||||||
|
setDebugMode(enabled: boolean): void { |
||||||
|
this.config.enableDebug = enabled |
||||||
|
this.config.level = enabled ? 'debug' : 'info' |
||||||
|
localStorage.setItem('jumble-debug', enabled.toString()) |
||||||
|
} |
||||||
|
|
||||||
|
// Check if debug mode is enabled
|
||||||
|
isDebugEnabled(): boolean { |
||||||
|
return this.config.enableDebug |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Create singleton instance
|
||||||
|
const logger = new Logger() |
||||||
|
|
||||||
|
// Expose debug toggle for development
|
||||||
|
if (import.meta.env.DEV) { |
||||||
|
;(window as any).jumbleLogger = logger |
||||||
|
} |
||||||
|
|
||||||
|
export default logger |
||||||
Loading…
Reference in new issue