Знаете ли вы, сколько у вас проблем с кодом онлайн?

внешний интерфейс

Автор этой статьи @李一君, фронтенд-разработчик JD.com.

предисловие

badjs, общий термин в иностранном стиле для интерфейсных исключений. Относится к ошибкам-исключениям, возникающим во внешнем интерфейсе, таким как «объект не найден», «неопределенный», «синтаксическая проблема» и т. д.

Автор отвечает за внешний бизнес Jingxi, который долгое время страдает от большого количества аномалий и часто не может найти причину. Иногда он ненормально взлетает вверх, а затем снова падает.Проблема не может быть локализована, и она глубоко нарушена. После длительного периода осадков анализ подвел ряд выводов и методов.

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

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

Я надеюсь, что это может вдохновить вас перед экраном.

ps: эта серия методов не работает с node.js

Бадж Кёнхи

Взгляните сначала на эту картинку:

badjs

Это бадж-тренд онлайн-бизнеса, за который я отвечаю. Я не знаю, что вы чувствуете, когда видите этот шип.Все равно я буду очень нервничать, когда увижу его.Что бы ни происходило в моей руке, я должен немедленно прыгать к компьютеру, чтобы проверить проблему, проанализировать лог , и сообщить о причине боссу...

зачем такая система

Как говорится, технологии служат бизнесу. Наша система ведения журнала badjs родилась по необходимости.

Возьмем, к примеру, бизнес с подробной информацией о продуктах в апплетах WeChat. Ежедневные просмотры составляют десятки миллионов просмотров.

Если есть проблема с внешним интерфейсом, что-то не движется, в результате чего посещает меньше пользователей. Конечный результат заключается в том, что количество заказов уменьшается, пользователи теряются, а работа студентов во всем отделе страдает. Я терпеть не могу этот горшок.

Столкнувшись с этими проблемами, позвольте мне спросить: если вы поддерживаете эту страницу, вы боитесь? Если это страница, которую вы собираетесь опубликовать, вы дрожите?

Для счастливой жизни программистов, чтобы заранее найти проблемы и убить черный котел в колыбели, такая система просто необходима.

принцип и сбор баджей

Мы не можем предсказать, какая часть кода пойдет не так, и самое дешевое решение — централизовать ее в централизованном месте и собрать.

происхождение баджей

ESSENCE JS BADJS JS выполняет логику не распознается, произошла исключение.

Например, операции с неопределенными, неправильными типами данных, исключения парсинга, синтаксические ошибки и т.д.:

花式错误

коллекция баджей

Когда при выполнении JavaScript возникает исключение, которое не перехватывается,windowвызоветErrorEventинтерфейсerrorсобытие и выполнитьwindow.onerror()

Мы можем справиться с исключениями в глобальном порядке двумя способами:

window.addEventListener('error', function(errorEvent) {
    const { message, filename, lineno, colno, error } = errorEvent
    ...
})
window.onerror = function(message, source, lineno, colno, error) { ... }

Эти два способа лучше первого, потому чтоerrorСобытия можно отслеживать в течение несколькихwindow.onerrorПодпишитесь только на один.

Жаль, что ie8 не поддерживал его раньшеErrorEvent, использовать толькоwindow.onerror. Так что это зависит от бизнеса необходимо использовать разумно.

а такжеtry...catchЭтот метод также может собирать глобальную информацию об ошибках в конкретном сценарии, но у этого метода много недостатков, о нем мы поговорим позже.

Через событие ошибки под окном мы обычно можем собирать пять типов информации:

Атрибуты имея в виду иллюстрировать
message сообщение об ошибке неправильное описание
filename(source) URL скрипта, где произошла ошибка существуетErrorEventсредний даfilename,существуетonErrorсредний даsource
lineno строка ошибки
colno URL скрипта, где произошла ошибка
error Объект ошибки error.stackважная информация

В консоли это выглядит так:

error信息

С ними мы уже дали нам достаточно информации, чтобы определить проблему.

