10分钟掌握Sentry

一句话说Sentry是干嘛的

Sentry 是一个开源的实时错误追踪系统,可以帮助开发者实时监控并修复异常问题。

创建一个项目实例

项目接入Sentr指南

安装依赖

Sentry通过在应用程序runtime使用SDK监控错误、性能

bash 复制代码
# Using npm 
npm install --save @sentry/vue @sentry/tracing @sentry/integrations


# Using yarn
yarn add @sentry/vue @sentry/tracing @sentry/integrations

Sentry配置

创建DSN

在项目settings中找到Client Keys; 里面有个DSN值用于项目中初始化Sentry

封装异常工具库

项目中新建register.js文件

typescript 复制代码
const registerSentryPlugin = {
   //初始化sentry
  init(Vue) {
    try {
      Sentry.init({
        dsn: 'xxxxxxxxx', //Client Keys  中有个DSN
        Vue,
        autoSessionTracking: true, //捕获与 Electron 主进程的生命周期相关的会话
        integrations: [], //服务集成
        tracingOptions: {
          trackComponents: true,
        },
        sampleRate: 1, // 错误收集率
        release: '1.0.0', //版本号  可与sourceMap进行关联
        tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.01 : 1,//采样率 1:每个异常都会上报到sentry
        // 设置环境
        environment: process.env.NODE_ENV,
      });
      // 版本号区分
      Sentry.configureScope((scope) => {
        scope.setTag('web_version', '1.0.0');
      });
       //捕获VUE组件中抛出的异常
      Vue.config.errorHandler = (err) => {
        this.captureMessage(`捕获异常:${err.message}`, { message: err.message });
      };
    } catch (error) {
      console.log('sentry:', error);
    }
  },
  /**
   * @name 主动上报捕获异常
   * @param { title } title 标识
   * @param { object } params 参数
   * @param { object } stack 错误对象或微信返回对象
   */
  async captureMessage(title, params, stack = {}) {
    try {
      const isError = typeof stack === 'object' && !!stack.stack;
      const errorName = (isError ? stack.message : stack.errMsg) || 'unknows';
      const extra = {
        params,
        errMsg: isError ? stack : stack.errMsg || '',
        href: location.href,
      };

      // 上报错误
      Sentry.withScope((scope) => {
        scope.setFingerprint([title, errorName]);
        const errMessage = new Error(errorName);
        errMessage.name = `前端异常上报:${title}`;
        console.log('前端异常:', title);
        Sentry.captureException(errMessage, {
          extra,
          level: 'error',
        });
      });
    } catch (error) {
      console.log('sentry:', error);
    }
  },

  /**
   * 上报服务请求异常
   * @param {*} stack
   * @returns
   */
  async httpSentryCaptureMessage(stack) {
    try {
      // 错误信息
      const errorMsg = stack.message;
      const errorCode = (stack.response && stack.response.status) || 0;
      if (errorCode === 403) {
        // 过滤403类凭证错误
        return;
      }
      // 检测是否过期
      let errorName;
      if (/timeout/.test(errorMsg)) {
        errorName = '接口超时';
      } else if (/^4\d{2}$/.test(errorCode)) {
        errorName = '服务端40X错误';
      } else if (/^5\d{2}$/.test(errorCode)) {
        errorName = '服务端50X错误';
      } else {
        errorName = '调用异常';
      }

      const extra = {
        ...(stack.config || {}),
        errMsg: stack,
        href: location.href,
      };

      
      const deleteKeys = ['cookie', 'sid', 'userid'];
      if (extra.header) {
        for (const key in deleteKeys) {
          const _item = deleteKeys[key];
          if (Object.prototype.hasOwnProperty.call(extra.header, _item)) {
            delete extra.header[_item];
            if (_item === 'cookie') {
              extra.hasCookie = true;
            }
          }
        }
      }

      //接口超时,上报接口的参数
      errorName === '客户端接口超时' && (extra.networkInfo = await this.getResourceLoad('xmlhttprequest', extra.url));
      
      Sentry.withScope((scope) => {
        scope.setFingerprint([extra.method, extra.url, errorName]);
        const errMessage = new Error(`异常接口地址: ${extra.url}`);
        errMessage.name = errorName;
        Sentry.captureException(errMessage, {
          extra,
          level: 'error',
        });
      });
    } catch (error) {
      console.log('sentry:', error);
    }
  },
  /**
   * @name 
   * @param { string } type 资源类型
   * @param { string } name 资源名称匹配
   */
  getResourceLoad(type = 'xmlhttprequest', name = '') {
    return new Promise((resolve) => {
      if (!window.performance) {
        resolve({});
        return;
      }
      setTimeout(() => {
        const list = window.performance.getEntries().filter((item) => item.initiatorType === type) || [];
        
        if (!name) {
          resolve(list);
          return;
        }

        
        let result = {};
        for (let i = list.length - 1; i >= 0; i -= 1) {
          if (list[i].name && list[i].name.indexOf(name) >= 0) {
            result = list[i];
            break;
          }
        }
        resolve(result);
      }, 50);
    });
  },
};

export default registerSentryPlugin;

初始化Sentry工具库

项目中入口文件(main.js)进行初始化

csharp 复制代码
import registerSentryPlugin  from './sentry/register';

try {
  registerSentryPlugin.init(Vue);
} catch (error) {}

项目中完成了上述基础配置,Sentry就能将项目中捕获的异常上报到Sentry后台,我们就能监控项目告警情况。

自定义异常

我们还可以根据项目的实际场景需求,在关键流程受阻时,自定义异常上报(通过工具类方法captureMessage上报)

告警通知

我们可以将项目上报的问题进行条件过滤上报到团队OA群里,方便大家及时关注到项目异常

总结

sentry是目前比较通用的异常信息收集的解决方案,接入成本曲线较低,易上手

1、sentry平台创建项目

2、项目安装sentry依赖库

3、初始化sentry,异常收集

4、处理异常问题,进行告警筛选

短短几分钟你就能完成项目异常信息收集已告警

参考资料

sentry官方文档

相关推荐
青锐CC10 分钟前
webman使用中间件验证指定的控制器及方法[青锐CC]
中间件·前端框架·php
还是大剑师兰特25 分钟前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解25 分钟前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~31 分钟前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding36 分钟前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
man201738 分钟前
【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
vue.js·spring boot·后端
阿征学IT40 分钟前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓41 分钟前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶213641 分钟前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了41 分钟前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js