Created
July 13, 2018 10:38
-
-
Save devarajchidambaram/8013bd719d0071e51482440b4f691cc1 to your computer and use it in GitHub Desktop.
how to profile nodejs applications
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'); | |
var profiler = require('@risingstack/v8-profiler') | |
var request = require('request') | |
var samplingIntervalMicros = 1000; | |
var express = require('express') | |
var app = express(); | |
var bodyParser = require('body-parser') | |
var enableProfiler = false; | |
app.use(bodyParser.json()) | |
app.use(bodyParser.urlencoded({ | |
extended: false | |
})) | |
app.get('/', function (req, res) { | |
var startTime = new Date(); | |
if(req.query.enable == 'true'){ | |
enableProfiler = true; | |
}else{ | |
enableProfiler = false; | |
} | |
if (enableProfiler) profiler.startProfiling('1', true); | |
request.get('https://nodejs.org/api/fs.html', function (err, data) { | |
if (err) throw err; | |
fs.stat('./package.json', function (err, stats) { | |
if (err) throw err; | |
fs.readFile(__filename, function readFileCallback(err, data) { | |
if (err) throw err; | |
setTimeout(function timeoutCallback() { | |
if (enableProfiler) { | |
var profile1 = profiler.stopProfiling(); | |
fs.writeFileSync('./profile1.json', JSON.stringify(profile1)); | |
var profileWithTimingInformation = exports.toTreeWithTiming(profile1, samplingIntervalMicros); | |
console.log('v8 profiler completed.......') | |
fs.writeFileSync('./profile1_modified.json', JSON.stringify(profileWithTimingInformation)); | |
} | |
console.log('execution time :', new Date() - startTime) | |
res.send('success!!!!!!!!!') | |
// console.log('profile header', profile1.getHeader()); | |
// profile1.export(function (error, result) { | |
// var profile = profiler.stopProfiling(); | |
// fs.writeFileSync('profile1.json', result); | |
// profile1.delete(); | |
// res.send('success!!!!!!!!!') | |
// }); | |
}, 9000) | |
}) | |
}) | |
}) | |
}) | |
exports.toTreeWithTiming = function toTreeWithTiming(profile) { | |
return processRawNode(profile.head); | |
}; | |
function processRawNode(rawNode) { | |
/** | |
S= self time & total time | |
self is how much time was spent doing work directly in that function. | |
total is how much time was spent in that function, and in the functions it called. | |
*/ | |
//How to calculate self time or method time and total time in V8 Profiler | |
//https://github.com/jlfwong/chrome2calltree | |
/** | |
"functionName": "(root)", | |
"url": "", | |
"lineNumber": 0, | |
"callUID": 108, | |
"bailoutReason": "", | |
"id": 1, | |
"scriptId": 0, | |
"hitCount": 2, | |
(%N = Name and line no. & Method name, %M = method time, %T = total time, %c = Class Name, %m = Method name | |
*/ | |
var node = { | |
functionName: rawNode.functionName, | |
url: rawNode.url, | |
lineNumber: rawNode.lineNumber, | |
sh: rawNode.hitCount, | |
th: rawNode.hitCount, | |
selfTime: 0, | |
totalTime: 0, | |
b: getBailoutReason(rawNode), | |
children: [] | |
}; | |
var children = rawNode.children; | |
for (var i = 0, len = children.length; i < len; i++) { | |
var childNode = processRawNode(children[i], samplingIntervalMicros); | |
node.children.push(childNode); | |
node.th += childNode.th; | |
} | |
node.totalTime = node.th * samplingIntervalMicros; | |
node.selfTime = node.sh * samplingIntervalMicros; | |
return node; | |
} | |
function getBailoutReason(rawNode) { | |
var reason = rawNode.bailoutReason; | |
if (!reason || reason === 'no reason') { | |
return undefined; | |
} | |
return reason; | |
} | |
app.listen(8080, function () { | |
console.log('app is listening in 8080 port') | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment