Authored by 周少峰

Merge branch 'feature/web-apm' into gray

... ... @@ -86,6 +86,7 @@ require('./doraemon/middleware/yoho-session')(app);
app.use((req, res, next) => {
req.user = {}; // 全局的用户数据
req.yoho = {}; // req和res绑定yoho对象,用于传递全局数据, 如req.yoho.channel等
req.isApmReport = _.get(req.app.locals, 'pc.open.bughd', false);
if (!req.session) {
req.session = {};
... ...
... ... @@ -67,6 +67,11 @@ module.exports = {
activity: '//activity.yohobuy.com',
index: '//yohobuy.com'
},
report: {
host: '10.66.0.139',
port: 8086,
db: 'web-apm'
},
useOneapm: false,
useCache: false,
memcache: {
... ... @@ -225,6 +230,11 @@ if (isProduction) {
return 1000 * 60 * 60 * 0.5;
}
return Math.min(options.attempt * 100, 1000);
},
report: {
host: 'influxdblog.web.yohoops.org',
port: 8086,
db: 'web-apm'
}
}
});
... ...
... ... @@ -5,6 +5,8 @@
const headerModel = require('../models/header');
const logger = global.yoho.logger;
const helpers = global.yoho.helpers;
const sender = global.yoho.apmSender;
const hostname = require('os').hostname();
const forceNoCache = (res) => {
if (res) {
... ... @@ -47,6 +49,30 @@ exports.serverError = () => {
return (err, req, res, next) => {
forceNoCache(res);
const uid = req.user ? req.user.uid : 0;
const udid = req.query.udid || req.cookies ? req.cookies._yasvd : 0;
if (req.isApmReport) {
// 上报服务端错误
sender.addMessage({
measurement: 'error-report',
tags: {
app: global.yoho.config.appName, // 应用名称
hostname,
type: 'server',
route: `[${req.method}]${req.route.path}`, // 请求路由
reqID: req.reqID,
uid,
udid,
code: err.code || 500
},
fields: {
message: err.message,
stack: err.stack
}
});
}
logger.error(`error at path: ${req.url}`);
logger.error(err);
... ...
... ... @@ -19,6 +19,17 @@
{{#dnsPrefetch.hosts}}
<link rel="dns-prefetch" href="{{this}}">
{{/dnsPrefetch.hosts}}
<!--[if lt IE 9]>
<script src="//cdn.yoho.cn/yohobuy-node/static/json2.js"></script>
<![endif]-->
<script>
window._timeStart = Date.now();
{{#ifand isProduction pc.open.bughd}}
window._yohoAppName = 'yohobuy-node';
!function(e){function t(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return e[n].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});var n=r(13),i=r(14);n.init(),i.init()},function(e,t){e.exports=function(e,t,r){if("undefined"==typeof t){var n=null;if(document.cookie)for(var i=document.cookie.split(";"),o=0;o<i.length;o++){var a=(i[o]||"").trim();if(a.substring(0,e.length+1)==e+"="){n=decodeURIComponent(a.substring(e.length+1));break}}return n}r=r||{},null===t&&(t="",r.expires=-1);var d="";if(r.expires&&("number"==typeof r.expires||r.expires.toUTCString)){var s;"number"==typeof r.expires?(s=new Date,s.setTime(s.getTime()+24*r.expires*60*60*1e3)):s=r.expires,d="; expires="+s.toUTCString()}var u=r.path?"; path="+r.path:"",p=r.domain?"; domain="+r.domain:"",c=r.secure?"; secure":"";document.cookie=[e,"=",encodeURIComponent(t),d,u,p,c].join("")}},,function(e,t,r){var n=r(1),i=window._yohoAppName||"unknown",o={config:{reportUrl:"//badjs.yoho.cn/apm/yas.gif"},stringify:function(e){for(var t=[],r=0;r<e.length;r++){var n=e[r],i=[];for(var o in n)n.hasOwnProperty(o)&&i.push(o+"::"+n[o]);t.push(i.join("$$"))}return t.join("**")},report:function(e,t){if(e){var r=new Image;r.src=this.config.reportUrl+"?s="+i+"&l="+e+"&t="+(new Date).getTime(),t&&t()}},getUdid:function(){var e=(n("yohobuy_session")||"").slice(2).split(".")[0];return e||0},getUid:function(){var e=(n("_UID")||"").split("::")[1];return e||0},getReqId:function(){return n("docreqid")||0}};e.exports=o},,,,,,,,,,function(e,t,r){var n=r(1),i=r(3),o="_errLog",a={writeError:function(e,t,r,a,d){var s=JSON.parse(n(o)||"[]");s.push({tp:"err",msg:e,sc:t,ln:r,cn:a,pt:location.href,u:i.getUid(),ud:i.getUdid(),rid:i.getReqId(),st:JSON.stringify(d&&d.stack)}),n(o,JSON.stringify(s)),s.length>=5&&this.reportError()},clearError:function(){n(o,"[]")},reportError:function(){var e=this,t=JSON.parse(n(o)||"[]"),r=i.stringify(t);i.report(r,function(){e.clearError()})},init:function(){var e=this;window.onerror=function(t,r,n,i,o){e.writeError(t,r,n,i,o)},this.reportError()}};e.exports=a},function(e,t,r){function n(e){var t=e.offsetTop;return null!==e.offsetParent&&(t+=n(e.offsetParent)),t}var i=r(3),o=window.screen.height,a=[],d=!1,s=!1,u=0,p=setInterval(function(){var e,t;if(d){if(a.length)for(e=0;e<a.length;e++){if(t=a[e],!t.complete){s=!1;break}s=!0}else s=!0;s&&(u=(new Date).getTime()-_timeStart,clearInterval(p))}else{var r=document.body.querySelector("img")||[];for(e=0;e<r.length;e++){t=r[e];var i=n(t);if(i>o){d=!0;break}i<=o&&!t.hasPushed&&(t.hasPushed=1,a.push(t))}}},0),c={reportTime:function(e){var t=i.stringify(e);i.report(t)},addEvent:function(){var e=this,t=[],r=location.href,n=i.getUid(),o=i.getUdid(),a=i.getReqId(),c=window.performance&&window.performance.timing.navigationStart||0;_timeStart=window._timeStart||0,document.addEventListener&&document.addEventListener("DOMContentLoaded",function(e){t.push({tp:"dcl",t:(new Date).getTime()-_timeStart,pt:r,u:n,ud:o,rid:a});var i=document.body.querySelector("img")||[];i.length||(d=!0)},!1),window.addEventListener&&window.addEventListener("load",function(i){t.push({tp:"ld",t:(new Date).getTime()-_timeStart,pt:r,u:n,ud:o,rid:a}),s=!0,d=!0,p&&clearInterval(p),u&&t.push({tp:"fs",t:u,pt:r,u:n,ud:o,rid:a}),t.push({tp:"pf",dcl:(window.performance&&window.performance.timing.domComplete||0)-c,ld:(window.performance&&window.performance.timing.loadEventStart||0)-c,pt:r,u:n,ud:o,rid:a}),e.reportTime(t)},!1)},init:function(){this.addEvent()}};e.exports=c}]);
{{/ifand}}
</script>
{{#if devEnv}}
<link rel="stylesheet" href="//{{devHost}}:5002/base.css">
... ... @@ -40,34 +51,15 @@
{{/if}}
{{> footer}}
{{#ifand isProduction pc.open.bughd}}
<script type="text/javascript" src="//cdn.yoho.cn/tool/bj-report-tryjs.min.js" crossOrigin="anonymous"></script>
<script>
BJ_REPORT && BJ_REPORT.init({
id: 3,
url: "//badjs.yoho.cn/badjs",
ignore: [/Script error/i],
offlineLog: false,
offlineLogAuto: false
});
</script>
{{/ifand}}
{{#if devEnv}}
<script src="//{{devHost}}:5002/libs.js"></script>
<script src="//{{devHost}}:5002/{{module}}.{{page}}.js"></script>
{{^}}
<script src="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/libs.js"></script>
<script src="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/{{module}}.{{page}}.js"></script>
<script src="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/libs.js" crossorigin="anonymous"></script>
<script src="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/{{module}}.{{page}}.js" crossorigin="anonymous"></script>
{{> analysis}}
{{/if}}
{{#ifand isProduction pc.open.bughd}}
<script>
BJ_REPORT && BJ_REPORT.tryJs().spyAll();
</script>
{{/ifand}}
<script>window.cdn='{{cdn}}';</script>
<script>window._version='{{version}}';</script>
</body>
... ...
{
"name": "yohobuy-node",
"version": "6.1.0",
"version": "6.1.1",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ... @@ -55,7 +55,7 @@
"urlencode": "^1.1.0",
"uuid": "^2.0.2",
"yoho-express-session": "^2.0.0",
"yoho-node-lib": "^0.2.28",
"yoho-node-lib": "=0.5.3",
"yoho-zookeeper": "^1.0.8"
},
"devDependencies": {
... ...
... ... @@ -99,6 +99,7 @@ module.exports = (env) => {
path: path.join(__dirname, 'bundle'), // absolute path
filename: '[name].js'
},
devtool: 'hidden-source-map',
module: {
rules: [{
test: /\.vue$/,
... ...
... ... @@ -10,7 +10,7 @@ let baseConfig = require('./webpack.base.config.js');
baseConfig = baseConfig('dev');
_.mergeWith(baseConfig, {
devtool: '#inline-source-map',
devtool: '#cheap-module-source-map',
output: {
publicPath: devInfo.publicPath
},
... ...
... ... @@ -43,7 +43,8 @@ _.mergeWith(baseConfig, {
mangle: {
screw_ie8: false
},
comments: false
comments: false,
sourceMap: true
})
]
}, function customizer(objValue, srcValue) {
... ...
... ... @@ -114,7 +114,7 @@ function getShoppingKey() {
a.src = j;
m.parentNode.insertBefore(a, m);
}(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//' + // eslint-disable-line
'cdn.yoho.cn/yas-jssdk/2.4.3/yas.js', '_yas')); // eslint-disable-line
'cdn.yoho.cn/yas-jssdk/2.4.6/yas.js', '_yas')); // eslint-disable-line
(function() {
var uid = getUid();
... ... @@ -124,7 +124,7 @@ function getShoppingKey() {
window._ozuid = uid; // 暴露ozuid
if (window._yas) {
window._yas(1 * new Date(), '2.4.3', 'yohobuy_web', uid, '', '');
window._yas(1 * new Date(), '2.4.6', 'yohobuy_web', uid, '', '');
}
}());
... ...