# Node-red-context-monitor: A node to monitor a Node-RED context

**URL:** <https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555>\
**Category:** Share Your Nodes\
**Created:** [2 November 2023 16:04 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555 "2023-11-02T16:04:01Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [2 November 2023 16:04 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/1 "2023-11-02T16:04:01Z")

</div>

[Recently](https://discourse.nodered.org/t/send-a-message-from-a-custom-function-node-without-output-option/82308) we had an exchange on the options to emit a `msg` from a node that had no output terminals ... and of course wasn't designed to support such a use case.  
This node yet facilitated a `function` like interface; `send()` was inoperational - but setting `context` was possible.

What if - there was a node capable to monitor a(ny) `context` and create a `msg` in case the context is written to?

Welcome [node-red-context-monitor](https://github.com/ralphwetzel/node-red-context-monitor) - a node designed to monitor a Node-RED context! 🎉

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/4/c428c7fd79d1d5cce886d20b232fbab8bbd70a1a.png)

This node allows to setup the reference to a context, then sends a message when this context is written to.

It sends a dedicated message on a separate port in case it detects that the value of the context was changed.

The message sent will carry the current value of the context as `msg.payload`. Monitoring details will be provided as `msg.monitoring`.

It is possible to monitor an infinite number of contexts with each instance of this node.

This node supports the three [context scope levels](https://nodered.org/docs/user-guide/context#context-scopes) `Global`, `Flow` & `Node`.

Feedback welcome - as always!

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [2 November 2023 16:14 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/2 "2023-11-02T16:14:49Z")

</div>

Hi @ralphwetzel - Nice!

Can it be password protected?  
I don't really want my Wife monitoring my Context?

Note: I moved this into `Share Your Nodes` (hope that's alright)

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [2 November 2023 16:37 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/3 "2023-11-02T16:37:53Z")

</div>

Not getting anything when injecting into function node that is setting context

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/7/67bb17f747a1a11fc2426c3a12a394223a04314e.png)  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/d/6d9da97eacee4411f1e4b4870a960b45eb74f8af.png)

[edit] Ignore  
I've seen my error 🙂

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/2/b23302581dd5095e61e342c781f5c5629fd12955.png)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [2 November 2023 16:40 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/4 "2023-11-02T16:40:58Z")

</div>

Hi @ralphwetzel,

Nice!!!

I am just wondering if this works in all cases. Because for some reason I have always thought this feature wasn't possible to implement in Node-RED, but I can't find the details quickly... [Here](https://discourse.nodered.org/t/can-nr-be-set-to-trigger-on-changes-in-global-scope-context-values/33826/3) is one of the related posts, but it doesn't contain much info. Or was there a problem with some types of context stores like e.g. an in-memory store. Don't remember it anymore. Getting old ...

Bart

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 16:41 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/5 "2023-11-02T16:41:47Z")

</div>

> [@ralphwetzel](#):
>
> This node allows to setup the reference to a context, then sends a message when this context is written to.

Great! I've been wanting to do something like this for a few years, just never had the time. Though I was thinking of it in terms of a new context type that had events built in. But this should work. Definitely going to give this a go, thanks for contributing it.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 16:53 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/6 "2023-11-02T16:53:35Z")

</div>

After install and adding to a flow:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/c/fc55c47e852543f1034e0d91a5c9bb26d6b95011.png)

```auto
0|Node-RED | *** Error while loading node-red-context-monitor:
0|Node-RED | Failed to calculate correct patch path.
0|Node-RED | Please raise an issue @ our GitHub repository, stating the following information:
0|Node-RED | > require.main.path: D:\src\nr\node_modules\node-red
0|Node-RED | > utils.js: D:\src\nr\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\context\index.js
0|Node-RED | 2 Nov 16:50:16 - [info] Added node types:
0|Node-RED | 2 Nov 16:50:16 - [info] - @ralphwetzel/node-red-context-monitor:context-monitor
0|Node-RED | 2 Nov 16:51:30 - [info] Stopping modified nodes
0|Node-RED | 2 Nov 16:51:31 - [info] [mqtt-broker:home] Disconnected from broker: mqtt://home.knightnet.co.uk:1883
0|Node-RED | 2 Nov 16:51:31 - [info] Stopped flows
0|Node-RED | 2 Nov 16:51:31 - [info] Updated flows
0|Node-RED | 2 Nov 16:51:31 - [info] Waiting for missing types to be registered:
0|Node-RED | 2 Nov 16:51:31 - [info] - context-monitor

```

Also, not specifying a thing to monitor does not mark the node as being in error and maybe it needs to?

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [2 November 2023 17:05 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/7 "2023-11-02T17:05:08Z")

</div>

> [@TotallyInformation](#):
>
> ```auto
> 0|Node-RED | Failed to calculate correct patch path.
> 0|Node-RED | Please raise an issue @ our GitHub repository, stating the following information:
> 0|Node-RED | > require.main.path: D:\src\nr\node_modules\node-red
> 0|Node-RED | > utils.js: D:\src\nr\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\context\index.js
> 
> ```

Looks like an issue finding the correct file for patching in your directory tree. I'll check.  
Thanks for giving it a try!

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [2 November 2023 17:06 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/8 "2023-11-02T17:06:38Z")

</div>

> [@BartButenaers](#):
>
> Don't remember it anymore. Getting old ...

It is slowly getting back...

I mostly store objects in memory, instead of primitives. Then I `get` (a _ **reference** _) to that object in memory, and I update the object (via that reference). In this case the API does not know that something has been changed, because I don't use `set`.

This simple flow for your node explains what I mean:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/a/2a805a3d08f7351d3307a5b3808f401f73aa96c5.png)

```auto
[{"id":"f2874060375785b7","type":"inject","z":"4980f94dd2c07b62","name":"Set","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"set","x":130,"y":80,"wires":[["b1d17d7418f7a28f"]]},{"id":"b1d17d7418f7a28f","type":"function","z":"4980f94dd2c07b62","name":"set or update object on node context","func":"if (msg.topic == \"set\") {\n context.set(\"node_test\", {\n someProperty: 25\n });\n}\n\nif (msg.topic == \"change\") {\n let context_reference = context.get(\"node_test\");\n // Update the context via the reference:\n context_reference.someProperty = 99;\n}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":80,"wires":[[]]},{"id":"42634cda458394e4","type":"context-monitor","z":"4980f94dd2c07b62","name":"","monitoring":[{"scope":"node","flow":"4980f94dd2c07b62","node":"b1d17d7418f7a28f","key":"node_test"},{"scope":"global","key":"global_test"},{"scope":"flow","flow":"4980f94dd2c07b62","node":"f2874060375785b7","key":"flow_test"}],"x":140,"y":200,"wires":[[],["12a15905dd250321"]]},{"id":"12a15905dd250321","type":"debug","z":"4980f94dd2c07b62","name":"debug on change","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":370,"y":200,"wires":[]},{"id":"46c751417be5d30d","type":"inject","z":"4980f94dd2c07b62","name":"Change","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"change","x":130,"y":120,"wires":[["b1d17d7418f7a28f"]]}]

```

The first Inject node automatically stores an object in the Function node's context memory (with property value 25). When I press the second Inject node, I get the object from memory and I update its property value to 99. That new value indeed arrives in my memory context store:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/0/80766c9f4bc9fe2fd3ad6092f3c2e8124f8daba6.png)

In this case your node doesn't send an output message, because nobody is aware that I changed the object in my memory...

**[EDIT 1]** This is of course only an issue when you use an _ **in-memory context store** _. When you store e.g. your context in a db, then you need to call `set` to update the object in the db.

**[EDIT 2]** Not sure whether **Object.observe()** or **Object.prototype.watch()** could somehow be a workaround for those cases, to keep an eye on the object changing...

It is not my intention at all to be a partystopper, because you created a real useful node! But it might be useful to mention this somewhere in the readme page.

Keep up the good work!!  
Bart

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 17:07 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/9 "2023-11-02T17:07:55Z")

</div>

You've also got a `node.on("input", function(msg, send, done) { ... }` but you don't actually have an input so that will never be called.

I was wondering how you were managing to achieve this - `// patching into` - ah, monkey patching. I wonder then, if this is a useful node, perhaps it should be adopted into core so that you didn't need to patch those core functions?

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [2 November 2023 17:13 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/10 "2023-11-02T17:13:19Z")

</div>

> [@TotallyInformation](#):
>
> You've also got a `node.on("input", function(msg, send, done) { ... }` but you don't actually have an input so that will never be called.

Nope. 😉  
Of course this will be called:

> <https://github.com/ralphwetzel/node-red-context-monitor/blob/1fba5ffe1173a5ea8d36668f27d424b4dfdfd0c4/monitor.js#L235>

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 17:13 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/11 "2023-11-02T17:13:47Z")

</div>

> [@BartButenaers](#):
>
> I don't use `set`.

You are discovering why you should always be using get/set Bart. 🙂

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [2 November 2023 17:19 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/12 "2023-11-02T17:19:16Z")

</div>

> [@TotallyInformation](#):
>
> You are discovering why you should always be using get/set Bart.

Don't need it 😉  
And I assume lots of others will use it also that way...

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 17:32 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/13 "2023-11-02T17:32:29Z")

</div>

> [@ralphwetzel](#):
>
> Nope. 😉  
> Of course this will be called:

What am I missing? That seems to be calling a receive function in a referenced node, not in this node?

> [@ralphwetzel](#):
>
> Looks like an issue finding the correct file for patching in your directory tree. I'll check.

Ah, yes, you've forgotten that node.js apps can be installed in multiple ways. In my case, Node-RED is installed locally not globally and the userDir is a sub-folder of the node-red install folder. But of course, it could be somewhere else entirely.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 17:34 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/14 "2023-11-02T17:34:25Z")

</div>

> [@BartButenaers](#):
>
> Don't need it 😉

Until you do. I've been caught out like that before, far too many times to count. So I'm rather more conservative these days. Because going back and re-coding - even finding - all those references is a pain in the rear-end.

> [@BartButenaers](#):
>
> And I assume lots of others will use it also that way...

I've no doubt.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [2 November 2023 17:39 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/15 "2023-11-02T17:39:11Z")

</div>

> [@TotallyInformation](#):
>
> Until you do

Yes I know you are right: if you want to be able to switch easily (without having to change anything) afterwards to another context store, you should call the `set` function always.

But you know that - with a development background - you will never do that when you have a reference to your object available...

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [2 November 2023 18:02 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/16 "2023-11-02T18:02:19Z")

</div>

> [@TotallyInformation](#):
>
> Ah, yes, you've forgotten that node.js apps can be installed in multiple ways. In my case, Node-RED is installed locally not globally and the userDir is a sub-folder of the node-red install folder. But of course, it could be somewhere else entirely.

The localisation algorithm usually is quite robust - but still an algorithm.  
Could you do me a favour and locate the absolute path of `node_modules\@node-red\runtime\lib\nodes\context\index.js` in your directory tree?

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [2 November 2023 18:12 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/17 "2023-11-02T18:12:40Z")

</div>

> [@BartButenaers](#):
>
> It is not my intention at all to be a partystopper, because you created a real useful node! But it might be useful to mention this somewhere in the readme page.

Thanks a lot for your feedback! That can't ever be a partystopper! 😀  
Think I'll follow your proposal & amend the documentation accordingly.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 November 2023 20:55 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/18 "2023-11-02T20:55:44Z")

</div>

> [@ralphwetzel](#):
>
> The localisation algorithm usually is quite robust - but still an algorithm.  
> Could you do me a favour and locate the absolute path of `node_modules\@node-red\runtime\lib\nodes\context\index.js` in your directory tree?

I manually hacked the node to get it to work:

```auto
const context_manager_path = path.join(__dirname, '../../../../node_modules/@node-red/runtime/lib/nodes/context/index.js')

```

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [5 November 2023 13:13 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/19 "2023-11-05T13:13:37Z")

</div>

> [@TotallyInformation](#):
>
> I manually hacked the node to get it to work:

I've reworked the localisation algorithm.  
Could please check if the latest commit (@GitHub) is able to spot the right path for your system?

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [5 November 2023 13:18 UTC](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555/20 "2023-11-05T13:18:22Z")

</div>

Hi @BartButenaers

> [@BartButenaers](#):
>
> In this case the API does not know that something has been changed, because I don't use `set`.

The node should now be able to monitor referenced object changes as well - even nested.  
Could you please verify? You need to install the latest commit from Github.  
Disclaimer: Currently this should work _only_ for objects. `Array` support is next ToDo on the list...

[Next page](https://discourse.nodered.org/t/node-red-context-monitor-a-node-to-monitor-a-node-red-context/82555.md?page=2)
