Skip to content

Commit 8b68171

Browse files
feat: add configurable logLevel to install options (#283)
* feat: add configurable logger with `quiet` mode and `ignoreLogs` support * docs: update README.md * fix: types * docs: add examples for install options * chore: use `logLevel` instead * docs: update `install` options in README.md * docs: minor change * chore: use enums --------- Co-authored-by: David Sanders <[email protected]>
1 parent 3ca688b commit 8b68171

File tree

4 files changed

+107
-10
lines changed

4 files changed

+107
-10
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,23 @@ if (isDev) {
4444

4545
## Devtron API
4646

47-
### `await devtron.install()`
47+
### `await devtron.install(options)`
4848

4949
Installs Devtron into the Electron app. Refer to [Configuring an Electron App to use Devtron](#configuring-an-electron-app-to-use-devtron) for installation instructions.
5050

51+
#### `Options`
52+
53+
| Option | Type | Default | Description |
54+
| ---------- | -------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
55+
| `logLevel` | `'debug' \| 'info' \| 'warn' \| 'error' \| 'none'` | `'debug'` | Sets the minimum log level for the logger. Messages below this level are ignored. <br><br> **Levels:** <br>• `debug` — logs: debug, info, warn, error <br>• `info` — logs: info, warn, error <br>• `warn` — logs: warn, error <br>• `error` — logs: error only <br>• `none` — disables all logging |
56+
57+
Examples:
58+
59+
```js
60+
// Only 'warn' and 'error' logs will appear in the terminal
61+
await devtron.install({ logLevel: 'warn' });
62+
```
63+
5164
### `await devtron.getEvents()`
5265

5366
Returns a **promise** that resolves to the array of IPC events recorded by the Devtron service worker since installation.

src/index.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { createRequire } from 'node:module';
44
import type {
55
Channel,
66
Direction,
7+
InstallOptions,
78
IpcEventData,
89
IpcEventDataIndexed,
910
ServiceWorkerDetails,
1011
} from './types/shared';
1112
import { excludedIpcChannels } from './common/constants';
13+
import { logger } from './utils/Logger';
1214

1315
interface TrackIpcEventOptions {
1416
direction: Direction;
@@ -65,7 +67,7 @@ function trackIpcEvent({
6567
if (excludedIpcChannels.includes(channel)) return;
6668

6769
if (!devtronSW) {
68-
console.error('The service-worker for Devtron is not registered yet. Cannot track IPC event.');
70+
logger.warn('The service-worker for Devtron is not registered yet. Cannot track IPC event.');
6971
return;
7072
}
7173

@@ -208,7 +210,7 @@ async function startServiceWorker(ses: Electron.Session, extension: Electron.Ext
208210
registerIpcListeners(ses, sw);
209211
registerServiceWorkerSendListener(ses, sw);
210212
} catch (error) {
211-
console.warn(`Failed to start Devtron service-worker (${error}), trying again...`);
213+
logger.warn(`Failed to start Devtron service-worker (${error}), trying again...`);
212214
/**
213215
* This is a workaround for the issue where the Devtron service-worker fails to start
214216
* when the Electron app is launched for the first time, or when the service worker
@@ -226,12 +228,12 @@ async function startServiceWorker(ses: Electron.Session, extension: Electron.Ext
226228
registerIpcListeners(ses, sw);
227229
registerServiceWorkerSendListener(ses, sw);
228230
ses.serviceWorkers.removeListener('registration-completed', handleDetails);
229-
console.log(`Devtron service-worker started successfully`);
231+
logger.info(`Devtron service-worker started successfully`);
230232
}
231233
};
232234
ses.serviceWorkers.on('registration-completed', handleDetails);
233235
} catch (error) {
234-
console.error('Failed to start Devtron service-worker:', error);
236+
logger.error('Failed to start Devtron service-worker:', error);
235237
}
236238
}
237239
}
@@ -373,10 +375,13 @@ function patchIpcMain() {
373375
};
374376
}
375377

376-
async function install() {
378+
async function install(options: InstallOptions = {}) {
377379
if (isInstalled) return;
378380
isInstalled = true;
379381

382+
// set log level
383+
if (options.logLevel) logger.setLogLevel(options.logLevel);
384+
380385
patchIpcMain();
381386

382387
const installToSession = async (ses: Electron.Session) => {
@@ -410,9 +415,9 @@ async function install() {
410415
const extensionPath = path.resolve(serviceWorkerPreloadPath, '..', '..', 'extension');
411416
devtron = await ses.extensions.loadExtension(extensionPath, { allowFileAccess: true });
412417
await startServiceWorker(ses, devtron);
413-
console.log('Devtron loaded successfully');
418+
logger.info('Devtron loaded successfully');
414419
} catch (error) {
415-
console.error('Failed to load Devtron:', error);
420+
logger.error('Failed to load Devtron:', error);
416421
}
417422
};
418423

@@ -430,12 +435,12 @@ async function install() {
430435
*/
431436
async function getEvents(): Promise<IpcEventDataIndexed[]> {
432437
if (!isInstalled) {
433-
console.warn('You are trying to get IPC events before Devtron is installed.');
438+
logger.warn('You are trying to get IPC events before Devtron is installed.');
434439
return [];
435440
}
436441

437442
if (!devtronSW) {
438-
console.warn('Devtron service-worker is not registered yet. Cannot get IPC events.');
443+
logger.warn('Devtron service-worker is not registered yet. Cannot get IPC events.');
439444
return [];
440445
}
441446

src/types/shared.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,33 @@ export interface IpcEventData {
2727
uuid?: UUID; // UUID to match requests and responses (for `invoke` and `sendSync` methods on `ipcRenderer`)
2828
}
2929

30+
export type LogLevelString = 'debug' | 'info' | 'warn' | 'error' | 'none';
31+
32+
export enum LogLevel {
33+
debug,
34+
info,
35+
warn,
36+
error,
37+
none,
38+
}
39+
40+
export interface InstallOptions {
41+
/**
42+
* Sets the minimum log level for the logger.
43+
* All messages below the specified level will be ignored.
44+
*
45+
* Available levels:
46+
* - 'debug' — logs: debug, info, warn, error
47+
* - 'info' — logs: info, warn, error
48+
* - 'warn' — logs: warn, error
49+
* - 'error' — logs: error only
50+
* - 'none' — disables all logging
51+
*
52+
* @default 'debug'
53+
*/
54+
logLevel?: LogLevelString;
55+
}
56+
3057
/* ------------------------------------------------------ */
3158

3259
/* ---------------------- EXTENSION --------------------- */

src/utils/Logger.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { LogLevelString } from '../types/shared';
2+
import { LogLevel } from '../types/shared';
3+
4+
class Logger {
5+
private currentLogLevel = LogLevel.debug;
6+
7+
setLogLevel(level: LogLevelString) {
8+
if (LogLevel[level] === undefined) {
9+
console.error(`Invalid log level: ${level}`);
10+
return;
11+
}
12+
13+
if (LogLevel[level] === this.currentLogLevel) return; // no change
14+
15+
this.currentLogLevel = LogLevel[level];
16+
}
17+
18+
private log(level: LogLevel, ...args: any[]) {
19+
if (this.currentLogLevel === LogLevel.none) return;
20+
if (level < this.currentLogLevel) return;
21+
22+
switch (level) {
23+
case LogLevel.debug:
24+
console.debug(...args);
25+
break;
26+
case LogLevel.info:
27+
console.log(...args);
28+
break;
29+
case LogLevel.warn:
30+
console.warn(...args);
31+
break;
32+
case LogLevel.error:
33+
console.error(...args);
34+
break;
35+
}
36+
}
37+
38+
debug(...args: any[]) {
39+
this.log(LogLevel.debug, ...args);
40+
}
41+
info(...args: any[]) {
42+
this.log(LogLevel.info, ...args);
43+
}
44+
warn(...args: any[]) {
45+
this.log(LogLevel.warn, ...args);
46+
}
47+
error(...args: any[]) {
48+
this.log(LogLevel.error, ...args);
49+
}
50+
}
51+
52+
export const logger = new Logger();

0 commit comments

Comments
 (0)