console.log into different terminal window - node.js - node.js

In our nodejs project, there are several pages of debug info logged into one default console window for each HTTP request. It is very difficutlt to find out the info that is logged by me.
I am not at liberty to edit other part of the code in this project. I'd like to to create a new terminal window and only log my debug info to this window.
Question:
It is possible to do it using console.log along? If not, anyway to launch a new terminal window and log my info there? I think nodejs can control local file system and call OS functions. There must be a way.
Thanks!

You can create custom Console objects:
var Console = require('console').Console;
var fs = require('fs')
var stream = fs.createWriteStream('/tmp/mylog');
var console = new Console(stream, stream);
var i = 0;
(function log () {
console.log(i++);
setTimeout(log, 1000);
} ())
Then just do tail -f /tmp/mylog

Use a different log. Winston supports tons of log formats as well as multiple logging channels. Instead of sending your debug info to the console, send it to a file. You can read it later or tail -f it in real time.

Related

NodeJS open local file using the default preview

I am trying to create a desktop app using electron which includes a function where a user can open a desired file saved in the local storage. Sine I am using MacOS, I want to use nodejs to be able to open the file (e.g. PDF doc) in the default preview software. is there any way to do this?
Thank you in advance.
A portable way is to make use of the Electron's shell API, specifically the shell.openPath method:
const { shell } = require('electron');
shell.openPath("/fullpath/to/file");
It is available both in the main process and in the renderer process, and it can also be used to open a folder in the Finder.
if anyone is wondering I found a way of using
const { exec } = require('child_process')
exec('open ~/path/to/file')
this used command shell (terminal) to open it. If there is any other better way to do it please let us know!

Tail a file efficiently in nodejs

I am creating an application which would watch a file and fetch the contents from that file (similar to tail but with the possibility of paging in previous data as well). I read up on quite a few solutions ranging from spawning a new process to getting only the updated bytes of the file but I am still a little confused on a few parts.
What I want to do exactly is the following:
Watch a file and trigger an event/callback whenever new data comes into the file
Read this new data from the file and efficiently send it to a client. Using a websocket or something else. (suggest a good way to do this please)
At the client end, take this data and display it to user and keep updating it with new data as it comes
If the user requests older data a way to fetch that data from the file we are watching
I am looking for efficient solutions for the above sub problems and any suggestions for a better approach are also welcome.
FYI I am new to nodejs so verbosity in your solutions would be highly appreciated.
Watch for changes
Suggest you look at chokidar, it is an optimized implementation of fs.watch, fs.events, the native node.js libraries.
// Initialize watcher.
const watcher = chokidar.watch('some/directory/**/*.xml', config);
// Add event listeners.
watcher
.on('add', path => log(`File ${path} has been added`))
.on('change', path => log(`File ${path} has been changed`))
.on('unlink', path => log(`File ${path} has been removed`));
To get the changed value
Here you can look at diff module. And you will need to store the state of the previous and current files. In order to build the changes.
To notify the client
You will need to create a websocket server, recommend you to use socket.io and then in your application you will create the diff and send a websocket message to the server. The server will notify/broadcast the message to the needed clients.

How to test advanced interactions when developing an Alexa Skill

