json log自动展开嵌套字段(expand nested fields)
source link: https://blog.csdn.net/oqqYuan1234567890/article/details/108969879
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
目前日志系统基本是走json log,一般公有云的log管理页面,都会有自动展开json log的功能。
在开发过程中,本地看json形式的日志有点麻烦,可读性不高。举个例子,有一行日志是这样的
{"level":"info","ts":1602161606.829082,"caller":"zap_test/main.go:44","msg":"embed","a":{"b":"bbb"},"json-str":"{\"Name\":\"a\",\"Age\":2}","stack":"/opt/go_work/src/mtest/misc/zap_test/main.go:43 (0x127d307)\n\tmain: stackOut,_ := utils.Stack(1)\n/opt/tools/go/src/runtime/proc.go:203 (0x1030585)\n\tmain: fn()\n/opt/tools/go/src/runtime/asm_amd64.s:1357 (0x105ae70)\n\tgoexit: BYTE\t$0x90\t// NOP\n"}
使用一些format工具,大概能处理成这样子:
{
"level": "info",
"ts": 1602161606.829082,
"caller": "zap_test/main.go:44",
"msg": "embed",
"a":{
"b":"bbb"
},
"json-str": "{\"Name\":\"a\",\"Age\":2}",
"stack": "/opt/go_work/src/mtest/misc/zap_test/main.go:43 (0x127d307)\n\tmain: stackOut,_ := utils.Stack(1)\n/opt/tools/go/src/runtime/proc.go:203 (0x1030585)\n\tmain: fn()\n/opt/tools/go/src/runtime/asm_amd64.s:1357 (0x105ae70)\n\tgoexit: BYTE\t$0x90\t// NOP\n"
}
但是可读性还是很差,主要有两种场景需要优化:
- 某个field是一个json字符串,标准json要求先转义,这样就很难读懂(哈哈,其实公有云也不一定有这个功能,不过我就想要)
- 某个field对应的字段,有换行符,如果可以换行显示最好
参考gcp的log expand nested fields的显示样式,用python实现了类似的功能。上面提及的两种场景的解决思路如下:
- 对于json转义的字段,尝试json反序列化,如果成功了,就把这个字段变成字典,继续遍历,否则就显示字符串
- 对于有换行符的字符串,换行显示
贴个demo:
# 自动展开json
import json
import argparse
parser = argparse.ArgumentParser(description='manual to this script')
parser.add_argument('--path', type=str, default=None)
args = parser.parse_args()
with open(args.path) as f:
data = json.load(f)
# print(data)
indent_space = " "
# 尝试把数据展开
def expand_dict(data, layer):
brace_indent = ""
indent = ""
for i in range(layer):
indent += indent_space
for i in range(layer-1):
brace_indent += indent_space
# left brace
if layer == 1:
print(brace_indent+"{")
for k in data:
item = data[k]
if isinstance(item, dict):
print('''{}"{}": '''.format(indent, k)+"{")
expand_dict(item, layer+1)
continue
if not isinstance(item, str):
print('''{}"{}": {}'''.format(indent, k, item))
continue
if len(item) < 6:
print('''{}"{}": "{}"'''.format(indent, k, item.replace("\n", "\n"+indent+(len(k)+4)*" ", 10)))
continue
if item[0] == "{" and item[-1] == "}":
try:
new_data = json.loads(item)
except Exception as e:
print("[parse json of data:{} data err {}][ignore this line*******]".format(item, e))
print('''{}"{}": "{}"'''.format(indent, k, item.replace("\n", "\n"+indent+(len(k)+4)*" ", 10)))
continue
data[k] = new_data
print('''{}"{}": '''.format(indent, k)+"{")
expand_dict(new_data, layer+1)
else:
# normal string
print('''{}"{}": "{}"'''.format(indent, k, item.replace("\n", "\n"+indent+(len(k)+4)*" ", 10)))
# left brace
print(brace_indent+"}")
expand_dict(data, 1)
保存为expand.py, 把最上面那行log保存成一个文件,然后执行python expand.py --path ./expand_input.json
输出
{
"level": "info"
"ts": 1602161606.829082
"caller": "zap_test/main.go:44"
"msg": "embed"
"a": {
"b": "bbb"
}
"json-str": {
"Name": "a"
"Age": 2
}
"stack": "/opt/go_work/src/mtest/misc/zap_test/main.go:43 (0x127d307)
main: stackOut,_ := utils.Stack(1)
/opt/tools/go/src/runtime/proc.go:203 (0x1030585)
main: fn()
/opt/tools/go/src/runtime/asm_amd64.s:1357 (0x105ae70)
goexit: BYTE $0x90 // NOP
"
}
这样子修改一下,基本达到预期,可读性高一些。不过需要保存log,脚本也要传参,感觉还是太不方便。准备移植为js代码,做成一个前端页面,这种小型工具在开发的时候挺方便。
Recommend
-
89
写在前面 不知大家有没遇到过像“横放着的金字塔”一样的if else嵌套: 我并没夸大其词,我是真的遇到过了!嵌套6、7层,一个函数几百行,简!直!看!死!人! if else作为每种编程语言都不可或缺的条件语句,我们在编程时会大量的用到。但if else一般不建议嵌套超...
-
54
号外:为读者持续整理了几份最新教程,覆盖了 Spring Boot、Spring Cloud、微服务架构等PDF。 获取方式:关注右侧公众号"泥瓦匠BYSocket",来领取吧! 摘要: 原创出处 https://www.bysocket...
-
2
在进行持久层数据维护(新增或修改)的时候,我们通常需要记录一些非业务字段,比如:create_time、update_time、update_by、create_by等用来维护数据记录的创建时间、修改时间、修改人、创建人等信息。通常情况下我们需要对这些字段进行手动赋值。...
-
7
objtyping 带类型定义的对象转换器Python不是强类型语言,开发人员没有给数据定义类型的习惯。这样虽然灵活,但处理复杂业务逻辑的时候却不够方便——缺乏类型检查可能导致很难发现错误,在IDE...
-
4
我又来啦.. 本篇主要记录如何针对CodeFirst做自动添加描述的扩展 为什么要用这个呢.. 因为EF Core3.1 CodeFirst 对于自动添加描述这块 只有少部分的数据库支持.. 然而我们的客户大佬们 对这个又有要求..所以..没办法 只能自己扩展~
-
4
Dynamic Web Form, fields can be nested to an arbitrary depth, also add / remove fields dynamically advertisements I am trying to build a web f...
-
3
ActionText is a power-packed tool to easily build WYSIWYG editors for your Rails applications. It comes with an array of editor options and transformers. One of them is the Plain Text transformer which converts HTML input to plain text output...
-
4
Python 展开嵌套序列...
-
7
新建测试跑道,宝马将与特斯拉展开自动驾驶大战2022/08/02 16:17|作者
-
5
SpringBoot中为什么不推荐字段依赖自动注入? 解道Jdon ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK