123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- from __future__ import division
- import redis
- import time
- import psutil
- import socket
- import pymongo
- from pymongo import MongoClient
- redis_report_ip = '192.168.4.94'
- redis_report_port = 6379
- mongodb_stats = "mongodb://192.168.4.97:27017"
- mongodb_info = "mongodb://192.168.4.98:27017"
- class DockerStats(object):
- def __init__(self, redis_report_ip, redis_report_port, redis_port, container):
- # self.cli = Client(base_url='tcp://%s:2375' % docker_ip)
- self.cli = Client(base_url='unix://var/run/docker.sock')
- self.redis_report_ip = redis_report_ip
- self.redis_report_port = redis_report_port
- self.redis_port = redis_port
- self.container = container
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- s.connect(('192.168.4.254', 0))
- self.host = s.getsockname()[0]
- @property
- def container_stat(self):
- self.stats_obj = self.cli.stats(self.container, stream=False)
- return self.stats_obj
- @property
- def docker_conns(self):
- for conn in psutil.net_connections():
- try:
- if conn[3][1] == self.redis_port:
- redis_pid = conn[-1]
- break
- except:
- pass
- redis_ins = psutil.Process(redis_pid)
- return len(redis_ins.connections())
- def redis_info(self):
- r = redis.StrictRedis(host=self.host, port=self.redis_port, db=0)
- info = r.info()
- redis_key = '%s:%s' % (self.host, self.redis_port)
- info['time'] = int(time.time())
- return redis_key, info
- def write_redis(self):
- r = redis.StrictRedis(host=self.redis_report_ip, port=self.redis_report_port, db=0)
- now_result = self.container_stat # Dict
- memory_usage = now_result["memory_stats"]["usage"]
- ##pid connections###
- cpuPercent = 0.0
- TotalUsage = now_result["cpu_stats"]["cpu_usage"]["total_usage"]
- SystemUsage = now_result["cpu_stats"]["system_cpu_usage"]
- previous = '%s:%s:%s' % (self.host, self.redis_port, 'previous')
- get_previous = r.hget('redis_stats_docker', previous)
- if not get_previous:
- r.hset('redis_stats_docker', previous, [TotalUsage, SystemUsage])
- else:
- previousCPU, previousSystem = eval(r.hget('redis_stats_docker', previous))
- cpuDelta = TotalUsage - previousCPU
- systemDelta = SystemUsage - previousSystem
- r.hset('redis_stats_docker', previous, [TotalUsage, SystemUsage])
- cpuPercent = '%.2f' % (
- (cpuDelta / systemDelta) * len(self.stats_obj["cpu_stats"]["cpu_usage"]["percpu_usage"]) * 100.0)
- ######################################{'conns': 33, 'cpu_usage': '1.20', 'mem_usage': 2788642816}
- redis_key = '%s:%s' % (self.host, self.redis_port)
- redis_value = {'conns': self.docker_conns,
- 'cpu_usage': cpuPercent,
- 'mem_usage': memory_usage,
- 'time': int(time.time())
- }
- r.hset('redis_stats', redis_key, redis_value)
- return redis_key, redis_value
- class RedisStats(object):
- def __init__(self, redis_report_ip, redis_report_port, psinfo):
- self.redis_report_ip = redis_report_ip
- self.redis_report_port = redis_report_port
- self.redis = psinfo
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- s.connect(('192.168.4.254', 0))
- self.host = s.getsockname()[0]
- @property
- def cpu_usage(self):
- self.cpu = '%.2f' % self.redis.cpu_percent(interval=0.8)
- return self.cpu
- @property
- def mem_usage(self):
- self.memory = self.redis.memory_info().rss
- return self.memory
- @property
- def conns(self):
- self.connections = self.redis.connections()
- return self.connections
- @property
- def get_redis_port(self):
- self.conns
- for conn in self.connections:
- if conn.status == 'LISTEN':
- self.port = conn.laddr[1]
- return self.port
- def redis_info(self):
- self.port = self.get_redis_port
- r = redis.StrictRedis(host=self.host, port=self.port, db=0)
- info = r.info()
- redis_key = '%s:%s' % (self.host, self.port)
- info['time'] = int(time.time())
- return redis_key, info
- def write_redis(self):
- self.cpu_usage
- self.mem_usage
- self.conns
- self.get_redis_port
- r = redis.StrictRedis(host=self.redis_report_ip, port=self.redis_report_port, db=0)
- key = '%s:%s' % (self.host, self.port)
- value = {'cpu_usage': self.cpu,
- 'mem_usage': self.memory,
- 'conns': len(self.connections),
- 'time': int(time.time())
- }
- r.hset('redis_stats', key, value)
- return key, value
- def get_container():
- contianers = []
- cli = Client(base_url='unix://var/run/docker.sock')
- for contianer in cli.containers():
- try:
- if contianer['State'] == 'running' and 'dyredis' in contianer['Image']:
- contianers.append(contianer['Names'][0][1:])
- except:
- pass
- return contianers
- def get_instance_ps():
- pslist = []
- ps = psutil.process_iter()
- for psinfo in ps:
- if psinfo.name() == 'redis-server':
- pslist.append(psutil.Process(psinfo.pid))
- return pslist
- def write_mongodb(redis_key, redis_value, type, isindex):
- if type == 'stats':
- client = MongoClient(mongodb_stats)
- elif type == 'info':
- client = MongoClient(mongodb_info)
- dbname = 'redis_stats' + str(redis_value['time'] // (60 * 60 * 24 * 30))
- collection_name = 'info' + str(redis_value['time'] // (60 * 60 * 24))
- redis_value.update({'instance': redis_key})
- json_data = redis_value
- db = eval('%s.%s' % ("client", dbname))
- collection = eval('%s.%s' % ("db", collection_name))
- if isindex:
- if "instance_1" in collection.index_information().keys():
- collection.ensure_index([("instance", pymongo.ASCENDING)])
- if "time_1" in collection.index_information().keys():
- collection.ensure_index([("time", pymongo.ASCENDING)])
- collection.insert_one(json_data)
- return collection_name
- def run(redis_report_ip, redis_report_port, last_collection_name, last_time, param):
- if param:
- loop = get_container()
- else:
- loop = get_instance_ps()
- try:
- for contianer in loop:
- if param:
- contianer_port = int(contianer.split('_')[-1])
- stats = DockerStats(redis_report_ip, redis_report_port, contianer_port, contianer)
- else:
- stats = RedisStats(redis_report_ip, redis_report_port, contianer)
- stats_key, stats_val = stats.write_redis()
- collection_name = 'info' + str(stats_val['time'] // (60 * 60 * 24))
- if int(time.time()) // 3600 > last_time:
- issharptime = True
- info_key, info_val = stats.redis_info()
- if collection_name == last_collection_name:
- last_collection_name = write_mongodb(stats_key, stats_val, 'stats', 0)
- last_time = int(time.time()) // 3600
- if issharptime:
- last_collection_name = write_mongodb(info_key, info_val, 'info', 0)
- else:
- last_collection_name = write_mongodb(stats_key, stats_val, 'stats', 1)
- last_time = int(time.time()) // 3600
- if issharptime:
- last_collection_name = write_mongodb(info_key, info_val, 'info', 1)
- except:
- pass
- return last_collection_name, last_time
- if __name__ == '__main__':
- last_collection_name = ""
- last_time = 0
- try:
- from docker import Client
- except:
- sys_env = 0
- else:
- sys_env = 1
- while 1:
- last_collection_name, last_time = run(redis_report_ip, redis_report_port, last_collection_name, last_time,
- sys_env)
- time.sleep(3)
|