Can I capture the console output in Node.js? - javascript

I am trying to kill a process at first, I executed with
exec = require('child_process').exec;
exec('kill xxx', function(error, stdout, stderr) {
if (error) {
console.log('exec error: ', error);
}else{
console.log(stdout)
}
});
I noticed the kill program probably started a child process, whose output cannot be captured here as stdout.
So can I generally capture these console output which seem to be not very relevant with the code?

Stolen: Node: log in a file instead of the console
var fs = require('fs');
var util = require('util');
var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;
console.log = function(d) { //
log_file.write(util.format(d) + '\n');
log_stdout.write(util.format(d) + '\n');
};
ANSWER #2
This message is not created by console.log rather just the Linux system itself. How to catch this?
I think you should be able to do something with fs like so...
var fs = require('fs');
var util = require('util');
var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;
const command = 'node your_node_script'; //Whatever you would run in terminal
cp.exec(command, (error, stdout, stderr) => {
if(error) {
log_file.write(error);
}
if(stdout) {
log_file.write(stdout);
}
if(stderr) {
log_file.write(stderr);
}
});

Related

Select a random file and move with node.js

i'm trying to fix a bug with my twitter bot, basically, there is an array with all the filenames of the folder, then selects one randomly and posts it, but sometimes posts the same image again, how can i fix it?
here is the code
var fs = require('fs'),
path = require('path'),
Twit = require('twit'),
set = require(path.join(__dirname, 'set.js'));
//array of files
files_memes = require(path.join(__dirname, 'files.js'))
var currentdate = new Date();
var upl = "Subido: "
+ currentdate.getHours() + ":"
+ currentdate.getMinutes()+ " hs.";
var setMin = 10;
var T = new Twit(set);
function random_file(){
var allFiles = (files_memes)//array
return allFiles[Math.floor(Math.random() * allFiles.length)];
}
var filename = (random_file());
var imgPATH = path.join(__dirname, '/memestorage/queue/' + filename);
//image selection and upload
function upload_random_image(){
console.log('Opening file...');
var image_path = imgPATH,
b64content = fs.readFileSync(image_path, { encoding: 'base64' });
console.log('Uploading file...');
T.post('media/upload', { media_data: b64content }, function (err, data, response) {
if (err){
console.log('ERROR');
console.log(err);
}
else{
console.log('File loaded!');
T.post('statuses/update', {
media_ids: new Array(data.media_id_string)
},
function(err, data, response) {
if (err){
console.log('Error!');
console.log(err);
}
else{
console.log('Tweeted!');
console.log(upl);
console.log('Next tweet in ' + setMin + ' min.');
}
}
);
}
});
}
//timer
setTimeout(
upload_random_image,
0
);
setInterval(
upload_random_image,
1000*10
);
I've tried with
...
var filename = (random_file());
var pfile = ("posted"+random_file());
var imgPATH = path.join(__dirname, '/memestorage/queue/' + filename);
var postedFile = path.join(__dirname, '/memestorage/posted/' + pfile);
fs.rename(imgPATH, postedFile, function(err) {
if ( err ) console.log('ERROR: ' + err);
});
//image selection and upload
function upload_random_image(){
console.log('Opening file...');
var image_path = imgPATH,
b64content = fs.readFileSync(imgPATH, { encoding: 'base64' });
...
But posts the same image over and over again, or sometimes gives this error message:
fs.js:640
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
^
Error: ENOENT: no such file or directory, open 'D:\memesbot\memestorage\queue\645 (2).jpg'
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at Object.fs.readFileSync (fs.js:508:33)
at Timeout.upload_random_image [as _onTimeout] (D:\memesbot\memes.js:29:23)
at ontimeout (timers.js:365:14)
at tryOnTimeout (timers.js:237:5)
at Timer.listOnTimeout (timers.js:207:5)
Hope someone can help me, thanks.
Code seem to be generating random file at start (var filename = (random_file());) but not at run of upload_random_image().
So, file is selected randomly one and upload_random_image is called multiple times with setInterval
Solution:
Move below line inside the method upload_random_image
var filename = (random_file());
var imgPATH = path.join(__dirname, '/memestorage/queue/' + filename);

Node.JS RemoteExec call not firing properly

Querying a database for a list of servers to perform a command on. The array is populated properly and echos out as planned, but none of the connections occur. I tried both passing the array directly into rexec and looping through a forEachAsync. Neither process the server list properly. Am I referencing the array elements improperly?
Mind the syntax errors at the end, I was just trying to include both methods I tried.
#!
var mysql = require('mysql');
var resultset = require('node-array');
var rexec = require('remote-exec');
var fs = require('fs');
var _ = require('lodash');
//var streamBuffers = require('stream-buffers');
var moment = require('moment');
var util = require('util');
var now = moment().format('YYYYMMDD_HHmmss');
var logStdout = process.stdout;
var errStderr = process.stderr;
console.log = function () {
logStdout.write(util.format.apply(null, arguments) + '\n');
}
console.error = function () {
errStderr.write(util.format.apply(null, arguments) + '\n');
}
var connection = mysql.createConnection({
host : 'abc',
user : 'user',
password : '******',
database : 'db'
});
var ssh_options = {
port: 22,
username: 'e109gh',
privateKey: fs.readFileSync('R:/nodeJS/sshkey.priv'),
stdout: fs.createWriteStream('./out.txt'),
stderr: fs.createWriteStream('./err.txt')
}
var my_conn_options = _.clone(ssh_options);
var cmds = ['hostname -i'];
connection.query('SELECT name FROM server', function(err, rows) {
rows.forEachAsync(function(element, index, array) {
console.log(element.name);
rexec(element.name,cmds,my_conn_options,function(err){
if (err) {
now = moment().format('YYYY-MM-DD HH:mm:ss');
console.error(err);
} else {
console.log("it worked for "+element.name);
}
});
});
});
// var buffer = new streamBuffers.WritableStreamBuffer();
connection.end(function(err) {});
// my_conn_options.stdout = buffer;
//
// rexec(rows,cmds,my_conn_options,function(err){
// if (err) {
// now = moment().format('YYYY-MM-DD HH:mm:ss');
// console.error(err);
// } else {
// console.log()
// }
// });
//
//});

Node.JS - want to move output off console into log/err files

Can someone give me a hand with converting the following code from console output to file output? I'm struggling with logging and the asynchronous nature of Node. The script works great in a console, but I'd like to pipe the sorted output into individual server sections within a file with STDERR going to another file.
var rexec = require('remote-exec');
var fs = require('fs');
var lineReader = require('line-reader');
var streamBuffers = require('stream-buffers');
var _ = require('lodash');
var conn_options = {
port: 22,
username: '*****',
privateKey: fs.readFileSync('R:/nodeJS/sshkey.priv')
}
// something that dumps out a bunch of data...
var cmds = ['df']
var filename = 'servers.txt';
lineReader.eachLine(filename,function(line,last,cb){
var buffer = new streamBuffers.WritableStreamBuffer();
var my_conn_options = _.clone(conn_options);
rexec(line,cmds,my_conn_options,function(err){
if (err) {
console.log(line, err);
} else {
console.log('>>>> Start: ' + line + '<<<<')
console.log(buffer.getContentsAsString());
console.log('>>>> End: ' + line + '<<<<')
};
});
if (last) {
cb(false); // stop reading
} else {
cb();
}
});
check this example, that should help..
var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream('log.txt', { flags: 'a' });
// Or 'w' to truncate the file every time the process starts.
var logStdout = process.stdout;
console.log = function () {
logFile.write(util.format.apply(null, arguments) + '\n');
logStdout.write(util.format.apply(null, arguments) + '\n');
}
console.error = console.log;

Reading a file line by line, parse them and insert them in mongo in node js

I have a file which is tab separated. It has thousands of data. How can I use nodeJs to read the file, line by line, parse them and create an object and insert them in a mongo DB.
I am just learning node and mongo. I come from different background. So how can this be done.
Finally the Mongo DB has to be populated with proper data.
I searched in net but I could not find the complete solution.
Thanks.
I had an issue with the answer by Juvenik. My problem was that the database would not be populated by the time readline had completed. The lines were being read synchronously, but the DB insertion was asynchronous.
Instead, I found a simpler solution with the line-reader package. It reads the lines and waits for a callback before continuing.
var MongoClient = require('mongodb').MongoClient
var dbName = 'yourDbName'
var url = 'mongodb://localhost:27017/' + dbName
var collectionName = 'yourCollectionName'
var filename = 'yourFileName.txt'
var printLine = 1000
MongoClient.connect(url, function(err, db) {
if (err) {
console.error('Problem connecting to database')
} else {
console.log('Connected correctly to server.')
var lineReader = require('line-reader')
var collection = db.collection(collectionName)
var lineNum = -1
var headers = []
lineReader.eachLine(filename, function(line, last, cb) {
lineNum++
try {
var split = line.split('\t')
var object = {}
if (lineNum > 0) {
for (var i = 0; i < split.length; i += 1) {
object[headers[i]] = split[i]
}
collection.insert(object, function (insertErr, insertObj) {
if (insertErr) console.error(insertErr)
if (lineNum % printLine === 0) console.log('Line ' + lineNum)
if (last) {
console.log('Done with ' + filename + ' (' + lineNum + ' records)')
process.exit(0)
} else {
cb()
}
})
} else {
headers = line.split('\t')
cb()
}
} catch (lineError) {
console.error(lineError)
}
})
}
})
I came across similar problem. This approach worked for me.
Have a look, it might be helpful.
var mongoDb = require('mongodb');
var mongoClient = mongoDb.MongoClient;
var dbname = 'YOUR_DB_NAME';
var collectionName = 'YOUR_COLLECTION_NAME';
var url = 'mongodb://localhost:27017/'+dbname;
var filename = 'FIle_Name.txt';
console.log('***************Process started');
mongoClient.connect(url,function(err,db){
if(err){
console.log('error on connection '+err);
}
else{
console.log('***************Successfully connected to mongodb');
var collection = db.collection(collectionName);
var fs = require('fs');
var readline = require('readline');
var stream = require('stream');
var instream = fs.createReadStream(filename);
var outstream = new stream;
var rl = readline.createInterface(instream,outstream);
console.log('***************Parsing, please wait ...');
rl.on('line',function(line){
try{
var arr = line.split('\t');
var object = {};
//Parse them here
//Example
object['name'] = arr[0]; //Just an example
var res = collection.insert(object);
}
catch (err){
console.log(err);
}
});
rl.on('close',function(){
db.close();
console.log('***************completed');
});
}
});
I am a learner too. If someone can make it better, it will be good.
Here is a more performant (inserting batches of objects) and updated version (using async and latest mongo driver) of frank-0's answer
const lineReader = require('line-reader');
async function readFileAndInsertInMongo(file) {
let total = 0;
return new Promise((resolve, reject) => {
let buffer = [];
lineReader.eachLine(file, (line, last, cb) => {
// prepare your object based on the line content
let insertObject = {'some_content': 'some_value'};
if (total % 10000 === 0 || last) {
collection.insertMany(buffer, function(err, res){
if (last) {
if (err) {
reject(err);
} else {
resolve(res);
}
} else {
buffer = [];
return cb();
}
});
} else {
buffer.push(insertObject);
return cb();
}
});
});
}
This really is the best solution I have found to parse huge files and insert them in the database without exploding Node's memory. Hope this can help ;)

Node js child_process.execFile return

I need to run a compiled file in C + + with node.js and bring me back a value from this file.
I tried to use child_process.execFile, but I have no problems.
This is the function I use:
var exec = require('child_process');
Test.prototype.write = function (m) {
var wRet;
exec.execFile ('./mainCmd', ['-o', '\\!' + m + '.']
function (error, stdout, stderr) {
wRet = stdout;
console.log ("wRet" + wRet);
return wRet;
});
}
The problem is that the wRet in "console.log" contains text me back from the file c + +, in the "return" remains undefined.
Can you help?
Thank you all!
You have to pass a callback to your test() function:
var chproc = require('child_process');
Test.prototype.write = function(m, cb) {
chproc.execFile(
'./mainCmd',
['-o', '\\!' + m + '.'],
function(error, stdout, stderr) {
if (error) return cb(error);
cb(null, stdout);
}
);
};
// usage ...
var t = new Test();
t.write('foo', function(err, result) {
if (err) throw err;
// use `result`
});

Categories

Resources