In the complex network environment and the browser environment, self-test, QA Testing and code Review are not enough, if the page stability and accuracy requirements, there must be a perfect code anomaly monitoring system, this article from the front-end code anomaly monitoring methods and problems to start, Try to fully describe the blocking and handling scenarios that may be encountered in each phase of the error log collection.
? Methods for collecting logs
Usually the means of collecting logs can be categorized into two aspects, one is the logic of the wrong judgment, for the active judgment; one is to use the language to provide us with a shortcut, violent access to error information, such as try..catch
and window.onerror
.
1. Active judgment
We get a desired result after some operations, but the result is not what we want.
// Test.js function Calc () { // code ... return Val;} if (Calc ()!== "Someval") { reporter.send ({ "Test.js::<function>calc" " Calc Error " });
This feedback, which is a logical error/State error, is much more in the interface status
judgment.
2. try..catch
Capture
To determine the error that exists in a code snippet:
Try { init (); // code ... Catch (e) { reporter.send (format (e));}
To the entrance of the init
program, all synchronous execution errors in the code will be captured, which is also a good way to avoid the program just run up and hang.
3.window.onerror
To catch a global error:
function () { var errinfo = format (arguments); Reporter.send (errinfo); return true ;};
Returned in the above function return true
, the error is not exposed to the console. The following is its parameter information:
/* * * @param {string} errormessage error message * @param {string} Scripturi error file * @param {Long} LineNumber The line number of the error code * @param {Long} columnnumber The column number of the error code * @param {Object} errorobj * /function(errormessage, Scripturi, linenumber,columnnumber,errorobj) { // code:}
window.onerror
is a particularly violent fault-tolerant approach, and try..catch
so, their bottom-up implementation is to use the statement in C/S, goto
once the error is found, no matter how deep the current stack, regardless of where the code is run, run directly to the top layer or try..catch
capture layer, This kind of kick-off error is not a good way to handle it.
? Problems with collecting logs
The purpose of collecting logs is to identify problems in a timely manner, and the best logs can tell us where the error is, and better yet, not only to tell the error, but also to tell us how to handle the error. The ultimate goal is to find errors, automatic fault tolerance, which is the hardest step.
1. No specific error message, Script error.
Let's look at the following example, test.html
<!--http://barret/test.html -<Script>Window.onerror= function() {console.log (arguments); };</Script><Scriptsrc= "Http://barret/test.js"></Script>
Test.js
// Http://barret/test.js function Test () { = 1; return a+1;} Test ();
The logs we expect to collect are specific information such as the following:
In order to better configure and manage resources, we often put static resources in the exotic
<!--http://barret/test.html -<Script>Window.onerror= function() {console.log (arguments); };</Script><Scriptsrc= "Http://localhost/test.js"></Script>
And the result is:
Opened Chromium WebCore source code, you can see:
In the case of cross-domain, the returned result is Script error.
.
// Http://trac.webkit.org/browser/branches/chromium/1453/Source/WebCore/dom/ScriptExecutionContext.cpp #L333 String message = errormessage; int line == sourceURL; // all the error messages have been received, but if found to be non-homologous, the ' sanitizescripterror ' replication error message sanitizescripterror (message, line, SourceName, Cachedscript);
The old version of the WebCore only Judge securityOrigin()->canRequest(targetURL)
, the new version of a more than a cachedScript
judgment, you can see the browser restrictions on this more and more stringent.
Under test locally:
Visible file://
under the agreement, securityOrigin()->canRequest(targetURL)
too false
.
? Why Script error.
?
Simple error: Script error
The goal is to avoid data leaks into insecure domains, a simple example:
<src= "bank.com/login.html"></script>
Above we did not introduce a JS file, but an HTML, this HTML is the bank's login page, if you have logged in bank.com
, then the login page will automatically jump to, Welcome xxx...
if not logged in then jump to Please Login...
, then JS error will be Welcome xxx... is not defined
, Please Login... is not defined
, this information can be used to determine whether a user login to his bank account number, to hacker provides a very convenient way to judge the channel, which is quite unsafe.
? crossOrigin
parameter skipping cross-domain restriction
Both the image and the script tag have the Crossorigin parameter, which is the function of telling the browser that I want to load an alien resource, and I trust this resource.
<src= "Http://localhost/test.js" crossorigin></ Script>
However, the error was:
This is expected error, the cross-domain resource sharing policy requires that the server also set Access-Control-Allow-Origin
the response header:
Header (' access-control-allow-origin: * ');
Looking back at the resources of our CDN,
These static resources, such as javascript/css/image/font/swf, have been added to the CORS response header early.
2. The compression code cannot be located to the exact location of the error
The code on the line is almost packaged and compressed, and dozens of files are compressed and packaged into one, with only a single line. When we receive a is not defined
, if only in a specific scenario to error, we simply can not locate the compressed a
is a thing, then the error log is invalid.
The first way to think of it is to use Sourcemap, which can be used to locate a point in the compression code at a specific location in the uncompressed code. The following is the format introduced by Sourcemap, which is added in the last line of code:
// # Sourcemappingurl=index.js.map
The previous use of '//@ ' as the beginning, now using '//# ', but for error reporting, this thing is useless. JS can not get his true number of rows, only through the Chrome DevTools tools such as assistant location, and not every online resource will add Sourcemap file. The use of Sourcemap is now only reflected in the development phase.
Of course, if you understand the Sourcemap VLQ encoding and location correspondence, you can also get the log to two times to parse, map to the real path location, this cost is higher, seemingly temporarily also no one tried.
So, is there any way to pinpoint the exact location of the error, or is there any way to narrow down the difficulty of locating the problem?
Consider this: When you pack, add 1000 blank lines between each of the two merged files, and the last file that goes online becomes
(function(){varLongcode ...}) ();//file 1//1000 Blank Lines(function(){varLongcode ...}) ();//File 2//1000 Blank Lines(function(){varLongcode ...}) ();//File 3//1000 Blank Lines(function(){varLongcode ...}) ();//File 4var_fileconfig = [' File 1 ', ' File 2 ', ' File 3 ', ' File 4 ']
If the error is on line No. 3001,
function (msg, URL, line, col, error) { // line = 3001 var linenum = line ; Console.log ("error location:" + _fileconfig[linenum% 1000-1]); // "Error Location: File 3"};
It can be calculated that errors appear in the third file, and the scope shrinks a lot.
3. Registration of error events
Registering the error event multiple times does not repeatedly execute multiple callbacks:
var function () { console.log (arguments);}; Window.addeventlistener ("error", FN); Window.addeventlistener ("error", FN);
After the error is triggered, the result of the above code is:
window.onerror
And addEventListener
both were executed, and were executed only once.
4. Amount of logs collected
It is not necessary to send all the error messages to Log, which is too large. If the webpage PV has 1kw, then a must-be error sent log information will have 1kw, about a G of the logs. We can Reporter
add a sample rate to the function:
function Needreport (sampling) { // sampling:0-1 return math.random () <= function(errinfo, sampling) { if(needreport (Sampling | | 1)) { reporten._send (errinfo); }};
This sampling rate can be processed as required, either with a random number, using the last letter/number of a field in the cookie (such as nickname), or by hashing the user's nickname, and then judging by the last letter/number In short, the method is many.
? Collect Log Layout points location
In order to get the error message more accurately and to effectively count the error log, we should use more active burying points, such as in an interface request:
//Module A Get shops Data$.ajax ({url:url, DataType:"Jsonp", Success:function(ret) {if(Ret.status = = = "Failed") { //buried point 1 returnreporter.send ({category:"WARN", msg:"Module_a_get_shops_data_failed" }); } if(!ret.data | |!ret.data.length) {//Buried point 2 returnreporter.send ({category:"WARN", msg:"Module_a_get_shops_data_empty" }); }}, Error:function() { //buried point 3reporter.send ({category:"ERROR", msg:"Module_a_get_shops_data_error" }); }});
We put three points accurately, and the description is very clear, and these three points will provide very favorable information for us to follow up on the online problem.
? About try..catch
the use of
For try..catch
the use of, my advice is: can not, try not to use. JS code is written out of their own, where there will be problems, what will arise, the mind should have a spectrum, usually used try..catch
only two places:
// JSON format is not correct Try { json.parse (jsonstring);} Catch (e) {} // There are non-decode characters Try { Decodecomponenturi (string);} Catch (e) {}
Mistakes like these are not very manageable. You can try..catch
think about whether you can use other ways to do compatibility in the places you use.
? About window.onerror
the use of
You can try the following code:
// Test.js Throw New Error ("SHOW ME"function() { console.log (arguments); // Prevent printing error messages in the console return true ;};
window.onerror
This error monitoring must be put to the forefront!
? Incorrect alerts and hints
When is the alarm? You can't report it without fault. It also says that because of the network environment and the browser environment factor, we allow 1 per thousand error rate for complex pages. Data graph after log processing:
There are two lines, the Orange Line is today's data, the light blue line is the past average data, every 10 minutes to produce a record, the horizontal axis is 0-24 points of the timeline, ordinate is the wrong amount. Can be clearly seen in the early morning around one or two, the service has been abnormal, the error message is the average of more than 10 times times, then this time to change the alarm.
Alarm conditions can be set to a more stringent, because false positives is a very annoying thing, text messages, mail, software and other information bombing, and sometimes still big in the middle of the night. Then, generally meet the following conditions can alarm:
- The error exceeds the threshold, such as 10 minutes to allow up to 100 errors, resulting in over 100
- The error exceeds the average of 10 times times, more than the average alarm, this logic is obviously not correct, but more than the average of 10 times times, basically can determine the service problem
- Before the inclusion of the comparison, to filter the error with the IP, such as an error occurs in a for loop or while loop, such as a user in the camp snapped, constantly refresh
? Friendly Error Hints
Compare the following two logs, catch error logs:
Uncaught REFERENCEERROR:VD is not defined
Custom error logs:
"The Eval parse error occurred while retrieving the backend interface information in the Birthday module, the error content is: VD was not defined."
This error occurred 1000 times in the last 10 minutes, the average error in the past is 50 times/10 minutes
? Network error log work draft
The Web performance Working group published a working draft of the network error log. This document defines a mechanism that allows a Web site to declare a network error reporting policy, which a user agent such as a browser can use to report network errors that affect the proper loading of resources. The document also defines a standard format for error reporting and its transport mechanism between the browser and the Web server.
Detailed draft: HTTP://WWW.W3.ORG/TR/2015/WD-NETWORK-ERROR-LOGGING-20150305/
? Summary
function, testing and monitoring are the kick of program development, many engineers can do the perfect function, but also understand some of the knowledge of testing, but in the direction of monitoring is basically in the brain blank. The collection and collation of error logs is a small part of the monitoring, but it is critical to our understanding of website stability. There is a missing place in the article hoping that the reader can add, the wrong place still look treatise.
? Expand Reading
- Establishing a front-end error log based on the Window.onerror event by Dx. Yang
- Build Web front-end anomaly monitoring system –fdsafe by Stone break
- JavaScript Source Map detailed by Ruan Yi Feng
- HTML5 Standard-window.onerror
- Msdn-window.onerror
- Mdn-window.onerror
- Network error log
Front-end Code Exception Log collection and monitoring