文章目录
日志的"老巢"藏在哪儿?
绝大多数Linux系统的日志都住在 /var/log/ 这个目录下。就好比公司所有部门的档案都放在一个档案室里,/var/log/ 就是这个档案室。
常见的几个"住户":
| 日志文件 | 通俗解释 |
|---|---|
| /var/log/messages | 系统级别的"大杂烩"日志,啥都往里面记 |
| /var/log/secure | 安全相关日志,有人暴力破解你的SSH密码,这里会记下来 |
| /var/log/nginx/access.log | Nginx访问日志——谁来过你的网站 |
| /var/log/nginx/error.log | Nginx错误日志——网站为啥打不开 |
| /var/log/application.log | Java/Go/Python应用日志(具体名字看公司怎么配) |
备注:如果公司日志还可能在 /opt/应用名/logs/ 或者 /home/应用名/logs/ 下。实在找不到,用 find / -name “*.log” | head -10 先搜几个看看。
一条典型的应用日志大概长这样:
2026-07-23 14:32:15.123 ERROR [payment-service] [thread-42] com.example.PaymentService - 支付接口调用失败,订单号:ORD123456,超时时间已到
拆开看就是:时间 + 日志级别 + 服务名 + 线程 + 类名 + 具体信息。
这个结构很适合用 grep 抓取的时候精准查询。
核心命令逐个击破
1,cd(任意门,去自己想去的地方)
cd 的全称是 change directory,“切换到哪个文件夹”。
基础用法是:
| 步骤 | 基础用法 |
|---|---|
| 去日志目录(最常用) | cd /var/log |
| 回到家目录(类似Windows按Home键) | cd ~ |
| 回到上一个目录(方便在两个目录间来回横跳) | cd - |
| 去根目录 | cd / |
备注:刚连上服务器,不知道自己在哪,先敲个 pwd(print working directory)看看当前路径,然后再 cd 去想去的地方。
2,ls(照妖镜,看看里面都有啥)
ls 是 list 的缩写,功能就是列出当前目录下的所有文件和文件夹。
基础用法是:
| 步骤 | 基础用法 |
|---|---|
| 按时间排序,最新的在最下面(最常用) | ls -lt |
| 显示详细信息(权限、大小、修改时间) | ls -l |
| 按时间排序,最新的在最上面(配合head使用更佳) | ls -lt |
| 人类可读的文件大小(显示1K、2M、3G而不是1024、2048) | ls -lh |
| 显示隐藏文件(以.开头的文件) | ls -a |
| 详细信息 + 人类可读 + 按时间排 | ls -lth |
| 按时间正序(最旧的在最上面) | ls -ltr |
举例:进到日志目录,敲 ls -lt,就能看到最新的日志文件在最下面(因为很多系统日志滚动生成,最新的文件往往在列表末尾)。如果想看最新的是哪个,直接 ls -lt | tail -1。
3,grep(大海捞针的神器,日志查询界的Ctrl+F)
grep 是 Global Regular Expression Print 的缩写,全局正则匹配输出。
grep命令最基本的用法:
在app.log里找所有包含"ERROR"的行: grep “ERROR” app.log
| 参数 | 含义 | 例子 |
|---|---|---|
| -i | ignore-case 忽略大小写(找错误,但记不清是大写还是小写) | grep -i “error” app.log |
| -n | line-number 显示行号 | grep -n “timeout” app.log |
| -B 5 | Before 显示匹配行的前5行 | grep -B 5 “Exception” app.log |
| -A 5 | After 显示匹配行的后5行 | grep -A 5 “Exception” app.log |
| -C 5 | Context 显示前后各5行 | grep -C 5 “Exception” app.log |
| -r | recursive 递归搜索目录 | grep -r “NullPointer” ./ |
| -E | 扩展正则(支持多个关键词) | grep -E "ERROR |
| -v | invert 反向匹配(排除) | grep -v “DEBUG” app.log |
| -c | count 只统计行数 | grep -c “ERROR” app.log |
-i、-n、-B/-A 这三个,能解决80%的问题。详细说明,再举例子:
| 场景 | 用法 | 解析 |
|---|---|---|
| 找错误,但记不清是大写还是小写 | grep -i “error” app.log | 不管error、Error、ERROR都能找到 |
| 找到错误后,我想看看上下文,到底前面发生了啥(写法1) | grep -B 3 -A 5 “支付超时” app.log | 显示前3行和后5行 |
| 找到错误后,我想看看上下文,到底前面发生了啥(写法2) | grep -C 5 “支付超时” app.log | 前后各5行 |
| 日志太吵了,DEBUG信息刷屏,我想屏蔽掉 | grep -v “DEBUG” app.log | grep “ERROR” | 先去掉DEBUG行,再找ERROR |
| 想同时查"超时"和"连接失败"两种情况(写法1) | grep -E “超时|连接失败” app.log | 同时查 |
| 想同时查"超时"和"连接失败"两种情况(写法2) | grep -e “超时” -e “连接失败” app.log | 同时查 |
| 不知道在哪个文件里,但我要搜整个目录 | grep -rn “订单号ORD123456” ./logs/ | r递归 n显示行号 |
| 只想知道今天一共报了多少次错 | grep -c “ERROR” app.log | 输出一个数字 |
| grep配合正则表达式 | grep “^2026-07-23” app.log | 匹配以"2026-07-23"开头的行 |
| grep配合正则表达式 | grep “ERROR$” app.log | 匹配以"ERROR"结尾的行 |
| grep配合正则表达式 | grep “[0-9]{6}” app.log | 匹配6位连续数字(比如订单号里的数字) |
| 查最新报错,带上下文,忽略大小写,限制行数,实时跟踪 | tail -f app.log | grep -i -C 3 error | head -50 | 组合查询 |
4,less(大文件阅读器,按需加载)
less最基本的使用方式:
less app.log
常用的less快捷键:
| 按键 | 作用 | 备注 |
|---|---|---|
| 空格键 或 f | 向下翻一页 | 最常用 |
| b | 向上翻一页 | backwards |
| 回车 或 j | 向下翻一行 | |
| k | 向上翻一行 | |
| g | 跳到文件开头 | go to top |
| G | 跳到文件末尾 | go to bottom |
| /关键词 | 向下搜索关键词 | 按n找下一个,N找上一个 |
| ?关键词 | 向上搜索关键词 | 按n找下一个,N找上一个 |
| F | 实时跟踪文件更新(类似tail -f) | 按 Ctrl+C 停止 |
| q | 退出 | quit |
| -N | 显示行号(需在less内输入) | 然后回车 |
组合举例:
我打开了一个日志文件,想找最近的一次异常:
按 G 跳到最后,
按 ?Exception 从下往上搜,
看到第一个异常后,按 n 继续往上找更早的,
看完按 q 退出 ;
5,grep+less组合
| 按键 | 作用 |
|---|---|
| grep -n “ERROR” app.log | less | 搜索所有ERROR,然后用less分页浏览 |
| grep --color=always “ERROR” app.log | less -R | 带颜色高亮,看着更舒服 |
| tail -f app.log | grep --color=always “ERROR|WARN” | less -R | 实时跟踪 + 过滤 + 分页 |
| grep --line-buffered ERROR app.log | less -R | 实时过滤大日志 |
| grep -C 5 ERROR app.log | less -R(管道后不丢上下文) | 查看匹配行的上下文 |
| grep --color=never ERROR app.log | less -S(不用颜色,避免宽字符错位) | 只看关键行且能左右滑动 |
要注意的点:
1)less -R 是让 less 能显示颜色转义符,不然 --color=always 会显示成乱码。
2)现象:grep long_running.log | less 时,屏幕长时间无输出,最后突然刷出一大堆。
原因:grep 默认使用块缓冲(Block Buffer)。当输出到管道(非终端)时,它会攒够 4KB~8KB 数据才写入,导致 less 收不到实时流。
解决方案(三选一):
强制行缓冲(推荐):grep --line-buffered pattern file | less
使用 stdbuf:stdbuf -oL grep pattern file | less
改用 awk:awk ‘/pattern/{print; fflush()}’ file | less(灵活性最高)
3)现象:我想在 less 中左右滑动看长行(less -S),使用grep | less -S 默认会截断匹配行的尾部,只显示屏幕宽度内的内容。如果用 grep 只匹配了行首,尾部报错信息可能直接被 less 物理裁剪,根本滑动不出来。
解决:必须加上 -R 参数(保留原始行长度):grep pattern file | less -SR(S 允许水平滚动,R 保留完整原始字符)。
4)现象:grep --color=always 搭配 less 后,屏幕出现大量 ESC[01;31m 乱码,或者搜索时高亮错位。
解决(三选一精准匹配):
保留颜色(推荐):grep --color=always pattern file | less -R(-R 解析 ANSI 颜色转义码)。
去掉颜色(管道场景):grep --color=never pattern file | less(更干净,便于二次复制粘贴)。
极简替代:直接用 less 自己的高亮(less -p pattern file),连 grep 都省了。
5)现象:退出 less 后,终端输入命令看不见字符,或者按回车不换行。
原因:grep 如果匹配到了二进制文件或包含控制字符(如 \r)的内容,less 会将终端的回显模式(Echo)搞乱。
解决方案:
强制过滤二进制:grep -a pattern file | less(-a 将二进制当文本处理)。
万能恢复命令:如果已经错乱,盲打 reset 回车,或者 stty sane 回车恢复。
6)场景:grep huge.log | less,我在 less 中按 q 快速退出。less 退出了,但管道那头的 grep 可能还在后台拼命扫描巨大的日志文件,耗尽 CPU 和 IO。
解决:
手动清理:退出后立即执行 jobs 查看,kill %1 杀掉残留的 grep。
自动跟随(终极方案):直接使用 less +F 模式,实时跟踪文件末尾less +F huge.log,
按 Ctrl+C 进入普通 less 浏览模式, 按 & 键,输入关键字(如 ERROR),less 会动态过滤显示(比 grep 管道快得多且无残留)。
综合实例
场景1,用户反馈"支付失败",半小时内定位
| 操作 | 命令 |
|---|---|
| 1. 进入日志目录 | cd /opt/payment-service/logs |
| 2. 看看最新的日志文件是哪个 | ls -lt | head -5 |
| 3. 先看最后100行,摸摸情况 | tail -100 app.log |
| 4. 搜索"支付失败"关键词,带上下文 | grep -B 5 -A 10 “支付失败” app.log |
| 5. 如果支付失败和某个订单号有关,根据订单号追查 | grep -B 10 -A 10 “ORD123456” app.log |
| 6. 如果日志滚动太快,用less慢慢看 | grep -n “支付” app.log | less |
场景2:想知道某个时间段发生了什么
| 操作 | 命令 |
|---|---|
| 方法1:直接grep时间 | grep “2026-07-23 15:” app.log |
| 方法2:用sed截取时间段 | sed -n ‘/2026-07-23 14:50/,/2026-07-23 15:10/p’ app.log |
| 方法3:结合awk | awk ‘/2026-07-23 14:50/,/2026-07-23 15:10/’ app.log |
场景3:统计今天不同类型的错误数量
| 操作 | 命令 |
|---|---|
| 统计ERROR总数 | grep -c “ERROR” app.log |
| 统计不同错误类型的次数 | grep “ERROR” app.log | awk -F ’ - ’ ‘{print $3}’ | sort | uniq -c | sort -rn |
| 查历史报错,统计频率排序 | grep -i -o “error.*” app.log | sort | uniq -c | sort -nr | head -20 |
备注:
【grep “ERROR” app.log | awk -F ’ - ’ ‘{print $3}’ | sort | uniq -c | sort -rn】的完整流程:
1,grep “ERROR” app.log → 筛选出所有包含"ERROR"的日志行;
2,awk -F ’ - ’ ‘{print $3}’ → 提取第三列(错误类型);
3,sort → 按字母排序;
4,uniq -c → 统计每种错误出现次数;
5,sort -rn → 按次数从高到低排序(-r 降序,-n 数值排序)
假设 app.log 内容如下:
2026-07-25 08:00:01 - INFO - Service started
2026-07-25 08:05:12 - ERROR - Connection timeout
2026-07-25 08:10:33 - WARN - Memory usage 85%
2026-07-25 08:15:44 - ERROR - Connection timeout
2026-07-25 08:20:55 - ERROR - Database deadlock
2026-07-25 08:25:06 - INFO - User login success
2026-07-25 08:30:17 - ERROR - Disk full
2026-07-25 08:35:28 - ERROR - Connection timeout
2026-07-25 08:40:39 - ERROR - Database deadlock
2026-07-25 08:45:50 - ERROR - Connection timeout
2026-07-25 08:50:01 - INFO - Health check ok
1,grep “ERROR” app.log → 筛选出所有包含"ERROR"的日志行;
作用:只保留包含 “ERROR” 的行
处理过程:逐行检查,有"ERROR"就留下,没有就丢掉
处理结果:
2026-07-25 08:05:12 - ERROR - Connection timeout
2026-07-25 08:15:44 - ERROR - Connection timeout
2026-07-25 08:20:55 - ERROR - Database deadlock
2026-07-25 08:30:17 - ERROR - Disk full
2026-07-25 08:35:28 - ERROR - Connection timeout
2026-07-25 08:40:39 - ERROR - Database deadlock
2026-07-25 08:45:50 - ERROR - Connection timeout
2,awk -F ’ - ’ ‘{print $3}’ → 提取第三列(错误类型);
作用:用 - 作为分隔符,取第3列(错误类型)
处理过程:每一行按 - 切开,取第3部分
处理结果:
Connection timeout
Connection timeout
Database deadlock
Disk full
Connection timeout
Database deadlock
Connection timeout
3,sort → 按字母排序;
作用:按字母顺序排序(A→Z)
处理过程:把上面7行按字典序排列
处理结果:排序后(所有相同的排在一起)第2步数据更新为:
Connection timeout
Connection timeout
Connection timeout
Connection timeout
Database deadlock
Database deadlock
Disk full
4,uniq -c → 统计每种错误出现次数;
作用:统计相邻的相同行出现的次数
处理过程:每一组连续相同的行,计个数
处理结果:
4 Connection timeout
2 Database deadlock
1 Disk full
5,sort -rn → 按次数从高到低排序(-r 降序,-n 数值排序)
作用:按数字(-n)降序(-r)排列,即从多到少
处理结果:排序后(次数多的排最前面),第4步的数据更新为:
4 Connection timeout
2 Database deadlock
1 Disk full
这里正好已经是降序了,所以看起来没变化。但如果顺序是 1, 4, 2,就会变成 4, 2, 1。
最终结果所以是:
4 Connection timeout
2 Database deadlock
1 Disk full
| 错误类型 | 出现次数 | 含义解读 |
|---|---|---|
| Connection timeout | 4 次 | 最高,优先排查 |
| Database deadlock | 2 次 | 中等 |
| Disk full | 1 次 | 较低 |
后台日志“黄金排查五步法”
口诀:先定目录,再看文件,尾巴扫一眼,grep抓重点,搜不到就递归翻。
| 步骤 | 命令 | 目的 |
|---|---|---|
| 第1步 | cd /var/log/应用名/ | 找到路径 |
| 第2步 | ls -lt | head | 锁定目标文件(实时数据是看最新的那个文件,非实时数据看公司对应按照时间归类的文件) |
| 第3步 | tail -200 app.log | 先看最新200行,快速了解当前状态 |
| 第4步 | grep -i -B 3 -A 5 “关键词” app.log | 精准打击,找到报错上下文 |
| 第5步 | grep -rn “关键词” ./ | less | 如果没找到,扩大搜索范围到整个目录 |
备注:
1,如果关键词的识别度高,可以直接操作第1步、第4步,即可出来具体的数据。
2,实时文件可以精准搜索app.log,非实时文件可以模糊匹配搜索app.*.log 。
常见的操作错误
与grep 相关
grep 忘记用 -i 忽略大小写
❌ grep “error” app.log 结果啥也没有,其实里面有 ERROR
✅ 养成习惯:查英文关键词一律加 -i
搜索时只搜固定字符串,不会用正则
❌ 搜 “订单号123” 搜不到,因为日志里是 “订单号:123”
✅ 学会用 grep -E “订单号.*123” 通配匹配
❌ 搜中文时忘记字符编码
grep “错误” app.log 搜不到,因为日志可能是 GBK 编码
✅ 先 file -i app.log 看编码,再用 iconv 转码或 grep -a 强制当文本处理
❌ grep 后只看到匹配行,没有上下文
看到一行 “ERROR” 但不知道前后发生了什么
✅ 学会 -C 5(前后5行)、-A 5(后5行)、-B 5(前5行)
❌ 搜多个关键词只会用 grep a | grep b
管道多了效率低,且可能漏掉顺序
✅ 用 grep -E “a|b”(或关系)、grep -E “a.*b”(先后关系)
❌ 搜 IP 或数字时被特殊字符干扰
grep “192.168.1.1” 里的 . 是正则通配符,会匹配 “192X168X1X1”
✅ 用 grep -F “192.168.1.1” 或 fgrep,当作纯字符串匹配
❌ 日志在滚动,grep 完又出新日志,想实时监控
grep “ERROR” app.log 只查历史
✅ 用 tail -f app.log | grep --line-buffered “ERROR” 实时过滤
与less有关
less 打开了不知道怎么退出
❌ 狂按 Ctrl+C 没用,然后关掉终端重连
✅ 记住:q 键退出
查日志用 cat 打开几G的文件
❌ 服务器卡死,被运维拉黑
✅ 大文件用 less,看最新几行用 tail
❌ 打开大文件后想跳到最后一行,按 G 但等太久
less 默认会加载整个文件到末尾,大文件卡死
✅ 用 less -N app.log 显示行号;打开后按 Shift+G 跳到末尾,但要等;更优:less +G app.log 直接打开在末尾
❌ 搜索时 /error 只搜到第一个,想继续看下一个
按 n 是下一个,但方向反了?
✅ / 向下搜,按 n 继续向下,N 向上;? 向上搜,按 n 继续向上
❌ 看到一半想看别的文件,退出再进麻烦
✅ less 里输入 :e /path/to/other.log 切换文件;:n 和 :p 浏览多个文件(启动时 less file1 file2)
❌ 想复制一行内容,鼠标选中但拖不动
✅ less -S 模式按 ←→ 横滚;复制用 v 键 调出 vi 编辑器,在里面复制更舒服
与cd 相关
❌ 以为 cd 能直接切到文件
cd /path/to/file.log → 报错"Not a directory"
✅ 记住:cd 只能接目录,想进文件所在目录用 cd $(dirname /path/to/file.log) 或先 cd /path/to/ 再操作文件
❌ 用相对路径在深层目录里绕晕
cd …/…/…/…/…/ 然后迷路,pwd 一看不知道自己在哪
✅ 多用 cd - 切回上一个目录;cd ~ 快速回家;pushd/popd 管理目录栈(高频切换神器)
❌ 手滑输入 cd / 然后执行了 rm -rf *(这个属于操作习惯)
✅ 养成习惯:cd 后立刻 pwd 确认
与ls 相关
❌ 用 ls 看目录,文件太多直接刷屏
日志目录下几万个文件,ls 一下终端卡死
✅ 用 ls -ltr 按时间排序,最新文件在最后,配合 | tail;用 ls -lh 看人类可读的文件大小
❌ 只看文件名,不知道是文件还是目录
ls 默认不区分,容易误操作
✅ 养成习惯:ls -l 或 ls -F(目录会带 / 后缀,可执行文件带 *)
❌ 想查隐藏文件(如 .env)却漏了
ls 默认不显示点文件
✅ 用 ls -la 或 ls -A(排除 . 和 …)
通用错误:
日志文件路径搞错
❌ 以为日志都在 /var/log/ 下
✅ 先去应用部署目录找,一般叫 logs 或 log (不同模块会有不同路径)
❌ 命令输一半发现权限不够,直接 sudo !!
有时会把上一个危险命令也 sudo 了
✅ 先 history 看编号,再用 !编号 精准重跑,或者 sudo ! 前先看一眼上条命令是什么
❌ 通配符 * 不加引号,文件名带空格直接炸
rm -rf * 遇到文件名 “my log file.log” 会拆成多个参数
✅ 用 find . -name “*.log” -exec 代替裸 *,或加引号 grep “error” * 加 – 分隔参数
❌ 查进程用 ps -ef | grep java,结果 grep 自己也被搜出来
✅ 用 ps -ef | grep [j]ava(方括号技巧,grep 命令本身不匹配),或者 pgrep -f java
❌ 磁盘满了,du 扫半天不知道哪里最大
du -sh * 在根目录执行会扫所有挂载点
✅ 用 ncdu /(交互式,按 d 删除,按 n 排序),没装的话用 du -h --max-depth=1 | sort -hr

1063

被折叠的 条评论
为什么被折叠?



