6月 24

监控mysql从机同步状态脚本1.1

  之前写了个一个检查mysql从机的脚本(http://www.simonzhang.net/?p=1823),但是在使用中发现一个问题。如果数据库被重启了,但是同步的没有启动,此脚本检查还是正常,不会进行报警,数据不会同步。
  我做了个调整,每次检查同步主机的pos,通过crontab进行调用,如果多次都没有变化则进行告警。如果10分钟调用一次,设为3次,就是半个小时内没有更新则报警。
crontab配置如下:
*/10 * * * * /bin/bash /script/check_mysql_slave/check_mysql_slave.sh start >/dev/null 2>&1
部分代码如下:

#!/usr/local/bin/python
# -*- coding:utf-8 -*-
# -------------------------------------------------------------------------------
# Filename:    check_nagios.py
# Revision:    1.1
# Date:        2013-06-24
# Author:      simonzhang
# Email:       simon-zzm@163.com
# -------------------------------------------------------------------------------
import os
import pexpect
import time
import smtplib
from email.mime.text import MIMEText

#### base se
mysql_bin = '/program/mysql5/bin/mysql'
mysql_user = 'checkslavestatus'
mysql_pass = 'xxxxxxxxxx'
#设置错多少次开始告警
max_error = 3
mail_host = 'smtp.exmail.qq.com'
mail_user = 'warning@xxx.net'
mail_pwd = 'xxxxxxxxx'
mail_cc = "simon-zzm@163.com"
####

def mail_warn(error_ip):
    content = 'IP %s mysql slave is error!'%error_ip
    msg = MIMEText(content)
    msg['From'] = mail_user
    msg['Subject'] = 'mysql warnning %s'%error_ip
    msg['To'] = mail_to
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pwd)
        s.sendmail(mail_user,[mail_to],msg.as_string())
        s.close()
    except Exception ,e:
        print e

def main():
    error_context = ''
    #读取上次检查master同步点的记录
    try:
        f = open('MasterPos.txt', 'rb').read()
        try:
            old_master_pos = f.split(':')[0]
            error_count = f.split(':')[1]
        except:
            old_master_pos = 0
            error_count = 0
    except:
        old_master_pos = 0
        error_count = 0
        pass
    # 获得数据库同步状态
    status = os.popen("%s -u%s -p%s -e 'show slave status\G'"%
                      (mysql_bin,mysql_user,mysql_pass)).readlines()
    # 查看同步主节点数据
    for status_l in status:
        if status_l.find('Read_Master_Log_Pos: ') > 0:
            f = open('MasterPos.txt', 'wb')
            # 防止出现空值
            try:
                new_master_pos = int(status_l.split(': ')[1])
            except:
                new_master_pos = 0
            if int(new_master_pos) == int(old_master_pos) or int(old_master_pos):
                f.write('%s:%s' % (new_master_pos, int(error_count)+1))
            else:
                f.write('%s:0' % new_master_pos)
            f.close()
            if int(error_count)+1 > max_error:
                error_context += 'slave error!'
    # 判断是否报警
    print error_context:
    if len(error_context) > 1:
        ip = os.popen("/sbin/ifconfig|grep 'inet addr'|awk '{print $2}'").read()
        get_local_ip = ip[ip.find(':')+1:ip.find('n')]
        mail_warn("%s"%get_local_ip)

if __name__ == "__main__":
    main()

源代码

4月 18

监控mysql从机同步状态脚本

  mysql数据库主从运行。为了知道从机的同步情况,写了个脚本,放在crontab中,如果同步出错,则邮件报警。去年写的,放上来做个备忘。

#!/usr/local/bin/python
# -------------------------------------------------------------------------------
# Filename:    .py
# Revision:    1.0
# Date:        2012-03-20
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
# -------------------------------------------------------------------------------
import os
import pexpect
import time
import smtplib
from email.mime.text import MIMEText

#### base se
mysql_bin = '/mysql5/bin/mysql'
mysql_user = ''
mysql_pass = ''
mail_host = 'smtp.exmail.qq.com'
mail_user = 'XXX@XXX.net'
mail_pwd = 'XXXX'
mail_to = "xxxxx@xxx.com"
####

def mail_warn(error_ip):
    content = 'IP %s mysql slave is error!'%error_ip
    msg = MIMEText(content)
    msg['From'] = mail_user
    msg['Subject'] = 'mysql warnning %s'%error_ip
    msg['To'] = mail_to
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pwd)
        s.sendmail(mail_user,[mail_to],msg.as_string())
        s.close()
    except Exception ,e:
        print e

def main():
    status = os.popen("%s -u%s -p%s -e 'show slave status\G'"%
                      (mysql_bin,mysql_user,mysql_pass)).read() 
    io_status = status[status.find('Slave_IO_Running: ')+18]
    sql_status = status[status.find('Slave_SQL_Running: ')+19]
    if (io_status == 'Y') or (sql_status == 'Y'):
        ip = os.popen("/sbin/ifconfig|grep 'inet addr'|awk '{print $2}'").read()
        get_local_ip = ip[ip.find(':')+1:ip.find('n')]
        mail_warn("%s"%get_local_ip)

