Colorize log output using Chalk

I've added chalk
npm install chalk

I've added it to functionGlobalContext

  functionGlobalContext: {
    chalk: require('chalk')
  },

I've restarted node-red.

I've added it to a function

var chalk = global.get('chalk');
console.log(chalk.blue('Hello world!'));

It's not working. The entry is logged with default color.

Specifying a color like so does change the foreground color of the log entry.

console.log('\x1b[36m%s\x1b[0m', 'cyan text');

I've confirmed that other packages added to functionGlobalContext work and msg.payload = chalk.toString(); results in payload: [object Function].

Am I missing something or is this just not a thing that's going to work?

what does debug show if you do this...

function --> debug node

var chalk = global.get('chalk');
msg.payload = chalk.blue('Hello world!');
return msg;

If the debug node writes to debug window it displays >

{"_msgid":"4f58986.a69dd68","payload":"Hello world!"}

If the debug node writes to system console it displays >

0|node-red  | 14 Dec 12:30:22 - [info] [debug:Write Log] Hello world!

Neither case shows colorized output.

Quite Strange. I would have expected to see the colour escape chars. It's like chalk isn't applying them.

What happens if you fire up a node cli from the node_module directory and try the same thing in command line ?

Have you tried others like color?

I don't exactly know how to run a node command from the CLI but I created a test project on the same box using npm init and added two lines to a file.

const chalk = require('chalk');
console.log(chalk.blue('Hello world!'));

Installed chalk npm i chalk

ran it node init.js

and it spit out Hello world! in blue.

I did try colors. It also didn't work and threw error ("TypeError: Cannot read property 'red' of undefined") if I tried chaining console.log('i like cake and pies'.underline.red);

For now, I've dumped all the color codes I want to a global and then built a subflow that colorizes output using passed params or set environment vars on the subflow. It's not great but it seems to be ok until I can resolve it.

[{"id":"e98b18f5.0a2b08","type":"subflow","name":"Colorized Output","info":"","category":"","in":[{"x":40,"y":40,"wires":[{"id":"ea5fb272.a74cb"}]}],"out":[{"x":400,"y":40,"wires":[{"id":"564fbdb9.ab76e4","port":0}]}],"env":[{"name":"color","type":"str","value":"Green"},{"name":"bgColor","type":"str","value":""},{"name":"bright","type":"bool","value":"true"},{"name":"output","type":"str","value":"Hello World"}],"color":"#DDAA99"},{"id":"564fbdb9.ab76e4","type":"function","z":"e98b18f5.0a2b08","name":"Colorize output","func":"let colors = global.get('logColors');\nlet bright = msg.bright ? colors.Bright : '';\nlet color = msg.color !== '' ? colors.fg[msg.color] : '';\nlet bgColor = msg.bgColor !== '' ? colors.bg[msg.bgColor] : '';\n\nconsole.log(bright, color, bgColor, msg.output, colors.Reset);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":40,"wires":[[]]},{"id":"ea5fb272.a74cb","type":"function","z":"e98b18f5.0a2b08","name":"Vars","func":"msg.color = msg.color || env.get(\"color\");\nmsg.bgColor = msg.bgColor || env.get(\"bgColor\");\nmsg.bright = msg.bright || env.get(\"bright\");\nmsg.ouput === msg.output || env.get(\"output\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":130,"y":40,"wires":[["564fbdb9.ab76e4"]]},{"id":"a22b39ce.1863b8","type":"template","z":"98803193.f8aa","name":"","field":"output","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{room}} turned off.","output":"str","x":420,"y":1060,"wires":[["7a5b894.db93578"]]},{"id":"7a5b894.db93578","type":"subflow:e98b18f5.0a2b08","z":"98803193.f8aa","name":"Colorized Log Output","env":[],"x":600,"y":1060,"wires":[["325436e6.c5bd8a"]]},{"id":"769f8836.726e58","type":"inject","z":"98803193.f8aa","name":"Timestamp","props":[{"p":"payload"},{"p":"room","v":"Living Room","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":260,"y":1060,"wires":[["a22b39ce.1863b8"]]},{"id":"325436e6.c5bd8a","type":"debug","z":"98803193.f8aa","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","statusVal":"","statusType":"auto","x":790,"y":1060,"wires":[]},{"id":"bf0a73b8.1ca97","type":"template","z":"98803193.f8aa","name":"","field":"output","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{room}} turned off.","output":"str","x":420,"y":1120,"wires":[["23b6d894.4192f8"]]},{"id":"23b6d894.4192f8","type":"subflow:e98b18f5.0a2b08","z":"98803193.f8aa","name":"Colorized Log Output","env":[],"x":600,"y":1120,"wires":[["c6252302.3f6ab"]]},{"id":"64911ff0.f763e","type":"inject","z":"98803193.f8aa","name":"Timestamp","props":[{"p":"payload"},{"p":"room","v":"Living Room","vt":"str"},{"p":"color","v":"Blue","vt":"str"},{"p":"bgColor","v":"Red","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":260,"y":1120,"wires":[["bf0a73b8.1ca97"]]},{"id":"c6252302.3f6ab","type":"debug","z":"98803193.f8aa","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","statusVal":"","statusType":"auto","x":790,"y":1120,"wires":[]}]

I think that the debug tab filters out the codes. They wouldn't work anyway of course since the debug tab uses HTML and not terminal colour codes.

Perhaps chalk is taking its environment into account and thinks that your terminal doesn't have colour support? How are you running Node-RED? I know that when I run it from systemd, I don't get all of the usual environment variables that you would expect from a full BASH shell and that includes the XTERM variable that you might need. Maybe try adding the appropriate variables to the systemd startup script.

I think it tries to be clever & not add the escape codes if it doesn't detect a capable console & as the node-red function node is sandboxed, i believe thats why it doesnt work.

Would be nice if there was an override flag to ignore console & output the strings regardless. there may be something in there but i dont know. would need to dig through code or ask on repo.

If the environment vars are set before starting Node-RED it might work? Maybe start it manually to see if it does.

I think if you set debugUseColors: true, in settings.js then you can just use ansi colour codes

[{"id":"546a404a.1d369","type":"inject","z":"ab9333b5.f44f6","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"\\033[31;1;4mHello\\033[0m","payloadType":"str","x":120,"y":2200,"wires":[["7043a930.ca3328"]]},{"id":"7043a930.ca3328","type":"function","z":"ab9333b5.f44f6","name":"","func":"console.log(\"\\033[31;1;4mHello\\033[0m\")\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":300,"y":2200,"wires":[[]]}]

Thanks all, I will take a look at all of this later and report back.

You're 100% right. It's detecting the console and setting a level of 0 (no color). Chalk is using another package https://github.com/chalk/supports-color to determine support. It looks like some environments are hard-coded. Otherwise it's CLI flags and environment variables.

One fix is to add the environment variable to settings.js.

process.env.FORCE_COLOR = "1";

However, it's also possible to instantiate the Chalk object with some startup parameters to force a color support level. I completely missed this in the README cuz I was skimming and searching the wrong phrases. It wasn't until I looked at the code and saw they were using level that I searched that term in the README.

var chalk = global.get('chalk');
chalk.level = 2  
console.log(chalk.green('Hello world!'));
return msg;

TL;DR RTFM

1 Like

I too only skimmed the readme - wasn't obvious

Working for me using the method described in the readme

image

var chalk = global.get('chalk');
const ctx = new chalk.Instance({level: 2});
msg.payload = ctx.blue.bgRed.bold('Hello world!')
console.log(msg.payload );
return msg;

I'd guessed that was the problem since I've hit similar issues in the past with consoles.