Здесь есть кое-что интересное в сообщении об ошибке. «Не пойманный» будет включен в сообщение, чтобы указать не пойманный. а такжеerror.stackБез этого префикса:

Uncaught

Междоменные сценарии:

Это идеальный сценарий. Реальная среда может включать междоменные области. В этом контексте часто может быть собрана только некоторая менее значимая информация.

跨域error信息

Подробно этот вопрос будет рассмотрен во второй половине статьи.

tips:

Событие ошибки под окном — это не все исключения, которые можно отловить.

Например, не будут срабатывать исключения, которые мы запускаем прямо в консоли, данные, перехваченные браузером, ресурс 404 и т.д.

апплеты:

Выше приведен внешний сбор ошибок с использованием html, и в апплете есть некоторые отличия. Возьмите апплет WeChat в качестве примера,

Глобальный захват исключений апплета можно найти вAppПодпишитесь по методу регистрации апплета.Связанные документы нажмите здесь

App({
  onLaunch (options) {
    // Do something initial when launch.
  },
  ...,
  onError (msg) {
    console.log(msg)
  }
})

Разница здесь в том, что есть только одна функция подписки onError.msgпараметр. похожий по содержаниюerror.stack

msg

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

отчет по баджам

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

Интерфейс должен сообщать данные:

категория источник Пример
content message + error.stack "ReferenceError: test is not defined at HTMLLIElement. (Всего 0,360 не в определенный .com/we C team/восемь часов…)
Полезная бизнес-информация / balabalabala

В дополнение к информации о стеке есть также некоторая бизнес-информация (например, документальный фильм, идентификатор пользователя и т. д.), которая может быть полезна для позиционирования, и вы можете выбрать ее самостоятельно в зависимости от своего опыта работы.

Кроме того, в сообщение включаются некоторые данные, которые могут быть собраны и отображены на стороне сервера, и интерфейсу не нужно сообщать об этом отдельно.

данные в сообщении:

категория источник Пример
ip / 58.20.191.9
time / May 20th 2020, 14:56:00.062
referer Headers.Referer Я иду искать. Jingdong.com/we C team? Да…
UA Headers.User-Agent Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.12(0x17000c2d) NetType/4G Language/zh_CN
Cookie Headers.Cookie pin=wecTeam;

сшивание данных:

Внешний интерфейс объединяет необходимые данные и подготавливает их к отправке на сервер. Аналогично этой ссылке:

Полностью. Jingdong.com/we C team/восемь часов…

Для передачи данныхgetспособ. проще в использованииimgпередача.

var _img = new Image();
_img.src = url;

должны знать о том,getСуществует ограничение на максимальную длину (2048 символов), обратите внимание на обрезку. Если вам нужно нарушить лимит, используйтеpostспособ сообщить.

Пример: bj-report.js

Может быть, вы спросите: я понимаю правду, но не хочу много работать, есть готовые?

имеют.

Порекомендуйте инструмент производства этой гусиной фабрики: bj-report.jsНажмите здесь, чтобы перейти на домашнюю страницу git

Это может помочь вам с отчетами о внешнем интерфейсе и мониторингом исключений JS. Просто инициализировав и передав некоторые параметры, вы можете пропустить все вышеперечисленные шаги~

BJ_REPORT.init({
  id: 1,                                // 上报 id, 不指定 id 将不上报
  uin: 123,                             // 指定用户 id, (默认已经读取 qq uin)
  delay: 1000,                          // 延迟多少毫秒,合并缓冲区中的上报(默认)
  url: "//badjs2.qq.com/badjs",         // 指定上报地址
  ignore: [/Script error/i],            // 忽略某个错误
  random: 1,                            // 抽样上报,1~0 之间数值,1为100%上报(默认 1)
  repeat: 5,                            // 重复上报次数(对于同一个错误超过多少次不上报)
                                        // 避免出现单个用户同一错误上报过多的情况
  onReport: function(id, errObj){},     // 当上报的时候回调。 id: 上报的 id, errObj: 错误的对象
  submit: null,                         // 覆盖原来的上报方式,可以自行修改为 post 上报等
  ext: {},                              // 扩展属性,后端做扩展处理属性。例如:存在 msid 就会分发到 monitor,
  offlineLog : false,                   // 是否启离线日志 [默认 false]
  offlineLogExp : 5,                    // 离线有效时间,默认最近5天
});

