json日志分析工具: jq
上篇文章介绍了jsawk,由于一些不足,这里又发现了一个更好的工具: jq
安装:
1 |
yum install -y jq |
用法:
1 |
man jq |
体验一下:
项目主页: https://stedolan.github.io/jq/
指南: https://stedolan.github.io/jq/tutorial/
手册: https://stedolan.github.io/jq/manual/
字符串连接
1 2 3 |
# echo '[{"from":"1","to":"2"},{"from":"1", "to":"2"}]'|jq -r '.[]| .from + ":" + .to' 1:2 1:2 |
(注意: 这里连接的是字符串,数字是不能直接当做字符串进行连接的)
类型转换:
1 2 3 4 5 |
# echo '[{"ID":1,"Name":"N1"},{"ID":2,"Name":"N2"}]'|jq '(.[].ID|tostring) + ":" + .[].Name' "1:N1" "2:N1" "1:N2" "2:N2" |
这里通过圆括号来单独处理一部分,然后通过tostring将输出内容转换为字符串; 也可以通过 @text 实现:
1 2 3 4 5 |
# echo '[{"ID":1,"Name":"N1"},{"ID":2,"Name":"N2"}]'|jq '(.[].ID|@text) + ":" + .[].Name' "1:N1" "2:N1" "1:N2" "2:N2" |
join:
1 2 3 |
# echo '[{"from":"1","to":"2"},{"from":"1", "to":"2"}]'|jq -r '.[]| join(":")' 1:2 1:2 |
获取对象的key:
1 2 3 |
# echo '{"a":"A", "b":"B"}'|jq -r 'to_entries[].key' a b |
等效于
1 2 3 |
# echo '{"a":"A", "b":"B"}'|jq -r 'to_entries[] |.key' a b |
等效于:
1 2 3 |
# echo '{"a":"A", "b":"B"}'|jq -r 'to_entries | .[] |.key' a b |
过滤:(通过select 过滤出Name为default的条目,然后只显示名字和ID列)
1 2 3 |
# openstack security group list -fjson|jq '.[]|select(.Name == "default")|.Name + ":" + .ID' "default:02dadaae-9d78-45ba-8fe5-496841b3c839" "default:1bfd33d7-6278-4718-9680-fd6f3328561d" |
错误的写法: (下面这个写法把Name和ID排列组合输出了)
1 |
openstack security group list -fjson|jq '.[].Name + ":" + .[].ID' |
如:
1 2 3 4 5 |
# echo '[{"ID":"1","Name":"N1"},{"ID":"2","Name":"N2"}]'|jq '.[].ID + ":" + .[].Name' "1:N1" "2:N1" "1:N2" "2:N2" |
根据path 和 select获取感兴趣的值:
1 2 3 4 5 |
# ceph status -f json|jq '(paths | select( .[-2:] == ["metadata", "ceph_version"])) as $path| getpath($path)' "ceph version 12.2.1 (3e7492b9ada8bdc9a5cd0feafd42fbca27f9c38e) luminous (stable)" "ceph version 12.2.1 (3e7492b9ada8bdc9a5cd0feafd42fbca27f9c38e) luminous (stable)" "ceph version 12.2.1 (3e7492b9ada8bdc9a5cd0feafd42fbca27f9c38e) luminous (stable)" "ceph version 12.2.1 (3e7492b9ada8bdc9a5cd0feafd42fbca27f9c38e) luminous (stable)" |
参考: https://stackoverflow.com/questions/25780807/can-i-use-a-relative-path-or-a-wildcard-in-jq
关联数组的key需要使用双引号,不能使用单引号:
1 2 |
# echo '{"a":"A", "b":"B"}'|jq -r '.["a"]' A |
1 2 3 4 |
# echo '{"a":"A", "b":"B"}'|jq -r ".['a']" jq: error: syntax error, unexpected INVALID_CHARACTER (Unix shell quoting issues?) at <top-level>, line 1: .['a'] jq: 1 compile error |
修改部分值
1 2 |
# echo '{"a":"A", "b":"B"}'|jq '.a="AA"' -c {"a":"AA","b":"B"} |
1 2 |
# echo '{"a":"A", "b":"B"}'|jq '.a="AA"|.b="BB"' -c {"a":"AA","b":"BB"} |
在任何一个级别中查找指定字段:
1 |
echo '[[{"a":1}]]' | jq ´..|.a?´ |
构造新对象:
关于paths的用法: 1.3 版本中还没有paths:
这里的paths放在圆括号内,不影响输出,就好比bash中的圆括号是在单独子进程中执行一样,不影响当前的环境,同时,使用as使得圆括号的输出保存在变量中,不影响后续的输入; 这样,使得getpath所在环境中的 dot 依然是原始的输入
参考资料: https://linuxtoy.org/archives/jq.html
https://github.com/stedolan/jq/issues/885
在线测试: https://jqplay.org/jq?
注意事项:
- 字符串只能使用双引号,不能使用单引号
- if 语句必须有else, 如果其中一个分支实在没啥说的就 select(false) 相当于empty
jsawk
主页: https://github.com/micha/jsawk
用途:一直以来,日志都采用 | 分隔的多个匿名的字段组成的,每个字段代表什么含义是基于位置确定的,应该说是很不用户友好的,对于不太熟悉系统的新手是不太愿意看这样的日志的,所以,如果把日志记录成json格式的,应该说是一个进步;但是,对于经常使用awk分析基于|分隔的日志的我们来讲,awk分析json似乎就太不方便了,那么,jsawk就是我们需要的分析json的awk级别的工具
体验一下:
感受:直接把一个有很多行json的日志文件直接cat给jsawk是不行的,jsawk每次只解析一个json对象(或一个包含很多json对象的数组);如果要聚合一些信息的话,还需要输出给另一个程序(awk?)进一步处理
要不改造一下jsawk?
stat荟萃
awstats
Advanced Web Statistics
ethstatus
Console-based ethernet statistics monitor
gitstats
Generates statistics based on GIT repository activity
iptstate
A top-like display of IP Tables state table entries
iostat
Report Central Processing Unit (CPU) statistics and input/output statistics for
devices, partitions and network filesystems (NFS)
netstat
netstat – Print network connections, routing tables, interface statistics, masquerade connec-
tions, and multicast membership
netstat-nat
A tool that displays NAT connections
ifstatus
Command line real time interface graphs using ncurses
pipestat
Watches data flowing over an anonymous pipe
vnstat
Console-based network traffic monitor
smemstat
Shared memory usage monitoring tool
sysstat
The sar and iostat system monitoring commands
statsd
A simple, lightweight network daemon to collect metrics over UDP
tcpstat
tcpstat reports certain network interface statistics much like vmstat does for system statistics. tcpstat gets its information by either monitoring a specific interface, or by reading previously saved tcpdump data from a file.
参考:
http://www.frenchfries.net/paul/tcpstat/
系列top
top
top – display Linux tasks
iotop
iotop – simple top-like I/O monitor
iftop
iftop – display bandwidth usage on an interface by host
ntop
ntop – display top network users
atop
atop – Advanced System & Process Monitor
ftop
ftop – show progress of open files and file systems
mytop
mytop – display MySQL server performance info like ‘top’
htop
htop – interactive process viewer
关于安装: 如果幸运的话,都可以通过yum install 搞定
tcprstat
tcprstat is a free, open-source TCP analysis tool that watches network traffic and computes the delay between requests and responses.
tcprstat is related to the tcpstat tool, but it focuses on response time measurements, not on the amount and size of the network traffic. This makes it useful for response time analysis, which is needed for techniques such as Goal-Driven Performance Optimization.
The advantages of tcprstat are as follows:
-
It is lightweight and unobtrusive. No bulky log files need be written and analyzed.
-
Requests and responses are timed with microsecond resolution.
-
The output is easy to import into spreadsheets, manipulate with command-line scripts, graph with gnuplot, and so on.
-
It is protocol-agnostic, and works well for a large variety of client-server protocols that have a simple request-response model.
参考资料:
mysql监控管理工具–innotop
INNOTOP是一个通过文本模式显示MySQL和InnoDB的监测工具。INNOTOP是用PERL语言写成的,这使它能更加灵活的使用在各种操作平台之上,它能详细的的监控出当前MYSQL和INNODB运行的状态,以DBA根据结果,可以合理的优化MYSQL,让MYSQL更稳定更高效的运行。
官方地址: http://innotop.googlecode.com/svn/html/index.html
github地址: https://github.com/innotop/innotop
安装: 先试试yum search innotop
参考资料: http://blog.csdn.net/wyzxg/article/details/8609981
gitlab 安装问题
安装方式:
- 通过百度离线下载功能下载gitlab的rpm(这样下载速度回快些)
- 安装rpm
- 修改配置文件
测试:
出现问题如下:
刚安装好就出现这样的问题,太让人不解了(关键是在不同的机器上用相同的方式安装,有时候就是好的)
经过N翻折腾,无果,还是直接去代码里面调试吧;
信息1: pre-receive hook
信息2: The project you were looking for could not be found.
在目录 /opt/gitlab 中搜索关键字: The project you were looking for could not be found.
发现文件: /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/git_access.rb 修改此文件:
重新测试,不报错了,而且提交成功了。先这样吧
由于ruby实在一点儿也不了解,没法debug,遂在z.cn买了一半ruby的入门书
纠结的进程关系
进程P起了两个进程p1和p2,然后wait(p1); p1通过管道写数据到p2;当p2工作异常后,p1写给p2的数据不能被处理,导致管道阻塞了p1;当发现p2异常后,试图kill -9 杀死p2;纠结出现了:
P当前只wait(p1),对于p2的死不做任何反应,由于暂时没人为p2收尸,p2只能处于<defunct>状态,虽然p2已经注定了死亡的命运,但是p1和p2之间的管道依然存在(还没被销毁,可见,p2的资源是需要P来回收的),p1将不会得到任何异常通知,依然在等待; 于是乎,出现了循环等待了。
解决办法倒是比较简单,把P给kill了就行了;只是这个状态比较纠结
gitlab 里面的runsvdir 居然能把进程的错误写到进程名上,如下(省的你看不见?):