-
Notifications
You must be signed in to change notification settings - Fork 0
2.3 Logging System
ClioDeck has two separate loggers, and they behave differently — this page previously covered only one of them.
-
@shared/logger(src/shared/logger.ts) — used in the renderer (stores, components). Everything below this section describes it: environment-based filtering,CLIODESK_DEBUG/CLIODESK_LOG_LEVEL, emoji-prefixed contextual output. -
src/main/utils/logger.ts— used throughout the main process (IPC handlers, services). Different API (logger.info(module, action, data)), different output format ([2026-…] INFO [ipc] fs:read-directory {...}), and — important — it does not readCLIODESK_LOG_LEVELor any other env var. It hardcodeslevel = 'info'and nothing in the codebase ever calls itssetLevel(). SettingCLIODESK_LOG_LEVEL=debugraises verbosity in the renderer only; main-processdebug-level logs from IPC handlers stay suppressed regardless.
If you're debugging something in src/main/ (IPC, services), the env vars below won't help — there is currently no way to raise that logger's level short of editing src/main/utils/logger.ts.
| Environment | console.log | console.info | console.warn | console.error |
|---|---|---|---|---|
| Development | Shown | Shown | Shown | Shown |
| Production | Filtered | Filtered | Shown | Shown |
In production, only console.warn and console.error are displayed to reduce console noise.
# macOS / Linux
CLIODESK_DEBUG=1 /path/to/ClioDeck.app/Contents/MacOS/ClioDeck
# Windows
set CLIODESK_DEBUG=1
"C:\Program Files\ClioDeck\ClioDeck.exe"# Available levels: debug, info, warn, error
CLIODESK_LOG_LEVEL=debug /path/to/ClioDeckDEBUG=1 /path/to/ClioDeckBy default, Electron DevTools are disabled in production.
To enable them, use the same environment variables:
# macOS / Linux
CLIODESK_DEBUG=1 /path/to/ClioDeck.app/Contents/MacOS/ClioDeck
# Windows
set CLIODESK_DEBUG=1
"C:\Program Files\ClioDeck\ClioDeck.exe"This enables both:
- Debug logs (
console.log,console.info) - Electron DevTools
For new development, use the centralized logger instead of console.log:
import { logger } from '@shared/logger';
// With explicit context
logger.debug('MyService', 'Debug message', { data });
logger.info('MyService', 'Important information');
logger.warn('MyService', 'Warning');
logger.error('MyService', 'Error', error);
// Or create a contextual logger
const log = logger.createContextLogger('MyService');
log.debug('Debug message');
log.info('Information');
log.warn('Warning');
log.error('Error', error);- Consistent format with emojis and context:
[MyService] Message - Automatic respect of configured log levels
- Typed methods for TypeScript
For code under src/main/ (IPC handlers, services), use the separate main-process logger instead:
import { logger } from '../../utils/logger.js';
logger.info('ipc', 'fs:read-directory', { dirPath });
logger.error('ipc', 'fs:read-directory', { error: error.message });
// Measuring duration:
const elapsed = logger.startTimer();
await someWork();
logger.info('ipc', 'pdf:index', { durationMs: elapsed() });Output: [2026-02-19T20:00:00.000Z] INFO [ipc] fs:read-directory { dirPath: "/home/user" }. Level defaults to info and cannot currently be changed at runtime — see the caveat above.
src/shared/
├── logger.ts # Renderer logger, env-var-controlled levels
└── console-filter.ts # Automatic console.* filter in production
src/main/utils/
└── logger.ts # Main-process logger, fixed at 'info', no env var
The console filter is automatically imported at application startup:
- Main process:
src/main/index.ts - Renderer process:
src/renderer/src/main.tsx
Environment is automatically detected via:
process.env.NODE_ENV === 'production'process.env.ELECTRON_IS_PACKAGED === 'true'
import { restoreConsole, rawConsole } from '@shared/console-filter';
// Restore all console.*
restoreConsole();
// Or use rawConsole to bypass filter
rawConsole.log('This message will always be displayed');import { getFilterStatus } from '@shared/console-filter';
const status = getFilterStatus();
console.log(status);
// { isProduction: true, isDebugEnabled: false, isFiltering: true }