keeping.py

 定时push+告警

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author         : 71standby@gmail.com
# Description    : Keep static-file cached in local, which provide to partner upstream.

import re
import json
import time
import socket
import logging
import urllib
import urllib2
import subprocess


class Utils(object):
    def __init__(self, logger):
        self.logger = logger

    @classmethod
    def from_logger(cls):
        logger = logging.getLogger(__name__)
        logger.setLevel(logging.INFO)
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        handler = logging.FileHandler("/path/keeping.log", mode='a')
        handler.setLevel(logging.INFO)
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        return cls(logger)

    def subprocess_caller(self, cmd):
        try:
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            output, error = p.communicate()
            code = p.returncode
        except Exception, e:
            self.logging.error('Execute %s failed: %s' % (cmd, e))
            return dict(output=output, error=error, code=1)
        return dict(output=output, error=error, code=code)

    def get_local_ip(self):
        inner_ips = []
        outer_ips = []
        ipaddr = "/sbin/ip addr | grep inet | grep -v inet6 | grep -v 127.0.0.1 | awk -F[' '/]+ '{print $3}'"
        ip_regex = re.compile(r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
        p = self.subprocess_caller(ipaddr)
        if 0 == p['code']:
            for ip in [ips.strip() for ips in p['output'].split('\n') if ips]:
                if ip_regex.match(ip) and ip.startswith(r'10.'):
                    inner_ips.append(ip)
                elif ip_regex.match(ip):
                    outer_ips.append(ip)
                else:
                    continue
            if inner_ips and outer_ips:
                return inner_ips[0],outer_ips[0]
            elif not inner_ips and outer_ips:
                return None,outer_ips[0]
            else:
                return None,'NoPublicIP'
        else:
            self.logging.error('Get ips failed: %s' % p['error'])
            return None,None

class PartnerDetection(object):
    def __init__(self, utils):
        self.logger = utils.logger
        self.private_ip,self.public_ip = utils.get_local_ip()
        self.subprocess_caller = utils.subprocess_caller
        self.url = "http://%s:80/path/test.file" % self.public_ip
        self.cmd = "dd if=/dev/zero of=/data/test.file bs=1K count=100"
        self.alarm_url = 'http://alert.standby.pub/event/interface/'
        self.topic_id = 666666
        self.secret_key = "1234567890xxxooo"
    
    @classmethod
    def from_subprocess(cls, utils):
        return cls(utils)

    def send_alarm(self, bodyDict):
        data = {
            "topic_id": self.topic_id,
            "secret_key": self.secret_key,
            "data": json.dumps(bodyDict)
        }
        try:
            data = urllib.urlencode(data)
            req = urllib2.Request(self.alarm_url, data)
            response = urllib2.urlopen(req, timeout=6)
            result = response.read()
            code = response.getcode()
            response.close()
        except Exception, e:
            self.logger.error("Alarm exception: %s" % e)
            return False
        else:
            if 200 != code:
                self.logger.error("Alarm faild: %s" % code)
                return False
        return True

    def active_cache(self):
        p = self.subprocess_caller(self.cmd)
        if 0 != p['code']:
            self.logger.error('Test file create failed: %s' %  p['error'])
            ret = self.send_alarm({'ip':self.private_ip, 'error':'test.file create failed'})
            if not ret:
                self.logger.error('Test file create alarm faile!!!')
        else:
            with open("/data/test.file", mode='r') as fr:
                data = fr.read()
            self.tspush(data)
    
    def tspush(self, data):
        response = "HTTP/1.1 200 OK\r\nContent-type:application/octet-stream\r\n\r\n"
        len_push = len(response) + len(data)
        push = "PUSH %s HTTP/1.0\r\nContent-Length:%d\r\n\r\n%s" % (self.url, len_push, response)
        push_bytes = push.encode('utf-8')
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect(('127.0.0.1', 55336))
            sock.send(push_bytes + data)
            msg = sock.recv(1024)
            if "200 OK" in msg or "201 Created" in msg:
                self.logger.info('Tspush successfully: %s' % msg.split('\r\n')[0])
            else:
                self.logger.error('Tspush failed: %s' % msg)
                ret = self.send_alarm({'ip':self.private_ip, 'error':'Tspush failed: %s' % msg})
                if not ret:
                    self.logger.error('Tspush alarm faile!!!')
        except Exception, e:
            self.logger.error('Tspush exception: %s' % e)
            ret = self.send_alarm({'ip':self.private_ip, 'error':'Tspush exception: %s' % e})
            if not ret:
                self.logger.error('Tspush exception alarm faile!!!')
        finally:
            sock.close()
    
    def url_test(self):
        try:
            response = urllib2.urlopen(url=self.url, timeout=6)
            code = response.getcode()
            data = response.read()
            response.close()
        except Exception, e:
            self.logger.error('Detect failed: %s' % e)
            code = 199
        finally:
            return code

    def running(self):
        while True:
            code = self.url_test()
            if 200 != code:
                self.logger.info("MISS, start to active cache...")
                ret = self.send_alarm({'ip':self.private_ip, 'error':'MISS at %s' % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())})
                if not ret:
                    self.logger.error('MISS alarm faile!!!')
                self.active_cache()
            else:
                self.logger.info("HIT")
            time.sleep(60)

if __name__ == '__main__':
    utils = Utils.from_logger()
    obj = PartnerDetection.from_subprocess(utils)
    obj.running()

  

posted @ 2018-03-02 11:53  lixin[at]hitwh  阅读(173)  评论(0编辑  收藏  举报