анализ данных

После разговора об отчетности данных давайте поговорим о том, как анализировать данные.

Извлечение данных

Система журналов, используемая в настоящее время Jingxi, настроена на основе Kibana, сторонней профессиональной системы анализа журналов:

kibana系统

Некоторые его функции просто отмечены на картинке, главное, что через него можно быстро и точно найти нужную информацию.

Если вам нужно избавить себя от некоторых проблем, вы также можете создать простую систему отчетности:

简单的报表系统

Если вы хотите избежать проблем, вы можете напрямую подключиться к серверу данных и экспортировать документ.

Получение отчетных данных не является частью темы этой статьи и не будет здесь представлено. Короче говоря, здесь мы извлекаем логи badjs.

Анализ аномалий

Имея данные, можно приступить к анализу быстрой (ку) музыки (би).

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

Мы должны уделять особое внимание первому, различать второе и максимально избегать влияния последнего на данные.

информация о содержании:

информация о содержанииmessageа такжеerror.stack, который является описанием ошибки и информацией о стеке.

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

Например, этот фрагмент информации о стеке (под хромом):

badjs

Давайте посмотрим на это построчно:

  1. Uncaught TypeError: Cannot read property 'style' of undefined

невозможноundefinedпосетить подstyleэто свойство. То есть под определенным объектом определенный атрибут пуст, и на этом основании к нему снова обращаются.styleПоэтому это свойство сообщило об ошибке.

  1. at removeAD (badjs.js:4)

Код исключения находится наbadjs.jsСтрока 4 в этом файле принадлежит методу с именемremoveAD.

  1. at window.fireBadjs (badjs.js:8)

передачаremoveADКод находится наbadjs.jsСтрока 8, имя метода, которому он принадлежит, называетсяwindow.fireBadjs.

  1. at badjs.html:16

передачаwindow.fireBadjsКод находится наbadjs.htmlСтрока 16 этого файла.

Имея такую ​​подробную информацию, сравните ее с исходным кодом и, в принципе, хорошо представляете причину баджей.

Существует также более короткое сообщение стека:

anonymous

Место, где возникает исключение, очень странное, первая строка и первый столбец, срабатывающие в анонимном. Вернитесь и проверьте код и обнаружите, что такого метода вообще нет в первой строке и первом столбце.

На самом деле это код, выполняемый в анонимной функции браузера (именно анонимной), аналогичный коду, набираемому непосредственно в консоли, либо черезevalКод, ожидающий выполнения функции.

Фактически, фон badjs на картинке выше заключается в том, что собственное приложение использует код js для прямого выполнения области окна в Webview.callback(которыйgetNetWrokCallback). Но этой функции не существует, поэтому возникает исключение.

Взглянем на эту ошибку с учетом приведенного выше основания.

某错误

Глядя на содержание ошибки, разве это не то же самое, что и в приведенном выше примере, но нет анонимной информации. Но в нашем коде этого нетSOHUZатрибут, поэтому сначала предположите, что исключение может быть вызвано кодом js, активно выполняемым приложением.

Дальнейший анализ должен включать информацию от UA. UA имеетkuaizhanAndroidWrapperЭто поле через универсальный интернет обнаружил, что идентификационная информация приложения «Быстрая станция» содержит это поле.

Вот и пришел вывод: страница посещалась в приложении "Быстрая станция", но не проверялась на непустое, а напрямую посещаласьSOHUZ, что приводит к тому, что в нашем бизнесе появляются отчеты о баджах. Не ошибся, дело закрыто.

UA:

Роль информации UA была представлена ​​заранее в конце предыдущего абзаца.

Мы можем сделать вывод об окружающей среде через UA: например, при работе в WeChat, приложении, браузере и т. д. Он также может определить, кто посещает нашу страницу: например, поисковый робот Baidu, поисковый робот xx, Али Байчуань и т. д.

UA можно просто использовать в качестве отпечатка пользователя пользователя. Страница Jingxi часто просматривается неизвестными Netizens, и она очень пунктуальна каждый день. Потому что я не уверен в источнике, я могу только игриво назвать это: кисть. Иногда мы встретимся много странных ошибок, но UAS позади них все одинаково, поэтому мы можем в основном предположить, что некоторые Netizens проводят наши страницы.

Важно подчеркнуть, что UA можно подделать. У некоторых опытных кистей каждый раз разный ПА, это очень сбивает с толку. Следовательно, является ли информация UA верной или нет, зависит от конкретной ситуации.

Ошибка скрипта в первый раз:

Фактически, большинство журналов баджей в бизнес-линии Jingxi H5 показывают только «Ошибку сценария».

Script error

Ошибка сценария возникает из-за того, что вводится междоменный сценарий. Например, другие js-файлы, не относящиеся к тому же домену, импортированные с помощью тега script, содержат badjs.В настоящее время информация о сообщении в событии onerror представляет собой только одно предложение.Script error, сообщение об ошибкеnull

跨域error信息

Данные об ошибках скрипта, о которых сообщалось, очень ограничены, и в большинстве случаев от них можно только отказаться.

Но решения этой проблемы нет, мы можем "открыть" информацию в Script error при репорте, а потом сообщить об этом. Например, междоменные сценарии устанавливают политики доверия и другие схемы.

Что касается подробной стратегии преодоления ошибки скрипта, мы обсудим ее далее в следующем содержании.

Script error

Вышеприведенное продало много очков.Давайте углубимся в этот абзац и обсудим, как найти эффективную информацию в ошибке сценария.

источник

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

Для всех междоменных скриптов, введенных через тег скрипта, в случае возникновения исключения событие ошибки под окном может получить только «Ошибка скрипта».

Script error

решение

Для проблемы «Ошибка сценария», вызванной междоменными сценариями, представленными тегами сценария, в отрасли существуют решения.

Общая идея такова: разве это не проблема безопасности, пока обе стороны чувствуют себя заслуживающими доверия, тогда мой браузер позволит вам снять это ограничение.

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

1. Добавьте в заголовок ответа Access-Control-Allow-Origin, указав имя доверенного домена.

Access-Control-Allow-Origin

2. Запрошенный тег script добавляет атрибут crossorigin

crossorigin

crossorigin имеет два значения, которые

  • anonymous
  • use-credentials

когдаcrossorigin='', или другие символы имеют тот же эффект, что и установка анонимного имени. анонимный полагается на Access-Control-Allow-Origin заголовка ответа. Следует отметить, что при использовании анонимного заголовок запроса не будет содержать информацию о пользователе, такую ​​как файлы cookie. И наоборот, использование учетных данных может принести информацию о пользователе.

use-credentials необходимо использовать в сочетании с Access-Control-Allow-Credentials в заголовке ответа.Когда Access-Control-Allow-Credentials возвращает значение true, браузер разрешает запуск скриптов и надежных источников. Также в этом случае для Access-Control-Allow-Origin нельзя установить значение*, должно быть конкретным доменным именем.

Access-Control-Allow-Credentials

Благодаря двум вышеуказанным шагам информация об ошибке в событии ошибки окна в веб-браузере не будет перехвачена браузером как «ошибка сценария».

Вариант сценария: jsonp

Вот вариант тега скрипта: jsonp

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

Поэтому, когда это выглядит ненормально, все равно будет ошибка сценария.

Обычный сценарий для исключений jsonp: обратный вызов не определен

callback 未定义

Хотя вы можете увидеть конкретную информацию об ошибке в консоли, в захваченной ошибке, поскольку URL-адрес является междоменным, дополнительное доверие не устанавливается, и может быть обнаружена только ошибка сценария.

Решение состоит в том, чтобы «деконструировать» ошибку сценария, выполнив два шага, перечисленных в «Общем решении».

Здесь есть проблема, заключающаяся в том, что большинство интерфейсов полагаются на информацию о пользователе, а интерфейс должен использоватьcrossorigin='use-credentials'способ привести информацию о файлах cookie к запросу. Следовательно, фон должен возвращать конкретное доменное имя в Access-Control-Allow-Origin и устанавливать для Access-Control-Allow-Credentials значение true, чтобы позволить браузеру пройти аутентификацию.

Access-Control-Allow-Credentials

use-credentials

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

специальное решение

Использование crossOrigin — обычное решение. Существует также специальный метод, который заключается в использованииtry...catch.

Возьмите простой каштан:

// https://xxx.badjs.js
window.fireBadjs = function () {
    ops
}
<script src="xxx.badjs.js" ></script>
<script>
    window.addEventListener('error', function (errorEvent) {
        const { message, filename, lineno, colno, error } = errorEvent
        debugger
    })
    fireBadjs()
    try {
        fireBadjs()
    } catch (error) {
        debugger
    }
</script>

В badjs.js есть файл с именем под окном.fireBadjsФункция, которая запускает строку кода, вызывающую исключение.

ПервыйfireBadjs()После бега,errorСобытие срабатывает, содержание следующее:

Script error

Вполне разумно, что событие ошибки может перехватывать только ошибки скрипта.

закомментировать первыйfireBadjs(), впуститьtry...catchсерединаfireBadjs()Казнить, баджс пойман уловом. Набрал в консоли, читается так:

错误信息

Удивительно, но то, что изначально было ошибкой сценария, было откопано.

Однако этот метод в конечном счете неэлегантен и более инвазивен для кода. И есть небольшая недоработка, то есть событие error под окном не сработает.

Далее поговорим о том, как улучшить.

попробуй уловить улучшение

try...catchЭто инструмент любви-ненависти. Много раз мы оборачиваем его, чтобы сделать код надежным.

Но однажды вtryЕсли в браузере возникает ошибка, браузер не будет печатать ошибку в консоли и не будет запускать событие ошибки.

Чтобы увидеть простой код:

try {
    JSON.stringify(apiData)
} catch (e) {}

Если возникает ошибка JSON.Stringify (Apidata), код может работать нормально, но окончательная производительность не такая ожидаемая, и мы не знаем, что здесь есть проблема. В конце концов, это могло быть большим кругом, чтобы вернуться сюда.

Проблема здесь в том, что после перехвата исключения нам не дается никакой подсказки. Решение также очень простое, просто добавьте подсказку вручную.

В это время вы можетеcatch, впишите ошибкуconsole.errorвнутрь, и завернуть вручнуюErrorEvent, выброшенный на захват события ошибки под окном.

try {
    JSON.stringify(apiData)
} catch (error) {
    console.error(error)
    if (ErrorEvent) {
        window.dispatchEvent(new ErrorEvent('error', { error, message: error.message })) // 这里也会触发window.onerror
    } else {
        window.onerror && window.onerror(null, null, null, null, error)
    }
}

Важно отметить, чтоtry...catchНедостатком является то, что вы не можете перехватывать исключения из асинхронного кода. НапримерsetTimeout,promise, события и т.д. Из-за этой проблемы мы не можем просто обернуть слой от начала до конца в коде.try...catchРешить все проблемы.

Hybrid

Разработчики часто вносят модификации и обновления в свои собственные башни из слоновой кости, но реальные производственные среды часто оказываются более сложными, чем ожидалось, например, гибридные.

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

Webview

Многие приложения имеют встроенные веб-просмотры для запуска страниц H5. Если badjs возникает в H5 в Webview, угадайте, какова производительность Webview?

Есть две среды iOS и Android.

1. Система iOS (тестовая версия системы: 9.0.2/11.0.3/13.4)

В Webview в iOS, если в асинхронном коде кроссдоменного скрипта встречается баджс (обратите внимание, что это асинхронный код), независимо от того, установлен ли кроссдоменный заголовок и crossOrigin по общепринятой схеме, можно только отловить ' в событии ошибки под окном.Ошибка сценария'.

Вы правильно поняли, если это веб-просмотр в iOS, будь то приложение для вашего бизнеса, WeChat или даже браузер.

Возьмите каштан: страница H5 открывается в WeChat на iPhone, а страница H5 ссылается на js-файл (междоменного) cdn. Когда событие внутри этого js-файла генерирует badjs и сообщает об этом, мы можем видеть только «Ошибка сценария» в системе журналов.

2. Система Android

Веб-просмотр в Android ведет себя так же, как веб-сторона. После установки междоменного заголовка и crossOrigin, если в междоменном скрипте возникают баджы, независимо от асинхронного и синхронного кода, детали ошибки можно поймать в событии ошибки под окном.

Возьмите онлайн-данные Jingxi h5 и просто проверьте это явление:

Бизнес, где большая часть трафика проходит через WeChat и мобильный QQ, в среде Android возникает ошибка 8043 Script.

25685 Ошибки скрипта на iOS

Кстати, под iOS всего 393 ошибки, не связанные со скриптом.

Обходной путь в основном для среды iOS. Потому что Android ведет себя так же, как веб-сторона.

1. Измените междоменный сценарий на сценарий того же домена.

Ошибка сценария не будет отображаться, если сообщается об этой же ошибке сценария домена.

2.попробовать... поймать пакет

Оберните асинхронный метод в междоменный скрипт с помощью try...catch и вручную инициируйте событие в catch. Ручная упаковка более хлопотна, вы можете рассмотреть возможность автоматической упаковки, когда вы упаковываете ее с помощью инструмента.

3. Используйте данные badjs Android для ссылки на iOS

Поскольку вероятность исключений в двух средах примерно одинакова, после выполнения междоменной работы сосредоточение внимания на устранении ошибок под Android может охватывать большинство исключений в iOS.

инъекция нативного кода

Разница между этим и предыдущим разделом заключается в том, что предыдущий раздел был H5 «свободным падением» в приложении, а этот раздел активно вмешивался приложением.

Собственный Webview приложения вводит код двумя способами. Первый преобразуется в нативный код js-кода, а затем отправляется в Webview в исполнении js-движка. Второй — с кодом C++, написанным непосредственно в нижней части движка, который становится нативным кодом.

Первый способ фактически выполняется через среду Webview, ничем не отличающуюся от js-кода. Обычно встречается в некоторых JSSDKcallbackпараметр.

Чтобы логика не была слишком сложной, приложение обычно выполняет ее непосредственно в Webview.window.callback, если обратный вызов не существует, возникает исключение, и поведение в Android и в Интернете одинаково.

Но в iOS есть только ошибка сценария.

Если вы видите ошибку в первой строке и первом столбце под анонимным в журнале, а UA — это среда приложения. Очень вероятно, что баджы генерируются активным вызовом приложения:

App 主动调用

Android нечего сказать, iOS покажет здесь ошибку сценария в содержании. Поскольку код генерируется приложением и отправляется в Webview, внешний интерфейс ничего не может сделать, чтобы деконструировать эту ошибку скрипта, поэтому мы можем только обсудить с одноклассниками приложения уровень защиты, например, проверить, функция определяется перед вызовом.

Второй метод заключается в написании кода C++ непосредственно на нижнем уровне движка, который обычно используется при создании собственного интерфейса для H5, чтобы использовать собственные возможности приложения, такие как jssdk. Сгенерированный таким образом код становится нативным кодом.

Пример нативного кода: console.log

native

Поскольку он работает в движке, при возникновении ошибки Webview может зависнуть. Front-end событие badjs в данном случае бессильно и его можно игнорировать.

