Skip to content

Commit

Permalink
fix: Add settings for finer control over debug log level (#22426)
Browse files Browse the repository at this point in the history
* Add settings for finer control over debug log level.

* Updates from feedback.
  • Loading branch information
Nerivec authored May 5, 2024
1 parent b754b9d commit eb49f52
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 39 deletions.
36 changes: 18 additions & 18 deletions lib/extension/bind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import utils from '../util/utils';
import Extension from './extension';
import stringify from 'json-stable-stringify-without-jsonify';
import debounce from 'debounce';
import * as zigbeeHerdsman from 'zigbee-herdsman/dist';
import {Zcl} from 'zigbee-herdsman';
import bind from 'bind-decorator';
import Device from '../model/device';
import Group from '../model/group';
Expand Down Expand Up @@ -97,12 +97,12 @@ const pollOnMessage: PollOnMessage = [
read: {cluster: 'genLevelCtrl', attributes: ['currentLevel']},
// When the bound devices/members of group have the following manufacturerIDs
manufacturerIDs: [
zigbeeHerdsman.Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
zigbeeHerdsman.Zcl.ManufacturerCode.ATMEL,
zigbeeHerdsman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHerdsman.Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
zigbeeHerdsman.Zcl.ManufacturerCode.TELINK_MICRO,
zigbeeHerdsman.Zcl.ManufacturerCode.BUSCH_JAEGER_ELEKTRO,
Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
Zcl.ManufacturerCode.ATMEL,
Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
Zcl.ManufacturerCode.TELINK_MICRO,
Zcl.ManufacturerCode.BUSCH_JAEGER_ELEKTRO,
],
manufacturerNames: [
'GLEDOPTO',
Expand Down Expand Up @@ -133,12 +133,12 @@ const pollOnMessage: PollOnMessage = [
},
read: {cluster: 'genOnOff', attributes: ['onOff']},
manufacturerIDs: [
zigbeeHerdsman.Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
zigbeeHerdsman.Zcl.ManufacturerCode.ATMEL,
zigbeeHerdsman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHerdsman.Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
zigbeeHerdsman.Zcl.ManufacturerCode.TELINK_MICRO,
zigbeeHerdsman.Zcl.ManufacturerCode.BUSCH_JAEGER_ELEKTRO,
Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
Zcl.ManufacturerCode.ATMEL,
Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
Zcl.ManufacturerCode.TELINK_MICRO,
Zcl.ManufacturerCode.BUSCH_JAEGER_ELEKTRO,
],
manufacturerNames: [
'GLEDOPTO',
Expand All @@ -165,11 +165,11 @@ const pollOnMessage: PollOnMessage = [
},
},
manufacturerIDs: [
zigbeeHerdsman.Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
zigbeeHerdsman.Zcl.ManufacturerCode.ATMEL,
zigbeeHerdsman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHerdsman.Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
zigbeeHerdsman.Zcl.ManufacturerCode.TELINK_MICRO,
Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
Zcl.ManufacturerCode.ATMEL,
Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
Zcl.ManufacturerCode.TELINK_MICRO,
// Note: ManufacturerCode.BUSCH_JAEGER is left out intentionally here as their devices don't support colors
],
manufacturerNames: [
Expand Down
51 changes: 36 additions & 15 deletions lib/extension/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,40 @@ export default class Bridge extends Extension {
'config/log_level': this.configLogLevel,
};

const mqtt = this.mqtt;
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
class EventTransport extends Transport {
log(info: {message: string, level: string}, next: () => void): void {
if (info.level !== 'debug') {
const payload = stringify({message: info.message, level: info.level});
if (payload !== self.lastBridgeLoggingPayload) {
self.lastBridgeLoggingPayload = payload;
mqtt.publish(`bridge/logging`, payload, {}, settings.get().mqtt.base_topic, true);
const debugToMQTTFrontend = settings.get().advanced.log_debug_to_mqtt_frontend;
const baseTopic = settings.get().mqtt.base_topic;

const bridgeLogging = (message: string, level: string, namespace: string): void => {
const payload = stringify({message, level, namespace});

if (payload !== this.lastBridgeLoggingPayload) {
this.lastBridgeLoggingPayload = payload;
this.mqtt.publish(`bridge/logging`, payload, {}, baseTopic, true);
}
};

if (debugToMQTTFrontend) {
class DebugEventTransport extends Transport {
log(info: {message: string, level: string, namespace: string}, next: () => void): void {
bridgeLogging(info.message, info.level, info.namespace);
next();
}
}

this.logTransport = new DebugEventTransport();
} else {
class EventTransport extends Transport {
log(info: {message: string, level: string, namespace: string}, next: () => void): void {
if (info.level !== 'debug') {
bridgeLogging(info.message, info.level, info.namespace);
}
next();
}
next();
}

this.logTransport = new EventTransport();
}

this.logTransport = new EventTransport();
logger.addTransport(this.logTransport);

this.zigbee2mqttVersion = await utils.getZigbee2MQTTVersion();
Expand Down Expand Up @@ -174,18 +191,22 @@ export default class Bridge extends Extension {
if (restartRequired) this.restartRequired = true;

// Apply some settings on-the-fly.
if (newSettings.hasOwnProperty('permit_join')) {
if (newSettings.permit_join != undefined) {
await this.zigbee.permitJoin(newSettings.permit_join);
}

if (newSettings.hasOwnProperty('homeassistant')) {
if (newSettings.homeassistant != undefined) {
await this.enableDisableExtension(newSettings.homeassistant, 'HomeAssistant');
}

if (newSettings.hasOwnProperty('advanced') && newSettings.advanced.hasOwnProperty('log_level')) {
if (newSettings.advanced?.log_level != undefined) {
logger.setLevel(newSettings.advanced.log_level);
}

if (newSettings.advanced?.log_debug_namespace_ignore != undefined) {
logger.setDebugNamespaceIgnore(newSettings.advanced.log_debug_namespace_ignore);
}

logger.info('Successfully changed options');
this.publishInfo();
return utils.getResponse(message, {restart_required: this.restartRequired}, null);
Expand Down
2 changes: 2 additions & 0 deletions lib/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ declare global {
log_file: string,
log_level: 'debug' | 'info' | 'error' | 'warn',
log_syslog: KeyValue,
log_debug_to_mqtt_frontend: boolean,
log_debug_namespace_ignore: string,
pan_id: number | 'GENERATE',
ext_pan_id: number[] | 'GENERATE',
channel: number,
Expand Down
14 changes: 14 additions & 0 deletions lib/util/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Logger {
private readonly directory: string;
private readonly logger: winston.Logger;
private readonly fileTransport: winston.transports.FileTransportInstance;
private debugNamespaceIgnoreRegex?: RegExp;

constructor() {
// What transports to enable
Expand Down Expand Up @@ -120,6 +121,8 @@ class Logger {
this.logger.add(new winston.transports.Syslog(options));
}

this.setDebugNamespaceIgnore(settings.get().advanced.log_debug_namespace_ignore);

this.info(logging);
}

Expand All @@ -136,6 +139,14 @@ class Logger {
this.logger.remove(transport);
}

public getDebugNamespaceIgnore(): string {
return this.debugNamespaceIgnoreRegex?.toString().slice(1, -1)/* remove slashes */ ?? '';
}

public setDebugNamespaceIgnore(value: string): void {
this.debugNamespaceIgnoreRegex = value != '' ? new RegExp(value) : undefined;
}

// TODO refactor Z2M level to 'warning' to simplify logic
public getLevel(): LogLevel | 'warn' {
return this.level === 'warning' ? 'warn' : this.level;
Expand All @@ -162,6 +173,9 @@ class Logger {
if (this.level !== 'debug') {
return;
}
if (this.debugNamespaceIgnoreRegex?.test(namespace)) {
return;
}

this.logger.debug(message, {namespace});
}
Expand Down
17 changes: 17 additions & 0 deletions lib/util/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,23 @@
"description": "Logging level",
"default": "info"
},
"log_debug_to_mqtt_frontend": {
"type": "boolean",
"title": "Log debug to MQTT and frontend",
"description": "Log debug level to MQTT and frontend (may decrease overall performance)",
"requiresRestart": true,
"default": false
},
"log_debug_namespace_ignore": {
"type": "string",
"title": "Log debug namespace ignore",
"description": "Do not log these namespaces (regex-based) for debug level",
"default": "",
"examples": [
"^zhc:legacy:fz:(tuya|moes)",
"^zhc:legacy:fz:(tuya|moes)|^zh:ember:uart:|^zh:controller"
]
},
"log_syslog": {
"type": "object",
"title": "syslog",
Expand Down
2 changes: 2 additions & 0 deletions lib/util/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ const defaults: RecursivePartial<Settings> = {
log_file: 'log.log',
log_level: /* istanbul ignore next */ process.env.DEBUG ? 'debug' : 'info',
log_syslog: {},
log_debug_to_mqtt_frontend: false,
log_debug_namespace_ignore: '',
pan_id: 0x1a62,
ext_pan_id: [0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD],
channel: 11,
Expand Down
Loading

0 comments on commit eb49f52

Please sign in to comment.