Показать сообщение отдельно
  #1 (permalink)  
Старый 14.04.2014, 19:46
Аватар для Hapson
Кандидат Javascript-наук
Отправить личное сообщение для Hapson Посмотреть профиль Найти все сообщения от Hapson
 
Регистрация: 23.07.2013
Сообщений: 122

Серверное логирование javascript ошибок
Знаю, знаю... да - написал велосипед
Вобщем вот:

JS часть
/**
 * Модуль отправки Javascript ошибок на сервер
 *
 * @author Hapson <hapson5703@gmail.com>
 * @copyright 2014 Hapson
 * @version 1.0.0
 */

var ErrorHandler = (function(win){

var EH = {}, oldH;

var SG = {
	url: undefined,
	debug: true,
	log: true
};

EH.setting = function(set){
	/**
	 * Установка настроек и запуск модуля логирования ошибок
	 * 
	 * @set {object} - массив настроек
	 * set.url {string} - URL, на который отсылать сообщения
	 * set.debug {boolean} - true: стандартный вывод ошибок
	 *                       false: попытка отключить стандартный вывод ошибок
	 * set.log {boolean} - true: отправлять ошибки на сервер
	 *                     false: не отправлять
	 */
	if(Object.prototype.toString.call(set) !== "[object Object]"){
		throw new TypeError("No configuration or incorrect ErrorHandler");
	}
	oldH = win.onerror; win.onerror = handler;
	SG.url = typeof set.url === "string" ? set.url : undefined;
	SG.debug = !!set.debug ? true : false;
	if(typeof win.opera !== "undefined"){SG.debug = !SG.debug;}
	SG.log = !!set.log ? true : false;
};

EH.log = function(error){
	/**
	 * Отправляет ошибку на сервер
	 *
	 * @error {string|object Error} - строка ошибки или объект класса Error
	 *    для получения более информативного стека, рекомендуется передавать объект класса Error
	 */
	if(Object.prototype.toString.call(error) !== "[object Error]"){
		try{throw new Error(""+ error);}catch(ex){error = ex;}
	}
	var ms, sk;
	ms = error.message || "noMessage";
	ms = (error.name || "noName") +": "+ ms +" at ";
	ms += (error.fileName || win.location.href) +":";
	ms += error.lineNumber || error.line || "noLine";
	sk = error.stacktrace || error.stack || getStack(EH.log) || "noStack";
	sendLog({type: "JS_EXCEPTION", message: ms, stack:sk});
};

function handler(message, file, line, col, error){
	/**
	 * Обработчик ошибок
	 *
	 * @message {string} - сообщение об ошибке
	 * @file {string} - файл, в котором произошла ошибка
	 * @line {number} - номер строки
	 * @col {number} - номер символа
	 * @error {object Error} - объект класса Error
	 */
	if(SG.log && SG.url){
		var res = prepareWinError(""+ message, file, line, col, error);
		if(res){sendLog(res);}
	}
	if(oldH){return oldH;}
	return SG.debug ? false : true;
}

function prepareWinError(message, file, line, col, error){
	/**
	 * Форматирует ошибку
	 *
	 * @return {object Object}
	 */
	if(message == "" || (/script *error/i.test(message) && line == 0)){return false;}
	col = col || "noColumn";
	var ms = message +" at "+ file +":"+ line +":"+ col;
	var sk = (error && (error.stacktrace || error.stack)) ? error.stacktrace || error.stack : getStack(ErrorHandler) || "noStack";
	return {type: "JS_ERROR", "message": ms, "stack": sk};
}

function sendLog(arr){
	/**
	 * Отправляет ошибку на сервер
	 * При наличии объекта XmlHttpRequest, отправляет ошибку методом POST
	 * В противном случае отправка производится методом GET
	 *
	 * @arr {object Object} - массив с полями type, message и stack
	 */
	var xhr = getXHR();
	var param = "type="+ arr.type +"&"+
		"message="+ encode(arr.message) +"&"+
		"stack="+ encode(arr.stack) +"&"+
		"platform="+ encode(navigator.platform) +"&"+
		"url="+ encode(win.location.href);
	if(!xhr){
		var url = SG.url + (/\?/.test(SG.url) ? "&" : "?") + param;
		try{new Image().src = url;}catch(ex){} return;
	}
	xhr.open("POST", SG.url, true);
	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xhr.setRequestHeader("HTTP_X_FORWARDED_FOR", "XmlHttpRequest");
	xhr.send(param);
}

function getXHR(){
	try{return new XMLHttpRequest();}catch(e){}
	try{return new ActiveXObject("Msxml2.XMLHTTP.3.0");}catch(er){return false;}
}

function getStack(fn){
	/**
	 * Формирует псевдо-стек. Работает преимущественно в IE
	 */
	if(!fn.caller){return false;}
	var stack = [], name;
	while(fn = fn.caller){
		name = fn.toString().replace(/\{[\s\S]*\}/gm, '');
		stack.push(name);
	}
	return stack.reverse().join(' -> ');
}

function encode(str){return encodeURIComponent(str);}

return EH;

}(window));

// настраиваем и включаем

ErrorHandler.setting({
	url: window.location.protocol +"//"+ window.location.hostname +"/js_log_handler.php",
	debug: false,
	log: true
});
Ответить с цитированием