由于程序设计不合理或者瞬间高并发访问时,很有可能会触发OOM(Out of memory),这里指的是操作系统级别的OOM。具体什么是OOM,以及怎样发生这里不在赘述,因为笔者认为这是IT从业工作者的基本常识了。本篇主要记录一下生产环境时对发生OOM的程序进行监控,便于我们及时发现以及事后问题的复盘。

在做这个监控时,笔者也做了很多考察搜索,幻想着会有那么一两个成熟的开源软件能实现这个监控,事与愿违,笔者并未找到这样的工具,无奈之下,只好自己动手实现了一个略显粗糙的程序来达到我的目的。

实现思路:

    Apr 18 12:11:25 php001 kernel: Out of memory: Kill process 13546 (php-fpm) score 31 or sacrifice child

系统每次触发OOM时会在/var/log/message文件下记下当时系统的运行状况,以及被杀程序的pid和评分。因此笔者从此文件入手,写下了这样一个脚本。

1、目录结构如下:
oom_monitor位于共享存储NFS上,生产环境的机器都挂载了该NFS,因此所有机器上都会有这么一个目录 [admin@prod.001:/mnt/alinas]$ tree -L 1 oom_monitor/
oom_monitor/
├── bin #存放可执行的脚本文件
└── log #存放日志文件 [admin@prod.001:/mnt/alinas]$ tree -L 1 oom_monitor/bin/
oom_monitor/bin/
├── oom_check.sh #过滤"Out of memory"从/var/log/message,并生成对应文件保存在log目录下,用于后面的发送警报
├── oom_dingding.py #发送OOM对应信息到钉钉群
├── oom_mail.py #发送OOM对应信息到邮箱
└── oom_send.sh #用于触发发送报警信息到钉钉和邮箱

2、具体内容如下:

