From 4edf047e6103c4b120c70ae7670b8cb805ea5b6c Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Thu, 5 Apr 2012 22:27:01 +0100 Subject: [PATCH 01/38] Code to proxy the console.log, console.info and console.error functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to use, say, console.log(foo) and have it perform our logging — and then also the default functionality. --- jQuery.clientSideLogging.js | 83 ++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 3dbf479..5969dae 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -33,40 +33,111 @@ $.extend(defaults, options || {}); }; + // Compatibility functions for IE + if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function () {}, + fBound = function () { + return fToBind.apply(this instanceof fNOP + ? this + : oThis || window, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; + } + + if (!Array.prototype.forEach) { + Array.prototype.forEach = function( callback, thisArg ) { + var T, k; + if ( this == null ) { + throw new TypeError("this is null or not defined"); + } + + var O = Object(this); + var len = O.length >>> 0; + + if ( {}.toString.call(callback) != "[object Function]" ) { + throw new TypeError( callback + " is not a function" ); + } + + if ( thisArg ) { + T = thisArg; + } + + k = 0; + while( k < len ) { + var kValue; + if ( k in O ) { + kValue = O[ k ]; + callback.call( T, kValue, k, O ); + } + k++; + } + }; + } + + // Make console.* behave like proper Functions in IE. + if (Function.prototype.bind && console && typeof console.log == "object") { + ["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function (method) { + console[method] = this.bind(console[method], console); + }, Function.prototype.call); + }; + /** * The function that will send error logs to the server. Also logs to the console using console.error() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) */ - $.error = function(what) { + var original_error = console.error; + console.error = function(what) { if (defaults.log_level >= 1) { _send(defaults.error_url, what); } - if(window.console&&window.console.error&&defaults.use_console)console.error(what); + if ( original_error.apply ) { + original_error.apply(this, arguments); + } }; /** * The function that will send info logs to the server. Also logs to the console using console.info() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) */ - $.info = function(what) { + var original_info = console.info; + console.info = function(what) { if (defaults.log_level >= 3) { _send(defaults.info_url, what); } - if(window.console&&window.console.info&&defaults.use_console)console.info(what); + if ( origin_info.apply ) { + original_info.apply(this, arguments); + } }; /** * The function that will send standard logs to the server. Also logs to the console using console.log() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) */ - $.log = function(what) { + var original_log = console.log; + console.log = function(what) { if (defaults.log_level >= 2) { _send(defaults.log_url, what); } - if(window.console&&window.console.log&&defaults.use_console)console.log(what); + if ( original_log.apply ) { + original_log.apply(this, arguments); + } }; // Log errors whenever there's a generic js error on the page. From c60d5cef2f4f1ec15c8c4b78880a19de5fe6d253 Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Fri, 6 Apr 2012 13:19:32 +0100 Subject: [PATCH 02/38] Link to MDC docs for our compatibility functions. --- jQuery.clientSideLogging.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 5969dae..8e5990e 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -33,7 +33,10 @@ $.extend(defaults, options || {}); }; - // Compatibility functions for IE + // First, we need some compatibility functions for IE. + + // Function.prototype.bind + // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind#Compatibility if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { @@ -58,6 +61,8 @@ }; } + // Array.prototype.forEach + // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach#Compatibility if (!Array.prototype.forEach) { Array.prototype.forEach = function( callback, thisArg ) { var T, k; From 79406c3fdacb90609010b9b9578e4f6f3c6883d2 Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Fri, 6 Apr 2012 13:23:11 +0100 Subject: [PATCH 03/38] Update compatibility functions to match our code style. --- jQuery.clientSideLogging.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 8e5990e..e66173d 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -38,7 +38,7 @@ // Function.prototype.bind // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind#Compatibility if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { + Function.prototype.bind = function(oThis) { if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 internal IsCallable function throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); @@ -46,11 +46,13 @@ var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP - ? this - : oThis || window, + fNOP = function() {}, + fBound = function() { + return fToBind.apply( + this instanceof fNOP + ? this + : oThis + || window, aArgs.concat(Array.prototype.slice.call(arguments))); }; @@ -64,27 +66,27 @@ // Array.prototype.forEach // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach#Compatibility if (!Array.prototype.forEach) { - Array.prototype.forEach = function( callback, thisArg ) { + Array.prototype.forEach = function(callback, thisArg) { var T, k; - if ( this == null ) { + if (this == null) { throw new TypeError("this is null or not defined"); } var O = Object(this); var len = O.length >>> 0; - if ( {}.toString.call(callback) != "[object Function]" ) { - throw new TypeError( callback + " is not a function" ); + if ({}.toString.call(callback) != "[object Function]") { + throw new TypeError(callback + " is not a function"); } - if ( thisArg ) { + if (thisArg) { T = thisArg; } k = 0; - while( k < len ) { + while (k < len) { var kValue; - if ( k in O ) { + if (k in O) { kValue = O[ k ]; callback.call( T, kValue, k, O ); } From 8f823db1eda6f8fa43f7df6eaac35c35da9167cf Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Fri, 6 Apr 2012 13:31:18 +0100 Subject: [PATCH 04/38] Make hijacking the inbuilt console methods an option. --- jQuery.clientSideLogging.js | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index e66173d..d65be55 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -16,6 +16,7 @@ log_level: 1, native_error:false, use_console:false, + hijack_console:true, query_var: 'msg', client_info: { location:false, @@ -106,47 +107,59 @@ * The function that will send error logs to the server. Also logs to the console using console.error() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) */ - var original_error = console.error; - console.error = function(what) { + $.error = function(what) { if (defaults.log_level >= 1) { _send(defaults.error_url, what); } - if ( original_error.apply ) { + if (defaults.hijack_console && original_error.apply) { original_error.apply(this, arguments); } }; + if (defaults.hijack_console) { + var original_error = console.error; + console.error = $.error; + } + /** * The function that will send info logs to the server. Also logs to the console using console.info() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) */ - var original_info = console.info; - console.info = function(what) { + $.info = function(what) { if (defaults.log_level >= 3) { _send(defaults.info_url, what); } - if ( origin_info.apply ) { + if (defaults.hijack_console && origin_info.apply) { original_info.apply(this, arguments); } }; + if (defaults.hijack_console) { + var original_info = console.info; + console.info = $.info; + } + /** * The function that will send standard logs to the server. Also logs to the console using console.log() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) */ - var original_log = console.log; - console.log = function(what) { + $.log = function(what) { if (defaults.log_level >= 2) { _send(defaults.log_url, what); } - if ( original_log.apply ) { + if (defaults.hijack_console && original_log.apply) { original_log.apply(this, arguments); } }; + if (defaults.hijack_console) { + var original_log = console.log; + console.log = $.log; + } + // Log errors whenever there's a generic js error on the page. window.onerror = function(message, file, line) { if (defaults.native_error) { From 3c79980bce2db67c0857c834c963c8a93b6877ae Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Sat, 7 Apr 2012 00:59:19 +0100 Subject: [PATCH 05/38] Actually apply options that are passed to .clientSideLogging. --- jQuery.clientSideLogging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 3213ca9..04be3ed 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -30,7 +30,7 @@ * @param options The custom options. */ $.clientSideLogging = function(options) { - $.extend(defaults, options || {}); + defaults = $.extend(defaults, options || {}); }; /** From 7fa87b5dd998118f7b7141b9f7709f7293c2c5ea Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Tue, 10 Apr 2012 14:42:19 +0100 Subject: [PATCH 06/38] Refine the throttling mechanism to be a little less heavy-handed. Instead of allowing one entry per X seconds, switch to allowing X entries per Y seconds; this way, you can have multiple logs on the same page (up to X), that will all be logged, all while running less risk of being spammed than if you opened things up entirely. --- test/log.php | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/test/log.php b/test/log.php index 05021a8..3fa2697 100644 --- a/test/log.php +++ b/test/log.php @@ -25,8 +25,10 @@ function stripslashes_deep($value) { define('LOG_FILE', dirname(__FILE__) . '/log.txt'); define('ACCESS_FILE', dirname(__FILE__) . '/access.txt'); -// Only allow one entry per … seconds. -define('THROTTLE_TIME', 60); +// Only allow X entries per Y seconds. The default is to allow 15 entries +// every 2 minutes. +define('THROTTLE_COUNT', 15); +define('THROTTLE_TIME', 120); define('IP_ADDRESS', $_SERVER['REMOTE_ADDR']); @@ -48,9 +50,6 @@ function stripslashes_deep($value) { $format = $_REQUEST['format']; } -// Initially, assume that this client hasn't logged anything in the last minute. -$has_accessed = false; - if ( !file_exists(ACCESS_FILE) ) { if ( is_writable(dirname(ACCESS_FILE)) ) { touch(ACCESS_FILE); @@ -62,37 +61,45 @@ function stripslashes_deep($value) { $accesses = file(ACCESS_FILE); // Clear out old access logs. +$access_count = 0; $accesses = array_filter( $accesses, function($access) { - global $has_accessed; + global $access_count; + + if ( trim($access) == '' ) { + return false; + } list($date, $ip) = explode("\t", $access); $date = trim($date); $ip = trim($ip); - $fresh = ( strtotime($date) + THROTTLE_TIME > time() ); + // Keep entries for twice as long as the throttle time… + $to_keep = ( strtotime($date) + ( THROTTLE_TIME * 2 ) > time() ); + // …but only consider ones within the throttle time. + $to_consider = ( strtotime($date) + THROTTLE_TIME > time() ); // If the user has accessed within the last minute, proceed with the // filtering — but we won't be logging anything later. - if ( $fresh && $ip == IP_ADDRESS ) { - $has_accessed = true; + if ( $to_consider && $ip == IP_ADDRESS ) { + $access_count++; } - return $fresh; + return $to_keep; } ); // Log an access from this IP. -if ( !$has_accessed ) { +if ( $access_count < THROTTLE_COUNT ) { $accesses[] = date('Y-m-d H:i:s') . "\t" . IP_ADDRESS; } file_put_contents(ACCESS_FILE, join("\n", $accesses)); -// If the user has submitted a log in the last minute, bail out silently. -if ( $has_accessed ) { +// If the user has been throttled, bail out silently. +if ( $access_count >= THROTTLE_COUNT ) { die; } From 086b0339b2f481dc1fae853bc034c8182735e4cd Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 10:19:06 +0100 Subject: [PATCH 07/38] Rename the 'test' folder to 'log', and 'log.php' to 'index.php' to more closely match the js default urls. --- log/access.txt | 1 + {test => log}/css/bootstrap-responsive.css | 0 {test => log}/css/bootstrap-responsive.min.css | 0 {test => log}/css/bootstrap.css | 0 {test => log}/css/bootstrap.min.css | 0 {test => log}/css/style.css | 0 {test => log}/img/glyphicons-halflings-white.png | Bin {test => log}/img/glyphicons-halflings.png | Bin test/log.php => log/index.php | 0 {test => log}/js/scripts.js | 0 log/log.txt | 1 + {test => log}/test.php | 0 {test => log}/view_logs.php | 0 13 files changed, 2 insertions(+) create mode 100755 log/access.txt rename {test => log}/css/bootstrap-responsive.css (100%) rename {test => log}/css/bootstrap-responsive.min.css (100%) rename {test => log}/css/bootstrap.css (100%) rename {test => log}/css/bootstrap.min.css (100%) rename {test => log}/css/style.css (100%) rename {test => log}/img/glyphicons-halflings-white.png (100%) rename {test => log}/img/glyphicons-halflings.png (100%) rename test/log.php => log/index.php (100%) rename {test => log}/js/scripts.js (100%) create mode 100755 log/log.txt rename {test => log}/test.php (100%) rename {test => log}/view_logs.php (100%) diff --git a/log/access.txt b/log/access.txt new file mode 100755 index 0000000..dbd7d81 --- /dev/null +++ b/log/access.txt @@ -0,0 +1 @@ +2012-04-05 17:51:38 127.0.0.1 \ No newline at end of file diff --git a/test/css/bootstrap-responsive.css b/log/css/bootstrap-responsive.css similarity index 100% rename from test/css/bootstrap-responsive.css rename to log/css/bootstrap-responsive.css diff --git a/test/css/bootstrap-responsive.min.css b/log/css/bootstrap-responsive.min.css similarity index 100% rename from test/css/bootstrap-responsive.min.css rename to log/css/bootstrap-responsive.min.css diff --git a/test/css/bootstrap.css b/log/css/bootstrap.css similarity index 100% rename from test/css/bootstrap.css rename to log/css/bootstrap.css diff --git a/test/css/bootstrap.min.css b/log/css/bootstrap.min.css similarity index 100% rename from test/css/bootstrap.min.css rename to log/css/bootstrap.min.css diff --git a/test/css/style.css b/log/css/style.css similarity index 100% rename from test/css/style.css rename to log/css/style.css diff --git a/test/img/glyphicons-halflings-white.png b/log/img/glyphicons-halflings-white.png similarity index 100% rename from test/img/glyphicons-halflings-white.png rename to log/img/glyphicons-halflings-white.png diff --git a/test/img/glyphicons-halflings.png b/log/img/glyphicons-halflings.png similarity index 100% rename from test/img/glyphicons-halflings.png rename to log/img/glyphicons-halflings.png diff --git a/test/log.php b/log/index.php similarity index 100% rename from test/log.php rename to log/index.php diff --git a/test/js/scripts.js b/log/js/scripts.js similarity index 100% rename from test/js/scripts.js rename to log/js/scripts.js diff --git a/log/log.txt b/log/log.txt new file mode 100755 index 0000000..9ef250e --- /dev/null +++ b/log/log.txt @@ -0,0 +1 @@ +{"incidence":{"4dcc19bd2aed51e827c184f9d95f81401eb40e03":{"first_logged":"2012-04-05 17:47:09","message":"test","type":"error","format":"text","count":1},"2a2a2607854f40d4c9456c80139c5899439748b0":{"first_logged":"2012-04-05 17:50:00","message":"Test log.","type":"log","format":"text","count":1},"c0fb6b01f755a43daf4e2d5e19c013528b81bca3":{"first_logged":"2012-04-05 17:51:38","message":"{\"msg\":\"Test log 2.\",\"user_agent\":\"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit\/535.19 (KHTML, like Gecko) Chrome\/18.0.1025.142 Safari\/535.19\",\"window_size\":\"2560 x 920\",\"screen_size\":\"2560 x 1414\",\"location\":\"http:\/\/clientsidelogging.webdev.bigfish.co.uk\/test\/test.php\"}","type":"log","format":"json","count":1}},"log":[{"time":"2012-04-05 17:47:09","message":"test","type":"error","format":"text","hash":"4dcc19bd2aed51e827c184f9d95f81401eb40e03"},{"time":"2012-04-05 17:50:00","message":"Test log.","type":"log","format":"text","hash":"2a2a2607854f40d4c9456c80139c5899439748b0"},{"time":"2012-04-05 17:51:38","message":"{\"msg\":\"Test log 2.\",\"user_agent\":\"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit\/535.19 (KHTML, like Gecko) Chrome\/18.0.1025.142 Safari\/535.19\",\"window_size\":\"2560 x 920\",\"screen_size\":\"2560 x 1414\",\"location\":\"http:\/\/clientsidelogging.webdev.bigfish.co.uk\/test\/test.php\"}","type":"log","format":"json","hash":"c0fb6b01f755a43daf4e2d5e19c013528b81bca3"}]} \ No newline at end of file diff --git a/test/test.php b/log/test.php similarity index 100% rename from test/test.php rename to log/test.php diff --git a/test/view_logs.php b/log/view_logs.php similarity index 100% rename from test/view_logs.php rename to log/view_logs.php From 352e84c778f0cdc6513a7738e84c3e453a2ddba9 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 10:25:28 +0100 Subject: [PATCH 08/38] Remove access.txt and log.txt accidentally added in last commit. --- log/access.txt | 1 - log/log.txt | 1 - 2 files changed, 2 deletions(-) delete mode 100755 log/access.txt delete mode 100755 log/log.txt diff --git a/log/access.txt b/log/access.txt deleted file mode 100755 index dbd7d81..0000000 --- a/log/access.txt +++ /dev/null @@ -1 +0,0 @@ -2012-04-05 17:51:38 127.0.0.1 \ No newline at end of file diff --git a/log/log.txt b/log/log.txt deleted file mode 100755 index 9ef250e..0000000 --- a/log/log.txt +++ /dev/null @@ -1 +0,0 @@ -{"incidence":{"4dcc19bd2aed51e827c184f9d95f81401eb40e03":{"first_logged":"2012-04-05 17:47:09","message":"test","type":"error","format":"text","count":1},"2a2a2607854f40d4c9456c80139c5899439748b0":{"first_logged":"2012-04-05 17:50:00","message":"Test log.","type":"log","format":"text","count":1},"c0fb6b01f755a43daf4e2d5e19c013528b81bca3":{"first_logged":"2012-04-05 17:51:38","message":"{\"msg\":\"Test log 2.\",\"user_agent\":\"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit\/535.19 (KHTML, like Gecko) Chrome\/18.0.1025.142 Safari\/535.19\",\"window_size\":\"2560 x 920\",\"screen_size\":\"2560 x 1414\",\"location\":\"http:\/\/clientsidelogging.webdev.bigfish.co.uk\/test\/test.php\"}","type":"log","format":"json","count":1}},"log":[{"time":"2012-04-05 17:47:09","message":"test","type":"error","format":"text","hash":"4dcc19bd2aed51e827c184f9d95f81401eb40e03"},{"time":"2012-04-05 17:50:00","message":"Test log.","type":"log","format":"text","hash":"2a2a2607854f40d4c9456c80139c5899439748b0"},{"time":"2012-04-05 17:51:38","message":"{\"msg\":\"Test log 2.\",\"user_agent\":\"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit\/535.19 (KHTML, like Gecko) Chrome\/18.0.1025.142 Safari\/535.19\",\"window_size\":\"2560 x 920\",\"screen_size\":\"2560 x 1414\",\"location\":\"http:\/\/clientsidelogging.webdev.bigfish.co.uk\/test\/test.php\"}","type":"log","format":"json","hash":"c0fb6b01f755a43daf4e2d5e19c013528b81bca3"}]} \ No newline at end of file From 13e7c2dc130c69a840a7615b9445eff045646cba Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 11:04:08 +0100 Subject: [PATCH 09/38] Neaten up the code a bit (according to sublime's js linter) --- jQuery.clientSideLogging.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index d65be55..a669e8c 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -50,11 +50,9 @@ fNOP = function() {}, fBound = function() { return fToBind.apply( - this instanceof fNOP - ? this - : oThis - || window, - aArgs.concat(Array.prototype.slice.call(arguments))); + this instanceof fNOP ? this : oThis || window, + aArgs.concat(Array.prototype.slice.call(arguments)) + ); }; fNOP.prototype = this.prototype; @@ -69,7 +67,7 @@ if (!Array.prototype.forEach) { Array.prototype.forEach = function(callback, thisArg) { var T, k; - if (this == null) { + if (this === null) { throw new TypeError("this is null or not defined"); } @@ -99,9 +97,9 @@ // Make console.* behave like proper Functions in IE. if (Function.prototype.bind && console && typeof console.log == "object") { ["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function (method) { - console[method] = this.bind(console[method], console); + console[method] = this.bind(console[method], console); }, Function.prototype.call); - }; + } /** * The function that will send error logs to the server. Also logs to the console using console.error() (if available and requested by the user) From 183dd9cae3162224a1470a0b992db026a63a886b Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 11:18:18 +0100 Subject: [PATCH 10/38] Remove the `use_console` option. Rather use the hijack_console option. This will send a log to the server as well as display your normal console.error/info/log. If you wish to keep the functionality for $.error and console.error (for example) separate, set hijack_console to false. --- jQuery.clientSideLogging.js | 1 - 1 file changed, 1 deletion(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index a669e8c..75527dd 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -15,7 +15,6 @@ log_url: '/log?type=log', log_level: 1, native_error:false, - use_console:false, hijack_console:true, query_var: 'msg', client_info: { From 4387db66f94ecf22a142fa6be0b68948ec5fe2db Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 11:24:36 +0100 Subject: [PATCH 11/38] Update README to reflect new hijack_console functionality. --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2bc7c00..6bfe13d 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ There are some default arguments that you can override. At the very least, you s log_url: '/log?type=log', // The url to which standard logs are sent log_level: 1, // The level at which to log. This allows you to keep the calls to the logging in your code and just change this variable to log varying degrees. 1 = only error, 2 = error & log, 3 = error, log & info native_error:true, // Whether or not to send native js errors as well (using window.onerror). - use_console:false, // Whether to show a console.error/info/log as well (when a console is present) + hijack_console:true, // Hijacks the default console functionality (ie: all your console.error/info/log are belong to us). query_var: 'msg', // The variable to send the log message through as. client_info: { // Configuration for what info about the client's browser is logged. location:true, // The url to the page on which the error occurred. @@ -44,7 +44,10 @@ The log will be sent to the backend as a normal `POST` request, which might look $.post('/log?type=error&msg=YOUR_ERROR_MESSAGE'); -`native_error` is set to `true` by default. This means that all browser errors will also be captured and passed to the backend. +#### Notes + +* `native_error` is set to `true` by default. This means that all browser errors will also be captured and passed to the backend. +* `hijack_console` is set to `true` by default and will log to the server as well as display your normal console.error/info/log. If you wish to keep the functionality for $.error and console.error (for example) separate, set hijack_console to false. ### Backend From 488e5c5199b1cfdc24e9bae1d114d84e6e06cd7b Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 11:53:10 +0100 Subject: [PATCH 12/38] Fallback for JSON being null in IE7 --- jQuery.clientSideLogging.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 7494f99..79d5770 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -223,6 +223,10 @@ * @param obj The JSON object to turn into a string. * @return A string representation of the JSON object. */ + var JSON; + if (!JSON) { + JSON = {}; + } JSON.stringify = JSON.stringify || function (obj) { var t = typeof (obj); if (t != "object" || obj === null) { From 1cdc7ff6e2740f84bf2c5c7da8ae27b2dea84175 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 11:55:36 +0100 Subject: [PATCH 13/38] Reorganize the structure of the functions in the file to make a bit more sense. --- jQuery.clientSideLogging.js | 135 ++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 68 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 79d5770..6ba9dce 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -33,73 +33,6 @@ defaults = $.extend(defaults, options || {}); }; - // First, we need some compatibility functions for IE. - - // Function.prototype.bind - // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind#Compatibility - if (!Function.prototype.bind) { - Function.prototype.bind = function(oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function() {}, - fBound = function() { - return fToBind.apply( - this instanceof fNOP ? this : oThis || window, - aArgs.concat(Array.prototype.slice.call(arguments)) - ); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; - } - - // Array.prototype.forEach - // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach#Compatibility - if (!Array.prototype.forEach) { - Array.prototype.forEach = function(callback, thisArg) { - var T, k; - if (this === null) { - throw new TypeError("this is null or not defined"); - } - - var O = Object(this); - var len = O.length >>> 0; - - if ({}.toString.call(callback) != "[object Function]") { - throw new TypeError(callback + " is not a function"); - } - - if (thisArg) { - T = thisArg; - } - - k = 0; - while (k < len) { - var kValue; - if (k in O) { - kValue = O[ k ]; - callback.call( T, kValue, k, O ); - } - k++; - } - }; - } - - // Make console.* behave like proper Functions in IE. - if (Function.prototype.bind && console && typeof console.log == "object") { - ["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function (method) { - console[method] = this.bind(console[method], console); - }, Function.prototype.call); - } - /** * The function that will send error logs to the server. Also logs to the console using console.error() (if available and requested by the user) * @param what What you want to be logged (String, or JSON object) @@ -168,7 +101,7 @@ } }; - /*===== Private Functions =====*/ + /*===== Private Functions =====*/ /** * Send the log information to the server. * @param url The url to submit the information to. @@ -218,6 +151,7 @@ return _info; }; + /*===== Compatibility Functions =====*/ /** * Fallback for older browsers that don't implement JSON.stringify * @param obj The JSON object to turn into a string. @@ -245,4 +179,69 @@ return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}"); } }; + + // Function.prototype.bind + // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind#Compatibility + if (!Function.prototype.bind) { + Function.prototype.bind = function(oThis) { + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function() {}, + fBound = function() { + return fToBind.apply( + this instanceof fNOP ? this : oThis || window, + aArgs.concat(Array.prototype.slice.call(arguments)) + ); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; + } + + // Array.prototype.forEach + // See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach#Compatibility + if (!Array.prototype.forEach) { + Array.prototype.forEach = function(callback, thisArg) { + var T, k; + if (this === null) { + throw new TypeError("this is null or not defined"); + } + + var O = Object(this); + var len = O.length >>> 0; + + if ({}.toString.call(callback) != "[object Function]") { + throw new TypeError(callback + " is not a function"); + } + + if (thisArg) { + T = thisArg; + } + + k = 0; + while (k < len) { + var kValue; + if (k in O) { + kValue = O[ k ]; + callback.call( T, kValue, k, O ); + } + k++; + } + }; + } + + // Make console.* behave like proper Functions in IE. + if (Function.prototype.bind && console && typeof console.log == "object") { + ["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function (method) { + console[method] = this.bind(console[method], console); + }, Function.prototype.call); + } })(jQuery); \ No newline at end of file From 3863e177a4645023032d668fd8a8087fe67f4d48 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 12:31:21 +0100 Subject: [PATCH 14/38] Show error type for each line when none is selected. --- log/css/style.css | 5 ++++- log/view_logs.php | 14 +++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/log/css/style.css b/log/css/style.css index a351c41..329f517 100644 --- a/log/css/style.css +++ b/log/css/style.css @@ -4,4 +4,7 @@ ul { list-style:none; margin-left:5px; } li { margin:5px 0; } .checkbox label { display:inline-block; } -.log_info { height:150px; overflow:auto; } \ No newline at end of file +.log_info { height:150px; overflow:auto; } + +.type { width:30px; } +.type.error { background:#D59392 !important; } \ No newline at end of file diff --git a/log/view_logs.php b/log/view_logs.php index b526afd..7ee3551 100644 --- a/log/view_logs.php +++ b/log/view_logs.php @@ -110,13 +110,19 @@ function($a, $b) { - + + + + incidence as $log ) : ?> + + + + + + + log as $log ) : ?> + + + + + + + + + +
# of Incidentstype# of Incidents Details
type ?> count ?> decoded_message ?> @@ -129,12 +135,18 @@ function($a, $b) {

All entries

+ + + log as $log ) : ?> + + + From f132bcf7658e961907883a3373bfb54bda11ca43 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 14:22:45 +0100 Subject: [PATCH 15/38] Nicer log type hint colouring when viewing all logs. --- log/css/style.css | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/log/css/style.css b/log/css/style.css index 329f517..2e6fe1c 100644 --- a/log/css/style.css +++ b/log/css/style.css @@ -6,5 +6,29 @@ li { margin:5px 0; } .log_info { height:150px; overflow:auto; } -.type { width:30px; } -.type.error { background:#D59392 !important; } \ No newline at end of file +.table td.type { + overflow:hidden; + position:relative; + text-align:center; + width:30px; +} +.type:before { + content:''; + display:block; + height:100%; + left:0; + position:absolute; + top:0; + width:5px; +} +.type.error:before { + background:#B94A48; +} +.type.log:before { + background:#3A87AD; +} +.type.info:before { + background:#C09853; +} + +.table th.span1 { text-align:center; } \ No newline at end of file From cd6fd4a396b0896fbf7718fcb579b75325299d1d Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 14:48:52 +0100 Subject: [PATCH 16/38] Increase visibility of errors. --- log/css/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/log/css/style.css b/log/css/style.css index 2e6fe1c..dae508b 100644 --- a/log/css/style.css +++ b/log/css/style.css @@ -25,10 +25,10 @@ li { margin:5px 0; } background:#B94A48; } .type.log:before { - background:#3A87AD; + background:#b9d5e2; } .type.info:before { - background:#C09853; + background:#BED5BE; } .table th.span1 { text-align:center; } \ No newline at end of file From 1a3ca1a31c893a0517b70d82487a609bd2703e57 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Thu, 12 Apr 2012 14:51:45 +0100 Subject: [PATCH 17/38] Fix typo. --- jQuery.clientSideLogging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 6ba9dce..d7210b5 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -61,7 +61,7 @@ _send(defaults.info_url, what); } - if (defaults.hijack_console && origin_info.apply) { + if (defaults.hijack_console && original_info.apply) { original_info.apply(this, arguments); } }; From 3e5a5b55e5210fdd35d7327f1b7270682837c824 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Fri, 27 Apr 2012 16:38:16 +0100 Subject: [PATCH 18/38] Reset default console.error|info|log functionality when hijack_console is false. --- jQuery.clientSideLogging.js | 41 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index d7210b5..88c1fab 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -10,20 +10,23 @@ */ (function($) { var defaults = { - error_url: '/log?type=error', - info_url: '/log?type=info', - log_url: '/log?type=log', - log_level: 1, - native_error:true, - hijack_console:true, - query_var: 'msg', - client_info: { - location:true, - screen_size:true, - user_agent:true, - window_size:true - } - }; + error_url: '/log?type=error', + info_url: '/log?type=info', + log_url: '/log?type=log', + log_level: 1, + native_error:true, + hijack_console:true, + query_var: 'msg', + client_info: { + location:true, + screen_size:true, + user_agent:true, + window_size:true + } + }, + original_error = console.error, + original_info = console.info, + original_log = console.log; /** * Initializing with custom options. Not strictly necessary, but recommended. @@ -31,6 +34,13 @@ */ $.clientSideLogging = function(options) { defaults = $.extend(defaults, options || {}); + + // We need to unset these again if they were set the first time. + if (!defaults.hijack_console) { + console.error = original_error; + console.info = original_info; + console.log = original_log; + } }; /** @@ -48,7 +58,6 @@ }; if (defaults.hijack_console) { - var original_error = console.error; console.error = $.error; } @@ -67,7 +76,6 @@ }; if (defaults.hijack_console) { - var original_info = console.info; console.info = $.info; } @@ -86,7 +94,6 @@ }; if (defaults.hijack_console) { - var original_log = console.log; console.log = $.log; } From f2e7ab427ac94383427826c5da31325a9692a053 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 10:09:23 +0100 Subject: [PATCH 19/38] Further improve the menu and colour coding for the different types of log. --- log/css/style.css | 20 +++++++++++++++++++- log/view_logs.php | 34 +++++++++++++++++----------------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/log/css/style.css b/log/css/style.css index dae508b..6b40ec6 100644 --- a/log/css/style.css +++ b/log/css/style.css @@ -1,5 +1,23 @@ body { padding:10px; } +.navbar .brand { padding-top:14px; } +.nav li.error:hover, .nav li.log:hover, .nav li.info:hover, +.nav li.error.active, .nav li.log.active, .nav li.info.active { + margin-bottom:0; +} +.nav li.error:hover, +.nav li.error.active { + border-bottom:5px solid #B94A48; +} +.nav li.log:hover, +.nav li.log.active { + border-bottom:5px solid #B9D5E2; +} +.nav li.info:hover, +.nav li.info.active { + border-bottom:5px solid #BED5BE; +} + ul { list-style:none; margin-left:5px; } li { margin:5px 0; } .checkbox label { display:inline-block; } @@ -25,7 +43,7 @@ li { margin:5px 0; } background:#B94A48; } .type.log:before { - background:#b9d5e2; + background:#B9D5E2; } .type.info:before { background:#BED5BE; diff --git a/log/view_logs.php b/log/view_logs.php index 7ee3551..096a899 100644 --- a/log/view_logs.php +++ b/log/view_logs.php @@ -89,23 +89,23 @@ function($a, $b) {
-
-

Client Side Logs

+
- -
+

Overview

type Time Message
type ?> time ?> decoded_message ?>
@@ -113,8 +113,8 @@ function($a, $b) { - - + + From 6d0bc70eddae95f49340ab1b1884e8f4ee981dcb Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 10:15:43 +0100 Subject: [PATCH 20/38] Add comments inside the clientSideLogging js file To make life a bit easier while working on the code itself. --- jQuery.clientSideLogging.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 88c1fab..3006106 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -10,18 +10,18 @@ */ (function($) { var defaults = { - error_url: '/log?type=error', - info_url: '/log?type=info', - log_url: '/log?type=log', - log_level: 1, - native_error:true, - hijack_console:true, - query_var: 'msg', - client_info: { - location:true, - screen_size:true, - user_agent:true, - window_size:true + error_url: '/log?type=error', // The url to which errors logs are sent + info_url: '/log?type=info', // The url to which info logs are sent + log_url: '/log?type=log', // The url to which standard logs are sent + log_level: 1, // The level at which to log. This allows you to keep the calls to the logging in your code and just change this variable to log varying degrees. 1 = only error, 2 = error & log, 3 = error, log & info + native_error:true, // Whether or not to send native js errors as well (using window.onerror). + hijack_console:true, // Hijacks the default console functionality (ie: all your console.error/info/log are belong to us). + query_var: 'msg', // The variable to send the log message through as. + client_info: { // Configuration for what info about the client's browser is logged. + location:true, // The url to the page on which the error occurred. + screen_size:true, // The size of the user's screen (different to the window size because the window might not be maximized) + user_agent:true, // The user agent string. + window_size:true // The window size. } }, original_error = console.error, From 07b9a971223ee495163f1aa5179c97f7f566af1e Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 10:16:19 +0100 Subject: [PATCH 21/38] Version bump! --- jQuery.clientSideLogging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 3006106..c6dd502 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -1,7 +1,7 @@ /* * Title: jQuery Client Side Logging Plugin * Author: Rémy Bach - * Version: 1.0.0 + * Version: 1.1.0 * License: http://remybach.mit-license.org * Url: http://github.com/remybach/jQuery.clientSideLogging * Description: From 36024de0603e7a43fb212b6b9a14e282128deef0 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 10:55:43 +0100 Subject: [PATCH 22/38] If clientSideLogging is called again with different params, reset the console.* if necessary. --- jQuery.clientSideLogging.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index c6dd502..047d12d 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -40,6 +40,10 @@ console.error = original_error; console.info = original_info; console.log = original_log; + } else { + console.error = $.error; + console.info = $.info; + console.log = $.log; } }; From 170ddcfc67d55c9a4730882148c0a8a52d600e11 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 11:26:58 +0100 Subject: [PATCH 23/38] Add a trailing slash to the default log url. --- jQuery.clientSideLogging.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index 047d12d..c741155 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -10,9 +10,9 @@ */ (function($) { var defaults = { - error_url: '/log?type=error', // The url to which errors logs are sent - info_url: '/log?type=info', // The url to which info logs are sent - log_url: '/log?type=log', // The url to which standard logs are sent + error_url: '/log/?type=error', // The url to which errors logs are sent + info_url: '/log/?type=info', // The url to which info logs are sent + log_url: '/log/?type=log', // The url to which standard logs are sent log_level: 1, // The level at which to log. This allows you to keep the calls to the logging in your code and just change this variable to log varying degrees. 1 = only error, 2 = error & log, 3 = error, log & info native_error:true, // Whether or not to send native js errors as well (using window.onerror). hijack_console:true, // Hijacks the default console functionality (ie: all your console.error/info/log are belong to us). From e11827db9faab8cd226b3c3c28b1713c1d4e7c07 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 12:35:46 +0100 Subject: [PATCH 24/38] Add a way of filtering the logs (by regular expressions) --- README.md | 2 +- log/js/view_logs.js | 13 +++++++++++++ log/view_logs.php | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 log/js/view_logs.js diff --git a/README.md b/README.md index 6bfe13d..c86865b 100644 --- a/README.md +++ b/README.md @@ -63,4 +63,4 @@ Also included with the distribution is a PHP frontend for parsing and displaying ## Credit -jQuery.clientSideLogging was developed by [Remy Bach](https://github.com/remybach) (JavaScript) and [Rob Miller](https://github.com/robmiller) (PHP).p \ No newline at end of file +jQuery.clientSideLogging was developed by [Remy Bach](https://github.com/remybach) (JavaScript) and [Rob Miller](https://github.com/robmiller) (PHP). diff --git a/log/js/view_logs.js b/log/js/view_logs.js new file mode 100644 index 0000000..a27fc45 --- /dev/null +++ b/log/js/view_logs.js @@ -0,0 +1,13 @@ +jQuery(function($) { + $('.navbar input:text').keyup(function(e) { + var filter = new RegExp(this.value, 'gim'); + + $('tr').each(function(i, val) { + if ($(this).html().match(filter)) { + $(this).show(); + } else { + $(this).hide(); + } + }); + }); +}); \ No newline at end of file diff --git a/log/view_logs.php b/log/view_logs.php index 096a899..86374b3 100644 --- a/log/view_logs.php +++ b/log/view_logs.php @@ -85,6 +85,9 @@ function($a, $b) { + + + @@ -101,6 +104,9 @@ function($a, $b) {
  • + + + From c0164f2165775bafe6161ad070cf1d12a6e2276e Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Mon, 30 Apr 2012 13:30:33 +0100 Subject: [PATCH 25/38] Be a little friendlier when there aren't any logs to see yet. --- log/view_logs.php | 216 ++++++++++++++++++++++++---------------------- 1 file changed, 111 insertions(+), 105 deletions(-) diff --git a/log/view_logs.php b/log/view_logs.php index 86374b3..93aaf6b 100644 --- a/log/view_logs.php +++ b/log/view_logs.php @@ -6,63 +6,63 @@ $logs = json_decode($log_json); if ( !$logs ) { $logs = array(); -} - -// We don't care about hashes on the frontend, and this lets us sort. -$logs->incidence = get_object_vars($logs->incidence); - -function format_log($log) { - $log->decoded_message = $log->message; - if ( $log->format == 'json' ) { - $log->decoded_message = print_r(json_decode($log->message), 1); - $log->decoded_message = preg_replace('/stdClass Object\s*/', '', $log->decoded_message); - $log->decoded_message = htmlentities($log->decoded_message); - $log->decoded_message = '
    ' . $log->decoded_message . '
    '; +} else { + // We don't care about hashes on the frontend, and this lets us sort. + $logs->incidence = get_object_vars($logs->incidence); + + function format_log($log) { + $log->decoded_message = $log->message; + if ( $log->format == 'json' ) { + $log->decoded_message = print_r(json_decode($log->message), 1); + $log->decoded_message = preg_replace('/stdClass Object\s*/', '', $log->decoded_message); + $log->decoded_message = htmlentities($log->decoded_message); + $log->decoded_message = '
    ' . $log->decoded_message . '
    '; + } } -} -foreach ( (array) $logs->incidence as $log ) { - $log = format_log($log); -} - -foreach ( (array) $logs->log as $log ) { - $log = format_log($log); -} + foreach ( (array) $logs->incidence as $log ) { + $log = format_log($log); + } -// Show log entries in reverse chronological order. -$logs->log = array_reverse($logs->log); - -// Sort incidence entries by count. -usort( - $logs->incidence, - function($a, $b) { - if ( $a->count == $b->count ) { - // If the counts are the same, sort by most recent. - if ( $a->first_logged == $b->first_logged ) { - return 0; - } - return ( $a->first_logged < $b->first_logged ) ? 1 : -1; - } - // We're sorting descending. - return ( $a->count < $b->count ) ? 1 : -1; + foreach ( (array) $logs->log as $log ) { + $log = format_log($log); } -); -// If we've been given a type, filter by type; otherwise display everything. -if ( !empty($_REQUEST['type']) ) { - $filter_type = function($log) { - return ( $log->type == $_REQUEST['type'] ); - }; + // Show log entries in reverse chronological order. + $logs->log = array_reverse($logs->log); - $logs->incidence = array_filter( + // Sort incidence entries by count. + usort( $logs->incidence, - $filter_type + function($a, $b) { + if ( $a->count == $b->count ) { + // If the counts are the same, sort by most recent. + if ( $a->first_logged == $b->first_logged ) { + return 0; + } + return ( $a->first_logged < $b->first_logged ) ? 1 : -1; + } + // We're sorting descending. + return ( $a->count < $b->count ) ? 1 : -1; + } ); - $logs->log = array_filter( - $logs->log, - $filter_type - ); + // If we've been given a type, filter by type; otherwise display everything. + if ( !empty($_REQUEST['type']) ) { + $filter_type = function($log) { + return ( $log->type == $_REQUEST['type'] ); + }; + + $logs->incidence = array_filter( + $logs->incidence, + $filter_type + ); + + $logs->log = array_filter( + $logs->log, + $filter_type + ); + } } ?> @@ -111,68 +111,74 @@ function($a, $b) {
    -
    -

    Overview

    -
    type # of IncidentsDetails#Details
    - - + +
    +

    Overview

    +
    + + + + + + + + + + + incidence as $log ) : ?> + + + + + + + + + +
    type#Details
    type ?>count ?> + decoded_message ?> +
    + +

    All entries

    + + - - - - - - incidence as $log ) : ?> - - - - - - - - - -
    type #Details
    type ?>count ?> - decoded_message ?> -
    - -

    All entries

    - - - - - - - - - - log as $log ) : ?> - - - - - - - - - -
    typeTimeMessage
    type ?>time ?>decoded_message ?>
    - - - +
    TimeMessage
    type ?>time ?>decoded_message ?>
    + + + + + */ ?> - */ ?> + +
    +

    No logs available as of yet.

    + From ad236d5f028cb322aabba5278749c772ab9c3c01 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Tue, 1 May 2012 10:39:39 +0100 Subject: [PATCH 26/38] Fix 'illegal invocation error'. --- jQuery.clientSideLogging.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jQuery.clientSideLogging.js b/jQuery.clientSideLogging.js index c741155..1beae2b 100644 --- a/jQuery.clientSideLogging.js +++ b/jQuery.clientSideLogging.js @@ -57,7 +57,7 @@ } if (defaults.hijack_console && original_error.apply) { - original_error.apply(this, arguments); + original_error.apply(console, arguments); } }; @@ -75,7 +75,7 @@ } if (defaults.hijack_console && original_info.apply) { - original_info.apply(this, arguments); + original_info.apply(console, arguments); } }; @@ -93,7 +93,7 @@ } if (defaults.hijack_console && original_log.apply) { - original_log.apply(this, arguments); + original_log.apply(console, arguments); } }; From 8f93a16ee984554a5b9c9a7e44a952a526ae22e2 Mon Sep 17 00:00:00 2001 From: Remy Bach Date: Tue, 1 May 2012 10:41:58 +0100 Subject: [PATCH 27/38] Clean up view_logs.php file. --- log/view_logs.php | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/log/view_logs.php b/log/view_logs.php index 93aaf6b..b12623e 100644 --- a/log/view_logs.php +++ b/log/view_logs.php @@ -85,9 +85,6 @@ function($a, $b) { - - - @@ -183,22 +180,8 @@ function($a, $b) { - - - - - - - - - - - + + - + -
    -
    -

    Client Side Logging Test

    -
    -
    - +
    +
    +
    +

    Client Side Logging Test

    +
    +
    + +
    +
    - - + - - - - - - - +