Различия в стеке iOS

На самом деле в стеке ошибок под iOS все еще есть подробные отличия, которые представлены здесь.

Тестовая модель:

  • iphone xs max 13.4
  • Honor V20 magicUI_3.0.0 andorid_10.0.0.194

Тестовый код:

<script>
    window.addEventListener('error', function (errorEvent) {
        confirm(errorEvent.error && errorEvent.error.stack)
    })
    nextLineBadjs // 触发同域badjs
</script>
<!-- 设置了跨域头的脚本 -->
<script src="//wq.360buyimg.com/badjs.js" crossorigin="anonymous"></script>
// badjs.js
setTimeout(() => {
    asyncBadjs // 异步代码
}, 1000);

syncBadjs // 同步代码

Веб-просмотр WeChat:

Под iOS:

iOS

Под Android:

Android

В iOS не отображается конкретный код ошибки, который называется «глобальным кодом». Асинхронные скрипты из разных источников показывают ошибку скрипта.

На Андроиде все работает нормально.

«Глобальный код» iOS немного увеличивает сложность позиционирования, но поскольку местоположение указано, проблема невелика. Кроме того, вот информация в error.stack, На самом деле сообщение содержит подробную информацию в «глобальном коде».

пройти черезconfirm(errorEvent.message)мы печатаем это

'global code'

Таким образом, сообщая информацию, вы можетеerrorEvent.messageВозьми это с собой.

Другие веб-просмотры:

Автор также протестировал другие мобильные приложения и браузеры, в том числе приложение Jingdong, браузер Baidu, chrome, браузер qq, firefox.

Поскольку результаты аналогичны и нет существенной разницы, они не будут здесь показаны.

Поговорим об истории и больших данных

Самым большим препятствием для большинства одноранговых пользователей в использовании системы ведения журнала badjs является фоновая конструкция. В соответствии со стандартным процессом сбора журналов, принятым в отрасли logstash, внешний интерфейс может выполнить только первый шаг: сбор. Он бессилен для хранения и демонстрации и требует вмешательства закулисных одноклассников.

Вот некоторые фоны, связанные с Jingxi для справки.

уровень данных

В дополнение к badjs, наши данные журнала также включают некоторую информацию бизнес-журнала, активно сообщаемую внешним интерфейсом. Поскольку в отделе много предприятий, процесс отчетности относительно стандартизирован, и сообщаемые данные увеличиваются по мере роста бизнеса. Сейчас в сутки поступает около 2,4 млрд единиц данных (2,5 Т). После отсеивания бизнес-отчетов чистые баджи составляют всего 0,67%.

Поскольку у нас есть ресурсы машины больших данных, эта информация работает на нашей собственной машине данных без дополнительных затрат.

оптимизация производительности

Хотя ресурсов машины относительно достаточно, она не может поддерживать бесконтрольное использование. У нас есть некоторые решения по оптимизации производительности для обеспечения стабильности службы журнала.

  • Данные очищаются каждые 5 дней
    • Периодически очищайте данные, чтобы обеспечить эффективный цикл хранения
    • Журналы с истекшим сроком действия больше не предоставляют возможности запросов
  • Сообщить о плане перехода на более раннюю версию
    • Внешний интерфейс имеет конфигурацию доступа: когда данные пропадают, частота дискретизации автоматически настраивается, и определенный процент отчетов сбрасывается.
    • Аналогичная конфигурация в фоновом режиме, объем данных слишком велик, а некоторые данные автоматически отбрасываются.

Первая версия системы сбора данных: вебмонитор

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

简单的报表系统

Данные журнала хранятся в hdfs. Используйте impala для грубой силы hdfs при запросе. Эффективность относительно невысокая, и на один раз проверка уходит около полминуты.

В этой системе больше нет фильтров на выбор, а представление очень сырое.

Система сбора данных второго издания: Elasticsearch + Kibana:

