Console.log Log transformation

Writing in the front


What do people use for mobile debugging? I believe that you have chosen the same tool as our group, vconsole. js. It is easy to use and can provide the front-end debugging panel in the mobile web page with log/network information, which is convenient for developers to locate problems. This could have been fun, so why did we change the log, because no one would have thought that the vConsole debug panel on the low end of the machine (performance drag, but the project is going to load ╮(╰ ▽╰ ╭)) because of the front end of the print log caused the application to freeze/crash, the test team was fed up, want a good log view. All right, our pot. We’ll fix it. O (╯ / ╰) o

Analysis of the phenomenon


Vconsole in the test environment is started with the project, all the front-end log has been stored in the debug version, normal log will not affect the program, but in the project, we have signature or face recognition functions, some interfaces will pass base64 or HTML strings such as data, The front end did not do direct printing to the panel, these base64 or some strings of data volume, machine performance is not good, slide two or three directly stuck on the page, and these very long strings for positioning analysis, there is no great effect, is to do the next processing.

solution


  1. Base64 is processed

In the project encountered debugging panel sliding stuck, generally is caused by printing base64 string, make a function to solve him, let Base64 do the next interception

@param {string,object, Array} data processing data * * / export function base64Filter (data) {if (Object. The prototype. ToString. Call (data) = = = '[Object Object]'  || Object.prototype.toString.call(data) === '[object Array]') { let applyObj try { applyObj = Parse (json.stringify (data)) // Make a copy of the object to avoid the impact of real data} catch (error) {return applyObj} for (const key in applyObj) { / / traverse data if (applyObj hasOwnProperty (key)) {if (Object. The prototype. ToString. Call (applyObj [key]) = = = '[Object Object]' | | Object. The prototype. ToString. Call (applyObj [key]) = = = '[Object Array]') {applyObj [key] = base64Filter (applyObj [key]) / / recursive matching } else {// Restrict parameters matching if (typeof applyObj[key] === 'string' && applyObj[key].indexof ('data:image') > -1) {applyObj[key] = 'base64Length' + applyObj[key]. Length // Convert base64 to length}}}} return applyObj} else if (Object. The prototype. ToString. Call (data) = = = '[Object String]') {/ / String type let stringdata = data const re = / {} [\ S \ S] * / Const match = stringdata.match(re) // match object if (match) {// Match parsed object try {// try parsed object filter let strobj = base64Filter(JSON.parse(match[0])) strobj = JSON.stringify(strobj) stringdata = stringdata.replace(re, Strobj) return stringData} catch (error) {return data}} else {// Unable to parse the object stringdata = stringdata.indexOf('data:image') > -1 ? Substr (0, stringdata.indexof ('data:image')) + '+ base64Length '+, stringdata.length: Stringdata return stringdata}} else {// Other types do not handle return data}}Copy the code

The base64 function can be used to limit the length of the base64 format. However, as mentioned earlier, there are also some interfaces that return HTML strings or other super-long characters, which can cause stalling. We can’t just fight bas64, we need to nip this risk in the head.

  1. Put a length limit on an all-attribute object

Determine the log type and try to parse it into objects. If a field length exceeds a certain length, intercept it.

@param {string,object, Array} data processing data * * / export function objectValLimit (data) {if (Object. The prototype. ToString. Call (data) = = = '[Object Object] '| | Object. The prototype. ToString. Call (data) = = =' [Object Array] ') {/ / original Object handle let strobj try {strobj = JSON.parse(JSON.stringify(data)) } catch (e) { return data } strobj = valueFilter(strobj) return strobj } else if (Object. The prototype. ToString. Call (data) = = = '[Object String]') {/ / String handling const re = / {} [\ S \ S] * / let STR = data const Match = str.match(re) // Match object if (match) {try {let strobj = match[0] strobj = valueFilter(json.parse (strobj)) strobj = JSON. Stringify (strobj) STR = str.replace(re, strobj) return STR} catch (error) {// error STR = str.length > 1000? STR. Substr (0, 1000) + '+length' + str.length: STR return STR}} else {// Plain string STR = str.length > 200? str.substr(0, 200) + '+length' + str.length : STR return STR}} else {// Other types do not handle return data}} /* Value length limit */ const valueFilter = function(data) {// Object passed for (const key in data) { if (data.hasOwnProperty(key)) { if (Object.prototype.toString.call(data[key]) === '[object Object] '| | Object. The prototype. ToString. Call (data [key]) = = =' [Object Array] ') {data [key] = valueFilter (data [key]) / / recursive matching } else if (data[key] && data[key].length > 100) {data[key] = data[key]. Substr (0, 100) + '+length' + data[key].length } } } return data }Copy the code
  1. Rewrite the console.log function
Let config = {// isLog: true, // Whether to print log isallLimit: } console.log = (function(logFunc) {return function() {if(! config.isLog)return; Try {const arr = [] arr. Push (... arguments) arr.forEach((item, index) => { arr[index] = config.isallLimit ? objectValLimit(item) : base64Filter(item) }) logFunc.call(console, ... arr) } catch (e) { console.warn(e) } } })(console.log)Copy the code

Things to this, it is time to come to an end, for the front-end output of most of the log can be good response, the implementation effect as shown in the following figure

Object matching:String matching:

After a while, the test team didn’t have any problem with the log, and the debug panel network was advised to make the interface input and output parameters handle the length like log, so (NEi) (Liu) should (man) allow (mian). : –

For network processing, the same operation. Down vconsole source, on the network have to deal with the network. The js file, we are in the window. The XMLHttpRequest. Prototype. Send function for a post request with the same as the log in to the processing function. And then you can package it and modify the send function

// mock send() window.XMLHttpRequest.prototype.send = function() { let XMLReq = this; let args = [].slice.call(arguments), data = args[0]; let item = that.reqList[XMLReq._requestID] || {}; item.method = XMLReq._method.toUpperCase(); let query = XMLReq._url.split('? '); // a.php? b=c&d=? e => ['a.php', 'b=c&d=', '?e'] item.url = query.shift(); // => ['b=c&d=', '?e'] if (query.length > 0) { item.getData = {}; query = query.join('? '); // => 'b=c&d=? e' query = query.split('&'); // => ['b=c', 'd=?e'] for (let q of query) { q = q.split('='); item.getData[ q[0] ] = decodeURIComponent(q[1]); } } if (item.method == 'POST') { // save POST data if (tool.isString(data)) { let arr = data.split('&'); item.postData = {}; Item.postdata [tool. ObjectValLimit (arr[0])] = undefined; // for (let q of arr) { // q = q.split('='); // item.postData[ q[0] ] = q[1]; // } } else if (tool.isPlainObject(data)) { item.postData = data; } } if (! XMLReq._noVConsole) { that.updateRequest(XMLReq._requestID, item); } return _send.apply(XMLReq, args); }; };Copy the code

The actual execution effect is shown in the figure below:

The road to reform has come to an end. There is a long way to go to fix bugs.

Thank you for reading, if there are any questions or suggestions, please exchange more, original articles, writing is limited, if there is anything wrong in the article, please kindly inform and correct.