Redirecting console.log

Posted on
  • I want to realize a certain logic, that would kind of change the way console.log works. I want it to send data not just into Espruino console, but into my webpage/node-red/somewhere else.
    What would be the most optimal way to do it?

    As I work with various Espruino devices, it's very important to choose the universal way, so I would rely on usb connection, but not bluetooth or something else.
    Thank in advance!

  • Espruino has something called Loopback. If you do LoopbackA.setConsole() anything that gets printed (including exceptions/etc) appears in a LoopbackB.on('data', ...) event, and the same the other way.

    That could potentially be a good solution, although it won't work if you're printing huge amounts of data. For up to ~1000 bytes at once it should be fine though

  • Hello again! That was a very helpful advice, but now I'm struggling with such a problem - obviously after LoopbackA.setConsole() I lose opportunity to prompt commands into IDE console and it is inacceptable accordint to my plans. What could You advise?

    P.S looks like I already fixed it by piping default console (USB in my case) with LoopbackB.

  • Yes, that's all you need - to pipe another input device in. You will lose the ability to do things like Ctrl-C to break out of executing code, but otherwise it's fine

  • Hello again. As REPL returns data (I am about data that comes on LoopbackB.on(data => ...) with various combinations of special symbols ['\r\n', '1x0B[', etc], I wanted to ask if it's possible to check all those "heads" and "tails" of messages.
    Yes, in a common case, it's not hard to parse text from there with regexps, but this way I can easily not to take some cases into account. Thanks for attention!

  • I'm not sure I really understand the question...

    There isn't anything built in to Espruino that separates specific commands in the output stream - it is just a sequence of characters (as would go to a VT100 terminal app).

    You may be seeing char code 8 which is a delete, because normally the console outputs > as a prompt, but to print something it must first delete that, write the text, and then re-add it.

    To avoid that you can run echo(0) which will turn off the console echoing back what you write (and the > prompt). When you type in the IDE the device will appear to be unresponsive, but it will still output the text you send it

  • If you are not interested in the interactive console I/O and just really care about output of console.log then you can override console.log (and global.print alias) method to call previous implementation and also do something else with the arguments

    >console.log == global.print
    >function mylog(){ print("arguments=",arguments);console.lo­g.apply(null,arguments);}
    =function () { ... }
    arguments= [ 1, 2, 3, 4 ]
    1 2 3 4
  • or full example - the oldlog("arguments=",arguments) call inside mylog is the "something else" part here

    =function () { [native code] }
    >function mylog(){ oldlog("arguments=",arguments);oldlog.ap­ply(null,arguments);}
    =function () { ... }
    =function () { ... }
    arguments= [
    hello world
  • I just wanted to say that when I catch console logs and answers from interactive console with code like this

    USB.on('data', data => {
    setTimeout(() => {E.setConsole(LoopbackA);}, 200);
    LoopbackB.on('data', data => {
    setTimeout(() => {
      console.log('some text');
    }, 500);
    setTimeout(() => {
    }, 1500);

    I get logs like this:

      "<- USB\r\n>",
      "\r\x1B[Jsome text\r\n>",
      "\r\x1B[J-> USB\r\n"

    That looks quite readable, but some situations lead to logs like this:

    "outLogs\r\n=[ \r\n  \"" ... "\\n ]\\r\\n>\"\r\n ]\r\n>"

    So I have to remove all special symbols somehow. Yeah, it's not hard at all to write a simple parser on regexps for those exact types of logs, but as I don't know how exactly IDE is formatting logs, I may easily trap into using code that doesnt work correctly for some cases. So, what would you advice?

  • Thanks for trying to help, but interactive I/O is needed.

  • Btw, I wanted to ask why it looks like I'm only slightly changing the route of data (as it still goes from REPL to IDE console through USB and vice versa) but on practice IDE console is loosing it's functionality ('ctrl+c' like u have said before, Up keyword doesn't print the previous command, backspaces don't properly clear console and etc). That all makes console kind of vulnerable for improper input. No way to change it?

  • I'm not sure quite what you're doing with inbuf? If you just had USB.on('data', data => LoopbackB.write(data)) I'd have thought up-arrow and stuff like that would work fine.

    Ctrl-C doesn't work because JS is effectively single-threaded. Data is only transferred between USB/Loopback when your JS is run which transfers it - but if you are running other code then the JS that does that doesn't run. To work around it normally there's some special code in the interpreter which looks for Ctrl-C as it comes in, in the interrupt.

    If you want to figure out how to properly interpret the data you're getting, google VT100 - that's effectively what you have. Espruino does have a very simplistic implementation in­s which handles writing everything out to a Graphics instance, and potentially you could use that if you really needed to.

  • Thanks for all answers and advices you have given me! All of that was extremly helpful.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Redirecting console.log

Posted by Avatar for Nicktonious @Nicktonious