Интеграция JavaScript с Sentry

JavaScript React.js Electron

Sentry-JavaScript

Sentry представляет собой набор проектов с открытым исходным кодом для отлова ошибок продукта и поддерживает множество языков и фреймворков.

Здесь описаны только операции обработки в направлении front-end JavaScript.

В предыдущих сценариях применения нашей компании многие проекты использовалиkibanaзаниматься статистикой. Но мы не можем точно знать, в каком состоянии работает приложение. Когда клиент использует наш продукт для разработки, если возникает ошибка или сбой. Пользователи могут только обратиться за помощью в службу поддержки, а затем передать нашим разработчикам для воспроизведения и ремонта. Среди них, поскольку конкретные данные не ясны, разработчики будут очень много времени воспроизводить.

а такжеSentryЦелью этого является решение этой болевой точки, что позволяет разработчикам быстро и точно определить основную причину проблемы, чтобы добиться быстрых исправлений, и позволить разработчикам больше сосредоточиться на разработке новых функций. Сокращение траты временных ресурсов.

1. JavaScript

1.1 Доступ

потому чтоSentryс помощьюHookТехнология функции ошибок для достижения цели обнаружения ошибок, поэтому мы можем получить доступ к существующим проектам без потерь.

НижеReactа такжеSentryНекоторые основные шаги для объединения.

React:

#SentryBoundary.js
import { Component } from "react";
import Raven from "raven-js";

export default class SentryBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }

  componentDidCatch(error, errorInfo) {
    this.setState({ error });
    // 发送错误信息
    Raven.captureException(error, { extra: errorInfo });
  }

  render() {
    if (this.state.error) {
      // 此处可以写成组件,当组件崩溃后,可以替换崩溃的组件
      console.log("React Error");
    }
    return this.props.children;
  }
}
#index.js
Raven.config("DSN", {
  release: release,
}).install();

ReactDOM.render(
  <div>
    <SentryBoundary>
      <App />
    </SentryBoundary>
  </div>,
  document.getElementById("root")
);

1.1.1. Загрузить исходную карту

Если приведенный выше код был сконфигурирован, то текущее приложение может поймать ошибку, но есть проблема, большинство наших текущих проектов используютwebpackУпаковка, а упакованный код является запутанным и зашифрованным кодом, который не может дать нам точного определения места возникновения ошибки. Итак, нам нужно загрузитьsource-mapЗагрузите запутанный файл вSentryна сервере. Нам удобно быстро найти местонахождение проблемы.

Конфигурация и команды для этой загрузки довольно громоздки. также сочетание проектовSentryтрудность.

загрузитьsource-mapНа данный момент есть два пути:

  • использоватьSentryкоторый предоставилWebpackПлагин конфигурации, но его гибкость не высока.
  • использоватьsentry-cliИ его гибкость относительно высока, его можно индивидуально настроить под разные проекты.

Его конфигурация более сложная и здесь описываться не будет. Конкретный пример React в сочетании с Sentry. Виден мой проект на github:react-sentry-demo. Для каждой конфигурации есть подробные инструкции. который загружаетsource-map, я использую второй метод и написал скрипт, который реализует:Операции упаковки, тестирования среды, проверки подлинности, загрузки исходных карт и удаления локальных исходных карт., для завершения автоматизации скрипт можно напрямую перенести в существующий проект, и изменения будут не слишком большими.

Основная команда загрузки выглядит следующим образом:

sentry-cli releases files v1.8 upload-sourcemaps {js文件和js.map所在目录。如果没有找到,sentry会遍历其子目录} --url-prefix '~/{过滤规则}'`;

1.2 Принцип мелкого входа

В JavaScript естьwindow.onerrorэтот метод, покаSentryОсновной принцип захвата во внешнем интерфейсе заключается в захвате всех ошибок путем переопределения этого метода. Код его реализации примерно такой:

let _winError = window.onerror;
window.onerror = function (message, url, lineNo, colNo, errorObj) {
    console.log(`
	错误信息: ${message}
	错误文件地址: ${url}
	错误行号: ${lineNo}
	错误列号: ${colNo}
	错误的详细信息 ${errorObj}`);
}

потомSentryЗадача состоит в том, чтобы получить данные без ошибок, такие как:user-agent,浏览器信息,系统信息,自定义信息дождитесь информации, а потом сдавайтеSentryФункция жизненного цикла и, наконец, отправляет данные вSentryНа стороне сервера отобразите сообщение об ошибке.

1.2.1 Совместимость

Упомянутая здесь совместимость на самом делеwindow.onerrorсовместимость

1.2.1.1 Совместимость с операционной средой

окружающая обстановка message url lineNo colNo errorObj
Firefox
Chrom
Edge
IE 11
IE 10
IE 9
IE 8
Safari 10 and up
Safari 9
Opera 15+
Android Browser 4.4
Android Browser 4 - 4.3
Веб-просмотр WeChat (Android)
Веб-просмотр WeChat (IOS)
WKWebview
UIWebview

1.2.1.2 Совместимость этикеток

Этикетка Можно ли захватить window.onerror?
img Могу
script Нужно добавить тег скриптаcrossoriginатрибут и разрешить междоменный доступ на сервере. Если это свойство не используется, сообщение об ошибке будет отображаться толькоScript error.
css не можем
iframe не можем

Можно обнаружить, что все браузеры поддерживают этот метод. Просто некоторые операционные среды не поддерживаютcolNoа такжеerrorObj, но этот кусок,SentryЗа вас уже позаботились, так что не волнуйтесь. Просто при отображении ошибки информация не полная.

1.3. Информация, которую можно получить

1.3.1 Сообщения об ошибках

Как видно из приведенного выше принципа неглубокого входа, захват ядраwindow.onerror. затем, пока он может ловить ошибки, он будет отправлен вSentryначальство.

а такжеwindow.onerrorуловимые ошибки, за исключениемPromise, в основном любые ошибки, которые могут появиться в консоли, будут зафиксированы. То есть ошибки времени выполнения, включая синтаксические ошибки.

О захватеPromiseНеправильная схема, можно использовать:

window.addEventListener('unhandledrejection', event => {})

для захвата, но совместимость этого события не очень хорошая, на данный момент толькоwebkit内核поддержите это мероприятие.

const p = new Promise((reslove, reject) => reject('Error'))
p.then(data => {
  console.log(data)
})
// Promise触发了reject回调函数,但是却没有相应到catch来应对。从而导致报错。

image

crashReporter.startsentry

import { crashReporter } from 'electron'

crashReporter.start({
  productName: 'aoc-desktop',
  companyName: 'alo7',
  submitURL:
    'https://sentry.com/api/34615/minidump/?sentry_key=3e05fe101f1f85008e853ff56908b7eb',  // sentry提供的minidump接口
  extra: {
    // 额外信息
  }
})

process.crash()

source-mapSymbolsource-map

dSYMpdbpdbdump_syms.exepdbsym

source-mapurl-prefix