Skip to content

Commit 7b1787f

Browse files
dceejayknolleary
authored andcommitted
Debug to status option (node-red#1499)
* Let debug optionally target the status line (32 chars only) * Add batching of messages to debug ws comms * let Debug handle simple case of NaN would also close node-red#1530 * Fixup debug tests for batch comms (no new tests yet) * mixup comms/api test to match new batch mode (no new tests) * Add test for NaN being sent OK. * redo original fix to padding / labels for new debug options * fix debug test (re-add fix from node-red#1444) * Fix up merge issues in debug tests
1 parent 7bd8d8c commit 7b1787f

9 files changed

Lines changed: 260 additions & 134 deletions

File tree

editor/js/comms.js

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,31 @@ RED.comms = (function() {
6464
}
6565
}
6666
ws.onmessage = function(event) {
67-
var msg = JSON.parse(event.data);
68-
if (pendingAuth && msg.auth) {
69-
if (msg.auth === "ok") {
70-
pendingAuth = false;
71-
completeConnection();
72-
} else if (msg.auth === "fail") {
73-
// anything else is an error...
74-
active = false;
75-
RED.user.login({updateMenu:true},function() {
76-
connectWS();
77-
})
67+
var message = JSON.parse(event.data);
68+
for (var m = 0; m < message.length; m++) {
69+
var msg = message[m];
70+
if (pendingAuth && msg.auth) {
71+
if (msg.auth === "ok") {
72+
pendingAuth = false;
73+
completeConnection();
74+
} else if (msg.auth === "fail") {
75+
// anything else is an error...
76+
active = false;
77+
RED.user.login({updateMenu:true},function() {
78+
connectWS();
79+
})
80+
}
7881
}
79-
} else if (msg.topic) {
80-
for (var t in subscriptions) {
81-
if (subscriptions.hasOwnProperty(t)) {
82-
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
83-
if (re.test(msg.topic)) {
84-
var subscribers = subscriptions[t];
85-
if (subscribers) {
86-
for (var i=0;i<subscribers.length;i++) {
87-
subscribers[i](msg.topic,msg.data);
82+
else if (msg.topic) {
83+
for (var t in subscriptions) {
84+
if (subscriptions.hasOwnProperty(t)) {
85+
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
86+
if (re.test(msg.topic)) {
87+
var subscribers = subscriptions[t];
88+
if (subscribers) {
89+
for (var i=0;i<subscribers.length;i++) {
90+
subscribers[i](msg.topic,msg.data);
91+
}
8892
}
8993
}
9094
}

nodes/core/core/58-debug.html

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,22 @@
66
<input id="node-input-complete" type="hidden">
77
</div>
88
<div class="form-row">
9-
<label for="node-input-console"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
10-
<select type="text" id="node-input-console" style="display: inline-block; width: 250px; vertical-align: top;">
11-
<option value="false" data-i18n="debug.debtab"></option>
12-
<option value="true" data-i18n="debug.tabcon"></option>
13-
</select>
9+
<label for="node-input-tosidebar"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
10+
<label for="node-input-tosidebar" style="width:70%">
11+
<input type="checkbox" id="node-input-tosidebar" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toSidebar"></span>
12+
</label>
13+
</div>
14+
<div class="form-row">
15+
<label for="node-input-console"> </label>
16+
<label for="node-input-console" style="width:70%">
17+
<input type="checkbox" id="node-input-console" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toConsole"></span>
18+
</label>
19+
</div>
20+
<div class="form-row" id="node-tostatus-line">
21+
<label for="node-input-tostatus"> </label>
22+
<label for="node-input-tostatus" style="width:70%">
23+
<input type="checkbox" id="node-input-tostatus" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toStatus"></span>
24+
</label>
1425
</div>
1526
<div class="form-row">
1627
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
@@ -26,7 +37,7 @@ <h3>Details</h3>
2637
<p>Alongside each message, the debug sidebar includes information about the time the message was received, the node that sent it and the type of the message.
2738
Clicking on the source node id will reveal that node within the workspace.</p>
2839
<p>The button on the node can be used to enable or disable its output. It is recommended to disable or remove any Debug nodes that are not being used.</p>
29-
<p>The node can also be configured to send all messages to the runtime log.</p>
40+
<p>The node can also be configured to send all messages to the runtime log, or to send short (32 characters) to the status text under the debug node.</p>
3041
</script>
3142
<script src="debug/view/debug-utils.js"></script>
3243

@@ -38,7 +49,9 @@ <h3>Details</h3>
3849
defaults: {
3950
name: {value:""},
4051
active: {value:true},
41-
console: {value:"false"},
52+
tosidebar: {value:true},
53+
console: {value:false},
54+
tostatus: {value:false},
4255
complete: {value:"false", required:true}
4356
},
4457
label: function() {
@@ -100,7 +113,6 @@ <h3>Details</h3>
100113
}
101114
},
102115
onpaletteadd: function() {
103-
104116
var options = {
105117
messageMouseEnter: function(sourceId) {
106118
if (sourceId) {
@@ -148,7 +160,7 @@ <h3>Details</h3>
148160

149161
var that = this;
150162
RED._debug = function(msg) {
151-
that.handleDebugMessage("",{
163+
that.handleDebugMessage("", {
152164
name:"debug",
153165
msg:msg
154166
});
@@ -170,7 +182,6 @@ <h3>Details</h3>
170182
var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
171183
if (sourceNode) {
172184
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name};
173-
174185
}
175186
RED.debug.handleDebugMessage(o);
176187
if (subWindow) {
@@ -225,6 +236,15 @@ <h3>Details</h3>
225236
delete RED._debug;
226237
},
227238
oneditprepare: function() {
239+
if (this.tosidebar === undefined) {
240+
this.tosidebar = true;
241+
$("#node-input-tosidebar").prop('checked', true);
242+
}
243+
if (typeof this.console === "string") {
244+
this.console = (this.console == 'true');
245+
$("#node-input-console").prop('checked', this.console);
246+
$("#node-input-tosidebar").prop('checked', true);
247+
}
228248
$("#node-input-typed-complete").typedInput({types:['msg', {value:"full",label:RED._("node-red:debug.msgobj"),hasValue:false}]});
229249
if (this.complete === "true" || this.complete === true) {
230250
// show complete message object
@@ -240,6 +260,16 @@ <h3>Details</h3>
240260
) {
241261
$("#node-input-typed-complete").typedInput('value','payload');
242262
}
263+
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
264+
$("#node-tostatus-line").show();
265+
}
266+
else { $("#node-tostatus-line").hide(); }
267+
});
268+
$("#node-input-complete").on('change',function() {
269+
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
270+
$("#node-tostatus-line").show();
271+
}
272+
else { $("#node-tostatus-line").hide(); }
243273
});
244274
},
245275
oneditsave: function() {
@@ -250,7 +280,6 @@ <h3>Details</h3>
250280
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
251281
}
252282
}
253-
254283
});
255284
})();
256285
</script>

nodes/core/core/58-debug.js

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,57 @@ module.exports = function(RED) {
55
var events = require("events");
66
var path = require("path");
77
var safeJSONStringify = require("json-stringify-safe");
8-
var debuglength = RED.settings.debugMaxLength||1000;
8+
var debuglength = RED.settings.debugMaxLength || 1000;
99
var useColors = RED.settings.debugUseColors || false;
1010
util.inspect.styles.boolean = "red";
1111

1212
function DebugNode(n) {
1313
RED.nodes.createNode(this,n);
1414
this.name = n.name;
1515
this.complete = (n.complete||"payload").toString();
16-
17-
if (this.complete === "false") {
18-
this.complete = "payload";
19-
}
20-
21-
this.console = n.console;
16+
if (this.complete === "false") { this.complete = "payload"; }
17+
this.console = ""+(n.console || false);
18+
this.tostatus = n.tostatus || false;
19+
this.tosidebar = n.tosidebar;
20+
if (this.tosidebar === undefined) { this.tosidebar = true; }
21+
this.severity = n.severity || 40;
2222
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
23+
this.status({});
24+
2325
var node = this;
26+
var levels = {
27+
off: 1,
28+
fatal: 10,
29+
error: 20,
30+
warn: 30,
31+
info: 40,
32+
debug: 50,
33+
trace: 60,
34+
audit: 98,
35+
metric: 99
36+
};
37+
var colors = {
38+
"0": "grey",
39+
"10": "grey",
40+
"20": "red",
41+
"30": "yellow",
42+
"40": "grey",
43+
"50": "green",
44+
"60": "blue"
45+
};
2446

2547
this.on("input",function(msg) {
2648
if (this.complete === "true") {
27-
// debug complete msg object
49+
// debug complete msg object
2850
if (this.console === "true") {
2951
node.log("\n"+util.inspect(msg, {colors:useColors, depth:10}));
3052
}
31-
if (this.active) {
32-
sendDebug({id:node.id,name:node.name,topic:msg.topic,msg:msg,_path:msg._path});
53+
if (this.active && this.tosidebar) {
54+
sendDebug({id:node.id, name:node.name, topic:msg.topic, msg:msg, _path:msg._path});
3355
}
34-
} else {
35-
// debug user defined msg property
56+
}
57+
else {
58+
// debug user defined msg property
3659
var property = "payload";
3760
var output = msg[property];
3861
if (this.complete !== "false" && typeof this.complete !== "undefined") {
@@ -53,7 +76,15 @@ module.exports = function(RED) {
5376
}
5477
}
5578
if (this.active) {
56-
sendDebug({id:node.id,z:node.z,name:node.name,topic:msg.topic,property:property,msg:output,_path:msg._path});
79+
if (this.tosidebar == true) {
80+
sendDebug({id:node.id, z:node.z, name:node.name, topic:msg.topic, property:property, msg:output, _path:msg._path});
81+
}
82+
if (this.tostatus === true) {
83+
var st = util.inspect(output);
84+
if (st.length > 32) { st = st.substr(0,32) + "..."; }
85+
node.oldStatus = {fill:colors[node.severity], shape:"dot", text:st};
86+
node.status(node.oldStatus);
87+
}
5788
}
5889
}
5990
});
@@ -196,9 +227,14 @@ module.exports = function(RED) {
196227
if (state === "enable") {
197228
node.active = true;
198229
res.sendStatus(200);
230+
if (node.tostatus) { node.status({}); }
199231
} else if (state === "disable") {
200232
node.active = false;
201233
res.sendStatus(201);
234+
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
235+
node.oldStatus.shape = "ring";
236+
node.status(node.oldStatus);
237+
}
202238
} else {
203239
res.sendStatus(404);
204240
}

nodes/core/core/lib/debug/debug-utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,9 @@ RED.debug = (function() {
439439
$('<span class="debug-message-name">'+name+'</span>').appendTo(metaRow);
440440
}
441441

442-
if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
442+
if ((format === 'number') && (payload === "NaN")) {
443+
payload = Number.NaN;
444+
} else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
443445
payload = JSON.parse(payload);
444446
} else if (/error/i.test(format)) {
445447
payload = JSON.parse(payload);

nodes/core/locales/en-US/messages.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,13 @@
103103
"output": "Output",
104104
"msgprop": "message property",
105105
"msgobj": "complete msg object",
106-
"to": "to",
106+
"to": "To",
107107
"debtab": "debug tab",
108108
"tabcon": "debug tab and console",
109+
"toSidebar": "debug window",
110+
"toConsole": "system console",
111+
"toStatus": "node status (32 characters)",
112+
"severity": "Level",
109113
"notification": {
110114
"activated": "Successfully activated: __label__",
111115
"deactivated": "Successfully deactivated: __label__"

red/api/comms.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ function start() {
6363
// https://github.com/websockets/ws/pull/632
6464
// that is fixed in the 1.x release of the ws module
6565
// that we cannot currently pickup as it drops node 0.10 support
66-
perMessageDeflate: false
66+
//perMessageDeflate: false
6767
});
6868

6969
wsServer.on('connection',function(ws) {
@@ -189,15 +189,27 @@ function publish(topic,data,retain) {
189189
}
190190
}
191191

192+
var stack = [];
193+
var ok2tx = true;
192194
function publishTo(ws,topic,data) {
193-
var msg = JSON.stringify({topic:topic,data:data});
194-
try {
195-
ws.send(msg);
196-
} catch(err) {
197-
removeActiveConnection(ws);
198-
removePendingConnection(ws);
199-
log.warn(log._("comms.error-send",{message:err.toString()}));
195+
if (topic && data) { stack.push({topic:topic,data:data}); }
196+
197+
if (ok2tx && (stack.length > 0)) {
198+
ok2tx = false;
199+
try {
200+
ws.send(JSON.stringify(stack));
201+
} catch(err) {
202+
removeActiveConnection(ws);
203+
removePendingConnection(ws);
204+
log.warn(log._("comms.error-send",{message:err.toString()}));
205+
}
206+
stack = [];
207+
var txtout = setTimeout(function() {
208+
ok2tx = true;
209+
publishTo(ws);
210+
}, 50); // TODO: OK so a 50mS update rate should prob not be hard-coded
200211
}
212+
201213
}
202214

203215
function handleRemoteSubscription(ws,topic) {

test/nodes/core/core/20-inject_spec.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,14 @@ describe('inject node', function() {
5151
function() {
5252
var n2 = helper.getNode("n2");
5353
n2.on("input", function(msg) {
54-
msg.should.have.property('topic', 't1');
55-
msg.should.have.property('payload');
56-
should(msg.payload).be.lessThan(timestamp.getTime());
57-
done();
54+
try {
55+
msg.should.have.property('topic', 't1');
56+
msg.should.have.property('payload');
57+
should(msg.payload).be.lessThan(timestamp.getTime());
58+
done();
59+
} catch(err) {
60+
done(err);
61+
}
5862
});
5963
});
6064
});

0 commit comments

Comments
 (0)