diff --git a/docs/api/driver.md b/docs/api/driver.md index e5e54edaea30..3da95dd28986 100644 --- a/docs/api/driver.md +++ b/docs/api/driver.md @@ -286,6 +286,7 @@ interface LogConfig { level: number; transports: Transport[]; logToFile: boolean; + nodeFilter?: number[]; filename: string; forceConsole: boolean; } @@ -295,6 +296,7 @@ interface LogConfig { - `level`: The numeric loglevel (like the `npm` [loglevels](https://github.com/winstonjs/triple-beam/blob/master/config/npm.js)), ranging from `0` (error) to `6` (silly). Default: `5` (debug) or whatever is configured with the `LOGLEVEL` environment variable. - `transports`: Custom [`winston`](https://github.com/winstonjs/winston) log transports. Setting this property will override all configured and default transports. Use `getConfiguredTransports()` if you want to extend the default transports. Default: console transport if `logToFile` is `false`, otherwise a file transport. - `logToFile`: Whether the log should go to a file instead of the console. Default: `false` or whatever is configured with the `LOGTOFILE` environment variable. +- `nodeFilter`: If set, only messages regarding the given node IDs are logged - `filename`: When `logToFile` is `true`, this is the path to the log file. The default file is called `zwave-${process.pid}.log` and located in the same directory as the main executable. - `forceConsole`: By default, `zwave-js` does not log to the console if it is not a TTY in order to reduce the CPU load. By setting this option to `true`, the TTY check will be skipped and all logs will be printed to the console, **except if `logToFile` is `true`**. Default: `false`. diff --git a/packages/core/src/log/shared.ts b/packages/core/src/log/shared.ts index 80715952788b..3a18c4bd6431 100644 --- a/packages/core/src/log/shared.ts +++ b/packages/core/src/log/shared.ts @@ -87,10 +87,19 @@ export interface LogConfig { level: number; transports: Transport[]; logToFile: boolean; + nodeFilter?: number[]; filename: string; forceConsole: boolean; } +function stringToNodeList(nodes?: string): number[] | undefined { + if (!nodes) return undefined; + return nodes + .split(",") + .map((n) => parseInt(n)) + .filter((n) => !Number.isNaN(n)); +} + export class ZWaveLogContainer extends winston.Container { private fileTransport: Transport | undefined; private consoleTransport: Transport | undefined; @@ -100,6 +109,7 @@ export class ZWaveLogContainer extends winston.Container { enabled: true, level: getTransportLoglevelNumeric(), logToFile: !!process.env.LOGTOFILE, + nodeFilter: stringToNodeList(process.env.LOG_NODES), transports: undefined as any, filename: require.main ? path.join( @@ -329,6 +339,15 @@ export class ZWaveLogContainer extends winston.Container { silent: this.isFileTransportSilent(), }); } + + /** + * Checks the log configuration whether logs should be written for a given node id + */ + public shouldLogNode(nodeId: number): boolean { + // If no filters are set, every node gets logged + if (!this.logConfig.nodeFilter) return true; + return this.logConfig.nodeFilter.includes(nodeId); + } } function getTransportLoglevel(): string { @@ -338,16 +357,6 @@ function getTransportLoglevelNumeric(): number { return loglevels[getTransportLoglevel()]; } -/** - * Checks the LOG_NODES env variable whether logs should be written for a given node id - */ -export function shouldLogNode(nodeId: number): boolean { - const activeFilters = (process.env.LOG_NODES ?? "*").split(","); - if (activeFilters.includes("*")) return true; - if (activeFilters.includes(nodeId.toString())) return true; - return false; -} - /** * Calculates the length the first line of a log message would occupy if it is not split * @param info The message and information to log diff --git a/packages/zwave-js/src/lib/log/Controller.ts b/packages/zwave-js/src/lib/log/Controller.ts index 3a21db0e45eb..35abdd488642 100644 --- a/packages/zwave-js/src/lib/log/Controller.ts +++ b/packages/zwave-js/src/lib/log/Controller.ts @@ -3,7 +3,6 @@ import { DataDirection, getDirectionPrefix, getNodeTag, - shouldLogNode, tagify, ValueAddedArgs, ValueID, @@ -101,7 +100,7 @@ export class ControllerLogger extends ZWaveLoggerBase { const { level, message, direction, endpoint } = messageOrOptions; const actualLevel = level || CONTROLLER_LOGLEVEL; if (!this.container.isLoglevelVisible(actualLevel)) return; - if (!shouldLogNode(nodeId)) return; + if (!this.container.shouldLogNode(nodeId)) return; this.logger.log({ level: actualLevel, @@ -222,7 +221,7 @@ export class ControllerLogger extends ZWaveLoggerBase { /** Logs the interview progress of a node */ public interviewStage(node: ZWaveNode): void { if (!this.isControllerLogVisible()) return; - if (!shouldLogNode(node.id)) return; + if (!this.container.shouldLogNode(node.id)) return; this.logger.log({ level: CONTROLLER_LOGLEVEL, @@ -240,7 +239,7 @@ export class ControllerLogger extends ZWaveLoggerBase { /** Logs the interview progress of a node */ public interviewStart(node: ZWaveNode): void { if (!this.isControllerLogVisible()) return; - if (!shouldLogNode(node.id)) return; + if (!this.container.shouldLogNode(node.id)) return; const message = `Beginning interview - last completed stage: ${ InterviewStage[node.interviewStage] diff --git a/packages/zwave-js/src/lib/log/Driver.ts b/packages/zwave-js/src/lib/log/Driver.ts index 76320af7559f..e081b6649294 100644 --- a/packages/zwave-js/src/lib/log/Driver.ts +++ b/packages/zwave-js/src/lib/log/Driver.ts @@ -3,7 +3,6 @@ import { DataDirection, getDirectionPrefix, messageRecordToLines, - shouldLogNode, tagify, ZWaveLogContainer, ZWaveLoggerBase, @@ -124,7 +123,9 @@ export class DriverLogger extends ZWaveLoggerBase { ): void { if (!this.isDriverLogVisible()) return; if (nodeId == undefined) nodeId = message.getNodeId(); - if (nodeId != undefined && !shouldLogNode(nodeId)) return; + if (nodeId != undefined && !this.container.shouldLogNode(nodeId)) { + return; + } const isCCContainer = isCommandClassContainer(message); const logEntry = message.toLogEntry();