Для второй версии системы журналов студенты, работающие с большими данными, подключались к ElasticSearch, создавали индекс файлов журналов, а затем беспрепятственно подключались к нему через систему Kibana. Из-за индекса скорость запроса выше, через Kibana порог запроса ниже, а анализ данных более размерный.

kibana系统

Повышение скорости запросов сделало качественный скачок в эффективности быстрого обнаружения и ответа на начальство.

Мы можем запросить по ключевым словам, отфильтровать бесполезное или выбрать интересную информацию.

Также удобно выбрать интервал в наборе данных, быстро проанализировать проблему и предложить решение.

Никогда не чувствовал, что счастье быть разработчиком может быть таким высоким.

резюме

как собирать баджи

  • пройти черезerrorEventилиwindow.onerror
  • В особых случаях рассмотрите возможность использованияtry...catch

отчет по баджам

  • Объединить информацию error.stack в URL
  • Отправляйте данные img и другими способами, обратите внимание на длину

анализ баджей

  • Вручную откатить код через информацию о стеке
  • Простое суждение об окружающей среде и личности пользователя через UA
  • Для информации об ошибках скрипта полезного значения не так много, и ее можно пропустить при анализе. Но найдите способ «деконструировать» его при сообщении

Распространенные сценарии, вызывающие ошибки скрипта

  • Сценарии между источниками и исключение, возникающее в перекрестном происхождении, не установлено
  • jsonp, crossorigin не задан, возникает исключение в js скрипте, сгенерированном скриптом
  • Произошло исключение в асинхронном коде междоменного скриптинга под iOS
  • Исключение возникает, когда натив активно выполняет js-код под iOS.

Замечания об асинхронном коде

  • Кросс домен под iosасинхронныйКод не может быть проанализирован Ошибка скрипта
  • попробуйте поймать не могу пойматьасинхронныйошибка в коде
  • jsonp в основномСинхронизироватькод

необходимость

Наконец, вернитесь и расскажите о необходимости этой системы.

Для бизнеса Jingxi такая система просто необходима. Поскольку безопасность очень важна, мы просто не можем взять на себя ответственность за долгосрочную онлайн-проблему.

Проанализируем его преимущества и недостатки.

Преимущество

Не уверен, что с вашим кодом что-то не так, это очень тревожная вещь. Если есть жалобы от клиентов и пользователей, они действительно большие.

Большая часть внешнего бизнес-кода тестируется и проверяется. Если он проходит достаточный тест, вероятность проблем с бизнес-логикой онлайн-кода относительно низка, поэтому основное внимание уделяется тому, есть ли какая-либо ошибка в коде.

Появление такой системы значительно повысило уверенность в себе первокурсников. После выпуска версии, если есть проблема, можно как можно скорее откатить код, чтобы найти проблему. Главное, к начальствучувство безопасности.

дефект

Однако такая система не является панацеей, и есть много других аспектов проблем, которые с ее помощью невозможно измерить. Если вы слишком зависимы и не полностью тестируете свой бизнес, просто загляните в журнал badjs, когда выйдете в интернет, и все готово.В Интернете может быть много серьезных проблем, ожидающих вашего решения.

Кроме того, стоимость этого ресурса также является проблемой, о которой необходимо упомянуть. Если у компании недостаточно ресурсов, ей требуются дополнительные накладные расходы на аренду серверов и устройств хранения.

как выбрать

Некоторые студенты могут спросить: «У нас нет этой штуки в нашем бизнесе, и мы полагаемся на так много ресурсов, что я никак не могу принять решение».

Многие предприятия на этапе роста могут вообще не иметь энергии для создания этих инфраструктур, но я верю, что когда-нибудь в будущем вам срочно понадобятся эти данные.

Спросите себя, насколько это может уменьшить онлайн-происшествия.

Возвращайтесь к этой статье, когда она вам понадобится.

Если ущерб, вызванный проблемой, превышает стоимость строительства и обслуживания, я уверен, что вы сможете убедить свою команду и своего босса.

использованная литература