@gregoriusrippenstein/node-red-contrib-introspection 0.8.3 → 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 CHANGED
@@ -82,13 +82,27 @@ 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
- ![img](https://cdn.openmindmap.org/content/1728588310213_msgtrace.gif)
85
+ ![img](https://cdn.openmindmap.org/content/1728655611060_msgtracer6.gif)
86
86
 
87
- Message tracing can be toggled on & off *without* redeploying the flow. So this can be used as a quick check for observing tricky situation.
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
 
89
- The nodes status will be replaced by 'msg received', so if the status should be showing something else, that is lost.
89
+ The nodes status will be replaced by 'msg received', so if the status should be showing something else, that will be replaced.
90
90
 
91
- Also this is an experimental feature liable to be [improved](https://discourse.nodered.org/t/message-tracing-for-beginners/92287).
91
+ Also this is an experimental feature liable to be [enhanced](https://discourse.nodered.org/t/message-tracing-for-beginners/92287).
92
+
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.
92
106
 
93
107
  ## Palette Nodes
94
108
 
@@ -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
- RED.httpAdmin.post("/ClientCode/msgtracer/on",
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
- RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHook)
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("/ClientCode/msgtracer/off",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gregoriusrippenstein/node-red-contrib-introspection",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "dependencies": {
5
5
  "got": "^13",
6
6
  "uglify-js": "^3.17.4",
@@ -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-toggle').on("change", function (e) {
251
- if ( $('#node-input-msgtracer-toggle').is(":checked") ) {
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" class="w-30">
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
- <button id="node-input-msgtrace-clear-trace-btn"
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