learn's People
learn's Issues
前端监控
前端监控
大纲
- 监控的意义。
- 线上问题报错,问题分类。
- 线上问题捕获。
- 捕获上报。
- 上报方式。
- 上报信息解析。
- 上报监控。
监控的意义
- 更快的发现问题和解决问题
线上问题分类
- js error
- promise error
- 资源加载异常
- 接口异常
线上问题捕获
js报错捕获
- 说细一点,优缺点对比一下
- 跨域捕获的坑
window.addEventListener
// 图片、script、css加载错误,都能被捕获 ✅
<script>
window.addEventListener('error', (error) => {
console.log('捕获到异常:', error);
}, true)
</script>
<img src="https://yun.tuia.cn/image/kkk.png">
<script src="https://yun.tuia.cn/foundnull.js"></script>
<link href="https://yun.tuia.cn/foundnull.css" rel="stylesheet"/>
// new Image错误,不能捕获 ❌
<script>
window.addEventListener('error', (error) => {
console.log('捕获到异常:', error);
}, true)
</script>
<script>
new Image().src = 'https://yun.tuia.cn/image/lll.png'
</script>
// fetch错误,不能捕获 ❌
<script>
window.addEventListener('error', (error) => {
console.log('捕获到异常:', error);
}, true)
</script>
<script>
fetch('https://tuia.cn/test')
</script>
/**
* @param {String} message 错误信息
* @param {String} source 出错文件
* @param {Number} lineno 行号
* @param {Number} colno 列号
* @param {Object} error Error对象
*/
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:', {message, source, lineno, colno, error});
}
先验证下几个错误是否可以捕获。
// 常规运行时错误,可以捕获 ✅
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:',{message, source, lineno, colno, error});
}
console.log(notdefined);
// 语法错误,不能捕获 ❌
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:',{message, source, lineno, colno, error});
}
const notdefined,
// 异步错误,可以捕获 ✅
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:',{message, source, lineno, colno, error});
}
setTimeout(() => {
console.log(notdefined);
}, 0)
// 资源错误,不能捕获 ❌
<script>
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:',{message, source, lineno, colno, error});
return true;
}
</script>
<img src="https://yun.tuia.cn/image/kkk.png">
Promise错误
// 全局统一处理Promise
window.addEventListener("unhandledrejection", function(e){
console.log('捕获到异常:', e);
});
fetch('https://tuia.cn/test')
vue错误
/**
* 全局捕获Vue错误,直接扔出给onerror处理
*/
Vue.config.errorHandler = function (err) {
setTimeout(() => {
throw err
})
}
React错误
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染能够显示降级后的 UI
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 你同样可以将错误日志上报给服务器
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 你可以自定义降级后的 UI 并渲染
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
class App extends React.Component {
render() {
return (
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
)
}
}
但error boundaries并不会捕捉以下错误:React事件处理,异步代码,error boundaries自己抛出的错误。
跨域问题
- 一般情况,如果出现 Script error 这样的错误,基本上可以确定是出现了跨域问题。
如果当前投放页面和云端JS所在不同域名,如果云端JS出现错误,window.onerror会出现Script Error。通过以下两种方法能给予解决。
- 后端配置Access-Control-Allow-Origin、前端script加crossorigin。
<script src="http://yun.tuia.cn/test.js" crossorigin></script>
const script = document.createElement('script');
script.crossOrigin = 'anonymous';
script.src = 'http://yun.tuia.cn/test.js';
document.body.appendChild(script);
- 如果不能修改服务端的请求头,可以考虑通过使用 try/catch 绕过,将错误抛出。
<!doctype html>
<html>
<head>
<title>Test page in http://test.com</title>
</head>
<body>
<script src="https://yun.dui88.com/tuia/cdn/remote/testerror.js"></script>
<script>
window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
try {
foo(); // 调用testerror.js中定义的foo方法
} catch (e) {
throw e;
}
</script>
</body>
</html>
会发现如果不加try catch,console.log就会打印script error。加上try catch就能捕获到。
我们捋一下场景,一般调用远端js,有下列三种常见情况。
- 调用远端JS的方法出错
- 远端JS内部的事件出问题远端JS内部的事件出问题
- 要么在setTimeout等回调内出错
可以通过封装一个函数,能装饰原方法,使得其能被try/catch。
<!doctype html>
<html>
<head>
<title>Test page in http://test.com</title>
</head>
<body>
<script src="https://yun.dui88.com/tuia/cdn/remote/testerror.js"></script>
<script>
window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
function wrapErrors(fn) {
// don't wrap function more than once
if (!fn.__wrapped__) {
fn.__wrapped__ = function () {
try {
return fn.apply(this, arguments);
} catch (e) {
throw e; // re-throw the error
}
};
}
return fn.__wrapped__;
}
wrapErrors(foo)()
</script>
</body>
</html>
错误过滤
域名过滤
过滤本页面script error,可能被webview插入其他js。
我们只关心自己的远端JS问题,因此做了根据本公司域名进行过滤。
if(!e.filename || !e.filename.match(/^(http|https):\/\/yun./)) return true
扩展
- 行为搜集
console.error
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.