NODE-RED global server-side events listening layer

TL;DR:
I'm currently developing an event listening mechanism and I want to suggest it as a feature request in order to receive your approval (hopefully) and make a pull request out of it

Long version

Hi all

I recently work on NODE-RED and noticed that the server-side is very poor in terms of events listening. Following the docs (api ref) I found that the main events are onInput (in a node context) and RED.events (which mainly cover nodes deployment use-cases).

I made a research and came to conclusion that using the log (add a handler and therefore "listen" to node events) is not the best practice for this purpose (log and event listeners are 2 different things and should be treated differently)

I've already started working on a global events listening layer (based on node EventEmitter) which will cover:
NODE-RED: onStart, onError and onExit (process level)
Node (base class of all nodes): onSend, onClose, onInput (in a global context)

Context handling is probably not required due to the new context store api (see here)

I truly believe that this feature will gain more control to developers over their NODE-RED instance. It is currently in progress and it would be nice if you share your thought about it

Thanks

Hi

With all of the ongoing activity on the runtime/editor split work and new runtime apis, anything in this area needs to be done as part of that work. Any events emitted by the runtime are a key part of the runtime api.

It would help if you could describe some use-cases you have for it, to help validate the requirement and demonstrate what problem it solves.

RED.events is the event emitter for the runtime and would be the basis for any work in this area. Is there a particular reason you want to introduce something different?

There are already a number of events defined - for the basic lifecycle events of the runtime. Since those docs were written (and please note the comment at the top of that wiki page: This is a work-in-progress that is out of date - do not use!) there are a number of other events defined. Similarly, the Node object has a set of events it uses for its internal use.

So the question is what events are you suggesting get added and what use-case do you have for exposing them. We would not choose to expose a Node's internal events as some sort of external api unless there was a compelling need to do so.

Nick

Hi Nick

First: thank you for your comprehensive answer.

To the point: it really triggered a discussion in our company, so.. let me share what we've got so far:

This is understandable - exposing internal data from NODE-RED to external sources sounds like a security risk. On the other hand, grant developers the ability to inspect NODE-RED process (programmatically) is entirely different scenario (NODE-RED integrity will be saved unless developers leak it explicitly)

In my own opinion, there are 2 main capabilities we can achieve here:

  1. response (programmatically) to NODE-RED lifecycle (whenever service is up or down). This behavior could be implemented by using a process manager (like PM2) and using current NODE-RED RED.events (when flows are deployed - if this is the first time then the service is up), but it ain't pretty.
  2. control messages when they modified: lots of stuff happens to messages as flows progress (values can added or deleted, the message itself can be deployed multiple times and so on). Although there are ways to track down changes (like using debug, or log the entire message to a logger) non of them is elegant enough - the flow itself becomes non intuitive as it grows

And they may satisfy some use-cases, like:

  1. listening whenever NODE-RED has an error and email admin (this can be achieved by a different NODE-RED instance which will have a custom node that will listen to on NODE-RED error event)
  2. log message field whenever it is added or changed (this could be any field inside the message in any step of the flow). This could be achieved with node on send event
  3. for heavy async nodes (like querying an external api with lots of data) - log whenever the operation completed. This could be achieved with node on close event
  4. inspect malicious injections attempts for all nodes in all flows (passing message fields, get values and inspect each of them). This could be achieved with node on input event (it is a global event that will allow developers to listen to all inputs from all nodes in all flows)

I know, it looks like that developers can use it for bad purposes BUT they can also use this for good ones (to better inspect and control their own instance). At the end of the day - we trust owner dev team to do the right thing (or simply ignore this feature)

So, my suggestions are:

  • node on input - fires for each node every time it recieves an input
  • node on send - fires for each node every time it sends a message
  • node on close - fires for each node every time it closes (message can be inspected to determine if operation completed successfully or not)

all the above listeners will have these parameters provided: flowId, nodeId, message

  • on NODE-RED start - fires every time NODE-RED service is up
  • on NODE-RED exit - fires every time NODE-RED service is down
  • on NODE-RED error - fires every time NODE-RED service throws an error (this listener will provide the Error object as a parameter)

Developers will be able to hook directly to these events with an external code file (attached by a special flag that will be provided to NODE-RED when executed) and create a more elegant solution (these hooks would not be able to prevent current code from running)

A reminder: we started to seek these directions because the listed use-cases are real (we do need to cover them in order to use NODE-RED). Any other alternatives / solutions may be welcomed (if you don't mind to specify them on this thread)

Thanks :slight_smile: