分佈式監控開發 03 表結構設計

一、設計探討

因爲歷史數據以key-value的方式存到redis中。redis

咱們這須要討論的就是Mysql的表結構設計,那麼有哪些東西須要存到MySQL中呢》?sql

主機得監控方式分爲好多種,那麼每一個主機到底怎麼去監控須要存儲起來。express

好比主機得分組吧,主機組和主機得對應關係。主機須要監控的服務應該寫成模板,這樣便於通用。django

那麼模板和監控項的對應關係須要存儲,主機和模板的對應關係,主機和模板的對應關係。app

 

二、具體表

 

 

三、代碼

from django.db import models
from monitor import auth
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)
    ip_addr =  models.GenericIPAddressField(unique=True)
    host_groups = models.ManyToManyField('HostGroup',blank=True) # A B C
    templates = models.ManyToManyField("Template",blank=True) # A D E
    monitored_by_choices = (
        ('agent','Agent'),
        ('snmp','SNMP'),
        ('wget','WGET'),
    )
    monitored_by = models.CharField(u'監控方式',max_length=64,choices=monitored_by_choices)
    status_choices= (
        (1,'Online'),
        (2,'Down'),
        (3,'Unreachable'),
        (4,'Offline'),
        (5,'Problem'),
    )
    host_alive_check_interval = models.IntegerField(u"主機存活狀態檢測間隔", default=30)
    status = models.IntegerField(u'狀態',choices=status_choices,default=1)
    memo = models.TextField(u"備註",blank=True,null=True)

    def __str__(self):
        return self.name

class HostGroup(models.Model):
    name = models.CharField(max_length=64,unique=True)
    templates = models.ManyToManyField("Template",blank=True)
    memo = models.TextField(u"備註",blank=True,null=True)

    def __str__(self):
        return self.name

class ServiceIndex(models.Model):
    name = models.CharField(max_length=64)
    key =models.CharField(max_length=64)
    data_type_choices = (
        ('int',"int"),
        ('float',"float"),
        ('str',"string")
    )
    data_type = models.CharField(u'指標數據類型',max_length=32,choices=data_type_choices,default='int')
    memo = models.CharField(u"備註",max_length=128,blank=True,null=True)

    def __str__(self):
        return "%s.%s" %(self.name,self.key)

class Service(models.Model):
    name = models.CharField(u'服務名稱',max_length=64,unique=True)
    interval = models.IntegerField(u'監控間隔',default=60)
    plugin_name = models.CharField(u'插件名',max_length=64,default='n/a')
    items = models.ManyToManyField('ServiceIndex',verbose_name=u"指標列表",blank=True)
    has_sub_service = models.BooleanField(default=False,help_text=u"若是一個服務還有獨立的子服務 ,選擇這個,好比 網卡服務有多個獨立的子網卡") #若是一個服務還有獨立的子服務 ,選擇這個,好比 網卡服務有多個獨立的子網卡
    memo = models.CharField(u"備註",max_length=128,blank=True,null=True)

    def __str__(self):
        return self.name


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


class TriggerExpression(models.Model):
    trigger = models.ForeignKey('Trigger',verbose_name=u"所屬觸發器")
    service = models.ForeignKey(Service,verbose_name=u"關聯服務")
    service_index = models.ForeignKey(ServiceIndex,verbose_name=u"關聯服務指標")
    specified_index_key = models.CharField(verbose_name=u"只監控專門指定的指標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(u"數據處理方式",choices=data_calc_type_choices,max_length=64)
    data_calc_args = models.CharField(u"函數傳入參數",help_text=u"如果多個參數,則用,號分開,第一個值是時間",max_length=64)
    threshold = models.IntegerField(u"閾值")


    logic_type_choices = (('or','OR'),('and','AND'))
    logic_type = models.CharField(u"與一個條件的邏輯關係",choices=logic_type_choices,max_length=32,blank=True,null=True)
    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(u'觸發器名稱',max_length=64)
    severity_choices = (
        (1,'Information'),
        (2,'Warning'),
        (3,'Average'),
        (4,'High'),
        (5,'Diaster'),
    )
    #expressions = models.ManyToManyField(TriggerExpression,verbose_name=u"條件表達式")
    severity = models.IntegerField(u'告警級別',choices=severity_choices)
    enabled = models.BooleanField(default=True)
    memo = models.TextField(u"備註",blank=True,null=True)

    def __str__(self):
        return "<serice:%s, severity:%s>" %(self.name,self.get_severity_display())


class Action(models.Model):
    name =  models.CharField(max_length=64,unique=True)
    host_groups = models.ManyToManyField('HostGroup',blank=True)
    hosts = models.ManyToManyField('Host',blank=True)
    triggers = models.ManyToManyField('Trigger',blank=True,help_text=u"想讓哪些trigger觸發當前報警動做")
    interval = models.IntegerField(u'告警間隔(s)',default=300)
    operations = models.ManyToManyField('ActionOperation')

    recover_notice = models.BooleanField(u'故障恢復後發送通知消息',default=True)
    recover_subject = models.CharField(max_length=128,blank=True,null=True)
    recover_message = models.TextField(blank=True,null=True)

    enabled = models.BooleanField(default=True)

    def __str__(self):
        return self.name

class ActionOperation(models.Model):
    name =  models.CharField(max_length=64)
    step = models.SmallIntegerField(u"第n次告警",default=1,help_text="當trigger觸發次數小於這個值時就執行這條記錄裏報警方式")
    action_type_choices = (
        ('email','Email'),
        ('sms','SMS'),
        ('script','RunScript'),
    )
    action_type = models.CharField(u"動做類型",choices=action_type_choices,default='email',max_length=64)
    notifiers= models.ManyToManyField('UserProfile',verbose_name=u"通知對象",blank=True)
    _msg_format = '''Host({hostname},{ip}) service({service_name}) has issue,msg:{msg}'''

    msg_format = models.TextField(u"消息格式",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',blank=True)
    host_groups = models.ManyToManyField('HostGroup',blank=True)
    content = models.TextField(u"維護內容")
    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")
    trigger = models.ForeignKey("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)

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('備註', 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 = '帳戶'
表結構設計
相關文章
相關標籤/搜索