Linux/Unix shell 监控Oracle告警日志
在Oracle数据库管理中,告警日志(Alert Log)是最重要的诊断工具之一。它记录了数据库实例的关键事件、错误信息、警告以及重要的操作记录。对于DBA来说,实时监控告警日志可以帮助及时发现并解决潜在问题。
本文将介绍如何使用Linux/Unix shell脚本监控Oracle告警日志文件,包括检测新出现的错误、发送邮件通知等功能。
1. Oracle告警日志简介
Oracle告警日志通常位于以下位置:
- $ORACLE_BASE/diag/rdbms/<db_name>/<instance_name>/trace/alert_<instance_name>.log
- 或通过SQL查询获取:SELECT value FROM v$diag_info WHERE name = 'Diag Trace';
告警日志包含的重要信息:
- 数据库启动和关闭事件
- 内部错误(ORA-错误)
- 块损坏错误
- 死锁信息
- 备份和恢复操作
- 空间管理问题
2. 监控脚本设计思路
监控脚本需要实现以下功能:
- 定期检查告警日志文件的新增内容
- 识别包含ORA-错误或其他关键信息的行
- 过滤掉已经处理过的错误信息
- 将新发现的错误通过邮件发送给DBA
- 记录监控日志以便后续审计
3. 完整监控脚本实现
以下是一个功能完整的shell脚本,用于监控Oracle告警日志:
#!/bin/bash
# Oracle告警日志监控脚本
# 作者: DBA Team
# 版本: 1.0
# 描述: 监控Oracle告警日志中的新错误并发送邮件通知
# 设置环境变量
export ORACLE_SID=orcl
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
# 配置参数
ALERT_LOG_FILE=/u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log
STATE_FILE=/tmp/oracle_alert_monitor.state
MAIL_TO="dba_team@ipipp.com"
MAIL_FROM="oracle_monitor@ipipp.com"
LOG_FILE=/var/log/oracle_alert_monitor.log
# 函数:记录日志
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}
# 函数:发送邮件
send_mail() {
local subject="$1"
local content="$2"
# 使用mailx发送邮件
echo "$content" | mailx -s "$subject" -r "$MAIL_FROM" "$MAIL_TO"
# 或者使用sendmail
# (
# echo "To: $MAIL_TO"
# echo "From: $MAIL_FROM"
# echo "Subject: $subject"
# echo ""
# echo "$content"
# ) | sendmail -t
}
# 函数:检查告警日志
check_alert_log() {
# 检查告警日志文件是否存在
if [ ! -f "$ALERT_LOG_FILE" ]; then
log_message "错误: 告警日志文件不存在: $ALERT_LOG_FILE"
return 1
fi
# 获取文件inode和修改时间,用于检测日志轮转
local current_inode=$(ls -i "$ALERT_LOG_FILE" | awk '{print $1}')
local current_mtime=$(stat -c %Y "$ALERT_LOG_FILE")
# 读取上次的状态
if [ -f "$STATE_FILE" ]; then
source "$STATE_FILE"
else
LAST_INODE=0
LAST_MTIME=0
LAST_POSITION=0
fi
# 检查日志是否发生轮转
if [ "$current_inode" != "$LAST_INODE" ] || [ "$current_mtime" -lt "$LAST_MTIME" ]; then
log_message "检测到日志轮转,重置读取位置"
LAST_POSITION=0
fi
# 获取文件当前大小
local current_size=$(wc -c < "$ALERT_LOG_FILE")
# 如果文件大小小于上次位置,说明发生了截断
if [ "$current_size" -lt "$LAST_POSITION" ]; then
log_message "检测到日志截断,重置读取位置"
LAST_POSITION=0
fi
# 如果没有新内容,直接返回
if [ "$current_size" -eq "$LAST_POSITION" ]; then
log_message "没有新的日志内容"
return 0
fi
# 提取新增的日志内容
local new_content=$(tail -c +$((LAST_POSITION + 1)) "$ALERT_LOG_FILE")
# 更新状态
LAST_POSITION=$current_size
LAST_INODE=$current_inode
LAST_MTIME=$current_mtime
# 保存状态到文件
cat > "$STATE_FILE" << EOF
LAST_INODE=$LAST_INODE
LAST_MTIME=$LAST_MTIME
LAST_POSITION=$LAST_POSITION
EOF
# 检查是否有ORA-错误或其他关键信息
if echo "$new_content" | grep -q -E "(ORA-|Error|Warning|Critical)"; then
log_message "发现新的错误或警告信息"
# 提取包含错误的行
local error_lines=$(echo "$new_content" | grep -E "(ORA-|Error|Warning|Critical)")
# 构建邮件内容
local mail_subject="Oracle告警日志 - 发现新的错误或警告"
local mail_content="在Oracle告警日志中发现新的错误或警告信息:\n\n"
mail_content+="数据库实例: $ORACLE_SID\n"
mail_content+="时间: $(date)\n"
mail_content+="告警日志文件: $ALERT_LOG_FILE\n\n"
mail_content+="错误信息:\n$error_lines\n"
# 发送邮件
send_mail "$mail_subject" "$mail_content"
# 记录到日志
log_message "已发送邮件通知: $mail_subject"
else
log_message "未发现新的错误或警告信息"
fi
}
# 主程序
main() {
log_message "开始监控Oracle告警日志"
# 检查必要的命令是否存在
if ! command -v mailx &> /dev/null && ! command -v sendmail &> /dev/null; then
log_message "错误: mailx 或 sendmail 命令未找到"
exit 1
fi
check_alert_log
log_message "监控完成"
}
# 执行主程序
main "$@"4. 脚本功能详解
4.1 状态管理
脚本使用状态文件(state file)来记录上次读取的位置,避免重复处理相同的日志内容。状态文件包含:
- 文件的inode号
- 文件的修改时间
- 上次读取的位置
4.2 日志轮转处理
脚本能够检测告警日志的轮转情况:
- 通过比较inode号判断文件是否被替换
- 通过比较修改时间判断文件是否被轮转
- 当检测到轮转时,重置读取位置
4.3 错误检测
脚本使用正则表达式匹配包含以下关键词的行:
- ORA-(Oracle错误代码)
- Error
- Warning
- Critical
4.4 邮件通知
脚本支持两种邮件发送方式:
- mailx命令(推荐)
- sendmail命令
5. 部署和使用
5.1 设置定时任务
将脚本添加到crontab中定期执行:
# 每5分钟检查一次告警日志 */5 * * * * /path/to/oracle_alert_monitor.sh # 或者每小时检查一次 0 * * * * /path/to/oracle_alert_monitor.sh
5.2 配置参数调整
根据实际环境修改脚本中的配置参数:
- ORACLE_SID:数据库实例名
- ORACLE_HOME:Oracle安装目录
- ALERT_LOG_FILE:告警日志文件路径
- MAIL_TO:接收通知的邮箱地址
- MAIL_FROM:发送通知的邮箱地址
5.3 权限设置
确保脚本有执行权限:
chmod +x oracle_alert_monitor.sh
6. 高级功能扩展
6.1 过滤特定错误
可以修改错误检测逻辑,只关注特定的错误代码:
# 只监控特定的ORA-错误 if echo "$new_content" | grep -q -E "(ORA-00600|ORA-07445|ORA-04031)"; then # 处理严重错误 fi
6.2 集成到监控系统
可以将脚本集成到Nagios、Zabbix等监控系统中:
# 返回适当的退出码供监控系统使用 if [ $ERROR_COUNT -gt 0 ]; then exit 2 # Critical elif [ $WARNING_COUNT -gt 0 ]; then exit 1 # Warning else exit 0 # OK fi
6.3 日志分析增强
可以添加更复杂的日志分析功能:
- 统计错误发生的频率
- 关联多个相关的错误事件
- 生成趋势报告
7. 故障排除
7.1 常见问题
- 脚本无法找到告警日志文件:检查ALERT_LOG_FILE路径是否正确
- 邮件发送失败:检查mailx或sendmail配置,确保SMTP服务可用
- 权限不足:确保运行脚本的用户有权限读取告警日志文件
7.2 调试技巧
可以通过增加日志详细程度来调试脚本:
# 在脚本开头添加 set -x # 启用调试模式 # 或者在关键位置添加详细的日志输出 log_message "调试信息: current_size=$current_size, last_position=$LAST_POSITION"
8. 总结
通过本文介绍的shell脚本,DBA可以实现对Oracle告警日志的自动化监控,及时发现数据库问题。该脚本具有以下优点:
- 轻量级,无需额外安装软件
- 易于部署和维护
- 可灵活配置监控参数
- 支持邮件通知
- 具备日志轮转处理能力
根据实际需求,可以进一步扩展脚本功能,如添加短信通知、集成到监控平台、实现自动故障恢复等,从而构建更完善的数据库监控体系。