if __name__ == "__main__":
    main()
3月 27

不明IP登陆linux服务器时邮件通知

  当有人登陆服务器时希望能知道是那个IP在登陆,如果是黑客登陆了也能及时知道。
  处理方法是,python时时检查linux下 secure 文件,如果是登陆成功的就发邮件。然后用shell脚本调用py启停,然后配置crontab定时检查py是否运行,如果检查进行不在则进行启动。
  python 脚本

#!/bin/python
#-*- coding:utf-8 -*-
# Filename:
# Revision:    1.0
# Date:        2013-3-26
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO
import re
import os
import time

import smtplib
from email.mime.text import MIMEText

#### 基础设置
mail_host = 'smtp.exmail.qq.com'
mail_user = 'warning'
mail_pwd = 'aaa'
mail_to = "simon-zzm@163.com"
mail_cc = "simon-zzm@"
secure_file = '/var/log/secure'
conn_fail_key = 'Failed password'
conn_access_key = 'Accepted password'
exclude_ip = ['192.168.100.8', \
              '192.168.100.10', \
              '192.168.100.11']
my_path = os.getcwd()


####
def mail_send(text):
    content = '%s' % text
    msg = MIMEText(content)
    msg['From'] = mail_user
    msg['Subject'] = 'access login server'
    msg['To'] = mail_to
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user, mail_pwd)
        s.sendmail(mail_user, [mail_to, mail_cc], msg.as_string())
        s.close()
    except Exception, e:
        print e

####
# get local host ip
####
def get_ip_address():
    ip = os.popen("/sbin/ifconfig | grep 'inet addr' | awk '{print $2}'").read()
    ip = ip[ip.find(':')+1:ip.find('\n')]
    return ip

#### 
def parse_secure(_data):
    # 获取IP地址
    re_ip = re.compile(r'''\d{2,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}''',re.DOTALL)
    try:
        get_ip = re_ip.findall(_data)[0]
    except:
        get_ip = ''
    #### 获得关键字位置
    try:
        key_index = _data.index(conn_access_key)
    except:
        key_index = 0
    #### 将正常登陆但不在已知范围的IP获取
    if (get_ip not in exclude_ip) and (get_ip != '') and (key_index > 0):
        return get_ip
    else:
        return ''


def main():
    #### 获取上次分析的最后一行
    try:
        last_line = open('%s/lastline.txt' % my_path, 'rb').readlines()[0][:-1]
    except:
        last_line = ''
    #### 打开安全日志,并记录最后一行
    get_secure = open(secure_file, 'rb').readlines()
    write_line = open('%s/lastline.txt' % my_path, 'wb')
    write_line.write(get_secure[-1])
    write_line.close()
    #### 获取没有处理的数据,如果最后一行为空着处理全部数据。
    if last_line != "":
        last_id = get_secure.index("%s\n" % last_line)
        get_secure = get_secure[last_id + 1:]
    #### 开始处理数据,只处理登陆成功和登陆失败部分数据
    access_login_list = ''
    for _get in get_secure:
        re_get_ip = parse_secure(_get)
        if re_get_ip != '':
            access_login_list += "%s " % re_get_ip
    #### 判断是否需要报警
    if len(access_login_list) > 1:
        mail_send("%s access login %s server" % (access_login_list, get_ip_address())) 


if __name__ == '__main__':
    while True:
        main()
        time.sleep(3)

  shell 脚本

#! /bin/bash
#
# make simon-zzm@163.com
#
#
### END INIT INFO

# Source function library.
. /etc/profile
cd `pwd`
key=monitoring_secure.py
# See how we were called.
case "$1" in
  stop)
     /bin/ps -ef|grep "${key}"|grep -v grep |awk ' ''{print $2}'|xargs kill -9
     ;;
  start)
      /usr/local/bin/python ${key} &
      ;;
  restart)
      stop
      sleep 1
      /usr/local/bin/python ${key} &
      ;;
  check)
      process_count=`/bin/ps -ef|grep "${key}"|grep -v grep|wc -l`
      case "${process_count}" in
          0)
            $0 start
            ;;
          1)
            ;;
          *)
           $0 stop
           sleep 1
           $0 start
           ;;
      esac
      ;;
  status)
      /bin/ps -ef|grep "${key}"|grep -v grep 
      ;;
  *)
        echo $"Usage: $0 {stop|start|restart|check|status}"
        exit 1
esac

exit

  crontab的配置,每8个小时检查一次。
0 */8 * * * /bin/sh /program/script/check_login_user/monitoring_secure.sh check >/dev/null 2>&1
代码下载

12月 06

