zoukankan      html  css  js  c++  java
  • 自动化监控系统(二)连接数据库,创建app,添加model,同步数据库

        数据库我使用:mysql5.7

        程序连接数据库的模块:pymysql

    一、创建数据库:

    dbname:automatedmonitor

    二、使用pip安装pymysql,这里我直接在pycharm上安装:

    三、在settings里配置数据库连接:

    DATABASES = {
        'default': {
            #指定数据库类型
            'ENGINE': 'django.db.backends.mysql',
            #数据库名
            'NAME': "automatedmonitor",
            #IP地址
            'HOST':"127.0.0.1",
            #用户名
            'USER':"root",
            #密码
            'PASSWORD':"123456",
            #端口
            'PORT':"3306"
    
        }
    }

    四、接下来是规划目录结构

    1、项目根目录下创建apps目录,所有app应用将会放在里面。

    2、创建static目录,存放静态文件-JS和CSS。

    3、创建media目录,用来存放媒体文件,比如:用户上传的文件等。

    4、创建log目录,存放日志文件。

    5、创建templates目录,用来存放HTML文件

    6、创建images目录,存放图片。

    PS:别的后面需要再添加。

    五、model表结构,monitor app:

    #!_*_coding:utf8_*_
    
    from django.db import models
    from django.utils.translation import ugettext_lazy as _
    from django.utils.safestring import mark_safe
    
    # Create your models here.
    
    
    
    #主机表
    class Host(models.Model):
        #主机名唯一
        name =  models.CharField(max_length=64,unique=True,verbose_name="主机名")
        #IP地址唯一
        ip_addr =  models.GenericIPAddressField(unique=True,verbose_name="IP地址")
        #主机组
        host_groups = models.ManyToManyField('HostGroup',blank=True,verbose_name="主机组") # A B C
        #默认模板
        templates = models.ManyToManyField("Template",blank=True,verbose_name="默认模板") # A D E
        monitored_by_choices = (
            ('agent','Agent'),
            ('snmp','SNMP'),
            ('wget','WGET'),
        )
        #监控选择
        monitored_by = models.CharField(max_length=64,choices=monitored_by_choices,verbose_name="监控方式")
        status_choices= (
            (1,'Online'),
            (2,'Down'),
            (3,'Unreachable'),
            (4,'Offline'),
            (5,'Problem'),
        )
        #
        host_alive_check_interval = models.IntegerField( default=30,verbose_name="主机存活状态检测间隔")
        #主机状态
        status = models.IntegerField(choices=status_choices,default=1,verbose_name="主机状态")
        #备注信息
        memo = models.TextField(blank=True,null=True,verbose_name="备注信息")
    
        def __str__(self):
            return self.name
    
    
    #主机组表
    class HostGroup(models.Model):
        #主机组名
        name =  models.CharField(max_length=64,unique=True,verbose_name="主机组名")
        #主机组模板
        templates = models.ManyToManyField("Template",blank=True,verbose_name="主机组模板")
        #备注信息
        memo = models.TextField(blank=True,null=True,verbose_name="备注信息")
        def __str__(self):
            return self.name
    
    
    #一个服务下有多个指标,指标表
    class ServiceIndex(models.Model):
        #指标名称
        name = models.CharField(max_length=64,verbose_name="指标名称")
        #具体指标,比如cpu下的idle
        key =models.CharField(max_length=64)
        data_type_choices = (
            ('int',"int"),
            ('float',"float"),
            ('str',"string")
        )
        #指标数据类型
        data_type = models.CharField(max_length=32,choices=data_type_choices,default='int',verbose_name="指标数据类型")
        #备注
        memo = models.CharField(max_length=128,blank=True,null=True,verbose_name="备注")
        def __str__(self):
            return "%s.%s" %(self.name,self.key)
    
    
    #服务表
    class Service(models.Model):
        #服务名称
        name = models.CharField(max_length=64,unique=True,verbose_name="服务名称")
        #监控间隔
        interval = models.IntegerField(default=60,verbose_name="监控间隔")
        #插件名,client拿到它来进行监控
        plugin_name = models.CharField(max_length=64,default='n/a',verbose_name="插件名")
        #指标列表,比如CPu下有多个指标,是一对多的关系
        items = models.ManyToManyField('ServiceIndex',blank=True,verbose_name="指标列表")
        #子服务
        has_sub_service = models.BooleanField(default=False,help_text=u"如果一个服务还有独立的子服务 ,选择这个,比如 网卡服务有多个独立的子网卡",verbose_name="子服务") #如果一个服务还有独立的子服务 ,选择这个,比如 网卡服务有多个独立的子网卡
        #备注
        memo = models.CharField(max_length=128,blank=True,null=True,verbose_name="备注")
    
        def __str__(self):
            return self.name
        #def get_service_items(obj):
        #    return ",".join([i.name for i in obj.items.all()])
    
    
    #模板表
    class Template(models.Model):
        name = models.CharField(u'模版名称',max_length=64,unique=True)
        services = models.ManyToManyField('Service',verbose_name=u"服务列表")
        triggers = models.ManyToManyField('Trigger',verbose_name=u"触发器列表",blank=True)
        def __str__(self):
            return self.name
    
    
    
    #触发一个报警,由多个指标来判断,触发关联表,一个表达式只能关联一个trigger
    class TriggerExpression(models.Model):
        #所属触发器
        trigger = models.ForeignKey('Trigger',verbose_name="所属触发器")
        #关联服务
        service = models.ForeignKey(Service,verbose_name="关联服务")
        #关联服务指标
        service_index = models.ForeignKey(ServiceIndex,verbose_name="关联服务指标")
        #只监控专门指定的指标key
        specified_index_key = models.CharField(verbose_name="只监控专门指定的指标key",max_length=64,blank=True,null=True)
        operator_type_choices = (('eq','='),('lt','<'),('gt','>'))
        #运算符
        operator_type = models.CharField(u"运算符",choices=operator_type_choices,max_length=32)
        data_calc_type_choices = (
            ('avg','Average'),
            ('max','Max'),
            ('hit','Hit'),
            ('last','Last'),
        )
        #数据处理方式
        data_calc_func= models.CharField(choices=data_calc_type_choices,max_length=64,verbose_name="数据处理方式")
        #函数传入参数
        data_calc_args = models.CharField(help_text="若是多个参数,则用,号分开,第一个值是时间",max_length=64,verbose_name="函数传入参数")
        #阈值
        threshold = models.IntegerField(u"阈值")
    
    
        logic_type_choices = (('or','OR'),('and','AND'))
        #与另一个表达式的关系
        logic_type = models.CharField(choices=logic_type_choices,max_length=32,blank=True,null=True,verbose_name="与一个条件的逻辑关系")
        def __str__(self):
            return "%s %s(%s(%s))" %(self.service_index,self.operator_type,self.data_calc_func,self.data_calc_args)
        class Meta:
            pass #unique_together = ('trigger_id','service')
    
    
    
    #触发报警的,触发器表
    class Trigger(models.Model):
        #触发器名称
        name = models.CharField(max_length=64,verbose_name="触发器名称")
        severity_choices = (
            (1,'Information'),
            (2,'Warning'),
            (3,'Average'),
            (4,'High'),
            (5,'Diaster'),
        )
        #expressions = models.ManyToManyField(TriggerExpression,verbose_name=u"条件表达式")
        #告警级别
        severity = models.IntegerField(choices=severity_choices,verbose_name="告警级别")
    
        enabled = models.BooleanField(default=True)
        #备注
        memo = models.TextField(blank=True,null=True,verbose_name="备注")
    
        def __str__(self):
            return "<serice:%s, severity:%s>" %(self.name,self.get_severity_display())
    
    
    
    #触发报警后的动作类型
    class Action(models.Model):
        #action名称
        name =  models.CharField(max_length=64,unique=True,verbose_name="动作名称")
        #关联哪个主机组
        host_groups = models.ManyToManyField('HostGroup',blank=True,verbose_name="主机组")
        #关联哪个主机
        hosts = models.ManyToManyField('Host',blank=True,verbose_name="主机")
        #告警条件
        conditions = models.TextField(verbose_name="告警条件")
        #触发器
        triggers = models.ManyToManyField('Trigger',blank=True,help_text=u"想让哪些trigger触发当前报警动作",verbose_name="触发器")
        #告警间隔
        interval = models.IntegerField(default=300,verbose_name="告警间隔(s)")
        #关联别的动作
        operations = models.ManyToManyField('ActionOperation',verbose_name='ActionOperation')
        #故障恢复是否要通知
        recover_notice = models.BooleanField(verbose_name='故障恢复后发送通知消息',default=True)
        #恢复后通知的主题是什么
        recover_subject = models.CharField(max_length=128,blank=True,null=True,verbose_name="通知主题")
        #通知文本
        recover_message = models.TextField(blank=True,null=True,verbose_name="通知文本")
        #是否停用
        enabled = models.BooleanField(default=True,verbose_name="是否停用")
    
        def __str__(self):
            return self.name
    
    
    #触发报警后的具体动作
    class ActionOperation(models.Model):
        name =  models.CharField(max_length=64,verbose_name="告警升级")
        step = models.SmallIntegerField(verbose_name="第n次告警",default=1,help_text="当trigger触发次数小于这个值时就执行这条记录里报警方式")
        action_type_choices = (
            ('email','Email'),
            ('sms','SMS'),
            ('script','RunScript'),
        )
        #通过告警次数,给告警级别升级,并且指定动作类型
        action_type = models.CharField(verbose_name="动作类型",choices=action_type_choices,default='email',max_length=64)
        #告警通知对象
        notifiers= models.ManyToManyField('UserProfile',verbose_name="通知对象",blank=True)
        _msg_format = '''Host({hostname},{ip}) service({service_name}) has issue,msg:{msg}'''
        #消息格式
        msg_format = models.TextField(verbose_name="消息格式",default=_msg_format)
        def __str__(self):
            return self.name
    
    
    
    #主机维护表
    class Maintenance(models.Model):
    
        name =  models.CharField(max_length=64,unique=True)
        #主机
        hosts = models.ManyToManyField('Host',verbose_name='主机',blank=True)
        #主机组
        host_groups = models.ManyToManyField('HostGroup',verbose_name='主机组',blank=True)
        #维护内容
        content = models.TextField(verbose_name="维护内容")
        #开始时间
        start_time = models.DateTimeField()
        #结束时间
        end_time = models.DateTimeField()
    
        def __str__(self):
            return self.name
    
    
    class EventLog(models.Model):
        """存储报警及其它事件日志"""
        event_type_choices = ((0,'报警事件'),(1,'维护事件'))
        event_type = models.SmallIntegerField(choices=event_type_choices,default=0)
        host = models.ForeignKey("Host",verbose_name="Host")
        trigger = models.ForeignKey("Trigger",verbose_name="Trigger",blank=True,null=True)
        log = models.TextField(blank=True,null=True)
        date = models.DateTimeField(auto_now_add=True)
    
    
        def __str__(self):
            return "host%s  %s" %(self.host , self.log)
    
    
    
    
    
    
    
    
    ''''
    CPU
        idle 80
        usage  90
        system  30
        user
        iowait  50
    
    memory :
        usage
        free
        swap
        cache
        buffer
    
    load:
        load1
        load 5
        load 15
    '''
    View Code

    users app:

    from django.db import models
    
    
    from users import auth
    # Create your models here.
    
    
    
    
    class UserProfile(auth.AbstractBaseUser, auth.PermissionsMixin):
        email = models.EmailField(
            verbose_name='email address',
            max_length=255,
            unique=True,
    
        )
        password = models.CharField(_('password'), max_length=128,
                                    help_text=mark_safe('''<a class='btn-link' href='password'>重置密码</a>'''))
    
        phone = models.BigIntegerField(blank=True,null=True)
        weixin = models.CharField(max_length=64,blank=True,null=True)
    
        is_active = models.BooleanField(default=True)
        is_admin = models.BooleanField(default=False)
        is_staff = models.BooleanField(
            verbose_name='staff status',
            default=True,
            help_text='Designates whether the user can log into this admin site.',
        )
        name = models.CharField(max_length=32)
        #role = models.ForeignKey("Role",verbose_name="权限角色")
    
        memo = models.TextField(verbose_name='备注', blank=True, null=True, default=None)
        date_joined = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    
        USERNAME_FIELD = 'email'
        # REQUIRED_FIELDS = ['name','token','department','tel','mobile','memo']
        REQUIRED_FIELDS = ['name']
    
        def get_full_name(self):
            # The user is identified by their email address
            return self.email
    
        def get_short_name(self):
            # The user is identified by their email address
            return self.email
    
        def __str__(self):  # __str__ on Python 2
            return self.email
    
        # def has_perm(self, perm, obj=None):
        #     "Does the user have a specific permission?"
        #     # Simplest possible answer: Yes, always
        #     return True
        def has_perms(self, perm, obj=None):
            "Does the user have a specific permission?"
            # Simplest possible answer: Yes, always
            return True
    
        def has_module_perms(self, app_label):
            "Does the user have permissions to view the app `app_label`?"
            # Simplest possible answer: Yes, always
            return True
    
    
        @property
        def is_superuser(self):
            "Is the user a member of staff?"
            # Simplest possible answer: All admins are staff
            return self.is_admin
    
    
        objects = auth.UserManager()
    
        class Meta:
            verbose_name = '账户'
            verbose_name_plural = '账户'
    View Code

    遇到个问题:

    原因:多对多manytomanyfield字段需要关联别的表,第一个参数需要加上表名

        host_groups = models.ManyToManyField('HostGroup',blank=True,verbose_name="主机组")
        #关联哪个主机
        hosts = models.ManyToManyField('Host',blank=True,verbose_name="主机")
        #告警条件
        conditions = models.TextField(verbose_name="告警条件")
        #触发器
        triggers = models.ManyToManyField('Trigger',blank=True,help_text=u"想让哪些trigger触发当前报警动作",verbose_name="触发器")
        #告警间隔
        interval = models.IntegerField(default=300,verbose_name="告警间隔(s)")
        #关联别的动作
        operations = models.ManyToManyField('ActionOperation',verbose_name='ActionOperation')

     对django自带的UserProfile进行扩展字段,但是发现在同步数据库的时候,会出现如下报错。

    原因:重载django自带的model,需要在settings里说明:

    #重载,这里是app名称.model的类名
    AUTH_USER_MODEL = 'monitor.UserProfile'
  • 相关阅读:
    docker安装部署命令
    kubernetes原理
    kubernetes安装部署
    Ansible安装
    模拟红绿灯(递归与队列)
    数据结构——顺序表
    数据结构——基本概念
    C语言高级编程
    Shell编程
    Shell命令
  • 原文地址:https://www.cnblogs.com/laonicc/p/6682889.html
Copyright © 2011-2022 走看看