Piwik — аналог google analytics, который ставится на свой домен. Копирует апи google analytics, так что всё описанное можно с небольшими изменениями применить и при использовании google analytics.
Логирование
Ошибки записываются и в пивик, и в html-элемент на странице (удобно для автоматического тестирования). Код содержится в файле error_logger.js
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
( function ( ) {
"use strict" ;
var logToHtmlId = window . app_config && window . app_config . log_errors_to_html_id ,
logToPiwikPermitted = window . app_config && window . app_config . log_errors_to_piwik ,
logHtmlEl ;
if ( window . app_config && window . app_config . debug ) {
return ;
}
/**
* Log error to some html element
*/
function logToHtml ( params )
{
if ( ! logToHtmlId ) {
return ;
}
if ( ! logHtmlEl ) {
logHtmlEl = document . getElementById ( logToHtmlId ) ;
}
if ( logHtmlEl ) {
document . getElementById ( logToHtmlId ) . innerHTML += JSON . stringify ( params ) ;
}
}
/**
* Log error to piwik
*/
function logToPiwik ( params )
{
if ( ! logToPiwikPermitted ) {
return ;
}
if ( ! window . _paq ) {
window . _paq = [ ] ;
}
window . _paq . push ( [ 'trackEvent' , params . type , params . msg , JSON . stringify ( params ) ] ) ;
}
window . logError = function logError ( params ) {
params = {
type : params . type || ' ' , // not empty string because this param is not optional for piwik and it does not want empty field
msg : params . msg || ' ' , // the same as for type
stack : params . stack || null ,
ua : navigator && navigator . userAgent ,
url : params . url || '' ,
href : window . location . href ,
line : params . line || null
} ;
logToHtml ( params ) ;
logToPiwik ( params ) ;
} ;
window . onerror = function ( msg , url , line )
{
var preventErrorAlert = true ;
var err = { msg : msg , url : url , line : line , type : 'unhandled-onerror' } ;
window . logError ( err ) ;
return preventErrorAlert ;
} ;
window . onload = function ( )
{
if ( ! window . __angularLoaded ) {
window . logError ( { type : 'app-not-started' } ) ;
}
} ;
} ( ) ) ;
Здесь, помимо объявления глобальной функции для логирования, есть ещё два важных момента:
window.onerror
логирует все неперехваченные js-ошибки;
window.onload
проверяет установку глобальной переменной window.__angularLoaded
, которая ставится внутри AngularJS-приложения, и в случае необходимости логирует факт незапустившегося приложения.
Использование внутри AngularJS
Осталось научиться записывать ошибки внутри AngularJS-приложения. В этом нам поможет Бен Надель — http://www.bennadel.com/blog/2542-logging-client-side-errors-with-angularjs-and-stacktrace-js.htm .
В итоге сервис логирования выглядит так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
( function ( ) {
"use strict" ;
/**
* @desc Service for logging angular errors to external services
* @link http://www.bennadel.com/blog/2542-logging-client-side-errors-with-angularjs-and-stacktrace-js.htm
*/
var module = angular . module ( 'Utils.UtilsNgErrorLogger' , [ ] )
. factory ( 'UtilsNgErrorLogger' , UtilsNgErrorLogger ) ;
UtilsNgErrorLogger . $ inject = [ '$log' ] ;
function UtilsNgErrorLogger ( $ log )
{
function log ( exception , cause )
{
$ log . error . apply ( $ log , arguments ) ;
exception = exception || { } ;
cause = cause || '' ;
var msg = ( exception . message || '' ) + '(caused by ' + cause + ')' ;
if ( window . logError )
{
window . logError ( {
type : 'ng-error' ,
msg : msg ,
stack : exception . stack || null
} ) ;
}
}
return log ;
}
} ( ) ) ;
Как при этом выглядит index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
< ! doctype html >
< html >
< head >
< link rel = "stylesheet" href = "/css/libs.css" >
< link rel = "stylesheet" href = "/css/app.css" >
<script type = "text/javascript" src = "/conf.js" > </script>
<script type = "text/javascript" src = "/js/error_logger.js" > </script>
<script type = "text/js-sm-errors" id = "js-error-id" > </script>
< / head >
< body
ng - app = "MyApp" >
< ! -- html - код приложения -- >
<script type = "text/javascript" src = "/js/libs.js" > </script>
<script type = "text/javascript" src = "/js/views.js" > </script>
<script type = "text/javascript" src = "/js/app.js" > </script>
<script type = "text/javascript" >
var _paq = _paq || [ ] ;
_paq . push ( [ "setDocumentTitle" , document . domain + "/" + document . title ] ) ;
_paq . push ( [ "setCookieDomain" , "*.<domain>" ] ) ;
_paq . push ( [ "setDomains" , [ "*.<domain>" ] ] ) ;
_paq . push ( [ "trackPageView" ] ) ;
_paq . push ( [ "enableLinkTracking" ] ) ;
( function ( ) {
var u = ( ( "https:" == document . location . protocol ) ? "https" : "http" ) + "://<piwik_host>/" ;
_paq . push ( [ "setTrackerUrl" , u + "piwik.php" ] ) ;
_paq . push ( [ "setSiteId" , "1" ] ) ;
var d = document , g = d . createElement ( "script" ) , s = d . getElementsByTagName ( "script" ) [ 0 ] ; g . type = "text/javascript" ;
g . defer = true ; g . async = true ; g . src = u + "piwik.js" ; s . parentNode . insertBefore ( g , s ) ;
} ) ( ) ;
</script>
< / body >
< / html >
Пояснения
Нужно заменить <domain>
на свой домен, а <piwik_host>
— на урл до сервера с пивиком.
Сюда пишутся ошибки для удобства автоматического тестирования:
<script type = "text/js-sm-errors" id = "js-error-id" > </script>
Здесь подгружаются конфиги для разрешения логирования в пивик и указания id элемента для записи ошибок:
<script type = "text/javascript" src = "/conf.js" > </script>
Например:
var app_config = {
log_errors_to_html_id : 'js-error-id' ,
log_errors_to_piwik : true
} ;
Ещё можно логировать время загрузки страницы пользователями
https://blog.bullgare.com/2015/05/%D0%BB%D0%BE%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%B8-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8-%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8/
Альтернативы
Ещё одно описание системы логирования js-ошибок в google analytics — http://blog.gospodarets.com/track_javascript_angularjs_and_jquery_errors_with_google_analytics/
Similar Posts