@gregoriusrippenstein/node-red-contrib-introspection 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -2
- package/nodes/60-client-code.js +40 -4
- package/package.json +1 -1
- package/plugins/sidebar.html +13 -28
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ The plugin replaces the name with the node Id, resets the nodes info content to
|
|
|
82
82
|
|
|
83
83
|
Sometimes it would be nice to observe the flow of messages through a flow. This is possible by using 'Trace Messages' found at the bottom of the 'Lint' tab:
|
|
84
84
|
|
|
85
|
-

|
|
86
86
|
|
|
87
87
|
Message tracing can be toggled on & off *without* redeploying the flow. So this can be used as a quick check for observing tricky situations.
|
|
88
88
|
|
|
@@ -90,7 +90,19 @@ The nodes status will be replaced by 'msg received', so if the status should be
|
|
|
90
90
|
|
|
91
91
|
Also this is an experimental feature liable to be [enhanced](https://discourse.nodered.org/t/message-tracing-for-beginners/92287).
|
|
92
92
|
|
|
93
|
-
*UPDATE*:
|
|
93
|
+
*UPDATE*:
|
|
94
|
+
|
|
95
|
+
This now has a [treeList](https://nodered.org/docs/api/ui/treeList/) of nodes and how often they received a message. Clicking on the node in the list will highlight the node, double-click will open the nodes edit panel.
|
|
96
|
+
|
|
97
|
+
*UPDATE2*:
|
|
98
|
+
|
|
99
|
+
It is now possible to send all messages to the debug panel. By toggling the 'msg to debug' checkbox, *all messages* will be sent to the Node-RED debug panel. This can be toggled on and off independently of the message tracing. That is, as long as message tracing is activated. It is therefore possible (as shown in the animation above) to active message tracing, then activate msg to debug to have msg appear in the debug panel and then deactive the msg to debug. The message tracing continues unabated.
|
|
100
|
+
|
|
101
|
+
This makes it possible to trace messages, if something critical happens, to activate the msg to debug and then deactivate again. Only those messages that occured in that timeframe are logged.
|
|
102
|
+
|
|
103
|
+
**But remember** all messages are logged to the debug panel, every single message that is sent within Node-RED will be set to the debug panel. This will cause major disappointments for those wishing to have a responsive editor.
|
|
104
|
+
|
|
105
|
+
Also this feature causes **no extra overhead** on the backend server if it is *not in use* - the hooks for capturing the data are removed if this feature is deactivated.
|
|
94
106
|
|
|
95
107
|
## Palette Nodes
|
|
96
108
|
|
package/nodes/60-client-code.js
CHANGED
|
@@ -4,10 +4,12 @@ module.exports = function(RED) {
|
|
|
4
4
|
|
|
5
5
|
const OnReceiveHookName = "onReceive.introspectionMsgTracer"
|
|
6
6
|
const OnPreuninstallHookName = "preUninstall.introspectionMsgTracer"
|
|
7
|
+
const debugLength = RED.settings.debugMaxLength || 1000
|
|
7
8
|
|
|
8
9
|
function msgTracerOnReceiveHook(evnt) {
|
|
9
10
|
try {
|
|
10
11
|
let nde = RED.nodes.getNode(evnt.destination.id)
|
|
12
|
+
|
|
11
13
|
nde.status({ fill: "green", shape: "ring", text: "msg received" })
|
|
12
14
|
setTimeout(() => { nde.status({}) }, 1000)
|
|
13
15
|
|
|
@@ -16,6 +18,31 @@ module.exports = function(RED) {
|
|
|
16
18
|
nodeid: evnt.destination.id
|
|
17
19
|
})
|
|
18
20
|
)
|
|
21
|
+
|
|
22
|
+
return nde
|
|
23
|
+
} catch (ex) {
|
|
24
|
+
console.error(ex)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function msgTracerOnReceiveHookWithDebug(evnt) {
|
|
29
|
+
try {
|
|
30
|
+
let nde = msgTracerOnReceiveHook(evnt)
|
|
31
|
+
|
|
32
|
+
// taken from the [debug node](https://github.com/node-red/node-red/blob/2854351909dee9f92597faba3f37239134294eec/packages/node_modules/%40node-red/nodes/core/common/21-debug.js#L227)
|
|
33
|
+
let msg = {
|
|
34
|
+
id: nde.id,
|
|
35
|
+
z: nde.z,
|
|
36
|
+
_alias: nde._alias,
|
|
37
|
+
path: nde._flow.path,
|
|
38
|
+
name: nde.name,
|
|
39
|
+
topic: evnt.msg.topic,
|
|
40
|
+
msg: evnt.msg
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
msg = RED.util.encodeObject(msg, { maxLength: debugLength });
|
|
44
|
+
RED.comms.publish("debug",msg);
|
|
45
|
+
|
|
19
46
|
} catch (ex) {
|
|
20
47
|
console.error(ex)
|
|
21
48
|
}
|
|
@@ -55,13 +82,22 @@ module.exports = function(RED) {
|
|
|
55
82
|
}
|
|
56
83
|
RED.nodes.registerType("ClientCode", ClientCodeFunctionality);
|
|
57
84
|
|
|
58
|
-
|
|
59
|
-
|
|
85
|
+
/**
|
|
86
|
+
* These are the two endpoints for the message tracer functionality.
|
|
87
|
+
* Rather badly placed in the ClientCode node code but the author
|
|
88
|
+
* didn't find a better place. The world is confusing, why should
|
|
89
|
+
* this codebase be any different.
|
|
90
|
+
*/
|
|
91
|
+
RED.httpAdmin.post("/MsgTracer/msgtracing/on",
|
|
60
92
|
RED.auth.needsPermission("ClientCode.write"),
|
|
61
93
|
(req, res) => {
|
|
62
94
|
try {
|
|
63
95
|
RED.hooks.remove(OnReceiveHookName)
|
|
64
|
-
|
|
96
|
+
if ( req.body.withDebug ) {
|
|
97
|
+
RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHookWithDebug)
|
|
98
|
+
} else {
|
|
99
|
+
RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHook)
|
|
100
|
+
}
|
|
65
101
|
|
|
66
102
|
// add hook on uninstall package so that the hook for the
|
|
67
103
|
// message tracer is removed on uninstall of this package.
|
|
@@ -79,7 +115,7 @@ module.exports = function(RED) {
|
|
|
79
115
|
}
|
|
80
116
|
});
|
|
81
117
|
|
|
82
|
-
RED.httpAdmin.post("/
|
|
118
|
+
RED.httpAdmin.post("/MsgTracer/msgtracing/off",
|
|
83
119
|
RED.auth.needsPermission("ClientCode.write"),
|
|
84
120
|
(req, res) => {
|
|
85
121
|
try {
|
package/package.json
CHANGED
package/plugins/sidebar.html
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
function setupTreelistAllLinksForLinkIn(e){e=collectAllLinksNodes(e);if(0==e.length){RED.notify("No links found",{type:"error",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e,"editor-tab-description")),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectAllLinksNodes(t){let n=[];RED.nodes.eachNode(e=>{"link call"!=e.type&&"link out"!=e.type||-1<e.links.indexOf(t)&&n.push(e)});var i=[],r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n,o=t.label,o=("function"==typeof o?o.call(e):o)||"";if(0===(n=e.type).indexOf("subflow:"))return}t&&o||(o=e.type),r[e.id]={node:e,label:o,sublabel:n,selected:!1,checkbox:!1},i.push(r[e.id])}),i}function collectNodeStats(){let t={},n=[],o={workspaces:0,junctions:0,subflows:0,configs:0,groups:0,wires:0,nodes:0},i=(RED.nodes.eachConfig(e=>{o.configs+=1}),RED.nodes.eachLink(e=>{o.wires+=1}),RED.nodes.eachJunction(e=>{o.junctions+=1}),RED.nodes.eachGroup(e=>{o.groups+=1}),RED.nodes.eachWorkspace(e=>{o.workspaces+=1}),RED.nodes.eachSubflow(e=>{o.subflows+=1}),RED.nodes.eachNode(e=>{o.nodes+=1,t[e.type]=(t[e.type]||0)+1}),Object.keys(t).forEach(e=>{n.push({label:e,sublabel:t[e],selected:!1,checkbox:!1})}),[]),r=0;return Object.keys(o).forEach(e=>{r+=o[e],i.push({label:e,sublabel:o[e],selected:!1,checkbox:!1})}),[{label:"__ TOTALS",sublabel:r,selected:!1,checkbox:!1,children:i}].concat(n.sort((e,t)=>e.label>t.label))}function setupTreeListForNodeStats(){var e=collectNodeStats();try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){}).on("treelistconfirm",function(e,t){}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e)}
|
|
16
16
|
|
|
17
|
-
function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var r;t.node&&(r=t.node.id,setTimeout(()=>{var e=RED.nodes.node(r);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),r==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var r=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),r.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),r.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}
|
|
17
|
+
function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var r;t.node&&(r=t.node.id,setTimeout(()=>{var e=RED.nodes.node(r);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),r==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var r=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),r.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),r.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}function toggleMsgTracingInBackend(e){let t=$("#node-input-msgtracer-toggle").is(":checked");var r=$("#node-input-msgtracer-msgtodebug").is(":checked");$.ajax({url:"MsgTracer/msgtracing/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({withDebug:r}),success:function(e){RED.notify("Message tracing is "+(t?"on":"off"),{type:"success",timeout:3e3})},error:function(e,t,r){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})}function handleMsgTracerToggles(e){$("#node-input-msgtracer-toggle").is(":checked")&&setupTreeMsgTracerlist(),toggleMsgTracingInBackend(e)}
|
|
18
18
|
|
|
19
19
|
// Add your plugin as a new tabsheet in the right sidebar AFTER the flow editor is completely started
|
|
20
20
|
var initialiseConfigNodeOnce = () => {
|
|
@@ -247,31 +247,8 @@
|
|
|
247
247
|
$("#node-input-msgtracer-trace-treelist").treeList('data', [])
|
|
248
248
|
})
|
|
249
249
|
|
|
250
|
-
$('#node-input-msgtracer-
|
|
251
|
-
|
|
252
|
-
setupTreeMsgTracerlist()
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
$.ajax({
|
|
256
|
-
url: "ClientCode/msgtracer/" + ($('#node-input-msgtracer-toggle').is(":checked") ? "on" : "off"),
|
|
257
|
-
type: "POST",
|
|
258
|
-
contentType: "application/json; charset=utf-8",
|
|
259
|
-
data: {},
|
|
260
|
-
success: function (resp) {
|
|
261
|
-
RED.notify("Message tracing succeed", {
|
|
262
|
-
type: "success",
|
|
263
|
-
timeout: 3000
|
|
264
|
-
})
|
|
265
|
-
},
|
|
266
|
-
|
|
267
|
-
error: function (jqXHR, textStatus, errorThrown) {
|
|
268
|
-
RED.notify("Message tracing failed: " +textStatus, {
|
|
269
|
-
type: "error",
|
|
270
|
-
timeout: 3000
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
})
|
|
250
|
+
$('#node-input-msgtracer-msgtodebug').on("change", toggleMsgTracingInBackend)
|
|
251
|
+
$('#node-input-msgtracer-toggle').on("change", handleMsgTracerToggles)
|
|
275
252
|
|
|
276
253
|
RED.actions.add( "introspection:show-link-call-links", highlightAllLinkCalls)
|
|
277
254
|
|
|
@@ -395,13 +372,21 @@
|
|
|
395
372
|
</div>
|
|
396
373
|
|
|
397
374
|
<div class="form-row" style="margin-left: 10px; margin-top: 40px">
|
|
398
|
-
<label for="node-input-msgtracer-toggle"
|
|
375
|
+
<label for="node-input-msgtracer-toggle">
|
|
399
376
|
<i class="fa fa-tag"></i>
|
|
400
377
|
<span>Trace Messages?</span>
|
|
401
378
|
</label>
|
|
402
379
|
<input type="checkbox" id="node-input-msgtracer-toggle"
|
|
403
380
|
style="display:inline-block; width:15px; vertical-align:baseline;">
|
|
404
|
-
|
|
381
|
+
|
|
382
|
+
<label for="node-input-msgtracer-msgtodebug">
|
|
383
|
+
<i class="fa fa-bug"></i>
|
|
384
|
+
<span>Msg to Debug?</span>
|
|
385
|
+
</label>
|
|
386
|
+
<input type="checkbox" id="node-input-msgtracer-msgtodebug"
|
|
387
|
+
style="display:inline-block; width:15px; vertical-align:baseline;">
|
|
388
|
+
|
|
389
|
+
<button id="node-input-msgtrace-clear-trace-btn" style="margin-left: 10px;"
|
|
405
390
|
class="red-ui-button">Clear Trace</button>
|
|
406
391
|
</div>
|
|
407
392
|
|