Authored by htoooth

fix

@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 }, 8 },
9 "scripts": { 9 "scripts": {
10 "test": "echo \"Error: no test specified\" && exit 1", 10 "test": "echo \"Error: no test specified\" && exit 1",
11 - "dev": "nodemon --ignore ./examples src/server.js", 11 + "dev": "nodemon --ignore ./dist src/server.js",
12 "fix": "eslint --fix ./src" 12 "fix": "eslint --fix ./src"
13 }, 13 },
14 "author": "", 14 "author": "",
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 "debug": "^3.1.0", 19 "debug": "^3.1.0",
20 "express": "^4.15.4", 20 "express": "^4.15.4",
21 "http-proxy-middleware": "^0.19.0", 21 "http-proxy-middleware": "^0.19.0",
22 - "influx-batch-sender": "^0.1.5", 22 + "influx-batch-sender": "=0.1.10",
23 "ip2region": "=1.1.0", 23 "ip2region": "=1.1.0",
24 "knex": "^0.14.1", 24 "knex": "^0.14.1",
25 "koa-compose": "^4.1.0", 25 "koa-compose": "^4.1.0",
@@ -16,10 +16,10 @@ module.exports = (app) => { @@ -16,10 +16,10 @@ module.exports = (app) => {
16 // new yas 16 // new yas
17 app.get('/apm/yas2.gif', middleware.getip, middleware.clientApm); 17 app.get('/apm/yas2.gif', middleware.getip, middleware.clientApm);
18 18
19 - // 服务器端收集,最新的 19 + // 老接口服务器端收集,老的格式 influx格式
20 app.post('/write', middleware.serverApm); 20 app.post('/write', middleware.serverApm);
21 -  
22 - // 监控  
23 app.post('/alert', middleware.alertApm); 21 app.post('/alert', middleware.alertApm);
  22 +
  23 + // 最新只有一个接口,所有的数据都过来, json 格式
24 app.post('/collect', middleware.serverApm2); 24 app.post('/collect', middleware.serverApm2);
25 }; 25 };
@@ -9,8 +9,7 @@ module.exports = { @@ -9,8 +9,7 @@ module.exports = {
9 apm, 9 apm,
10 clientApm, 10 clientApm,
11 serverApm, 11 serverApm,
12 - alertApm,  
13 getip, 12 getip,
14 - serverApm, 13 + alertApm,
15 serverApm2 14 serverApm2
16 }; 15 };
  1 +const _ = require('lodash');
  2 +
  3 +function slowRouter(m) {
  4 + let uid = _.get(m, 'uid', '0');
  5 +
  6 + return {
  7 + app: _.get(m.data, 'app', ''),
  8 + type: _.get(m.data, 'type', ''),
  9 + hostname: _.get(m.data, 'hostname', ''),
  10 + preqid: _.get(m.data, 'preqid', ''),
  11 + reqid: _.get(m.data, 'reqID', ''),
  12 + uid: _.parseInt(uid),
  13 + udid: _.get(m.data, 'udid', ''),
  14 + api: _.get(m.data, 'api', ''),
  15 + route: _.get(m.data, 'route', ''),
  16 + duration: _.get(m.data, 'duration', ''),
  17 + create_time: _.get(m.data, 'time', 0)
  18 + };
  19 +}
  20 +
  21 +function errorRouter(m) {
  22 + let uid = _.get(m.data, 'uid', '0');
  23 + let line = _.get(m.data, 'line', '0');
  24 + let column = _.get(m.data, 'column', '0');
  25 +
  26 + return {
  27 + app: _.get(m.data, 'app', ''),
  28 + api: _.get(m.data, 'api', ''),
  29 + type: _.get(m.data, 'type', ''),
  30 + hostname: _.get(m.data, 'hostname', ''),
  31 + preqid: _.get(m.data, 'preqid', ''),
  32 + reqid: _.get(m.data, 'reqID', ''),
  33 + uid: _.parseInt(uid),
  34 + udid: _.get(m.data, 'udid', ''),
  35 + route: _.get(m.data, 'path', ''),
  36 + url: _.get(m.data, 'url', ''),
  37 + ip: _.get(m.data, 'ip', ''),
  38 + code: _.parseInt(_.get(m.data, 'code', -1)),
  39 + line: _.parseInt(line),
  40 + column: _.parseInt(column),
  41 + script: _.get(m.data, 'script', ''),
  42 + message: _.get(m.data, 'message', ''),
  43 + stack: _.get(m.data, 'stack', ''),
  44 + useragent: _.get(m.data, 'useragent', ''),
  45 + create_time: _.get(m.data, 'time', 0)
  46 + };
  47 +}
  48 +
  49 +module.exports = {
  50 + slowRouter,
  51 + errorRouter
  52 +};
  1 +const compose = require('koa-compose');
  2 +const _ = require('lodash');
  3 +
  4 +const enable = require('./enable');
  5 +const qpsPath = require('./qps-path');
  6 +
  7 +const disableBelow = require('./disable');
  8 +const ipFilter = require('./ip');
  9 +const userFilter = require('./user');
  10 +const userAgentFilter = require('./useragent');
  11 +const xhrFilter = require('./xhr');
  12 +const zk = require('./zk');
  13 +const whitelistIpFilter = require('./whitelist-ip');
  14 +const whitelistPathFilter = require('./whitelist-path');
  15 +const qps = require('./qps');
  16 +
  17 +const logger = global.yoho.logger;
  18 +
  19 +const APP_NAME = {
  20 + 'yohobuy-node': 'pc',
  21 + 'yohobuywap-node': 'wap',
  22 + UNKNOWN: ''
  23 +};
  24 +
  25 +const APP_TYPE = {
  26 + 'yohobuy-node': 'web',
  27 + 'yohobuywap-node': 'h5',
  28 + UNKNOWN: ''
  29 +};
  30 +
  31 +module.exports = () => {
  32 + const handlers = compose([
  33 + enable,
  34 + qpsPath,
  35 +
  36 + disableBelow,
  37 + userFilter,
  38 + xhrFilter,
  39 + whitelistIpFilter,
  40 + whitelistPathFilter,
  41 + ipFilter,
  42 + userAgentFilter,
  43 + qps
  44 + ]);
  45 +
  46 + return async(playload, next) => {
  47 + if (playload.type !== 'web-server-duration' && playload.data.type !== 'route') {
  48 + return next();
  49 + }
  50 +
  51 + logger.debug('[request] %j', playload);
  52 +
  53 + const user = {
  54 + uid: _.parseInt(_.get(playload, 'data.uid', '0'), 10),
  55 + ip: _.get(playload, 'data.ip', ''),
  56 + app: APP_NAME[_.get(playload, 'data.app', 'UNKNOWN')],
  57 + appName: _.get(playload, 'data.app', ''),
  58 + appType: APP_TYPE[_.get(playload, 'data.app', 'UNKNOWN')],
  59 + path: decodeURIComponent(_.get(playload, 'data.path', '')),
  60 + userAgent: decodeURIComponent(_.get(playload, 'data.userAgent', '')),
  61 + ajax: _.parseInt(_.get(playload, 'data.ajax', 0))
  62 + };
  63 +
  64 + if (!user.ip || !user.app) {
  65 + if (_.get(zk, `${user.app}.open.logNoIp`, false)) {
  66 + logger.error('miss ip or app %j but get %j', playload, user);
  67 + }
  68 + return;
  69 + }
  70 +
  71 + await handlers({user});
  72 +
  73 + next();
  74 + };
  75 +};
  1 +const Sender = require('influx-batch-sender');
  2 +const MysqlSender = require('../lib/mysql-sender');
  3 +const config = require('../common/config');
  4 +const msg2row = require('./msg2row2');
  5 +
  6 +
  7 +const logger = global.yoho.logger;
  8 +const errorSqlSender = new MysqlSender(config.table.error);
  9 +const slowRouterSqlSender = new MysqlSender(config.table.slow);
  10 +
  11 +const routeInfluxSender = new Sender(config.reportRoute);
  12 +const apiInfluxSender = new Sender(config.reportApi);
  13 +const alertInfluxSender = new Sender(config.reportAlert);
  14 +
  15 +const _ = require('lodash');
  16 +
  17 +const API_BLACK_LIST = [
  18 + 'app.shop.banner'
  19 +];
  20 +
  21 +async function handleWebServerDuration(playload, next) {
  22 + if (playload.type !== 'web-server-duration') {
  23 + return next();
  24 + }
  25 +
  26 + let duration = _.parseInt(playload.data.duration);
  27 +
  28 + if (duration > config.slowRoute.min / 10 && duration < config.slowRoute.max) {
  29 + const newData = _.merge({}, playload, {
  30 + fields: {
  31 + duration
  32 + }
  33 + });
  34 +
  35 + slowRouterSqlSender.addMessage(msg2row.slowRouter(newData));
  36 + }
  37 +
  38 + if (playload.data.type.toLowerCase() === 'api') {
  39 + if (_.includes(API_BLACK_LIST, playload.tags.api)) {
  40 + return;
  41 + }
  42 +
  43 + logger.debug('[api] route info [%s]', JSON.stringify(playload));
  44 +
  45 + apiInfluxSender.addMessage({
  46 + tags: {
  47 + app: playload.data.app,
  48 + host: playload.data.hostname,
  49 + api: playload.data.api
  50 + },
  51 + fields: {
  52 + duration: duration,
  53 + times: 1
  54 + }
  55 + });
  56 + }
  57 +
  58 + if (playload.data.type.toLowerCase() === 'route') {
  59 + logger.debug('[server] route info [%s]', JSON.stringify(playload));
  60 +
  61 + routeInfluxSender.addMessage({
  62 + tags: {
  63 + app: playload.data.app,
  64 + host: playload.data.hostname,
  65 + route: playload.data.route
  66 + },
  67 + fields: {
  68 + duration: duration
  69 + }
  70 + });
  71 + }
  72 +
  73 + next();
  74 +}
  75 +
  76 +function handleErrorReport(playload, next) {
  77 + if (playload.type !== 'error-report') {
  78 + return next();
  79 + }
  80 +
  81 + routeInfluxSender.addMessage({
  82 + measurement: 'error-info',
  83 + tags: {
  84 + app: playload.data.app,
  85 + host: playload.data.hostname,
  86 + route: playload.data.route,
  87 + code: playload.data.code
  88 + },
  89 + fields: {
  90 + times: 1
  91 + }
  92 + });
  93 +
  94 + // 排除情况
  95 + const msg = _.get(playload, 'data.message', '');
  96 +
  97 + if (!msg) {
  98 + return;
  99 + }
  100 +
  101 + if (msg === '""') {
  102 + return;
  103 + }
  104 +
  105 + const type = _.get(playload, 'data.type', '');
  106 +
  107 + if (type === 'api') {
  108 + logger.debug('[api] error info [%s]', JSON.stringify(playload));
  109 + } else {
  110 + logger.debug('[server] error info [%s]', JSON.stringify(playload));
  111 + }
  112 +
  113 + errorSqlSender.addMessage(msg2row.errorRouter(playload));
  114 +
  115 + next();
  116 +}
  117 +
  118 +function handleProcessInfo(playload, next) {
  119 + if (playload.type !== 'process-info') {
  120 + return next();
  121 + }
  122 +
  123 + logger.debug('[process] info [%s]', JSON.stringify(playload));
  124 +
  125 + playload.measurement = 'process-info';
  126 +
  127 + routeInfluxSender.addMessage({
  128 + measurement: 'process-info',
  129 + tags: playload.tags,
  130 + fields: playload.fields
  131 + });
  132 +
  133 + next();
  134 +}
  135 +
  136 +function handleAlertInfo(playload, next) {
  137 + if (playload.type !== 'monitor_success_report') {
  138 + return next();
  139 + }
  140 +
  141 + alertInfluxSender.addMessage({
  142 + measurement: playload.type,
  143 + tags: playload.tags,
  144 + fields: playload.fields
  145 + });
  146 +
  147 + next();
  148 +}
  149 +
  150 +module.exports = {
  151 + handleErrorReport,
  152 + handleProcessInfo,
  153 + handleWebServerDuration,
  154 + handleAlertInfo
  155 +};