raspberry pi 开机wifi自动启动并发邮件通知

  安装好USB的wifi模块,自动获取IP地址。获取到IP后邮件通知。这样每次重启就不用再连显示器了。

以下几个的安装是为了方便使用与本次无关。
安装vim
$ sudo apt-get install vim
将时区改为上海
$ sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
安装校时工具
$ sudo apt-get install ntpdate
通过网络同步时间
$ /usr/sbin/ntpdate stdtime.gov.hk

  把USB的wifi接口接好。
  我接了一个腾达W311M的wifi无线,用命令看到无线网卡已经加载。如下:
$ lsusb
Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
image

  然后可以在图形化界面中wpa_gui配置。如果使用命令行可以用wpa_cli。我是直接修改配置文件。我的配置文件如下:

无线配置文件位置/etc/wpa_supplicant/wpa_supplicant.conf
文件内容如下:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=0

network={
ssid=”simonzhang”
psk=”xxxxxxx”
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}

网络部分配置/etc/network/interface
文件内容如下:
auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

  配置完毕,将启动后发送邮件的脚本放到家目录中,脚本如下,如果邮件服务器认证不严的话用sendmail会更简单:

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Filename:   
# Revision:
# Date:        2012-12-5
# Author:      simonzhang
# Email:       simon-zzm@163.com
# Web:         www.simonzhang.net
# -------------------------------
import os
import time
import socket
import fcntl
import struct
import smtplib
from email.mime.text import MIMEText


mail_host = 'smtp.exmail.qq.com'
mail_user = 'xxxxxxx'
mail_pwd = 'xxxxxxx'

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
         )[20:24])
    except IOError, e:
        return e

 
def mail_send(content, mailto, get_sub):
    msg = MIMEText(content.encode('utf8'), _subtype='html',  _charset='utf8')
    msg['From'] = mail_user
    msg['Subject'] = u'%s' % get_sub
    msg['To'] = mailto
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pwd)
        s.sendmail(mail_user,[mailto],msg.as_string())
        s.close()
        send = "OK"
    except Exception ,e:
        send = "ERROR! %s" % e
    return send


def main():
    _count_loop = 0
    while 1:
        ip_list = []
        if _count_loop == 0:
            os.system('sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf')
            time.sleep(0.5)
            os.system('sudo dhclient wlan0')
        try:
            ip_list.append(get_ip_address('eth0'))
        except:
            pass
        try:
            ip_list.append(get_ip_address('wlan0'))
        except Except,e:
            pass
        _get_send_status =  mail_send('my pi ip', 'simon-zzm@163.com', '%s' % ip_list)
        _count_loop +=1
        if (_get_send_status == "OK") or (_count_loop == 3):
            break
        time.sleep(3)

if __name__ == "__main__":
    main()

NotificationIP脚本

  脚本测试通过,配置开机启动。

$ sudo vim /etc/rc.local

# Print the IP address
_IP=$(hostname -I) || true
if [ “$_IP” ]; then
printf “My IP address is %s\n” “$_IP”
fi
# start wifi
echo “Starting WiFi…”
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
sleep .5s
dhclient wlan0
echo “WiFi should be started”

# notification my ip
python /home/pi/script/NotificationIP.py

exit 0

失败经验总结:
1)之前是用的下面代码,但是在除掉网线后路由里的默认网关没有,用“sudo route add default gw 192.168.1.1”添加,如果有网线只是报有一个ip。
def get_local_ip_address():
ipaddr = ”
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((‘1.1.1.1’, 8000))
ipaddr = s.getsockname()[0]
s.close()
except:
ipaddr = “ERROR”
return ipaddr

2)系统应该不支持热插拔,每次查usb wifi时都会重启。

3)不知道是电力原因,还是USB wifi原因,连接质量很不好,容易断开。

参考文档:
http://stinebaugh.info/auto-start-your-wifi-on-raspberry-pi/

11月 13

python 通过邮件服务器发送 邮件

很早写的,本来觉得意义不大,还是放上来,以备丢了。python2.6下发送通过。

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------------------------------------------------------
# Filename:    sendmail.py
# Revision:    1.0
# Date:        2012-7-18
# Author:      simonzhang
# Email:       simon-zzm@163.com
# Web:         www.simonzhang.net
# -------------------------------------------------------------------------------
import smtplib
from email.mime.text import MIMEText

#
mail_host = 'smtp.exmail.qq.com'
mail_user = 'XXXXXXXX'
mail_pwd = 'XXXXXXXXX'

def mail_send(content, mailto, get_sub):
    msg = MIMEText(content.encode('utf8'), _subtype='html',  _charset='utf8')
    msg['From'] = mail_user
    msg['Subject'] = u'%s' % get_sub
    msg['To'] = mailto
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pwd)
        s.sendmail(mail_user,[mailto],msg.as_string())
        s.close()
    except Exception ,e:
        print e