fronttalks: Алексей Андросов (Яндекс), «Ошибки, которые мы...

62

Click here to load reader

Upload: yandex

Post on 22-May-2015

841 views

Category:

Technology


0 download

DESCRIPTION

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

TRANSCRIPT

Page 1: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Ошибки, которые мылюбим

Алексей Андросов

Старший разработчик интерфейсов

FrontTalks, Екатеринюург, 5 июля 2013 года

www.princexml.com
Prince - Non-commercial License
This document was created with Prince, a great way of getting web content onto paper.
Page 2: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Обо мне[email protected] @doochik

● По образованию – специалист по защите

информации

● 6 лет в Яндексе, 2 года ведущий разработчик

фронтенда в Я.Почте

● Люблю копаться в браузерах и внедрять новые фичи из HTML5

● Можете спрашивать про JS, CSS и frontend в целом

02

Page 3: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Баги – это нормально

Page 4: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Баги – это нормально● Браузер – неконтроллируемая среда для исполнения вашего кода.

04

Page 5: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Баги – это нормально● Браузер – неконтроллируемая среда для исполнения вашего кода.

● Дефграгменация рынка браузеров.

05

Page 6: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Баги – это нормально● Браузер – неконтроллируемая среда для исполнения вашего кода.

● Дефграгменация рынка браузеров.

● Человеку свойственно ошибаться.

Если вы меряете эффективность своей работы по количеству

багов, поздравляю, у вас серьёзные проблемы.

06

Page 7: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Первое правило:вы — дурак,а все вокруг —Д'Артаньяны

Page 8: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Второе правило:ошибка не в вашемкоде, а в коде вашейкоманды

Page 9: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Релизный цикл

[Object]

[Object]

[Object]

[Object]09

Page 10: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Релизный цикл

[Object]

[Object]

[Object]

[Object]

[Object]10

Page 11: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Релизный цикл + мониторинг

[Object]

[Object]

[Object]

[Object]

[Object]11

Page 12: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Зачем мониторинг?● Сломаться может в любой момент

12

Page 13: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Зачем мониторинг?● Сломаться может в любой момент

● Никто не гарантирует, что релиз заработает у реальных

пользователей

13

Page 14: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Зачем мониторинг?● Сломаться может в любой момент

● Никто не гарантирует, что релиз заработает у реальных

пользователей

● Превысили допустимый предел ошибок – послали уведомление

14

Page 15: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Зачем мониторинг?● Сломаться может в любой момент

● Никто не гарантирует, что релиз заработает у реальных

пользователей

● Превысили допустимый предел ошибок – послали уведомление

● Можно строить статистику

15

Page 16: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

На что смотрим● Доступность сервиса (код HTTP-ответа = 200)

16

Page 17: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

На что смотрим● Доступность сервиса (код HTTP-ответа = 200)

● Скорость отдачи страниц

17

Page 18: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

На что смотрим● Доступность сервиса (код HTTP-ответа = 200)

● Скорость отдачи страниц

● Количество совершенных действий

18

Page 19: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

На что смотрим● Доступность сервиса (код HTTP-ответа = 200)

● Скорость отдачи страниц

● Количество совершенных действий

● Количество писем в службу поддержки

● и т.п.

19

Page 20: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

А причем здесьфронтенд?

Page 21: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Что можно отследить вбраузере

● onload

● ondomcontentload

● Инициализация JS-компонентов

● JS-ошибки

● и т.п.

21

Page 22: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

А еще можно считать...● скорость загрузки

● скорость инициализации

● время ответа бекенда

● и т.п.

22

Page 23: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Почему именно в браузере● Эти события нельзя отследить по-другому

23

Page 24: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Почему именно в браузере● Эти события нельзя отследить по-другому

● Если сервер ответил на HTTP-запрос, это не значит, что браузер

его принял

24

Page 25: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Пример (запуск сервиса)$(projectNS.init);

25

Page 26: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Пример (запуск сервиса)if (window['jQuery']) {

$(projectNS.init);

} else {

log({type: 'fatal', error: 'no-jquery'});

}

26

Page 27: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Пример (запуск сервиса)if (window['jQuery']) {

if (window['projectNS']) {

$(projectNS.init);

} else {

log({type: 'fatal', error: 'no-project-js'});

}

} else {

log({type: 'fatal', error: 'no-jquery'});

}

27

Page 28: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Одна функция на все временаfunction log(data) {

var props = [];

for (var key in data) {

var value = encodeURIComponent(data[key]);

var key = encodeURIComponent(key);

props.push(key + '=' + value);

}

new Image().src = '/log?' + props.join('&');

}

28

Page 29: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

window.onerror● Обработчик всех JS-ошибок в браузере

● Есть errorMessage, scriptUrl, line

● Нет стека вызовов

29

Page 30: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

window.onerrorwindow.onerror = function(msg, url, line) {

log({

type: 'jserror',

msg: msg,

url: url,

line: line

})

})

30

Page 31: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Но......первые логи вам выдадут вот такую статистику

95% msg=Script error.&url=&line=0

0.2% ...

0.1% ...

01.

02.

03.

31

Page 32: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Главная проблемаwindow.onerrorIf the location URL does not have a same origin as the origin, then set

message to "Script error.", set location to the empty string, and set line

to 0.

http://dev.w3.org/html5/spec/webappapis.html#report-the-error“

32

Page 33: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Главная проблемаwindow.onerrorРешается только в Firefox 13+ с помощью

<script src="…" crossorigin="anonymous" ></script>.

А сервер должен ответить CORS-заголовком

Access-Control-Allow-Origin: *

Атрибут есть в черновике HTML 5.1. Ждем…

33

