linux查询日志
在linux中可以使用head、tail等命令查看日志等文本文件,例如:
#显示文件前10行
head -n 10 catalina.out
#显示文件后10行
tail -n 10 catalina.out
#持续刷新
tail -f catalina.out
那么如果我们需要进行关键字查询,则需要使用grep命令;
grep后面有三个参数:A/B/C +数字;分别代表输出后N行、前N行、上下N行;
如果字符串中有空格或者特殊符号,如:”2020-03-30 14:57:24.301 INFO 4145 -“,则需要加上双引号:
grep -A 5 需要匹配的字符串 catalina.out
# 特殊符号
grep -A 5 "2020-03-30 14:57:24.301 INFO 4145 -" catalina.out
限制输出
如果查询的匹配项过多,而我们需要进行limit,则需要进行限制(-m参数):
#只获取前N个匹配项
grep -m 3 -A 10 需要查询的字符串 catalina.out
#只获取后N个匹配项,需要结合tac命令使用
tac catalina.out | grep -m 3 -A 10 需要查询的字符串
tac命令用于将文件以行为单位的反序输出,即第一行最后显示,最后一行先显示。
如果说只限制输出条数,可以结合head、tail命令使用:
grep -A 10 需要查询的字符串 catalina.out |head -n 100
grep -A 10 需要查询的字符串 catalina.out |tail -n 100
线程数查询
在web应用程序中,tomcat线程是一个需要关注的地方。
tomcat中Connector连接器负责创建请求和返回响应,默认只有200个并发(maxThread);当maxThread占满,线程会进行等待(等待线程数量acceptCount);如果超过这个数值,tomcat会放弃线程,并返回connection Refused 异常。
假设我们需要持续性的监控tomcat的线程数,可以按照以下流程:
# 查询PID
ps -ef|grep tomcat
# 根据Pid查询线程数
ps -Lf 找到的pid|wc -l
需要注意的是,tomcat线程并不能反映实际的连接情况,毕竟一个请求可能会运行多个子线程。
CPU占用以及代码定位
可以使用top或者htop查看CPU和内存消耗,htop命令更加直观和强大
# 更改刷新频率可以加d参数,单位-秒
top -d 1
# 单独查看进程加P参数
top -p PID
#根据ID查看进程详细信息
ps -aef|grep PID
假设一个java进程导致CPU飚高,我们需要根据top命令,通过进程ID找到那些高占用的线程。
这里主要关注CPU使用率以及线程执行时长两个因素。
#查询进程中的线,H参数要大写
top -p PID -H
找到对应的线程后,需要将10进制的线程ID转换为16进制,并进行搜索
#线程ID转换为16进制得到线程标记(注意是线程ID)
printf "%x\n" 线程ID
#jstack 查询(注意jstack -l后面是进程ID,grep -A 50 匹配后50条输出)
jstack -l 26068 |grep -A 50 65f3
通过查看代码,发现的确是写了个死循环
内存占用情况以及代码定位
一般情况下,如果内存消耗线性增长,则需要考虑是否存在泄露问题导致GC无法回收造成的。
top命令同样会显示内存消耗,可以使用-a参数,或者键盘大写按下M键进行排序。
配合jvm的小工具jmap命令,可以扫描堆中对象信息,定位内存高占用的原因。
#查看内存占用排序( -ab是根据内存正排序,-n 代表执行一次)
top -ab -n 1 |head -n 20
#jmap命令输出堆信息,histo:live输出状态是live的对象
jmap -histo:live PID |head -n 20
通过下面图片可以看到,JVM中有一个自定义的实体类有500W+个实例,这显然是有问题的。
以上只是简单的查看问题,此时需要通过dump heap快照并通过mat、jprofiler等工具进行更深层次的分析。
存储空间查看
主要使用df和du命令:
df 查看文件系统内部的 inode
du 查看文件和目录磁盘使用情况
linux文件都必须有一个inode,因此有可能发生inode已经用光但硬盘还未存满的情况;这时就无法在硬盘上创建新文件。
相关blog:文件和inode关系资料
查看inode空间占用
df -h
df -h 命令默认是当前目录,可以使用 df -h /usr/ 查看指定目录
第1列是代表文件系统对应的设备文件的路径名。
第2、3、4列分别表示总共、已用、可用空间。
第3、4列之和会略小于第二列,主要是系统保留少量空间给管理员使用;当普通用户的容量占用100%时,管理员还可以登录系统操作。
查看磁盘空间占用
统计文件夹磁盘占用
#查看整体空间占用
du -sh /usr/
#当前目录-各个文件夹占用
du --max-depth=1 -h
#指定目录-各个文件夹占用
du --max-depth=1 -h /usr/
#指定目录-各个文件夹占用-并排序
du --max-depth=1 /usr/ |sort -nr
du --max-depth=1 /usr/ |sort -nr |head -n 前N行
linux文件描述符(句柄)
句柄是windows中的概念,linux中主要指文件描述符。
句柄可以大致理解为:进程打开的文件的内存地址的引用。
在linux中,操作文件、创建socket连接(尤其注意通过http访问外部接口),都会占用句柄数。
每个进程所能占用的句柄数是有上限的,当进程打开文件、socket等超过了系统设置(或者是打开后未关闭),则会出现too many open files错误。
查看句柄数
linux对每个进程设置了允许最大操作的句柄数(默认1024);使用以下命令查看
ulimit -n
或者
more /proc/sys/fs/file-max
lsof命令
lsof即:list open files,常常用来查看进程打开了多少文件
统计进程使用的句柄总数
统计所有进程:
lsof -P -n |wc -l
查看所有进程打开的句柄数,并进行倒排序,取前十个
lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr |head -n 10
第一列是句柄数,第二列是进程ID
统计单个进程句柄:
lsof -p PID |wc -l
查看进程详细信息
根据上面查看到的进程ID,可以查看其对应的应用程序
ps -aef|grep 进程ID
或者根据PID查看程序运行目录
ll /proc/进程ID/cwd
查看进程打开的文件
lsof -p 进程PID
或者搜索指定文件
lsof -p 进程PID |grep 文件名
结合docker使用
查看容器的PID:
docker ps
docker top 容器ID
再根据上面的统计单个进程句柄命令进行容器句柄统计:
lsof -p PID |wc -l