[admin@prod.001:/mnt/nfs/oom_monitor/bin]$ cat oom_check.sh
#!/bin/sh
#获取主机名
host_name=`hostname` #定义获取到的OOM日志存储位置
oom_scrape_file=/mnt/nfs/oom_monitor/log/oom_scrape_$host_name #定义上次发生OOM时的对应信息,用于去重,防止重复报警
old_oom_scrape_file=/mnt/nfs/oom_monitor/log/old_oom_scrape_$host_name #获取OOM报警信息
msg=$(sudo grep -i "out of memory" /var/log/messages|awk 'END {print}') #获取报警产生的时间
time=`echo $msg | awk '{print $3}'` #获取被杀的程序类型(java/php/mysql/...)
killed=`echo $msg | awk 'END {print $12}'` #获取上次OOM的信息
old_msg=`cat $old_oom_scrape_file` #判断两次信息是否相同,相同则不再记录此次信息,防止重复报警
if [ "$msg" == "$old_msg" ];then
exit 1
else #如果两次报警信息不相同则把这次获取的信息覆盖上次的信息
[ ! -z "$msg" ] && echo "$msg" > $old_oom_scrape_file
fi #记录此次信息持久化到文件
if [ ! -z "$msg" ];then
echo > $oom_scrape_file
echo -e "发生时间: $time" >> $oom_scrape_file
echo -e "日志信息: $msg" >> $oom_scrape_file
echo -e "被杀程序: $killed" >> $oom_scrape_file
echo -e "发生主机: $host_name" >> $oom_scrape_file
fi [admin@prod.001:/mnt/nfs/oom_monitor/bin]$ cat oom_send.sh
#!/bin/sh #定义获取到的OOM日志存储位置、OOM发送报警脚本位置
#这里用*的原因是:机器很多,每台机器一个文件,所以用*
oom_scrape_file=/mnt/nfs/oom_monitor/log/oom_scrape*
oom_warn_script=/mnt/nfs/oom_monitor/bin/oom_mail.py
oom_dingding_script=/mnt/nfs/oom_monitor/bin/oom_dingding.py
History_file=/mnt/nfs/oom_monitor/log/history_oom_scrape
basedir=/mnt/nfs/oom_monitor/log/
cd $basedir
for file in `ls $oom_scrape_file`
do
hostname=`grep "发生主机" $file|awk '{print $2}'`
warn_time=`grep "发生时间" $file |awk '{print $2}'`
killed=`grep "被杀程序" $file |awk '{print $2}'` #发送邮件报警,把日志信息全部发出去
/usr/local/bin/python3 $oom_warn_script $file #发送钉钉报警
/usr/local/bin/python3 $oom_dingding_script $hostname $killed $warn_time #报警信息发出后把日志信息追加到历史信息文件中,然后删除对应的oom信息文件,防止重复报警
cat $file >> $History_file && mv $file /tmp
done [admin@prod.001:/mnt/nfs/oom_monitor/bin]$ cat oom_mail.py
#!/usr/bin/env python3
'''
当收到系统OOM时,触发脚本发出邮件报警信息,信息格式如下: 您的主机「hostname」发生OOM,具体信息如下:
/var/log/message中的信息 '''
import os
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import time
import sys
def send_email(file_name):
try: # 读取测试报告中的内容作为邮件的内容
with open(file_name, 'r', encoding='utf8') as f:
mail_body = f.read() # 发件人地址
send_addr = '此处替换为发件人的邮箱用户名' # 收件人地址
reciver_addr = ['接收人a的邮箱地址','接收人b的邮箱地址',] # 发送邮箱的服务器地址,这里用的是阿里云的
mail_server = 'smtp.mxhichina.com'
now = time.strftime("%Y-%m-%d %H:%M:%S") # 邮件标题
subject = '[OOM报警触发]' + now # 发件人的邮箱及邮箱密码
username = '此处替换为发件人的邮箱用户名'
password = '此处替换为发件人的邮箱密码' # 邮箱的内容和标题
message = MIMEText(mail_body, 'html', 'utf8')
message['From'] = send_addr
message['To'] = ','.join(reciver_addr)
message['Subject'] = Header(subject, charset='utf8') # 发送邮件,使用的使smtp协议
smtp = smtplib.SMTP() #端口注意下,通常服务器的25端口是关闭的,所以我这里用了80、或者465也阔以
smtp.connect(mail_server,80)
smtp.login(username, password)
smtp.sendmail(send_addr, message['To'].split(','), message.as_string())
smtp.quit()
print("邮件发送成功!")
except:
print("发送邮件失败!") send_email(file_name=sys.argv[-1]) [admin@prod.001:/mnt/nfs/oom_monitor/bin]$ cat oom_dingding.py
#!/usr/bin/env python3
import json
import requests
import datetime
import sys
def sendmessage(hostname,killed,warn_time):
now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') #替换成你自己的钉钉群的webhook
url = 'https://oapi.dingtalk.com/robot/send?access_token=917b00b5faee51bcb67e862c13b0a0ff605f0f74f4f692c9a70fe32351' HEADERS = {
"Content-Type": "application/json;charset=utf-8"
}
message='''
【OOM报警触发】:
报警主机:%s
被杀进程:%s
报警时间:%s
''' %(hostname,killed,warn_time)
String_textMsg = {
"msgtype": "text",
"text": {"content": message},
"at": {
"atMobiles": [
"110120119" # 如果需要@某人,这里写他的手机号
],
"isAtAll": 0 # 如果需要@所有人,这些写1
}
}
String_textMsg = json.dumps(String_textMsg)
res = requests.post(url, data=String_textMsg, headers=HEADERS)
print(res.text)
sendmessage(sys.argv[-3],sys.argv[-2],sys.argv[-1])

3、结果演示:

