from django.db import models from django.utils import timezone # 引入loguru库用于日志记录 try: from loguru import logger except ImportError: import logging logger = logging.getLogger(__name__) class ServiceGroup(models.Model): name = models.CharField(max_length=100, unique=True, verbose_name="服务分组") description = models.TextField(blank=True, null=True, verbose_name="描述") def __str__(self): return self.name class Meta: verbose_name = '服务分组' verbose_name_plural = '服务分组' class Service(models.Model): STATUS_CHOICES = [ ('UP', '正常'), ('DOWN', '故障'), ('UNKNOWN', '未知'), ] name = models.CharField(max_length=200, verbose_name="服务名称") group = models.ForeignKey(ServiceGroup, on_delete=models.CASCADE, related_name='services', verbose_name="所属分组") host = models.CharField(max_length=255, verbose_name="主机/IP") port = models.PositiveIntegerField(null=True, blank=True, verbose_name="端口(可选)") check_type = models.CharField(max_length=50, default='ping', choices=[ ('ping', 'Ping检测'), ('tcp', 'TCP端口检测'), ('http', 'HTTP请求'), ('custom', '自定义脚本'), ], verbose_name="检测类型") description = models.TextField(blank=True, null=True, verbose_name="描述") is_active = models.BooleanField(default=True, verbose_name="是否启用监控") created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") def __str__(self): return f"{self.name} ({self.host})" def get_latest_status(self): """获取最新状态""" latest_record = self.records.first() if latest_record: return latest_record.status return 'UNKNOWN' def get_latest_check_time(self): """获取最新检测时间""" latest_record = self.records.first() if latest_record: return latest_record.checked_at return None def get_latest_response_time(self): """获取最新响应时间""" latest_record = self.records.first() if latest_record: return latest_record.response_time return None class Meta: verbose_name = '服务' verbose_name_plural = '服务' class ServiceCheckRecord(models.Model): service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name='records') status = models.CharField(max_length=10, choices=Service.STATUS_CHOICES, verbose_name="状态") response_time = models.FloatField(null=True, blank=True, verbose_name="响应时间(ms)") message = models.TextField(blank=True, null=True, verbose_name="返回信息/错误原因") checked_at = models.DateTimeField(default=timezone.now, verbose_name="检测时间") class Meta: ordering = ['-checked_at'] verbose_name = '服务检测记录' verbose_name_plural = '服务检测记录' def __str__(self): return f"{self.service.name} - {self.status} at {self.checked_at}" def save(self, *args, **kwargs): logger.info(f"保存服务检测记录: {self.service.name}, 状态: {self.status}, 响应时间: {self.response_time}ms") super().save(*args, **kwargs)