I know that some folk have difficulty accessing Node-RED logs and sharing them. So it occurred to me that it might be useful to be able to surface the log in Node-RED itself.
Then you could forward it anywhere you like. To a UIBUILDER page for example
So here is a test flow that does the first part.
[{"id":"4ae8ae735f8ce4f8","type":"group","z":"4a3fcf357a20bf56","name":"TEST: Acces to journalctl","style":{"label":true},"nodes":["7ffadef3ea96cc9d","a6b7bf014cec9e5c","fa7b810c980cd879","4bc60421eda247ff"],"x":94,"y":1499,"w":552,"h":122},{"id":"7ffadef3ea96cc9d","type":"inject","z":"4a3fcf357a20bf56","g":"4ae8ae735f8ce4f8","name":"journalctl","props":[{"p":"topic","vt":"str"},{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":"0","topic":"journalctl","payload":"nrmain","payloadType":"str","x":220,"y":1540,"wires":[["a6b7bf014cec9e5c"]]},{"id":"a6b7bf014cec9e5c","type":"function","z":"4a3fcf357a20bf56","g":"4ae8ae735f8ce4f8","name":"set up/cancel journalctl","func":"// const Journalctl = require('journalctl')\n\n/* \n identifier: Just output logs of the given syslog identifier (cf. man journalctl, option '-t')\n unit: Just output logs originated from the given unit file (cf. man journalctl, option '-u')\n filter: An array of matches to filter by (cf. man journalctl, matches)\n all: Show all fields in full, even if they include unprintable characters or are very long. (cf. man journalctl, option '-a')\n lines: Show the most recent journal events and limit the number of events shown (cf. man journalctl, option '-n')\n since: Start showing entries on or newer than the specified date (cf. man journalctl, option '-S')\n*/\nconst opts = {\n unit: msg.payload,\n lines: 50, // to allow for flows not starting immediately\n}\n\n// We have to track this to be able to cancel it\nlet journalctl = global.get('journalctl')\n\n// If already exists, done run again\nif (journalctl) {\n // 'stop' will end the listener, unload the lib and delete the global\n if (msg.payload === 'stop') {\n node.warn('stopping journalctl')\n journalctl.stop( () => {\n global.set('journalctl', undefined)\n })\n return\n }\n\n node.warn('journalctl is already running.\\nSend a payload of \"stop\" to end.')\n return\n}\n\n// If it doesn't exist, create and save the reference\njournalctl = new Journalctl(opts)\nglobal.set('journalctl', journalctl)\n\n\n// Set up a persistent listener for new journal entries\n// NOTE: THIS WILL CARRY ON WORKING\n// Even after the function node completes\n// You only ever need to run it once\njournalctl.on('event', (event) => {\n node.send({\n topic: 'journalctl-event',\n payload: event,\n })\n})\nnode.warn('journalctl listener started')","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"Journalctl","module":"journalctl"}],"x":420,"y":1540,"wires":[["fa7b810c980cd879"]]},{"id":"fa7b810c980cd879","type":"debug","z":"4a3fcf357a20bf56","g":"4ae8ae735f8ce4f8","name":"journalctl","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload.MESSAGE","targetType":"msg","statusVal":"","statusType":"counter","x":585,"y":1540,"wires":[],"l":false},{"id":"4bc60421eda247ff","type":"inject","z":"4a3fcf357a20bf56","g":"4ae8ae735f8ce4f8","name":"journalctl-stop","props":[{"p":"topic","vt":"str"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"0","topic":"journalctl-stop","payload":"stop","payloadType":"str","x":210,"y":1580,"wires":[["a6b7bf014cec9e5c"]]}]
You will need to change the systemd service name in the inject called journalctl
to whatever you are using - mine is set to something custom.
Note that you will probably also need to use visudo -e
to let your node-red user to run journalctl
without a password. Please let me know cause my server is already set up that way.
There is a slight issue in that flows don't start until a couple of seconds after Node-RED has started, so this flow doesn't show the startup log even though I've told it to show 50 lines. Stopping and restarting does the trick. I'll try to find a way around that.
So not perfect but may be of use.
Let me know if you want to see a UIBUILDER page that shows the log.