CentOS 配置OOM监控报警的更多相关文章

  1. 总zabbix配置-搭建-邮件报警-微信报警-监控mysql

    Centos7安装Zabbix4.0步骤 官方搭建zabbix4.0的环境要求: 1. 环境搭建LAMP 前提Centos系统安装完成:  确认一下: 1 2 cat /etc/redhat-rele ...

  2. 基于ELK 7.50搭建elastalert 监控报警和权限控制

    ELK+监控报警全步骤 需求: 公司要求对出在windows服务器上的日志进行日志分析并根据关键字进行报警,并配置kibana权限控制.下面为详细步骤 环境: centos 7.6 elk版本7.50 ...

  3. SQL Server监控报警架构_如何添加报警

    一.数据库邮件报警介绍 数据库邮件是从SQL Server数据库引擎发送电子邮件企业解决方案,使用简单传输协议(SMTP)发送邮件.发送邮件进程与数据库的进程隔离,因此可不用担心影响数据库服务器. 数 ...

  4. Windows Azure功能更新:弹性伸缩(autoscale)、监控报警、移动服务及网站服务商用、新的虚拟机镜像

    Windows Azure功能又更新了.此次更新包括1项重要更新和两个功能更新: 重要更新:云服务.网站支持按策略进行弹性伸缩 功能更新:两个预览版的服务(网站和移动)进入商用,虚拟机服务支持SQL ...

  5. Python-WXPY实现微信监控报警

    概述: 本文主要分享一下博主在学习wxpy 的过程中开发的一个小程序.博主在最近有一个监控报警的需求需要完成,然后刚好在学习wxpy 这个东西,因此很巧妙的将工作和学习联系在一起. 博文中主要使用到的 ...

  6. Zabbix配置邮件监控

    zabbix服务端配置 安装软件并配置 使用第三方邮件实现报警 1. 安装软件 $ yum -y install mailx 2. 配置发送邮件账号密码和服务器 $ vim /etc/mail.rc ...

  7. Kubernetes集群的监控报警策略最佳实践

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79652064 本文为Kub ...

  8. (转)Nagios 配置及监控

    Nagios 配置及监控 原文:http://blog.csdn.net/linuxlsq/article/details/52606824 Nagios 监控 在互联网日益发展的今天,监控的重要性已 ...

  9. Ganglia与Centreon整合构建智能化监控报警平台

    一.智能运维监控报警平台的组成 随着大数据时代的来临,运维工作的难度越来越大,每个运维人员都要面临不计其数的服务器和海量的数据,如何保证众多服务器和业务系统稳定高效地运行并尽量减少死机时间,成为考核运 ...

随机推荐

  1. search(3)- elastic4s-QueryDSL

    elastic4s是elasticsearch一个第三方开发的scala语言终端工具库(Elastic4s is a concise, idiomatic, reactive, type safe S ...

  2. HBU-数据库第五周作业

    第五周数据库作业 注意 MySQL的数据库名.表名.列名.别名大小写规则是这样的: 1.数据库名与表名是严格区分大小写的: 2.表的别名是严格区分大小写的: 3.列名与列的别名在所有的情况下均是忽略大 ...

  3. POJ1270 toposort+DFS+回溯

    题目链接:http://poj.org/problem?id=1270 这道题其实就是求所有满足条件的topo序,我们考虑到给定的字符是确定的,也就是他们的长度都是一样的,所以为了得到所有的情况,我们 ...

  4. 关于手机淘宝3.25bug我的一些思考与建议

    这两天被手淘ios版3.25bug刷屏了,影响还是挺大的,仅3.25日当天截止到下午5点在微博上的话题阅读量,已经突破8000万.给广大网友带来一次吃瓜盛宴.我们先简单回顾下这个bug的故事线: 我查 ...

  5. 【2019南昌网络赛】B-Fire-Fighting Hero

    题目链接 分析 英雄方面很简单,跑一遍 Dijkstra 就行了,但是灭火团队就有点麻烦了. 这里可以借助一下最大流的建边来解决这个问题: 我们可以另外找一个点作为起点,然后建立从那个点到每一个团队的 ...

  6. win 7 系统过期处理办法

    超级尴尬,刚装的win7 系统居然过期了.下次再也不装盗版了,吼吼吼 处理方法就是下载oem7F7 软件安装,不用再怎么操作就好了. 就是这么简单,并不用像网上那样找什么激活码.

  7. 干货|Python基础入门 课程笔记(三)

    目录 列表 元组 字典 三元表达式 一.列表 前面学习的字符串可以用来存储一串信息,那么想一想,如果现在有很多人,总不能每个人都起一个变量名把?那岂不得疯~ 咱们可以使用列表. (1)列表得格式和输出 ...

  8. TensorFlow系列专题(八):七步带你实现RNN循环神经网络小示例

    欢迎大家关注我们的网站和系列教程:http://panchuang.net/ ,学习更多的机器学习.深度学习的知识! [前言]:在前面的内容里,我们已经学习了循环神经网络的基本结构和运算过程,这一小节 ...

  9. php 设置允许跨域请求

    php 服务端代码 <?php header('Content-Type: text/html;charset=utf-8'); header('Access-Control-Allow-Ori ...

  10. python中的函数及作用域的理解

    内置函数 常用的几个内置函数 function des len 求长度 min 求最小值 max 求最大值 sorted 排序 reversed 反向 sum 求和 进制转换函数 function d ...