一个程序的目录结构:
bin:可执行文件
conf:配置文件
core:逻辑关系
plugins:各种插件
var:日志
客户端:
1、设置一个程序入口,运行该文件A就能启动客户端。
2、给A传位置参数(start 或 stop),通过获取位置参数名称,使用反射来调用相应方法,做到启动或者停止client。
3、启动客户端后,通过发起HTTP请求,获取service下发的任务(监控哪些服务:CPU、memory、network。。。。。。)
发送请求中,应该有client相关配置信息:主机Id、主机IP地址、主机端口、url配置、请求超时时间和更新监控配置时间。
暂时这些,后面再添加
client端通过特定url,发送http请求,然后server端返回相应的信息,告诉client需要监控什么服务
在服务端也需要添加相应的url和view,返回客户端的请求信息。
view
from django.shortcuts import render # Create your views here. from django.views.generic import View from django.http import HttpResponse import json from .serializer import ClientHandler class client_config_view(View): #返回客户端需要监控信息 def get(self,request,client_id): #获取client信息 # client_configs = ClientHandler(client_id).fetch_configs() client_obj = ClientHandler(client_id) client_config = client_obj.fetch_configs() print("客户端ID",client_id) if client_config: return HttpResponse(json.dumps(client_config),content_type="application/json")
serializer
#!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = "BIGNI" __date__ = "2017/4/29 16:34" import traceback from django.views.generic import View from .models import Host class ClientHandler(View): #初始化 def __init__(self,client_id): self.client_id = client_id #client配置 self.client_configs = { "services":{} } def fetch_configs(self): try: host_obj_id = Host.objects.get(id=self.client_id) print(">>>>>>>>>",host_obj_id) #获取模板list template_list = list(host_obj_id.templates.select_related()) print(">>>>",template_list) #获取主机组obj host_group_obj = host_obj_id.host_groups.select_related() #把主机组下的目标添加进来 template_list.extend([template for template in host_group_obj]) print("--->",template_list) #获取服务列表 for template in template_list: for service in template.services.select_related(): print(service) #获取插件名和间隔时间 self.client_configs['services'][service.name] = [service.plugin_name,service.interval] except: traceback.print_exc() return self.client_configs # test = ClientHandler(1) # print(test,test.fetch_configs())
测试下:
调用特定url,server端可以返回需要监控的信息。
{"services": {"LinuxCPU": ["get_linux_cpu", 15], "LinuxNetwork": ["GetNetworkStatus", 60], "LinuxMemory": ["get_memory_info", 60]}}
返回这种格式{"services":{"监控的服务":["插件名",监控间隔]}}
client拿到这个信息后会根据插件名调用相关的脚本,拿到数据返回给server,这一过程会在线程里完成。
接下来继续client端的开发:
1、通过运行monitor_client启动客户端,执行main_command方法。
2、main_command方法自带start和stop两个方法
#!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = "BIGNI" __date__ = "2017/4/15 23:48" from .client import ClientHandlers class main_command(object): #初始化 def __init__(self,sys_argv): self.sys_argv = sys_argv if len(sys_argv) < 2 : exit("请输入start或stop") else: self.entry_command() #根据命令调用方法 def entry_command(self): print("##############################################") if hasattr(self.sys_argv[1]): func = getattr(self,self.sys_argv[1]) return func() else: print("请输入正确的命令") def start(self): client = ClientHandlers() client.forever_run() def stop(self): pass
3、start方法会创建ClientHandlers对象,接着调用里面的forever_run方法,获取server端返回的信息,并根据插件名给各个服务进行监控
#!/usr/bin/env python3 # _*_ coding:utf-8 _*_ __author__ = "BIGNI" __date__ = "2017/4/29 11:42" import time,threading,json import requests from conf import settings from plugins import plugin_api class ClientHandlers(object): def __init__(self): #初始化监控服务 self.monitor_services = {} def load_lastest_config(self): """ 加载最新的配置信息 :return: """ #request请求方式 request_type = settings.configs["urls"]["get_configs"][1] #拼接url request_url = "%s/%s" % (settings.configs['urls']['get_configs'][0], settings.configs['HostID']) lastest_config = self.url_request(request_type,request_url) #把最小配置更新到监控服务字典中 self.monitor_services.update(lastest_config) def forever_run(self): #启动客户端 exit_flag = False #第一次启动时初始化最新配置时间 config_lastest_update_time = 0 while not exit_flag: if time.time() - config_lastest_update_time > settings.configs['ConfigUpdateInterval']: self.load_lastest_config() print("Lastest_config:",self.monitor_services) config_lastest_update_time = time.time() """ Lastest_config: {'services': {'LinuxCPU': ['get_linux_cpu', 15], 'LinuxMemory': ['get_memory_info', 60], 'LinuxNetwork': ['GetNetworkStatus', 60]}} """ for service_name,val in self.monitor_services['services'].items(): if len(val) ==2: # 第一次启动插件时,初始化当前时间,给每个服务维护一个计时器 self.monitor_services['services'][service_name].append(0) #获取监控间隔和最新插件时间 monitor_interval = val[1] last_invoke_time = val[2] if time.time() - last_invoke_time > monitor_interval: print("--->",last_invoke_time,"--->",time.time()) #重置计时器时间 self.monitor_services['services'][service_name][2] = time.time() t = threading.Thread(target=self.invoke_plugin,args=(service_name,val)) t.start() print("启动监控的服务: [{ServiceName}]".format(ServiceName=service_name)) else: #需要等待监控间隔时间 print("监控的服务: {ServiceName} 距离下次启动时间:{interval} secs".format(ServiceName=service_name, interval=monitor_interval - (time.time() - last_invoke_time))) time.sleep(5) time.sleep(1) #运行插件 def invoke_plugin(self,service_name,val): #{"services": {"LinuxNetwork": ["n/a", 60,0], "LinuxMemory": ["n/a", 60,0], "LinuxCPU": ["n/a", 60,0]}} #获取插件名 plugin_name = val[0] if hasattr(plugin_api,plugin_name): func = getattr(plugin_api,plugin_name) plugin_callback = func() print("####################################################") print(plugin_callback) print("####################################################") report_data = { 'client_id':settings.configs['HostID'], 'service_name':service_name, 'data':plugin_callback } #请求方式get or post request_action = settings.configs['urls']['service_report'][1] #请求路径 request_url = settings.configs['urls']['service_report'][0] #report_data = json.dumps(report_data) # print('---report data(发送的数据):',report_data) #调用url_request方法,以post方式发送request self.url_request(request_action, request_url, params=report_data) else: print("