Резюме:Записывая поведение пользователя, можно быстро воспроизвести сценарии ОШИБОК.
- Автор: Шаг за шагом
- оригинал:Построение системы внешнего мониторинга (альтернатива) статистика поведения пользователей и мониторинг (как быстро найти онлайн-проблемы)
FundebugПерепечатано с разрешения, авторские права принадлежат оригинальному автору.
Шаг за шагом, чтобы создать серию блогов о системе внешнего мониторинга:
- Шаг за шагом создайте систему мониторинга внешнего интерфейса: мониторинг ошибок JS
- Шаг за шагом создайте систему внешнего мониторинга: как сообщать о скриншотах веб-страниц?
- Пошаговое построение системы внешнего мониторинга: мониторинг исключений запросов интерфейса
- Пошаговое построение системы мониторинга внешнего интерфейса: как найти онлайн-проблемы внешнего интерфейса?
- Пошаговое построение фронтенд-системы мониторинга: как записывать поведение пользователей?
**Общие сведения.** На рынке представлено множество систем мониторинга, большинство из которых платные. Для небольших интерфейсных проектов это должно быть проблемой. Другая основная причина заключается в том, что, хотя функция является общей, она может не удовлетворять наши собственные потребности, поэтому может быть хорошим способом стать самодостаточными.
Это вторая глава о построении системы мониторинга внешнего интерфейса. В ней в основном рассказывается, как подсчитывать ошибки js. Следуйте за мной шаг за шагом, и вы также сможете создать собственную систему мониторинга внешнего интерфейса.
Онлайн-демонстрации, которые уже запущены:Система внешнего мониторинга
Код и объяснение размещены в этой статье:Введение и код системы мониторинга
Если развернуть действительно хлопотно, демо-система может обеспечить объем мониторинга на 7 дней, а я буду поддерживать ее еще долго:Развертывание в один клик
Долгое время фронтенд-проекты были полностью черным ящиком для фронтенд-программистов. После того, как проект запущен, мы совершенно не знаем, что пользователь сделал в нашем проекте, куда переходить или было ли сообщено об ошибке. Как только возникает проблема с онлайн-пользователями, и мы не можем ее воспроизвести, мы можем понять, что такое отчаяние. Как бы ни было тяжело, вопрос всегда будет рядом с вами. Поэтому, если мы можем превратить онлайн-проект в белый ящик, чтобы мы могли знать, что пользователь сделал в сети, это уже не сложно воспроизвести, хорошо ли это для фронтенд-программистов?
То, что я собираюсь написать дальше, является важной особенностью, поскольку она значительно улучшает мою способность решать проблемы и оказывает большое влияние на мою работу.
Вот посмотрите, что я сделал до сих пор:
Отчеты по статистике PV / UV, отчеты и анализ ошибок js, отчеты по статистике интерфейса и отчеты по статистике скриншотов страниц. Затем, добавив «отчеты о поведении пользователей по кликам», которые будут написаны сегодня, мы можем в основном анализировать, что пользователь делает на странице.
1. Как записывать поведение онлайн-пользователей
Базовое поведение онлайн-пользователей включает в себя: посещение страниц, поведение при нажатии, запрос поведения интерфейса и поведение отчетов об ошибках js.Эти точки могут в основном четко фиксировать все онлайн-поведение пользователей. Конечно, сюда также входят: поведение при загрузке ресурсов, поведение при прокрутке страницы, элементы, попадающие в поле зрения пользователя и т. д. Это более подробная статистика поведения, которая может быть улучшена в будущем, но приведенные выше четыре поведения уже могут выполнять нашу статистическую задачу. потребности.
Посетите страницу, у нас уже есть поведение отчетов об ошибках js, давайте посмотрим, как подсчитывать поведение кликов и поведение интерфейса запроса.
поведение кликов
// 用户行为日志,继承于日志基类MonitorBaseInfo
function BehaviorInfo(uploadType, behaviorType, className, placeholder, inputValue, tagName, innerText) {
setCommonProperty.apply(this);
this.uploadType = uploadType;
this.behaviorType = behaviorType;
this.className = utils.b64EncodeUnicode(className);
this.placeholder = utils.b64EncodeUnicode(placeholder);
this.inputValue = utils.b64EncodeUnicode(inputValue);
this.tagName = tagName;
this.innerText = utils.b64EncodeUnicode(encodeURIComponent(innerText));
}
/**
* 用户行为记录监控
* @param project 项目详情
*/
function recordBehavior(project) {
// 行为记录开关
if (project && project.record && project.record == 1) {
// 记录行为前,检查一下url记录是否变化
checkUrlChange();
// 记录用户点击元素的行为数据
document.onclick = function (e) {
var className = "";
var placeholder = "";
var inputValue = "";
var tagName = e.target.tagName;
var innerText = "";
if (e.target.tagName != "svg" && e.target.tagName != "use") {
className = e.target.className;
placeholder = e.target.placeholder || "";
inputValue = e.target.value || "";
innerText = e.target.innerText.replace(/\s*/g, "");
// 如果点击的内容过长,就截取上传
if (innerText.length > 200) innerText = innerText.substring(0, 100) + "... ..." + innerText.substring(innerText.length - 99, innerText.length - 1);
innerText = innerText.replace(/\s/g, '');
}
var behaviorInfo = new BehaviorInfo(ELE_BEHAVIOR, "click", className, placeholder, inputValue, tagName, innerText);
behaviorInfo.handleLogInfo(ELE_BEHAVIOR, behaviorInfo);
}
}
};
Давайте сначала посмотрим на код поведения щелчка. На самом деле это очень просто. Нужно переписать метод документа onclick, а затем сохранить атрибуты, содержимое и т. д. соответствующего элемента. **Но, ** Мы потратили так много усилий. Это пустая трата времени — сохранять столько журналов только для того, чтобы просто записывать действия пользователя по клику. Таким образом, эта статистика поведения кликов будет добавлена в будущий анализ удержания, а функция записи журналов без скрытых точек будет реализована в то же время, что сделает нашу систему мониторинга более мощной и богатой. Анализ удержания будет относиться кGrowingIo, если интересно, то можно узнать.
Нам нужно записать className элемента, tagName, innerText и т. д. Нам нужно достаточно содержимого, чтобы определить, какую кнопку нажал пользователь. Этот метод относительно умственно отсталый, и будет улучшен при написании функции анализа удержания в будущем, но пока его достаточно для удовлетворения наших требований.
поведение интерфейса запроса
// 接口请求日志,继承于日志基类MonitorBaseInfo
function HttpLogInfo(uploadType, url, status, statusText, statusResult, currentTime) {
setCommonProperty.apply(this);
this.uploadType = uploadType;
this.httpUrl = utils.b64EncodeUnicode(url);
this.status = status;
this.statusText = statusText;
this.statusResult = statusResult;
this.happenTime = currentTime;
}
/**
* 页面接口请求监控
*/
function recordHttpLog() {
// 监听ajax的状态
function ajaxEventTrigger(event) {
var ajaxEvent = new CustomEvent(event, {
detail: this
});
window.dispatchEvent(ajaxEvent);
}
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener('abort', function () { ajaxEventTrigger.call(this, 'ajaxAbort'); }, false);
realXHR.addEventListener('error', function () { ajaxEventTrigger.call(this, 'ajaxError'); }, false);
realXHR.addEventListener('load', function () { ajaxEventTrigger.call(this, 'ajaxLoad'); }, false);
realXHR.addEventListener('loadstart', function () { ajaxEventTrigger.call(this, 'ajaxLoadStart'); }, false);
realXHR.addEventListener('progress', function () { ajaxEventTrigger.call(this, 'ajaxProgress'); }, false);
realXHR.addEventListener('timeout', function () { ajaxEventTrigger.call(this, 'ajaxTimeout'); }, false);
realXHR.addEventListener('loadend', function () { ajaxEventTrigger.call(this, 'ajaxLoadEnd'); }, false);
realXHR.addEventListener('readystatechange', function() { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
window.addEventListener('ajaxLoadStart', function(e) {
var currentTime = new Date().getTime()
setTimeout(function () {
var url = e.detail.responseURL;
var status = e.detail.status;
var statusText = e.detail.statusText;
if (!url || url.indexOf(HTTP_UPLOAD_LOG_API) != -1) return;
var httpLogInfo = new HttpLogInfo(HTTP_LOG, url, status, statusText, "发起请求", currentTime);
httpLogInfo.handleLogInfo(HTTP_LOG, httpLogInfo);
}, 2000)
});
window.addEventListener('ajaxLoadEnd', function(e) {
var currentTime = new Date().getTime()
var url = e.detail.responseURL;
var status = e.detail.status;
var statusText = e.detail.statusText;
if (!url || url.indexOf(HTTP_UPLOAD_LOG_API) != -1) return;
var httpLogInfo = new HttpLogInfo(HTTP_LOG, url, status, statusText, "请求返回", currentTime);
httpLogInfo.handleLogInfo(HTTP_LOG, httpLogInfo);
});
}
Давайте взглянем на код статистики поведения интерфейса, изначально я хотел рассказать об этом отдельно, но сейчас у меня так много времени на разработку сопутствующих функций, что я написал только короткую версию.
Статистика поведения интерфейса включает в себя: инициирование запросов, получение запросов, статус получения и продолжительность запроса.Благодаря внешней статистике и анализу интерфейсов мы можем наблюдать за качеством онлайн-интерфейсов, и в то же время мы можно внести соответствующие коррективы в логику интерфейса, достигнута оптимальная загрузка страниц. Определения полей базы данных находятся вСерверная часть анализаВ проекте можно сразу посмотреть.
В первую очередь нам нужно следить за ajax запросом страницы.Как было показано выше, мы написали кусок кода для контроля ajax запроса (спасибо подобрал из интернета), мы можем мониторить все ajax запросы на странице , и проводить весь процесс запроса ajax.Атомарный анализ, мы можем отслеживать события в любой момент в процессе запроса, что очень полезно. **Но** очень важно, что если ваш проект использует выборку для запроса данных, то эти слушатели будут недействительны. Поскольку код выборки вводится браузером, он должен сначала выполняться с кодом мониторинга, а затем, если вы будете отслеживать ajax, он будет вообще бесполезен. Поэтому вам нужно переписать код выборки после написания прослушивателя ajax, чтобы он вступил в силу. Ну, эта часть не находится в центре внимания этой страницы, мы остановимся здесь.
2. Как узнать поведение онлайн-пользователей
Наконец, мы успешно загрузили оставшиеся две записи о поведении, так как же нам их всех опрашивать? Давайте сначала посмотрим на результаты моего запроса на странице.
Поскольку экран слишком мал для отображения всех записей, информация о записи включает в себя: имя поведения, время возникновения поведения, страницу возникновения поведения, сообщение об ошибке, снимок экрана ошибки и определяемое пользователем время загрузки снимков экрана.
Сказав это, есть несколько незначительных проблем, о которых следует знать.
- Поскольку Js используется в качестве зонда, трудно гарантировать, что userId пользователя может быть вставлен в каждую запись при ведении журнала.
- Итак, мы определяем customerKey для каждого пользователя, чтобы различать, если пользователь не удалит приложение и не очистит кеш приложения, customerKey останется неизменным.
- При запросе записи поведения пользователя вам необходимо сначала запросить все CustomerKeys пользователя (их может быть несколько), а затем использовать customerKey для запроса, вы можете получить точные результаты.
3. Как анализировать поведение онлайн-пользователей
На самом деле, мы так много сделали и так много записали для этой цели: анализировать поведение и быстро локализовать проблемы.
Итак, как мы локализуем проблему, я могу привести пример:
- Поведение JS при блокировке ошибок, мы можем видеть поведение до и после возникновения ошибки, и мы можем быстро и точно локализовать проблему.
- Произошла ошибка при сложном переходе по ссылке. Некоторые ошибки возникают после того, как фронтальная страница будет проходить сложные скачки и откаты, даже тестировщикам сложно протестировать такие проблемы, потому что может возникнуть любое поведение онлайн-пользователей. Часто все, что мы знаем, это то, что на последней странице, на которой он остановился, была ошибка. Таким образом, после проверки журнала поведения мы можем воспроизвести поведение пользователя, чтобы воспроизвести ОШИБКУ.
- Исключение интерфейса. При нормальных обстоятельствах передний интерфейс устанавливает период ожидания.Тем не менее, внутренний интерфейс считается нормальным, но передний конец не может нормально выполняться.В этой проблеме не отображается явление ошибки, и онлайн-обратная связь не является точной.Только передняя часть может нести горшок. Ведение журнала может записывать время отправки запроса и время его возврата, а также можно с первого взгляда узнать, истекло ли время ожидания.
- Онлайн-пользователи вообще не сообщают об аномалиях, все, что они могут сделать, это рассказать вам о том, что они видели в последний раз. Бог знает, какие шаги они прошли раньше. В итоге получается проблема с передком, а потом виноват, ха-ха.
Короче говоря, мы знаем, что пользователи делают на странице, поэтому нам больше не нужно беспокоиться о проблемах, и мы больше не будем спешить при возникновении проблем.
О Фундебаге
FundebugСосредоточьтесь на JavaScript, апплете WeChat, мини-игре WeChat, апплете Alipay, React Native, Node.js и мониторинге ошибок онлайн-приложений Java в режиме реального времени. С момента официального запуска Double Eleven в 2016 году Fundebug обработала в общей сложности более 1 миллиарда ошибок, включая Sunshine Insurance, Walnut Programming, Lizhi FM, Head 1:1, Weimai, Youth League Club и многие другие бренды. Бесплатная пробная версия приветствуется!