I am developing an Alexa Skill, and I am struggling a bit in understanding if I setup everything in the best way possible to debug while developing.
Right now I am developing locally using Node.js, uploading to the cloud when ready, and testing all the responses to intents using the Service Simulator in the Test section of the developer console.
I find the process a bit slow but working... But still, I have two questions:
1) Is there a way of avoiding the process of uploading to the cloud?
And mostly important 2) How do I test advanced interactions, for examples multi-step ones, in the console? How for example to test triggering the response to an intent, but then asking the user for confirmation (Yes/No)? Right now the only way of doing it is using the actual device.
Any improvement is highly appreciated
Like #Tom suggested - take a look at bespoken.tools for testing skills locally.
Also, the Alexa Command Line Interface was recently released and it has some command line options you might look into.
For example, the 'api invoke-skill' command lets you invoke the skill locally via the command line (or script) so you don't have to use the service simulator. Like this...
$ask api invoke-skill -s $SKILL_ID -f $JSON --endpoint-region $REGION --debug
Here is a quick video I did that introduces the ASK CLI. It doesn't specifically cover testing but it will provide a quick intro.
https://youtu.be/p-zlSdixCZ4
Hope that helps.
EDIT: Had another thought for testing locally. If you're using node and Lambda functions, you can call the index.js file from another local .js file (example: test.js) and pass in the event data and context. Here is an example:
//path to the Lambda index.js file
var lambdaFunction = require('../lambda/custom/index.js');
// json representing the event - just copy from the service simulator
var event = require('./events/GetUpdateByName.json');
var context = {
'succeed': function (data) {
console.log(JSON.stringify(data, null,'\t') );
},
'fail': function (err) {
console.log('context.fail occurred');
console.log(JSON.stringify(err, null,'\t') );
}
};
function callback(error, data) {
if(error) {
console.log('error: ' + error);
} else {
console.log(data);
}
}
// call the lambda function
lambdaFunction.handler (event, context, callback);
Here's how I'm testing multi-step interactions locally.
I'm using a 3rd party, free, tool called BSTAlexa:
http://docs.bespoken.tools/en/latest/api/classes/bstalexa.html
It emulates Amazon's role in accepting requests, feeding them to your skill, and maintaining the state of the interactions.
So I start my test script by configuring BSTAlexa - pointing it to my skill config (eg. intents) and to a local instance of my skill (in my case I'm giving it a local URL).
Then I feed BSTAlexa a sequence of textual requests and verify that I'm getting back the expected responses. And I put all this in a Mocha script.
It works quite well.
Please find answers (Answering in reverse order),
You can test multiple steps using simulator (echosim.io) but each time you have to press and hold Mic button (Or hold on space bar). Say for example first you are asking something to Alexa with echosim and alexa responding to confirm'yes/no' then you have to press and hold mic button again to respond to confirm it.
You can automate the lambda deployment process. Please see the link,
http://docs.aws.amazon.com/lambda/latest/dg/automating-deployment.html
It would be good to write complete unit tests so that you can test your logic before uploading Lambda. Also it will help to reduce the number of Lambda deployments

Running a jar file in bluemix, inside a dialog app

I'm currently trying to create an application like a Virtual Agent, using Watson Dialog. I have to use Node.js with this Watson service, but I have never used it before, so I took my time.
For now, I can use Java to call the dialog service to simulate an user. But I want to use Node.js to call Java to simulate the Agent.
In Watson Dialog, the Agent has a number of sentences written in a file like dialog.xml. But instead I want my Agent to ask specific questions according to the user's profile.
That's why I'm using a BRMS tool, written in Java. I created a .jar and want to call it in /public/demo.js to fill the variable response:
var texts = dialog.conversation.response;
var response = texts.join('<br/>');
I tried this in /public/demo.js:
var exec = require('child_process').exec;
var child = exec('java -jar C:\\PATH\\Example.jar',
function (error, stdout, stderr){
response += stdout;
if(error !== null){
console.log("Error -> "+error);
}
});
Using that code in another application, it works without any problem, I can run my .jar. I'm sure of it. But once written in my Bluemix app, the first line make it crash. Am I missing something in the manifest.yml file? Do I need to change a config? Or maybe it comes from the demo.js file?
Thank you for helping.

Is there a way change a node.js while it's running?

Is there a way change a node.js while it's running?
Like edit the javascript files while it's running and then it change accordingly while it's running.
Yes.
You'll have to load your file through another file that watches the script for changes. You will probably need some setup/teardown code that runs in the script whenever it is restarted.
var fs = require('fs');
var file = 'file.js';
var script;
function loadScript() {
if (script) {
if (typeof script.teardown === 'function') {
script.teardown();
}
delete require.cache[file];
}
script = require(file);
}
fs.watch(file, function(event, filename) {
if (event !== 'change') return;
loadScript();
});
loadScript();
The fs.watch API is not 100% consistent across platforms, and is unavailable in some situations.
Have you checked Node-supervisor
No, it is not possible. When you startup a Node server / app it will load in the current versions of the files. If you make a change after startup it will be unaware. You will have to kill the app and restart for these changes to take affect.
There are some utilities like node-dev which do this for you. They monitor the filesystem for changes and restart the app as needed (along with some other features like growl notification).
I prefer restarting the app manually. That way you know exactly what version it's running, and can save changes to a file multiple times before deciding to try it out again.
You can use nodemon.
nodemon will watch the files in the directory in which nodemon was started, and if any files change, nodemon will automatically restart your node application.
Perfect solution to work with Node during development.
This is totally possible.
Just don't require your modules in the header; instead, load them by calling at the time of need.
In addition, you can also call require.undef('./myModule') to ditch existing versions before including the new module. You can scan the file system for any new module names, if you feel like dropping in new behavior at runtime.
I have implemented the plugin pattern numerous times with node, such that a submodule update will include new plugins that will be picked up at runtime.
Enjoy.

Resources