在现代IT基础设施中,Linux系统监控是保障服务稳定运行的关键环节。一个完善的监控体系不仅能够及时发现问题,还能预测潜在风险,为运维决策提供数据支撑。本文将深入探讨Linux系统监控的各个方面,从基础监控指标到企业级监控架构的设计与实现。
系统监控基础理论
监控的核心价值
系统监控在现代运维中发挥着至关重要的作用:
- 故障预防:通过监控关键指标,在问题发生前进行预警
- 快速定位:当故障发生时,快速定位问题根源
- 性能优化:基于监控数据进行系统性能调优
- 容量规划:为系统扩容和资源规划提供数据依据
- SLA保障:确保服务水平协议的达成
监控指标体系
1. 系统资源监控
CPU监控指标:
- CPU使用率(user、system、idle、iowait)
- 负载平均值(1分钟、5分钟、15分钟)
- CPU核心数和频率
- 进程和线程数量
内存监控指标:
- 内存使用率和可用内存
- Swap使用情况
- 缓存和缓冲区使用量
- 内存分配和释放速率
磁盘监控指标:
- 磁盘使用率和可用空间
- 磁盘I/O读写速率
- 磁盘队列长度和响应时间
- inode使用情况
网络监控指标:
- 网络接口流量(入站/出站)
- 网络连接数和状态
- 网络错误和丢包率
- TCP连接状态分布
2. 应用层监控
进程监控:
- 进程状态和资源使用
- 进程启动时间和运行时长
- 进程文件描述符使用
- 进程内存映射
服务监控:
- 服务可用性和响应时间
- 服务端口监听状态
- 服务日志错误统计
- 服务依赖关系检查
基础监控工具与命令
系统内置监控命令
1. 实时监控命令
1 |
|
2. 高级监控脚本
1 |
|
企业级监控解决方案
Prometheus + Grafana 监控架构
1. Prometheus 配置
1 | # prometheus.yml |
2. 告警规则配置
1 | # rules/system-alerts.yml |
3. Node Exporter 部署
1 |
|
4. 自定义监控指标
1 |
|
Grafana 仪表板配置
1. 系统概览仪表板
1 | { |
日志监控与分析
1. 系统日志监控
1 |
|
2. 应用日志监控
#!/bin/bash
# 应用日志监控脚本
# 专门监控应用程序日志
APP_LOG_DIR="/var/log/applications"
ALERT_LOG="/var/log/app-alerts.log"
CONFIG_FILE="/etc/app-log-monitor.conf"
METRICS_FILE="/var/lib/node_exporter/textfile_collector/app_log_metrics.prom"
# 创建必要目录
mkdir -p $(dirname $ALERT_LOG)
mkdir -p $(dirname $METRICS_FILE)
# 应用日志配置
if [ ! -f $CONFIG_FILE ]; then
cat > $CONFIG_FILE << 'EOF'
# 应用日志监控配置
# 格式: 应用名:日志文件:错误模式:告警阈值(每分钟)
web-app:/var/log/applications/web-app.log:ERROR:5
api-service:/var/log/applications/api.log:Exception:3
database:/var/log/mysql/error.log:ERROR:2
nginx:/var/log/nginx/error.log:error:10
redis:/var/log/redis/redis-server.log:WARNING:5
EOF
fi
# 应用日志分析函数
function analyze_app_logs() {
local app_name=$1
local log_file=$2
local error_pattern=$3
local threshold=$4
local current_time=$(date +"%Y-%m-%d %H:%M:%S")
local one_minute_ago=$(date -d "1 minute ago" +"%Y-%m-%d %H:%M:%S")
if [ ! -f "$log_file" ]; then
return
fi
# 统计最近1分钟的错误数量
local error_count=$(awk -v start="$one_minute_ago" -v pattern="$error_pattern" '
{
# 简化的时间比较,假设日志格式包含时间戳
if ($0 >= start && tolower($0) ~ tolower(pattern)) {
count++
}
} END {print count+0}' "$log_file")
# 生成Prometheus指标
echo "# HELP app_log_errors_total Total number of application log errors" >> $METRICS_FILE.tmp
echo "# TYPE app_log_errors_total counter" >> $METRICS_FILE.tmp
echo "app_log_errors_total{app=\"$app_name\",pattern=\"$error_pattern\"} $error_count" >> $METRICS_FILE.tmp
# 检查是否超过阈值
if [ $error_count -gt $threshold ]; then
local alert_msg="应用 $app_name 在最近1分钟内出现 $error_count 个 '$error_pattern' 错误(阈值: $threshold)"
echo "[$current_time] [WARNING] $alert_msg" >> $ALERT_LOG
# 提取最近的错误日志样本
echo "错误样本:" >> $ALERT_LOG
grep -i "$error_pattern" "$log_file" | tail -3 >> $ALERT_LOG
echo "" >> $ALERT_LOG
# 发送告警
send_app_alert "WARNING" "应用日志告警" "$alert_msg"
fi
}
# 应用性能指标分析
function analyze_app_performance() {
local app_name=$1
local log_file=$2
local current_time=$(date +"%Y-%m-%d %H:%M:%S")
if [ ! -f "$log_file" ]; then
return
fi
# 分析响应时间(假设日志中包含响应时间信息)
local avg_response_time=$(awk '
/response_time/ {
match($0, /response_time[=:]([0-9.]+)/, arr)
if (arr[1] != "") {
sum += arr[1]
count++
}
} END {
if (count > 0) print sum/count
else print 0
}' "$log_file")
# 生成性能指标
echo "# HELP app_response_time_seconds Average response time in seconds" >> $METRICS_FILE.tmp
echo "# TYPE app_response_time_seconds gauge" >> $METRICS_FILE.tmp
echo "app_response_time_seconds{app=\"$app_name\"} $avg_response_time" >> $METRICS_FILE.tmp
# 分析请求量
local request_count=$(grep -c "request" "$log_file" 2>/dev/null || echo 0)
echo "# HELP app_requests_total Total number of requests" >> $METRICS_FILE.tmp
echo "# TYPE app_requests_total counter" >> $METRICS_FILE.tmp
echo "app_requests_total{app=\"$app_name\"} $request_count" >> $METRICS_FILE.tmp
}
# 日志轮转检查
function check_log_rotation() {
local current_time=$(date +"%Y-%m-%d %H:%M:%S")
# 检查大文件
find /var/log -name "*.log" -size +100M 2>/dev/null | while read large_file; do
local file_size=$(du -h "$large_file" | cut -f1)
echo "[$current_time] [WARNING] 发现大日志文件: $large_file ($file_size)" >> $ALERT_LOG
done
# 检查磁盘空间
local log_disk_usage=$(df /var/log | awk 'NR==2 {gsub(/%/, "", $5); print $5}')
if [ $log_disk_usage -gt 80 ]; then
echo "[$current_time] [WARNING] 日志分区磁盘使用率过高: ${log_disk_usage}%" >> $ALERT_LOG
send_app_alert "WARNING" "