Effective Logging in Node-RED: Exploring Built-in Options and Third-Party Modules like Winston

I’m currently using console.log for backend logging in my Node-RED setup but am considering moving to a more robust solution with structured logging, such as Winston or another third-party module. However, I want to ensure I’m not overlooking Node-RED’s built-in logging capabilities.

Could anyone provide insights on the following:

  1. Node-RED’s Built-in Logging Options: How effective are Node-RED’s default logging options for maintaining logs in production environments? Are there ways to adjust configurations (like log level or format) directly in settings.js for more detailed insights?
  2. Benefits of Third-Party Logging: If switching to a third-party logging system (e.g., Winston), what are the best practices for integrating it seamlessly with Node-RED? Are there specific middleware options, or should it be added within custom function nodes?
  3. Combining Node-RED and External Logging: Can I set up Node-RED’s internal logging for general operational logs while using Winston for application-specific logs? Any examples of hybrid setups would be helpful!

I’d love to hear from others who have experience with logging strategies in Node-RED, especially for scaling and production use cases. Thanks in advance for any guidance or example configurations!

You should find in settings.js:

/** Configure the logging output */
    logging: {
        /** Only console logging is currently supported */
        console: {
            /** Level of logging to be recorded. Options are:
             * fatal - only those errors which make the application unusable should be recorded
             * error - record errors which are deemed fatal for a particular request + fatal errors
             * warn - record problems which are non fatal + errors + fatal errors
             * info - record information about the general running of the application + warn + error + fatal errors
             * debug - record information which is more verbose than info + info + warn + error + fatal errors
             * trace - record very detailed logging + debug + info + warn + error + fatal errors
             * off - turn off all logging (doesn't affect metrics or audit)
             */
            level: "info",
            /** Whether or not to include metric events in the log output */
            metrics: false,
            /** Whether or not to include audit events in the log output */
            audit: false
        }
    },

Also you might like to look at node-red-contrib-flogger.

Thanks for sharing !. Currently, I’m using Express middleware for session and event management in my Node-RED setup. I’d like to understand how to set up logging effectively for this middleware, as the Node-RED default configurations mostly cover application-level logs.

I realize that console.log is not ideal for production environments due to its lack of structured logging and filtering capabilities. What are the alternatives for creating more detailed, manageable logs in a production setup?

Could have any suggestion regarding this issue?

@Colin suggested flogger (node-red-contrib-flogger). It is very effective. It included the option to limit the size of the log files, the rotation...
When it is stored in a file, then, you can plug loki or ELK or... to search in these log.

Flogger probably is the best answer. However, when developing for uibuilder, I often need to have trace-level logging for uibuilder nodes but don't want trace for everything.

So all of my log outputs have a specific text pattern at the start of the output and I have a custom log configured in settings.js that outputs to MQTT in my case:

    logging: {
        console: ....,
        mqttLog: {
            level: 'trace',
            metrics: false,
            audit: false,
            handler: function(settings) {
                const nrLogLevels = { // eslint-disable-line no-unused-vars
                    10: 'FATAL', 20: 'ERROR', 30: 'WARN ', 40: 'INFO ', 50: 'DEBUG', 60: 'TRACE', 98: 'AUDIT', 99: 'MTRIC'
                }
                const myCustomLevels = { // eslint-disable-line no-unused-vars
                    levels: {
                        'FATAL': 10,
                        'ERROR': 20,
                        'WARN ': 30,
                        'INFO ': 40,
                        'DEBUG': 50,
                        'TRACE': 60,
                        'AUDIT': 98,
                        'MTRIC': 99
                    },
                    colors: {
                        'FATAL': 'redBG',
                        'ERROR': 'red',
                        'WARN ': 'orange',
                        'INFO ': 'yellow',
                        'DEBUG': 'green',
                        'TRACE': 'cyan',
                        'AUDIT': 'grey',
                        'MTRIC': 'grey'
                    }
                }

                const mqtt = require('mqtt')
                const client  = mqtt.connect('mqtt://localhost')

                return function(msg) {
                    if ( msg.level < 51 || msg.msg.includes('[uibuilder') || msg.msg.startsWith('+-') || msg.msg.startsWith('| ') || msg.msg.startsWith('>>') ) {
                        client.publish( 'nrlog/dev', JSON.stringify(msg) )
                    }
                }
            }
        },
    },

I have a small flow that outputs that MQTT data to a web page as well.