关于前端日志的收集和上报(ssr项目)
关于服务端 401未登录的上报
目前很多项目都对用户未登录信息做了日志收集,如果没有特殊的业务需求,我们可以过滤掉。
if (err.response.status >= 400 && err.response.status < 500) { // 如果是非401等 4xx code 则logger错误日志 if (IS_SERVER && err.response.status !== 401) { logger.error('400_ERROR', reqUrl, `status:${err.response.status}, statusText:${err.response.statusText}, headers:${JSON.stringify(err.response.headers)}, data:${JSON.stringify(err.response.data)}`) } return { ...err.response.data, code: err.response.data.code || 120500002, success: false } }
关于超时日志的上报
当服务端的接口返回慢的时候,有必要统计下访问较慢的接口的url和接口返回时间,日志类型为warn
//在apiMiddleware中统计fetch 开始到结束的时长 const apiStart = new Date().getTime() const others = otherParams(ctx) const options = { url: ctx.req.url, method: ctx.method, data: ctx.request.body, ...others } let result try { result = await fetch(options) const apiEnd = new Date().getTime() if (apiEnd - apiStart >= 2000) { // 接口返回慢 logger.warn('API_MIDDLEWARE,API Request Time > 2s', apiEnd - apiStart, ctx.req.url) } ctx.body = result } catch (e) { } }
关于客户端报错日志上报及优雅降级
1.我们目前的服务端框架目前对于客户端报错是很粗暴的在前台抛出了一个“Interval server error” ,这个是koa 对于onerror的统一处理。这样的用户体验很差。
2.客户端报错信息也没有有效的收集起来。所以要对前端的渲染中间件和客户端发生报错的样式展示做一下修改。
修改如下:
在客户端:
我们需要在router 组件里通过react 16的新Api :componentDidCatch 对错误信息进行定位和反馈。如果捕捉到客户端发生错误,例如undefind 等,有一个公共的样式兜住,并渲染报错的 组件UI
componentDidCatch(error, info) { this.setState({ hasError: true }) console.log(`报错信息:${error}`) console.log(`报错调用栈的组件: ${JSON.stringify(info)}`) } render() { if (this.state.hasError) { // 你可以自定义降级后的 UI 并渲染 return <h1>Sorry,Something went wrong.</h1> } const { menuItems } = this.state const routeWithSubRoutes = (route, index) => ( <Route key={index} exact={route.exact || false} path={route.path} render={props => <route.component {...props} menuItems={menuItems} routes={route.routes} />} /> ) return ( <div className="mobile-container" style={{ height: '100%' }}> <Switch> {routes.map((route, index) => routeWithSubRoutes(route, index))} </Switch> </div> ) }
实例如下:
在服务端:
我们需要在渲染我们的页面的时候去捕捉到报错信息,并让页面继续渲染,而不是被koa 的error捕获
let rootContent = null try { rootContent = renderToString( <Provider store={store}> <StaticRouter location={ctx.req.url} context={routerContext}> <App /> </StaticRouter> </Provider> ) } catch (error) { // 在这里去上报日志 logger.error('客户端报错:', error) }
实例如下:
这样的话,我们就能在客户端的时候获取到报错和优雅的用户错误页面展示,并且将客户端报错上传给服务器
关于服务端告警和通知的意见
1.我们需要统计一定时间内发生同一个错误或者接口超时的日志次数,如果超过约定次数则报警并用钉钉通知。
2.如果是客户端报错,则立即反馈到钉钉。
3.阿里云的日志功能应该可以去接钉钉。alertmanager 报警,webhook到钉钉