Skip to content

Commit

Permalink
Add a new feature: Trace Profiling (#335)
Browse files Browse the repository at this point in the history
Signed-off-by: Daxin Wang <[email protected]>
Co-authored-by: sangyangji <[email protected]>
Co-authored-by: jundizhou <[email protected]>
Co-authored-by: huxiangyuan <[email protected]>
Co-authored-by: yaofighting <[email protected]>
Co-authored-by: niejiangang <[email protected]>
Co-authored-by: yiqianxu <[email protected]>
  • Loading branch information
7 people authored Oct 25, 2022
1 parent da7d7e0 commit 0c5ae59
Show file tree
Hide file tree
Showing 139 changed files with 40,014 additions and 366 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
build/
probe/src/probe/cmake-build-debug/
probe/build/
probe/cmake-build-debug

collector/docker/kindling-collector
collector/docker/libso/libkindling.so
collector/docker/kindling-falcolib-probe.tar.gz

node_modules
*.log
logs
19 changes: 19 additions & 0 deletions camera-front/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM node:16.18.0-alpine3.15 AS appbuild
RUN npm install -g cnpm --registry=https://registry.npmmirror.com
WORKDIR /app/camera-front
COPY package*.json .
RUN cnpm install
COPY . .
RUN npm run build

FROM node:16.18.0-alpine3.15
RUN npm install -g cnpm --registry=https://registry.npmmirror.com
RUN cnpm install pm2 -g
WORKDIR /app/camera-front
COPY node/ ./node
RUN chmod +x /app/camera-front/node/start.sh
WORKDIR /app/camera-front/node
RUN cnpm install
WORKDIR /app/camera-front
COPY --from=appbuild /app/camera-front/dist ./dist
CMD ["/app/camera-front/node/start.sh"]
10 changes: 10 additions & 0 deletions camera-front/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# The Camera Front-end
## How to build the image
```
docker build -t camera-front .
```

## How to run the image
```
docker run -d --rm -p 9504:9504 camera-front:latest
```
13 changes: 13 additions & 0 deletions camera-front/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kindling APP</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
7 changes: 7 additions & 0 deletions camera-front/main.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare module 'rc-calendar/lib/RangeCalendar';
declare module 'rc-calendar/lib/locale/zh_CN';

declare module 'rc-time-picker/lib/Panel';

declare module 'd3-tip';
declare module 'd3-flame-graph';
75 changes: 75 additions & 0 deletions camera-front/node/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const express = require('express');
const app = express();
const http = require('http');
const serveStatic = require('serve-static');
const bodyParser = require('body-parser');
const _ = require('lodash');
const async = require('async');
const path = require('path');
const compression = require('compression');
const history = require('connect-history-api-fallback');
const { createProxyMiddleware } = require('http-proxy-middleware');

const settings = require('./settings');
const port = settings.port;

const restream = function (proxyReq, req) {
let masterIp = req.headers.authorization;
proxyReq.setHeader('Authorization', masterIp || '');
};
const esserverAdress = 'http://' + settings.apmServerConfig.host + ':' + settings.apmServerConfig.port;
const esserverProxy = createProxyMiddleware('/camera', {
target: esserverAdress,
secure: false,
changeOrigin: true,
// onProxyReq: restream,
// onProxyRes: async function (proxyRes, req, res) {
// // console.log(proxyRes, 'proxyRes');
// if (typeof req.session.username === 'undefined') {
// req.session.destroy();
// res.status(401).json({
// msg: noAuthorizeMsg,
// });
// }
// },
});
app.use(esserverProxy);
const profileAddress = 'http://' + settings.profileConfig.host + ':' + settings.profileConfig.port;
const profileProxy = createProxyMiddleware('/profile', {
target: profileAddress,
secure: false,
changeOrigin: true,
});
app.use(profileProxy);


app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.use(bodyParser.json());
app.use(compression());
// app.use(history());

app.use(express.static('../dist'));
console.log(__dirname);
// app.set('views', path.join(__dirname, 'dist'));
// app.use(serveStatic(path.join(__dirname, 'dist')));

app.get("/test", function(req, res, next) {
// res.render("test.html");
res.status(200).json({
test: true
});
});

app.use('/file', require('./routers/file.js'));

var httpServer = http.createServer(app);
// var httpsServer = https.createServer(credentials, app);
httpServer.listen(port, function() {
console.log('Express http server listening on port ' + port);
});
16 changes: 16 additions & 0 deletions camera-front/node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "camera_node",
"version": "1.0.0",
"description": "node for kindling camera",
"main": "index.js",
"author": "thousand",
"license": "MIT",
"dependencies": {
"async": "^3.2.4",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
"express": "^4.18.2",
"http-proxy-middleware": "^2.0.6",
"lodash": "^4.17.21"
}
}
137 changes: 137 additions & 0 deletions camera-front/node/routers/file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@