1 -const lineparse = require('../lib/line-parse');  
2 const bb = require('bluebird'); 1 const bb = require('bluebird');
  2 +const compose = require('koa-compose');
3 3
4 const logger = global.yoho.logger; 4 const logger = global.yoho.logger;
5 5
6 const { 6 const {
7 handleErrorReport, 7 handleErrorReport,
8 handleProcessInfo, 8 handleProcessInfo,
9 - handleWebServerDuration  
10 -} = require('./serverapm-service'); 9 + handleWebServerDuration,
  10 + handleAlertInfo
  11 +} = require('./serverapm-service2');
11 12
12 -const riskService = require('./risk-service'); 13 +const riskService = require('./risk-service/index2');
13 const handleRisk = riskService(); 14 const handleRisk = riskService();
14 15
  16 +const handlers = compose([
  17 + handleWebServerDuration,
  18 + handleRisk,
  19 + handleErrorReport,
  20 + handleProcessInfo,
  21 + handleAlertInfo
  22 +]);
  23 +
15 const server = { 24 const server = {
16 async handle(msgs) { 25 async handle(msgs) {
17 try { 26 try {
18 await bb.map(msgs, async(m) => { 27 await bb.map(msgs, async(m) => {
19 - if (!m.measurement) { 28 + if (!m.type) {
20 return; 29 return;
21 } 30 }
22 31
23 - switch (m.measurement) {  
24 - case 'web-server-duration': {  
25 - handleWebServerDuration(m);  
26 -  
27 - if (m.tags.type === 'route') {  
28 - await handleRisk(m);  
29 - }  
30 - break;  
31 - }  
32 - case 'error-report': {  
33 - handleErrorReport(m);  
34 - break;  
35 - }  
36 - case 'process-info': {  
37 - handleProcessInfo(m);  
38 - break;  
39 - }  
40 - default: {  
41 - logger.error('[server] handle ERROR [%s]', JSON.stringify(m));  
42 - break;  
43 - }  
44 - } 32 + await handlers(m);
45 33
46 }, {concurrency: 2}); 34 }, {concurrency: 2});
47 35
@@ -53,7 +41,7 @@ const server = { @@ -53,7 +41,7 @@ const server = {
53 }; 41 };
54 42
55 module.exports = function(req, res) { 43 module.exports = function(req, res) {
56 - let data = req.body || ' '; 44 + let data = req.body || {};
57 45
58 server.handle(data).catch(err => { 46 server.handle(data).catch(err => {
59 logger.error(err); 47 logger.error(err);
This diff could not be displayed because it is too large.