Ubuntu系统运维中,80%以上的故障都能通过系统日志快速定位根因。核心思路就一句话:先看/var/log/syslog和/var/log/kern.log抓错误信息,再用journalctl按时间和服务过滤,最后配合Prometheus+Grafana或Zabbix做实时监控告警,把被动救火变成主动预防。下面我把这套完整流程拆解成具体操作,每一步都给你可直接执行的命令和配置。
一、Ubuntu系统日志体系快速认知
Ubuntu的日志体系主要由三部分构成:传统文本日志(rsyslog)、systemd日志(journald)和应用自定义日志。传统日志存放在/var/log/目录下,包括syslog(系统综合日志)、kern.log(内核日志)、auth.log(认证日志)、dmesg(内核环形缓冲区)。systemd的journalctl则统一管理所有服务日志,支持按时间、优先级、服务名精确查询。实际运维中,建议以journalctl为主、传统日志为辅,因为journalctl支持结构化查询,效率远高于grep翻文本。
二、高频故障场景与日志定位方法
1. 磁盘空间满导致服务崩溃
这是最常见的故障之一。当根分区使用率达到100%,数据库、Web服务、甚至SSH都可能无法正常工作。排查命令如下:
df -h du -sh /var/log/* | sort -rh | head -10
先用df -h确认哪个分区满了,再用du定位大文件。通常/var/log下的syslog、journal日志会疯狂增长。清理方法:
journalctl --vacuum-size=500M find /var/log -name "*.gz" -mtime +30 -delete
journalctl --vacuum-size限制日志总量,find命令删除30天前的归档日志。根本解决方案是配置logrotate,编辑/etc/logrotate.d/rsyslog,设置rotate 7、daily、compress等参数,让日志自动轮转压缩。
2. 内存不足触发OOM Killer
系统内存耗尽时,Linux内核会启动OOM Killer杀掉占用内存最高的进程。在dmesg或syslog中搜索关键字"Out of memory"和"Killed process":
dmesg | grep -i "out of memory" journalctl -k | grep -i "killed process"
找到被杀进程后,分析是否是应用内存泄漏。可以用smem或ps aux --sort=-%mem查看实时内存占用。长期方案是调整vm.swappiness参数,或者在关键服务上设置内存限制(systemd的MemoryLimit)。
3. 网络连接异常与DNS故障
网络问题在日志中的表现通常是连接超时、DNS解析失败。查看网络相关日志:
journalctl -u NetworkManager -n 50 cat /var/log/syslog | grep -i "dns\|timeout\|connection refused"
如果是DNS问题,检查/etc/resolv.conf配置,用dig和nslookup测试解析。如果是服务端口不通,用ss -tlnp查看监听状态,用telnet或nc测试连通性。很多时候是防火墙规则误删或iptables/ufw配置冲突导致的。
4. 服务启动失败与依赖问题
某个服务起不来,第一时间看它的状态和日志:
systemctl status nginx.service journalctl -u nginx.service -e --no-pager
-e跳到末尾,-e --no-pager避免分页卡住。常见原因包括配置文件语法错误、端口被占用、依赖服务未启动。用systemctl list-dependencies可以查看服务依赖树,快速找到上游问题。
三、journalctl高级用法:精准过滤故障信息
journalctl是Ubuntu运维的瑞士军刀,掌握以下过滤技巧能大幅提升排查效率:
journalctl --since "2024-01-15 08:00:00" --until "2024-01-15 10:00:00" journalctl -u sshd.service -p err journalctl -b -1 # 查看上次启动的日志
--since和--until按时间段过滤,-u指定服务单元,-p按优先级过滤(err及以上级别),-b -1查看上次开机日志(系统崩溃后特别有用)。还可以用-o json-pretty输出JSON格式,方便脚本解析。
四、搭建实时监控告警体系
光靠人工翻日志是不够的,必须建立自动化监控。目前主流方案有三种,根据团队规模选择:
1. Prometheus + Grafana + Node Exporter(推荐中大型团队)
Node Exporter采集系统指标(CPU、内存、磁盘、网络),Prometheus定时抓取并存储,Grafana做可视化和告警。安装步骤:
sudo apt install prometheus node-exporter grafana sudo systemctl enable --now prometheus node-exporter grafana-server
在Prometheus的prometheus.yml中添加抓取目标,Grafana导入社区仪表盘(ID 1860),配置Alertmanager发送告警通知到邮件或企业微信/钉钉。
2. Zabbix(适合传统运维团队)
Zabbix Agent部署简单,Web界面配置直观,自带模板监控Ubuntu常用指标。安装agent后在服务端添加主机,关联Linux模板即可。适合不想写太多配置文件的团队。
3. 自定义脚本 + 邮件告警(轻量级方案)
如果资源有限,写个Shell脚本定时检查关键指标,异常时发邮件:
#!/bin/bash
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
MEM_USAGE=$(free | awk '/Mem/{printf "%.0f", $3/$2*100}')
if [ "$DISK_USAGE" -gt 90 ] || [ "$MEM_USAGE" -gt 90 ]; then
echo "WARNING: Disk ${DISK_USAGE}% or Memory ${MEM_USAGE}% is high on $(hostname)" | \
mail -s "Server Alert" ops@example.com
fi
配合crontab每5分钟执行一次,零成本实现基础告警。
五、日志监控告警的关键指标与阈值建议
不是所有指标都需要告警,要抓重点。以下是Ubuntu运维必须监控的核心指标和建议阈值:
磁盘使用率:超过85%告警,超过95%紧急告警。重点监控/、/var、/home分区。
内存使用率:超过80%告警,超过95%紧急告警。同时关注swap使用情况。
CPU负载:1分钟负载超过核心数2倍时告警,持续5分钟以上升级为紧急。
系统日志错误率:用journalctl -p err统计单位时间内error级别日志数量,突增时告警。
服务存活状态:关键服务(nginx、mysql、ssh)每分钟检测一次,宕机立即通知。
网络连通性:对关键外部依赖(数据库从库、API接口)做ICMP或TCP探测,丢包率超过10%告警。
六、实战经验总结与避坑指南
第一,永远不要只看一个日志文件。故障往往是多因素叠加,syslog看系统层,journalctl看服务层,应用日志看业务层,三者交叉比对才能还原全貌。
第二,日志轮转一定要配置。我见过太多服务器因为日志文件涨到几十GB把磁盘撑爆的案例。logrotate是Ubuntu自带的,默认配置基本够用,但要确认/etc/logrotate.conf中的设置是否合理。
第三,监控告警要分级。告警太多等于没有告警,把信息、警告、紧急三级分开,紧急告警用电话或即时通讯推送,警告用邮件,信息只记录不通知。
第四,定期做故障复盘。每次故障解决后,把根因、排查路径、解决方案记录到运维知识库,下次遇到同类问题能直接秒定位。
第五,不要忽视内核参数调优。很多高频故障(如连接数耗尽、文件句柄不够)本质是内核参数没调好。/etc/sysctl.conf中的net.core.somaxconn、fs.file-max、vm.max_map_count等参数,根据业务场景合理设置能避免大量隐性问题。
总结来说,Ubuntu运维故障排查的核心能力就是"会看日志、会过滤、会监控"。把journalctl用熟,把监控体系搭起来,把告警规则定好,90%的故障你都能在用户感知之前解决掉。这不是什么高深技术,而是日复一日积累的手感和体系化思维。