'use strict';
const router = require('express').Router();
const _ = require('lodash');
const fs = require('fs');

const settings = require('../settings');
const basicFloder = settings.traceFilePath;

router.get("/getFolders", function(req, res, next) {
let list = [], result = [];
fs.readdir(basicFloder, function(err, files) {
if (err) {
console.error("Error: ", err);
res.status(500).json({
success: false,
message: err
})
}
_.forEach(files, file => {
let fileStats = fs.statSync(basicFloder + "/" + file);
if (fileStats.isDirectory()) {
let fileNameList = file.split('_');
if (fileNameList.length === 4) {
list.push(fileNameList);
}
}
});
let workloadlist = _.groupBy(list, item => item[0]);
_.forEach(workloadlist, (list, workload) => {
let workloadObj = {
title: workload,
value: workload,
selectable: false,
children: []
};
let podList = _.groupBy(list, item => item[1]);
_.forEach(podList, (list2, pod) => {
let podObj = {
title: pod,
value: `${workload}_${pod}`,
selectable: false,
children: []
};
_.forEach(list2, item => {
podObj.children.push({
title: `${item[2]}(${item[3]})`,
value: _.join(item, '_')
});
});
workloadObj.children.push(podObj);
});
result.push(workloadObj);
});
// console.log(result);
res.status(200).json({
success: true,
data: result
});
});
});

router.get("/getAllTraceFileList", function(req, res, next) {
let folderName = req.query.folderName;
const filePath = basicFloder + "/" + folderName;
let list = [];
try {
let files = fs.readdirSync(filePath);
_.forEach(files, function(file) {
let fileStats = fs.statSync(filePath + "/" + file);
if (fileStats.isFile) {
let fileNameList = file.split('_');
let contentKeyBuffer = new Buffer.from(fileNameList[1], 'base64')
let contentKey = contentKeyBuffer.toString();
let newList = [].concat(fileNameList);
newList[1] = contentKey;
let showFileName = _.join(newList, '_');
list.push({
fileName: file,
showFileName,
contentKey,
ctime: new Date(fileStats.ctime).getTime()
});
}
});
list = _.sortBy(list, 'ctime');
} catch (err) {
console.error(err);
}
// console.log(list);
res.status(200).json({
"success": true,
"data": list
});
});

router.get('/getTraceFile', function(req, res, next) {
let fileName = req.query.fileName;
let folderName = req.query.folderName;
const filePath = basicFloder + '/' + folderName + '/' + fileName;
console.log(fileName, filePath)
fs.readFile(filePath, function(err, buffer) {
if (err) {
console.error("Error: ", err);
res.status(500).json({
success: false,
message: err
});
}
let result = buffer.toString();
let resList = result.split('---');
let traceData = JSON.parse(_.head(resList));
let cpuEventStrs = _.slice(resList, 1);
let cpuEventsList = [];
let cpuEvents = [];

_.forEach(cpuEventStrs, (str) => cpuEventsList.push(JSON.parse(str)));
cpuEvents = _.map(cpuEventsList, 'labels');
_.forEach(cpuEvents, item => {
item.cpuEvents = JSON.parse(item.cpuEvents);
item.javaFutexEvents = JSON.parse(item.javaFutexEvents);
item.transactionIds = JSON.parse(item.transactionIds);
});

let finalResult = {
trace: traceData,
cpuEvents: cpuEvents
};

res.status(200).json({
"success": true,
"data": finalResult
});
});
});

module.exports = router;
13 changes: 13 additions & 0 deletions camera-front/node/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const setting = {
apmServerConfig: {
host: 'localhost',
port: '2234',
},
profileConfig: {
host: 'localhost',
port: '9503',
},
traceFilePath: '/tmp/kindling',
port: 9504,
};
module.exports = setting;
14 changes: 14 additions & 0 deletions camera-front/node/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
cd `dirname $0`
pids=$(netstat -ltnp|grep 9900|awk '{print $7}');
if [ $pids ] ; then
pm2-runtime restart camera-node
else
pm2-runtime start index.js --name camera-node
fi
# pids=$(netstat -ltnp|grep 9091|awk '{print $7}');
# if [ $pids ] ; then
# pm2 restart apm-grafana-proxy
# else
# pm2 start grafana.js --name apm-grafana-proxy
# fi
Loading

0 comments on commit 0c5ae59

Please sign in to comment.