Authored by htoooth

fix

... ... @@ -8,7 +8,7 @@
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon --ignore ./examples src/server.js",
"dev": "nodemon --ignore ./dist src/server.js",
"fix": "eslint --fix ./src"
},
"author": "",
... ... @@ -19,7 +19,7 @@
"debug": "^3.1.0",
"express": "^4.15.4",
"http-proxy-middleware": "^0.19.0",
"influx-batch-sender": "^0.1.5",
"influx-batch-sender": "=0.1.10",
"ip2region": "=1.1.0",
"knex": "^0.14.1",
"koa-compose": "^4.1.0",
... ...
... ... @@ -16,10 +16,10 @@ module.exports = (app) => {
// new yas
app.get('/apm/yas2.gif', middleware.getip, middleware.clientApm);
// 服务器端收集,最新的
// 老接口服务器端收集,老的格式 influx格式
app.post('/write', middleware.serverApm);
// 监控
app.post('/alert', middleware.alertApm);
// 最新只有一个接口,所有的数据都过来, json 格式
app.post('/collect', middleware.serverApm2);
};
... ...
... ... @@ -9,8 +9,7 @@ module.exports = {
apm,
clientApm,
serverApm,
alertApm,
getip,
serverApm,
alertApm,
serverApm2
};
... ...
const _ = require('lodash');
function slowRouter(m) {
let uid = _.get(m, 'uid', '0');
return {
app: _.get(m.data, 'app', ''),
type: _.get(m.data, 'type', ''),
hostname: _.get(m.data, 'hostname', ''),
preqid: _.get(m.data, 'preqid', ''),
reqid: _.get(m.data, 'reqID', ''),
uid: _.parseInt(uid),
udid: _.get(m.data, 'udid', ''),
api: _.get(m.data, 'api', ''),
route: _.get(m.data, 'route', ''),
duration: _.get(m.data, 'duration', ''),
create_time: _.get(m.data, 'time', 0)
};
}
function errorRouter(m) {
let uid = _.get(m.data, 'uid', '0');
let line = _.get(m.data, 'line', '0');
let column = _.get(m.data, 'column', '0');
return {
app: _.get(m.data, 'app', ''),
api: _.get(m.data, 'api', ''),
type: _.get(m.data, 'type', ''),
hostname: _.get(m.data, 'hostname', ''),
preqid: _.get(m.data, 'preqid', ''),
reqid: _.get(m.data, 'reqID', ''),
uid: _.parseInt(uid),
udid: _.get(m.data, 'udid', ''),
route: _.get(m.data, 'path', ''),
url: _.get(m.data, 'url', ''),
ip: _.get(m.data, 'ip', ''),
code: _.parseInt(_.get(m.data, 'code', -1)),
line: _.parseInt(line),
column: _.parseInt(column),
script: _.get(m.data, 'script', ''),
message: _.get(m.data, 'message', ''),
stack: _.get(m.data, 'stack', ''),
useragent: _.get(m.data, 'useragent', ''),
create_time: _.get(m.data, 'time', 0)
};
}
module.exports = {
slowRouter,
errorRouter
};
... ...
const compose = require('koa-compose');
const _ = require('lodash');
const enable = require('./enable');
const qpsPath = require('./qps-path');
const disableBelow = require('./disable');
const ipFilter = require('./ip');
const userFilter = require('./user');
const userAgentFilter = require('./useragent');
const xhrFilter = require('./xhr');
const zk = require('./zk');
const whitelistIpFilter = require('./whitelist-ip');
const whitelistPathFilter = require('./whitelist-path');
const qps = require('./qps');
const logger = global.yoho.logger;
const APP_NAME = {
'yohobuy-node': 'pc',
'yohobuywap-node': 'wap',
UNKNOWN: ''
};
const APP_TYPE = {
'yohobuy-node': 'web',
'yohobuywap-node': 'h5',
UNKNOWN: ''
};
module.exports = () => {
const handlers = compose([
enable,
qpsPath,
disableBelow,
userFilter,
xhrFilter,
whitelistIpFilter,
whitelistPathFilter,
ipFilter,
userAgentFilter,
qps
]);
return async(playload, next) => {
if (playload.type !== 'web-server-duration' && playload.data.type !== 'route') {
return next();
}
logger.debug('[request] %j', playload);
const user = {
uid: _.parseInt(_.get(playload, 'data.uid', '0'), 10),
ip: _.get(playload, 'data.ip', ''),
app: APP_NAME[_.get(playload, 'data.app', 'UNKNOWN')],
appName: _.get(playload, 'data.app', ''),
appType: APP_TYPE[_.get(playload, 'data.app', 'UNKNOWN')],
path: decodeURIComponent(_.get(playload, 'data.path', '')),
userAgent: decodeURIComponent(_.get(playload, 'data.userAgent', '')),
ajax: _.parseInt(_.get(playload, 'data.ajax', 0))
};
if (!user.ip || !user.app) {
if (_.get(zk, `${user.app}.open.logNoIp`, false)) {
logger.error('miss ip or app %j but get %j', playload, user);
}
return;
}
await handlers({user});
next();
};
};
... ...
const Sender = require('influx-batch-sender');
const MysqlSender = require('../lib/mysql-sender');
const config = require('../common/config');
const msg2row = require('./msg2row2');
const logger = global.yoho.logger;
const errorSqlSender = new MysqlSender(config.table.error);
const slowRouterSqlSender = new MysqlSender(config.table.slow);
const routeInfluxSender = new Sender(config.reportRoute);
const apiInfluxSender = new Sender(config.reportApi);
const alertInfluxSender = new Sender(config.reportAlert);
const _ = require('lodash');
const API_BLACK_LIST = [
'app.shop.banner'
];
async function handleWebServerDuration(playload, next) {
if (playload.type !== 'web-server-duration') {
return next();
}
let duration = _.parseInt(playload.data.duration);
if (duration > config.slowRoute.min / 10 && duration < config.slowRoute.max) {
const newData = _.merge({}, playload, {
fields: {
duration
}
});
slowRouterSqlSender.addMessage(msg2row.slowRouter(newData));
}
if (playload.data.type.toLowerCase() === 'api') {
if (_.includes(API_BLACK_LIST, playload.tags.api)) {
return;
}
logger.debug('[api] route info [%s]', JSON.stringify(playload));
apiInfluxSender.addMessage({
tags: {
app: playload.data.app,
host: playload.data.hostname,
api: playload.data.api
},
fields: {
duration: duration,
times: 1
}
});
}
if (playload.data.type.toLowerCase() === 'route') {
logger.debug('[server] route info [%s]', JSON.stringify(playload));
routeInfluxSender.addMessage({
tags: {
app: playload.data.app,
host: playload.data.hostname,
route: playload.data.route
},
fields: {
duration: duration
}
});
}
next();
}
function handleErrorReport(playload, next) {
if (playload.type !== 'error-report') {
return next();
}
routeInfluxSender.addMessage({
measurement: 'error-info',
tags: {
app: playload.data.app,
host: playload.data.hostname,
route: playload.data.route,
code: playload.data.code
},
fields: {
times: 1
}
});
// 排除情况
const msg = _.get(playload, 'data.message', '');
if (!msg) {
return;
}
if (msg === '""') {
return;
}
const type = _.get(playload, 'data.type', '');
if (type === 'api') {
logger.debug('[api] error info [%s]', JSON.stringify(playload));
} else {
logger.debug('[server] error info [%s]', JSON.stringify(playload));
}
errorSqlSender.addMessage(msg2row.errorRouter(playload));
next();
}
function handleProcessInfo(playload, next) {
if (playload.type !== 'process-info') {
return next();
}
logger.debug('[process] info [%s]', JSON.stringify(playload));
playload.measurement = 'process-info';
routeInfluxSender.addMessage({
measurement: 'process-info',
tags: playload.tags,
fields: playload.fields
});
next();
}
function handleAlertInfo(playload, next) {
if (playload.type !== 'monitor_success_report') {
return next();
}
alertInfluxSender.addMessage({
measurement: playload.type,
tags: playload.tags,
fields: playload.fields
});
next();
}
module.exports = {
handleErrorReport,
handleProcessInfo,
handleWebServerDuration,
handleAlertInfo
};
... ...
const lineparse = require('../lib/line-parse');
const bb = require('bluebird');
const compose = require('koa-compose');
const logger = global.yoho.logger;
const {
handleErrorReport,
handleProcessInfo,
handleWebServerDuration
} = require('./serverapm-service');
handleWebServerDuration,
handleAlertInfo
} = require('./serverapm-service2');
const riskService = require('./risk-service');
const riskService = require('./risk-service/index2');
const handleRisk = riskService();
const handlers = compose([
handleWebServerDuration,
handleRisk,
handleErrorReport,
handleProcessInfo,
handleAlertInfo
]);
const server = {
async handle(msgs) {
try {
await bb.map(msgs, async(m) => {
if (!m.measurement) {
if (!m.type) {
return;
}
switch (m.measurement) {
case 'web-server-duration': {
handleWebServerDuration(m);
if (m.tags.type === 'route') {
await handleRisk(m);
}
break;
}
case 'error-report': {
handleErrorReport(m);
break;
}
case 'process-info': {
handleProcessInfo(m);
break;
}
default: {
logger.error('[server] handle ERROR [%s]', JSON.stringify(m));
break;
}
}
await handlers(m);
}, {concurrency: 2});
... ... @@ -53,7 +41,7 @@ const server = {
};
module.exports = function(req, res) {
let data = req.body || ' ';
let data = req.body || {};
server.handle(data).catch(err => {
logger.error(err);
... ...
This diff could not be displayed because it is too large.