I want to know what are the option of logging with Express similar to what good is to HAPI. I tried Morgan but not sure how can I log response time and other response information.
Thanks in advance for help,
Devang Desai
You could use custom token in Morgan.
For example, if you wanna log the HTTP method, status code, response time, and process ID, you could use this
// Define a custom token 'pid'
morgan.token('pid', function (request, response) { return process.pid; });
// Do the logging
app.use(morgan(function (tokens, request, response) {
var log = tokens['method'](request, response) + ' ';
log += tokens['status'](request, response) + ' ';
log += tokens['response-time'](request, response) + ' ms - PID: ' + tokens['pid'](request, response);
return log;
}));
Related
I am needing to find a way to get a response as a result of a https post request. So far from what I hae found that is only provided in the call back function, which does not include the result after data is written to the request and is ended as shown below:
**Note: the code below would be wrapped inside a "app.post" method.
const https = require("https");
var url = "https://someurl.com";
var options = {option1: "some option"}
var jsonData = {data1: "some data"};
const request = https.request(url, options, function (repsonse) {
// HERE THE STATUS CODE ONLY CAPTURES IF THE RESOURCE WAS AVAILABLE
// NOT IF THE REQUEST WAS SUCCESSFUL
console.log(response.statusCode);
});
request.write(jsonData);
request.end();
After the "request.end()" code i need to be able to get the status code returned from the request to determine if the actual request was successful. I would want to do something like this:
if (response.statusCode !== 200) {
res.sendFile(__dirname + "/failure.html");
}
else {
res.sendFile(__dirname + "/success.html");
}
The if statement should run after request.end() to determine if the actual request was successful. This is standard for using API frameworks such as Flask-Python, but I can't seem to find a way to catch this in express.js. Any help would be appreciated.
https.request works asynchronously. Whether the request is successful or not cannot be determined synchronously after the request.end(), but only in the callback function (where you can evaluate response.statusCode) or in the error event (if the request could not be made at all, for example because the server was unreachable).
const request = https.request(url, options, function (response) {
console.log(response.statusCode);
if (response.statusCode !== 200)
res.sendFile(__dirname + "/failure.html");
else
res.sendFile(__dirname + "/success.html");
});
request.on("error", function(err) {
console.error(err);
res.sendFile(__dirname + "/failure.html");
});
request.write(jsonData);
request.end();
Basically, I'm trying to get Access Token from Facebook in my callBack GET method. Below is my code.
getAccessToken is not called at all. What's the right way to implement it?
app.get('/fbcallback', function(req, res) {
var code = req.query.code;
var getAccessToken = 'https://graph.facebook.com/v2.12/oauth/access_token?'+
'client_id='+client_id+
'&redirect_uri='+redirect_uri+
'&client_secret='+client_secret+
'&code='+code;
app.use(getAccessToken, function(req, res) {
console.log('Token Call');
});
});
You should not use app.use inside get the call.
You must be trying to do something like below. Inside get call make another get call for getting token.
var request = require('request');
app.get('/fbcallback', function (req, res) {
var code = req.query.code;
var getAccessToken = 'https://graph.facebook.com/v2.12/oauth/access_token?' +
'client_id=' + client_id +
'&redirect_uri=' + redirect_uri +
'&client_secret=' + client_secret +
'&code=' + code;
request(getAccessToken, function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML for the Google homepage.
});
});
var http = require('http');
var fs = require('fs');
var path = process.argv[2];
var str="";
function onRequest(request, response) {
str += "";
console.log("Request received" + path);
fs.readdir(path, function(err, items) {
str += items;
});
response.writeHead(200, {"Context-Type": "text/plain"});
response.write(new Buffer(str).toString());
response.end();
}
http.createServer(onRequest).listen(8000);
The above snippet creates a http server which gets a directory path from the user as argument. Make a http request to get the list of files available in the directory and send them back as a response.
The response is written to the page only on the second request. The page is shown empty on the first request.
Could anyone help. Thanks in advance!!
Javascript is non blocking, so
response.writeHead(200, {"Context-Type": "text/plain"});
response.write(new Buffer(str).toString());
response.end();
will be executed before
str += items;
With
fs.readdir(path, function(err, items) {
// Handle error
str += items;
response.writeHead(200, {"Context-Type": "text/plain"});
response.write(new Buffer(str).toString());
response.end();
});
it will send the response after readdir.
And in Javascript the program will not be started for every new Request (like in PHP). So your global variable will be shared between all requests. If you don't want that put the var str=""; in onRequest.
If you have multiple routes you also want to look into something like express, because the http module doesn't include routing.
My source code:
var http = require("http");
var count=1;
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hi, you are number "+count+" visitors");
response.end();
count++;
}).listen(8888);
I got 1,3,5,7,..... in each visit. Why to increment the count by 2?
The request to favicon.ico is triggering an extra request (I confirmed this by logging the details for each request and then making a normal request with Chrome).
You will need to look explicitly for the type of request (url, method, etc) you're wanting to match.
Also, keep in mind, if your server dies, which it probably will at some stage, your count will be reset. If you don't want that, you should persist it somewhere less volatile, such as a database.
If your server is just a simple counter and knowing that the request to favicon.ico is triggering an extra request, then you can simple count every request as a half so it will result in exact number of visits.
counter = counter + 0.5;
You could ignore the request for the favicon.ico:
var server = http.createServer(function (req, res) {
if(req.url === '/favicon.ico'){
console.log('favicon');
return;
}
userCount++;
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('Hello!\n');
res.write('We have had ' + userCount + ' visits!\n');
res.end();
});
Node.js (express) web server
Request handler in web server
app.get('/documents/ajax/:id.:format?', function(req, res) {
console.log ('Request Received');
var body = 'hello world';
res.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
})
ajax request from client side javascript
$.ajax({
url : "/documents/ajax/" + item,
success : function(msg) {
alert ("success" + msg);
},
error : function(request, status, error) {
alert("Error, returned: " + request);
alert("Error, returned: " + status);
alert("Error, returned: " + error);
}
});
I am able to receive the request on server side and I send 4 requests
But my success event is not getting called in client side JS. Also, when I stop my web server, then I see my error handlers get called.
Please help.
The main issue is that you are not ending the response so the server never actually sends anything to the client. The server should respond with something like a file, a redirect, some text, etc. You need to finish the callback with a res.end, res.send, res.sendfile, res.redirect, res.render... See the docs.
Furthermore, with express you want to use res.set to set the http headers:
app.get('/documents/ajax/:id.:format?', function(req, res) {
console.log ('Request Received');
var body = 'hello world';
res.set({'Content-Type': 'text/plain'});
res.send(body);
});
200 is the default response code, so you don't need to specify that and the length will be computed for you. These things are often easier to debug from the command line via curl:
curl http://localhost:3000/documents/ajax/1
and
curl -I http://localhost:3000/documents/ajax/1
I had to res.end in server request handler. After that I was able to generate success event in client side JS