2

I want to get the console contents of the current running Node.js script.

I've tried to do this event but it doesn't work:

setInterval(function() { console.log("Hello World!") }, 1000);

process.stdout.on('message', (message) => {
    console.log('stdout: ' + message.toString())
})

It doesn't listen to the event.

8
  • maybe this event doesn't fire Commented Jan 27, 2019 at 15:04
  • @Vadi how? I tried to set a timer every second to send a message using console.log but this event still doesn't do anything. Commented Jan 27, 2019 at 15:05
  • @gabudu with just code provided, hard to say, why it doesn't do anything. Add other parts, related timer. Commented Jan 27, 2019 at 15:07
  • @Vadi i edited it and added the timer Commented Jan 27, 2019 at 15:17
  • there's no other parts for now Commented Jan 27, 2019 at 15:17

3 Answers 3

1

This is not a fully Node.js solution but it is very good in case you run Linux.

  1. Create a start.sh file.

  2. Put the following into it:

start.sh:

#!/bin/bash
touch ./console.txt
node ./MyScript.js |& tee console.txt &

wait
  1. Now open your Node.js script (MyScript.js) and use this Express.js event:

MyScript.js:

const fs = require('fs');
app.get('/console', function(req, res){
    var console2 = fs.readFileSync("./console.txt", 'utf8');
    res.send(console2);
});
  1. Always start your Node.js application by calling start.sh

Now calling http://example.com/console should output the console!

  • A part of this answer was used.

  • NOTE: To format the line breaks of the console output to be shown correctly in the browsers, you can use a module like nl2br.

  • An advice: The problems aren't always solved the direct way, most of the problems are solved using indirect ways. Keep searching about the possible ways to achieve what you want and don't search about what you're looking for only.

Sign up to request clarification or add additional context in comments.

1 Comment

Using readFileSync on an express route, is wrong. Aside from blocking the event loop, if the file is too large, you will get an out of memory error crashing the server. You should use fs.createReadStream and pipe it to res.
1

There's no 'message' event on process.stdout.

I want to make a GET in my Express.js app called /getconsole .. it should return the console of the current running Node.js script (which is running the Express.js app too)

What you should use is a custom logger, I recommend winston with a file transport, and then you can read from that file when you issue a request to your endpoint.

const express = require('express');
const fs = require('fs');
const winston = require('winston');
const path = require('path');

const logFile = path.join(__dirname, 'out.log');
const app = express();

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.json(),
    transports: [
        new winston.transports.Console({
            format: winston.format.simple()
        }),
        new winston.transports.File({
            filename: logFile
        })
    ]
});


// Don't use console.log anymore.
logger.info('Hi');


app.get('/console', (req, res) => {
    // Secure this endpoint somehow
    fs.createReadStream(logFile)
        .pipe(res);
});

app.get('/log', (req, res) => {
    logger.info('Log: ' + req.query.message);
});

app.listen(3000);

You can also use a websocket connection, and create a custom winston transport to emit the logs.

Comments

0

stdout, when going to a tty (terminal) is an instance of a writable stream. The same is true of stderr, to which node writes error messages. Those streams don't have message events. The on() method allows solicitation of any named event, even those that will never fire.

Your requirement is not clear from your question. If you want to intercept and inspect console.log operations, you can pipe stdout to some other stream. Similarly, you can pipe stderr to some other stream to intercept and inspect errors.

Or, in a burst of ugliness and poor maintainability, you can redefine the console.log and console.error functions to something that does what you need.

It sounds like you want to buffer up the material written to the console, and then return it to an http client in response to a GET operation. To do that you would either

  1. stop using console.log for that output, and switch over to a high-quality logging npm package like winston.

  2. redefine console.log (and possibly console.error) to save its output in some kind of simple express-app-scope data structure, perhaps an array of strings. Then implement your GET to read that array of strings, format it, and return it.

My first suggestion is more scalable.

By the way, please consider the security implications of making your console log available to malicious strangers.

1 Comment

What if I want to get the Node.js errors too (which are stored in the console)?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.