in middleware/controllers/pyroscope.js [84:144]
async function explainFlamegraph(req, res) {
const { query, from = "now-5m", until = "now", format = "pprof", test = false } = req.body;
const baseUrl = buildUrl(getEnv("PYROSCOPE_BASE_URL"), {
query: `${query}.cpu`,
from: from,
until: until,
format: format,
});
const config = {
method: 'get',
maxBodyLength: Infinity,
url: baseUrl,
responseType: 'arraybuffer',
};
if(test){
const testFilePath = path.join(__dirname, '../tmp/dummy_analysis.md')
const data = fs.readFileSync(testFilePath)
return res.type("text/markdown").send(data)
}
try {
const response = await axios.request(config);
const profileDir = path.join(__dirname, '../tmp');
if (!fs.existsSync(profileDir)) {
fs.mkdirSync(profileDir, { recursive: true });
}
const timestamp = Date.now();
const profilePath = path.join(profileDir, `profile-${timestamp}.pprof`);
fs.writeFileSync(profilePath, response.data);
try {
const markdown = await convertPprofToMarkdown(profilePath);
try {
const insights = await analyzeProfileContent(markdown);
return res.type("text/markdown").send(insights);
} catch (analysisError) {
logger.error('Error analyzing profile:', analysisError);
return res.type("text/markdown").send(markdown);
}
} catch (conversionError) {
logger.error('Error converting profile to markdown:', conversionError);
return res.send({
"error": "Unable to parse pprof data"
});
} finally {
fs.unlinkSync(profilePath);
}
} catch (error) {
logger.error(error);
return res.status(500).send({
error: error.message || "Error fetching profiling data",
});
}
}