日志文件中提取json--开发小记
2020/1/15 5:23:21
本文主要是介绍日志文件中提取json--开发小记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
之前交接过来的工作里有个页面本地调试麻烦,因为它的数据是后端实时上报而来,每次一报bug,都是给一个几兆的日志文本(上面记录了实际出问题的上报数据【json格式】),通过肉眼分析日志搭配页面逻辑人工解读,太难了……后面在页面加了mock的逻辑,但遇到一个问题,就是把日志中的数据配置到mock接口那边
=> 于是有了写脚本从日志文件里提取json数据的想法。
如何识别json字符串
- 用正则匹配json,json的数据格式不一致且多层嵌套{}。 => 放弃
替换方案:来自Stack Overflow>>
原理:通过对字符串进行"{}"识别和截取,利用JSON.parse对截取的字符串进行尝试转换,如果成功则返回,失败(抛出异常)则捕获异常并继续缩窄字符串内容范围。
该段原理逻辑识别不了所有json,优先匹配第一个出现的json,我改成了从后往前来识别json,主要是结合需求的日志重点在后面的json
function extractJSON(str) { var firstOpen, firstClose = str.length - 1, candidate; firstClose = str.lastIndexOf('}'); do { // debugger firstOpen = str.indexOf('{'); // console.log('firstOpen: ' + firstOpen, 'firstClose: ' + firstClose); if(firstClose <= firstOpen) { return null; } do { candidate = str.substring(firstOpen, firstClose + 1); // console.log('candidate: ' + candidate); try { var res = JSON.parse(candidate); return [res, firstOpen, firstClose + 1]; } catch(e) { // console.log('...failed'); } firstOpen = str.indexOf('{', firstOpen+1); } while(firstClose > firstOpen && firstOpen !== -1); firstClose = str.lastIndexOf('}', firstClose - 1); } while(firstClose != -1); return null; }
如此,就可以解决如何从一段文本中提取出json内容来。
接下来就是如何合理提取json为好,日志文件内容的特征是每行输出信息,而基本每行能提取一个关键json的数据来,那么可以用上nodejs的流来实现按行读取同时提取json
注:只是看中了用stream来处理文件读取方便,对于较为大一点的文件(我遇到的日志最大不超过1g),可以按参考链接里的event-stream来处理
该部分的内容就不做重复说明,直接贴代码。
const fs = require('fs'); const readline = require('readline'); const stream = require('stream'); const instream = fs.createReadStream('test.log.txt'); const outstream = new stream(); const rl = readline.createInterface(instream, outstream); function extractJSON(str) { var firstOpen, firstClose = str.length - 1, candidate; firstClose = str.lastIndexOf('}'); do { // debugger firstOpen = str.indexOf('{'); // console.log('firstOpen: ' + firstOpen, 'firstClose: ' + firstClose); if(firstClose <= firstOpen) { return null; } do { candidate = str.substring(firstOpen, firstClose + 1); // console.log('candidate: ' + candidate); try { var res = JSON.parse(candidate); // console.log('...found'); return [res, firstOpen, firstClose + 1]; } catch(e) { // console.log('...failed'); } firstOpen = str.indexOf('{', firstOpen+1); } while(firstClose > firstOpen && firstOpen !== -1); firstClose = str.lastIndexOf('}', firstClose - 1); } while(firstClose != -1); return null; } // 记录行数 let lineCount = 0; // 收集json数据 const results = []; rl.on("line", lineStr => { lineCount++; const extractRes = extractJSON(lineStr); if (extractRes) { results.push({ line: lineCount, content: extractRes[0] }) } }); rl.on('close', () => { // 对收集来的json数据再做一下过滤,提取目标json const fileContents = results.filter(res => res.content.msg_content); // 一般结果都不少,直接写入输出文件中 fs.writeFileSync('res.txt', fileContents.map(obj => { return ' 行:' + obj.line + '\n' + JSON.stringify(obj.content); }).join('\n\n')); });
如此一来,写好脚本以后就方便过滤日志文件提取必要信息用于分析了,也可以拿来mock用。
发现从code上复制的代码贴到sf编辑器,会加入\
的转义符,还得复制到sublime 再复制回来才正常 - -||
这篇关于日志文件中提取json--开发小记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-30React Native常用组件-点击组件
- 2024-05-30uniapp+vue3+uv-ui手机端后台OA管理模板
- 2024-05-29Python网络爬虫的时候json=就是让你少写个json.dumps()
- 2024-05-27React Native常用组件-展示组件
- 2024-05-27React Native常用组件-列表组件
- 2024-05-09vue3开发前端表单缓存自定义指令,移动端h5必备插件
- 2024-05-09React Hooks在class组件中的使用方式
- 2024-03-30[OIDC in Action] 2. 基于OIDC(OpenID Connect)的SSO(纯JS客户端)
- 2024-03-29terraform jsonencode
- 2024-03-13vuex-persist