Page 34: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Главная проблемаcrossorigin="anonymous"Если Chrome, Firefox или Opera не получит правильный заголовок

Access-Control-Allow-Origin , то заблокирует загрузку

скрипта.

34

Page 35: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

try-catch?Все обернуть в try-catch сложно, потому что JS – асинхронный

язык.

Также стоит учитывать, что try-catch влияет на

производительность.

35

Page 36: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»
Page 37: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Другие способыисполнения JS

Page 38: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Общий принцип1. Грузим JS как текст (XHR, localStorage)

2. Исполняем в браузере в same-origin policy

38

Page 39: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

createElement('script')onerror

msgonerror

urlonerror

linecatchmsg

catchurl

catchline

Chrome 26 + - - + - *

Fx 22 + - - + - *

IE 9 + - - + - -

IE 10 + - - + - *

Opera 12.15 + - - + - *

* – строка без урла почти бесполезна

39

Page 40: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

eval / new Function / setTimeoutonerror

msgonerror

urlonerror

linecatchmsg

catchurl

catchline

Chrome 26 + - * + - *

Fx 22 + - - + - -

IE 9 + - - + - -

IE 10 + - * + - *

Opera 12.15 + - * + - *

* – строка без урла почти бесполезна

40

Page 41: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

<script src="data:..."onerror

msgonerror

urlonerror

linecatchmsg

catchurl

catchline

Chrome 26 - - - + * **

Fx 22 - * - + * -

Opera 12.15 - - - + * **

<script src="data:text/javascript,...">

* – урлом является весь src (исходный текст)

** – код вытягивается в одну строку

41

Page 42: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

<a href="javascript:..."onerror

msgonerror

urlonerror

linecatchmsg

catchurl

catchline

Chrome 26 + - - + - **

Fx 22 + * - + * -

IE 9 + - - + - -

IE 10 + - ** + - **

Opera 12.15 - - - + * **

* – урлом является весь src (исходный текст)** – код вытягивается в одну строку42

Page 43: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Blobvar blob = new Blob([code],

{type: 'text/javascript'});

var url = URL.createObjectURL(blob);

var script = document.createElement('script');

script.src = url;

URL.revokeObjectURL(url);

document.body.appendChild(script);

43

Page 44: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Blobonerror

msgonerror

urlonerror

linecatchmsg

catchurl

catchline

Chrome 26 + * + + * +

Fx 22 + * + + * +

IE 10 + * + + * +

* – урлом является id Blob'а. Если исполняется несколько кусков

кода, то можно сделать простой маппинг ресурсов

44

Page 45: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Что еще надо знатьпро window.onerror?

Page 46: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Избавляемся от вечного"error at line 1"После минификации весь код вытягивается в одну строку, из-за

этого неудобно искать ошибки с символе 30768.

Поможет UglifyJS

$ uglifyjs page.js -b beautify=false,max-line-len=100

46

Page 47: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Вместо msg может бытьсобытие...о незагрузке скрипта

if (msg && typeof msg != 'string') {

if (msg.type && msg.target) {

try {

url = msg.target.src;

} catch(e) {}

msg = 'Error loading script';

}

}47

Page 48: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Фильтруем не наши ошибкиif (url && (

/(miscellaneous|extension)_bindings/.test(url) ||

/^chrome:/.test(url) ||

/^file:/.test(url)

) {

return;

}

48

Page 49: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Обрабатываем JSONPif (url && /(&|\?)callback=/.test(url)) {

errorType = 'noJSONPResponse';

}

49

Page 50: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Что ещё можнологировать?

Page 51: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Неожиданное поведениеif (data && data.status === 'OK') {

// все хорошо

} else {

log({

'type': 'something_went_wrong',

'some_usefull_data': data

)}

}

51

Page 52: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Важный код в try-catchtry {

// все хорошо

} сatch (e) {

log({

'type': 'exception',

'msg': e.message || e.toString(),

'stack': e.stacktrace || e.stack

)}

}

52

Page 53: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Транспорты и долговисящиесоединенияИх можно отлаживать с помощью скрытой консоли, доступной по

хоткею.

● Всегда можно посмотреть все события

● Можно отправлять весь лог на анализ

53

Page 54: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Логи для ленивых и богатых● Errorception (платный)

● ExceptionHub (платный)

● JSLogger (платный)

● Muscula (пока бесплатный)

● Proxino (платный)

● Qbaka (платный)

54

Page 55: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Подводим итоги

Page 56: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Логируем поведениепользователя

● Всегда знаете как релиз работает у настоящих пользователей.

56

Page 57: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Логируем поведениепользователя

● Всегда знаете как релиз работает у настоящих пользователей.

● Всегда знаете что не работает у пользователя.

57

Page 58: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Логируем поведениепользователя

● Всегда знаете как релиз работает у настоящих пользователей.

● Всегда знаете что не работает у пользователя.

● Проще анализировать проблему, проще службе поддержки, проще

исправить.

58

Page 59: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Логируем поведениепользователя

● Всегда знаете как релиз работает у настоящих пользователей.

● Всегда знаете что не работает у пользователя.

● Проще анализировать проблему, проще службе поддержки, проще

исправить.

● Резко возрос рейт ошибок? Всем разослали смс-ку и начинаем

чинить.

59

Page 60: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

И помните1. Если в каждом релизе количество ошибок вырастает на 1%, то

через 10 релизов будет +11%

60

Page 61: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

И помните1. Если в каждом релизе количество ошибок вырастает на 1%, то

через 10 релизов будет +11%.

2. Логов много не бывает!

61

Page 62: FrontTalks: Алексей Андросов (Яндекс), «Ошибки, которые мы любим»

Алексей Андросов

Старший разработчик интерфейсов

[email protected]

@doochik

github.com/doochik