forked from iti-framework/iTi-Flask
优化influxdb链接,修改采集端和设备关联,添加告警功能相关表
parent
675d2fad8f
commit
191ef60413
@ -0,0 +1,40 @@
|
|||||||
|
from iti.applications.extensions import db
|
||||||
|
from iti.applications.common.crud import TimeModelMixin
|
||||||
|
from iti.applications.common.utils import BaseSchema
|
||||||
|
from apiflask.fields import String, Integer, DateTime, Nested
|
||||||
|
|
||||||
|
|
||||||
|
class IotAlertLog(db.Model, TimeModelMixin):
|
||||||
|
"""
|
||||||
|
告警日志表
|
||||||
|
"""
|
||||||
|
__tablename__ = "iot_alert_log"
|
||||||
|
id = db.Column(
|
||||||
|
db.Integer,
|
||||||
|
primary_key=True,
|
||||||
|
autoincrement=True,
|
||||||
|
comment="标识",
|
||||||
|
)
|
||||||
|
alert_tag = db.Column(db.String(255), nullable=False, comment="告警标签")
|
||||||
|
alert_target_name = db.Column(db.String(255), nullable=False, comment="告警对象名称")
|
||||||
|
alert_content = db.Column(db.String(2048), nullable=False, comment="告警文本")
|
||||||
|
alert_level = db.Column(db.Integer, nullable=False, comment="告警级别 0-预警,1-一般,2-紧急,3-严重")
|
||||||
|
status = db.Column(db.Integer, nullable=False, default=1, comment="状态 1-告警中,0-已恢复")
|
||||||
|
trigger_count = db.Column(db.Integer, nullable=False, default=0, comment="触发次数")
|
||||||
|
|
||||||
|
class IotAlertLogSchema(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警日志表响应结构
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
name = "IotAlertLog"
|
||||||
|
|
||||||
|
id = Integer()
|
||||||
|
alert_tag = String()
|
||||||
|
alert_target_name = String()
|
||||||
|
alert_content = String()
|
||||||
|
alert_level = Integer()
|
||||||
|
status = Integer()
|
||||||
|
trigger_count = Integer()
|
||||||
|
created_at = DateTime(format="%Y-%m-%d %H:%M:%S")
|
||||||
|
updated_at = DateTime(format="%Y-%m-%d %H:%M:%S")
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
from iti.applications.extensions import db
|
||||||
|
from iti.applications.common.crud import TimeModelMixin
|
||||||
|
from iti.applications.common.utils import BaseSchema
|
||||||
|
from apiflask.fields import String, Integer, DateTime, Nested
|
||||||
|
|
||||||
|
class IotAlertPush(TimeModelMixin, db.Model):
|
||||||
|
"""
|
||||||
|
告警推送表
|
||||||
|
"""
|
||||||
|
__tablename__ = "iot_alert_push"
|
||||||
|
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="标识")
|
||||||
|
target_name = db.Column(db.String(255), nullable=False, comment="接收对象名称")
|
||||||
|
push_url = db.Column(db.String(2048), nullable=False, comment="告警推送URL")
|
||||||
|
alert_level = db.Column(db.String(255), nullable=False, comment="告警等级")
|
||||||
|
status = db.Column(db.Integer, nullable=False, default=1, comment="状态 1-启用,0-禁用")
|
||||||
|
|
||||||
|
|
||||||
|
class IotAlertPushSchema(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警推送表响应结构
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
name = "IotAlertPush"
|
||||||
|
|
||||||
|
id = Integer()
|
||||||
|
target_name = String()
|
||||||
|
push_url = String()
|
||||||
|
alert_level = String()
|
||||||
|
status = Integer()
|
||||||
|
created_at = DateTime(format="%Y-%m-%d %H:%M:%S")
|
||||||
|
updated_at = DateTime(format="%Y-%m-%d %H:%M:%S")
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
from iti.applications.extensions import db
|
||||||
|
from iti.applications.common.crud import TimeModelMixin
|
||||||
|
from iti.applications.common.utils import BaseSchema
|
||||||
|
from apiflask.fields import String, Integer, DateTime, Nested
|
||||||
|
|
||||||
|
|
||||||
|
class IotAlertRule(db.Model, TimeModelMixin):
|
||||||
|
"""
|
||||||
|
告警规则表
|
||||||
|
"""
|
||||||
|
__tablename__ = "iot_alert_rule"
|
||||||
|
id = db.Column(
|
||||||
|
db.Integer,
|
||||||
|
primary_key=True,
|
||||||
|
autoincrement=True,
|
||||||
|
comment="标识",
|
||||||
|
)
|
||||||
|
rule_name = db.Column(db.String(255), nullable=False, comment="告警规则名称")
|
||||||
|
node_id = db.Column(db.Integer, nullable=False, comment="采集节点ID")
|
||||||
|
trigger_count = db.Column(db.Integer, nullable=False, comment="阈值触发次数,超过次数后告警")
|
||||||
|
alert_rule = db.Column(db.String(255), nullable=False, comment="告警触发表达式")
|
||||||
|
alert_text = db.Column(db.String(2048), nullable=False, comment="告警文本")
|
||||||
|
alert_level = db.Column(db.Integer, nullable=False, comment="告警级别 0-预警,1-一般,2-紧急,3-严重")
|
||||||
|
status = db.Column(db.Integer, nullable=False, default=1, comment="状态 1-启用,0-禁用")
|
||||||
|
|
||||||
|
class IotAlertRuleSchema(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警规则表响应结构
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
name = "IotAlertRule"
|
||||||
|
|
||||||
|
id = Integer()
|
||||||
|
rule_name = String()
|
||||||
|
node_id = Integer()
|
||||||
|
trigger_count = Integer()
|
||||||
|
alert_rule = String()
|
||||||
|
alert_text = String()
|
||||||
|
alert_level = Integer()
|
||||||
|
status = Integer()
|
||||||
|
created_at = DateTime(format="%Y-%m-%d %H:%M:%S")
|
||||||
|
updated_at = DateTime(format="%Y-%m-%d %H:%M:%S")
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
from apiflask import APIBlueprint
|
||||||
|
from iti.applications.service.iot.alert import add_endpoint_alert_log
|
||||||
|
from iti.applications.extensions import db
|
||||||
|
from iti.applications.common.utils import success, page_schema, page
|
||||||
|
from iti.applications.models import (
|
||||||
|
IotAlertLog,
|
||||||
|
IotAlertLogSchema,
|
||||||
|
)
|
||||||
|
from .schemas.alert_log import (
|
||||||
|
AlertLogQuery,
|
||||||
|
AlertLogAddRequest,
|
||||||
|
AlertLogUpdateRequest,
|
||||||
|
)
|
||||||
|
from iti.applications.common import ModelFilter
|
||||||
|
from iti.applications.common.exceptions.biz_exp import BizException
|
||||||
|
from flask_jwt_extended import jwt_required
|
||||||
|
from sqlalchemy import select, delete, exists
|
||||||
|
from sqlalchemy.sql.functions import func
|
||||||
|
from sqlalchemy.orm import noload
|
||||||
|
from iti.applications.common import permission
|
||||||
|
|
||||||
|
bp = APIBlueprint("iot_alert_log", __name__, url_prefix="/alertLog", tag="告警中心")
|
||||||
|
|
||||||
|
@bp.get("/list")
|
||||||
|
@jwt_required()
|
||||||
|
@bp.doc(security="JWT")
|
||||||
|
@permission("iot:alertLog:list")
|
||||||
|
@bp.input(AlertLogQuery.Schema(partial=True), location="query")
|
||||||
|
@bp.output(IotAlertLogSchema(many=True))
|
||||||
|
def list_alert_log(query_data: AlertLogQuery):
|
||||||
|
"""
|
||||||
|
获取告警日志列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
return success(get_list_or_page(query_data))
|
||||||
|
|
||||||
|
@bp.get("/page")
|
||||||
|
@jwt_required()
|
||||||
|
@bp.doc(security="JWT")
|
||||||
|
@permission("iot:alertLog:list")
|
||||||
|
@bp.input(AlertLogQuery.Schema(partial=True), location="query")
|
||||||
|
@bp.output(page_schema(IotAlertLogSchema))
|
||||||
|
def page_alert_log(query_data: AlertLogQuery):
|
||||||
|
"""
|
||||||
|
获取告警日志分页列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
return success(get_list_or_page(query_data))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.post("/add/<int:endpoint_id>")
|
||||||
|
# @jwt_required()
|
||||||
|
# @bp.doc(security="JWT")
|
||||||
|
# @permission("iot:alertLog:add")
|
||||||
|
def add_alert_log(endpoint_id: int):
|
||||||
|
"""
|
||||||
|
添加采集端网络不可达告警日志
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = add_endpoint_alert_log(endpoint_id)
|
||||||
|
if len(result) > 0:
|
||||||
|
raise BizException(result)
|
||||||
|
|
||||||
|
return success()
|
||||||
|
|
||||||
|
@bp.post("/recover/<int:id>")
|
||||||
|
@jwt_required()
|
||||||
|
@bp.doc(security="JWT")
|
||||||
|
@permission("iot:alertLog:update")
|
||||||
|
def recover_alert_log(id: int):
|
||||||
|
"""
|
||||||
|
恢复告警日志
|
||||||
|
"""
|
||||||
|
|
||||||
|
alert_log = db.session.scalar(select(IotAlertLog).filter_by(id=id))
|
||||||
|
if not alert_log:
|
||||||
|
raise BizException("告警日志不存在")
|
||||||
|
|
||||||
|
alert_log.trigger_count =0
|
||||||
|
alert_log.status = 0
|
||||||
|
db.session.commit()
|
||||||
|
return success()
|
||||||
|
|
||||||
|
def get_list_or_page(query_data: AlertLogQuery):
|
||||||
|
"""
|
||||||
|
获取告警日志列表
|
||||||
|
"""
|
||||||
|
query = select(IotAlertLog).order_by(IotAlertLog.created_at.desc())
|
||||||
|
if query_data.alert_tag is not None:
|
||||||
|
query = query.filter(IotAlertLog.alert_tag == query_data.alert_tag)
|
||||||
|
if query_data.status is not None:
|
||||||
|
query = query.filter(IotAlertLog.status == query_data.status)
|
||||||
|
if query_data.page and query_data.size:
|
||||||
|
return db.paginate(query, page=query_data.page, per_page=query_data.size)
|
||||||
|
else:
|
||||||
|
return db.session.scalars(query).all()
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
from apiflask import APIBlueprint
|
||||||
|
from iti.applications.extensions import db, sys_log
|
||||||
|
from iti.applications.common.utils import success, page_schema, page
|
||||||
|
from iti.applications.models import (
|
||||||
|
IotAlertPush,
|
||||||
|
IotAlertPushSchema,
|
||||||
|
)
|
||||||
|
from .schemas.alert_push import (
|
||||||
|
AlertPushQuery,
|
||||||
|
AlertPushAddRequest,
|
||||||
|
AlertPushUpdateRequest,
|
||||||
|
)
|
||||||
|
from iti.applications.common import ModelFilter
|
||||||
|
from iti.applications.common.exceptions.biz_exp import BizException
|
||||||
|
from flask_jwt_extended import jwt_required
|
||||||
|
from sqlalchemy import select, delete, exists
|
||||||
|
from sqlalchemy.sql.functions import func
|
||||||
|
from sqlalchemy.orm import noload
|
||||||
|
from iti.applications.common import permission
|
||||||
|
|
||||||
|
bp = APIBlueprint("iot_alert_push", __name__, url_prefix="/alertPush", tag="消息通知")
|
||||||
|
|
||||||
|
@bp.get("/list")
|
||||||
|
@jwt_required()
|
||||||
|
@bp.doc(security="JWT")
|
||||||
|
@permission("iot:alertPush:list")
|
||||||
|
@bp.input(AlertPushQuery.Schema(partial=True), location="query")
|
||||||
|
@bp.output(IotAlertPushSchema(many=True))
|
||||||
|
def list_alert_push(query_data: AlertPushQuery):
|
||||||
|
"""
|
||||||
|
获取消息通知列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
return success(get_list_or_page(query_data))
|
||||||
|
|
||||||
|
@bp.get("/page")
|
||||||
|
@jwt_required()
|
||||||
|
@bp.doc(security="JWT")
|
||||||
|
@permission("iot:alertPush:list")
|
||||||
|
@bp.input(AlertPushQuery.Schema(partial=True), location="query")
|
||||||
|
@bp.output(page_schema(IotAlertPushSchema))
|
||||||
|
def page_alert_push(query_data: AlertPushQuery):
|
||||||
|
"""
|
||||||
|
获取消息通知分页列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
return success(get_list_or_page(query_data))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.post("/add")
|
||||||
|
@jwt_required()
|
||||||
|
@bp.doc(security="JWT")
|
||||||
|
@permission("iot:alertPush:add")
|
||||||
|
@bp.input(AlertPushAddRequest,location="json")
|
||||||
|
def add_alert_push(json_data: dict):
|
||||||
|
"""
|
||||||
|
添加消息通知
|
||||||
|
"""
|
||||||
|
|
||||||
|
alert_push = IotAlertPush(**json_data)
|
||||||
|
alert_push.status = 0
|
||||||
|
db.session.add(alert_push)
|
||||||
|
db.session.commit()
|
||||||
|
return success()
|
||||||
|
|
||||||
|
|
||||||
|
def get_list_or_page(query_data: AlertPushQuery):
|
||||||
|
"""
|
||||||
|
获取消息通知列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
query = select(IotAlertPush).order_by(IotAlertPush.created_at.desc())
|
||||||
|
if query_data.keyword:
|
||||||
|
kw = ModelFilter.escape_like(query_data.keyword)
|
||||||
|
query = query.filter(
|
||||||
|
IotAlertPush.target_name.like(f"%{kw}%")
|
||||||
|
)
|
||||||
|
if query_data.status is not None:
|
||||||
|
query = query.filter(IotAlertPush.status == query_data.status)
|
||||||
|
if query_data.page and query_data.size:
|
||||||
|
return db.paginate(query, page=query_data.page, per_page=query_data.size)
|
||||||
|
else:
|
||||||
|
return db.session.scalars(query).all()
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
from apiflask import APIBlueprint
|
||||||
|
from iti.applications.extensions import db, sys_log
|
||||||
|
from iti.applications.common.utils import success, page_schema, page
|
||||||
|
from iti.applications.models import (
|
||||||
|
IotAlertRule,
|
||||||
|
IotAlertRuleSchema,
|
||||||
|
)
|
||||||
|
from .schemas.alert_rule import (
|
||||||
|
AlertRuleQuery,
|
||||||
|
AlertRuleAddRequest,
|
||||||
|
AlertRuleUpdateRequest,
|
||||||
|
)
|
||||||
|
from iti.applications.common import ModelFilter
|
||||||
|
from iti.applications.common.exceptions.biz_exp import BizException
|
||||||
|
from flask_jwt_extended import jwt_required
|
||||||
|
from sqlalchemy import select, delete, exists
|
||||||
|
from sqlalchemy.sql.functions import func
|
||||||
|
from sqlalchemy.orm import noload
|
||||||
|
from iti.applications.common import permission
|
||||||
|
|
||||||
|
bp = APIBlueprint("iot_alert_rule", __name__, url_prefix="/alertRule", tag="告警规则")
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
from dataclasses import field
|
||||||
|
from marshmallow_dataclass import dataclass
|
||||||
|
from marshmallow import validates_schema, ValidationError
|
||||||
|
from iti.applications.common.utils.schema import BaseSchema, Pagination
|
||||||
|
from typing import ClassVar, Optional
|
||||||
|
from apiflask import fields
|
||||||
|
|
||||||
|
@dataclass(base_schema=BaseSchema)
|
||||||
|
class AlertLogQuery(Pagination):
|
||||||
|
"""
|
||||||
|
告警日志信息查询请求
|
||||||
|
"""
|
||||||
|
alert_tag: str = field(
|
||||||
|
default=None,
|
||||||
|
metadata={
|
||||||
|
"required": False,
|
||||||
|
"metadata": {"example": "ep1-nd0", "description": "告警标签"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status: int = field(
|
||||||
|
default=None,
|
||||||
|
metadata={
|
||||||
|
"required": False,
|
||||||
|
"metadata": {"example": 0, "description": "状态"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
Schema: ClassVar[BaseSchema] = BaseSchema
|
||||||
|
|
||||||
|
class AlertLogAddRequest(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警日志信息添加请求
|
||||||
|
"""
|
||||||
|
|
||||||
|
alert_tag = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ep1-nd0",
|
||||||
|
"description": "告警标签",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
alert_target_name = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ep1-nd0",
|
||||||
|
"description": "告警对象名称",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
trigger_count = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": 1,
|
||||||
|
"description": "触发次数",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": 0,
|
||||||
|
"description": "状态",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
alert_content = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ep1-nd0",
|
||||||
|
"description": "告警内容",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
alert_level = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": 0,
|
||||||
|
"description": "告警级别",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
class AlertLogUpdateRequest(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警日志信息更新请求
|
||||||
|
"""
|
||||||
|
alert_tag = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ep1-nd0",
|
||||||
|
"description": "告警标签",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
alert_target_name = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ep1-nd0",
|
||||||
|
"description": "告警对象名称",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
trigger_count = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": 1,
|
||||||
|
"description": "触发次数",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": 0,
|
||||||
|
"description": "状态",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
alert_content = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ep1-nd0",
|
||||||
|
"description": "告警内容",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
alert_level = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": 0,
|
||||||
|
"description": "告警级别",
|
||||||
|
},
|
||||||
|
)
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
from dataclasses import field
|
||||||
|
from marshmallow_dataclass import dataclass
|
||||||
|
from marshmallow import validates_schema, ValidationError
|
||||||
|
from iti.applications.common.utils.schema import BaseSchema, Pagination
|
||||||
|
from typing import ClassVar, Optional
|
||||||
|
from apiflask import fields
|
||||||
|
|
||||||
|
@dataclass(base_schema=BaseSchema)
|
||||||
|
class AlertPushQuery(Pagination):
|
||||||
|
"""
|
||||||
|
告警推送信息查询请求
|
||||||
|
"""
|
||||||
|
keyword: Optional[str] = field(
|
||||||
|
default=None,
|
||||||
|
metadata={
|
||||||
|
"required": False,
|
||||||
|
"metadata": {
|
||||||
|
"description": "关键字 [消息对象名称] 模糊查询"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status: int = field(
|
||||||
|
default=None,
|
||||||
|
metadata={
|
||||||
|
"required": False,
|
||||||
|
"metadata": {"example": 0, "description": "状态"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
Schema: ClassVar[BaseSchema] = BaseSchema
|
||||||
|
|
||||||
|
class AlertPushAddRequest(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警推送信息添加请求
|
||||||
|
"""
|
||||||
|
target_name = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ERP",
|
||||||
|
"description": "告警对象名称",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
push_url = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "https://www.baidu.com",
|
||||||
|
"description": "告警推送URL",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={
|
||||||
|
"example": 1,
|
||||||
|
"description": "状态 0-禁用,1-启用",
|
||||||
|
},
|
||||||
|
load_default=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
class AlertPushUpdateRequest(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警推送信息更新请求
|
||||||
|
"""
|
||||||
|
target_name = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "ERP",
|
||||||
|
"description": "告警对象名称",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
push_url = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={
|
||||||
|
"example": "https://www.baidu.com",
|
||||||
|
"description": "告警推送URL",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 1, "description": "状态 0-禁用,1-启用"},
|
||||||
|
load_default=1,
|
||||||
|
)
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
from dataclasses import field
|
||||||
|
from marshmallow_dataclass import dataclass
|
||||||
|
from marshmallow import validates_schema, ValidationError
|
||||||
|
from iti.applications.common.utils.schema import BaseSchema, Pagination
|
||||||
|
from typing import ClassVar, Optional
|
||||||
|
from apiflask import fields
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(base_schema=BaseSchema)
|
||||||
|
class AlertRuleQuery(Pagination):
|
||||||
|
"""
|
||||||
|
告警规则信息查询请求
|
||||||
|
"""
|
||||||
|
node_id: int = field(
|
||||||
|
default=None,
|
||||||
|
metadata={
|
||||||
|
"required": False,
|
||||||
|
"metadata": {"example": 1, "description": "节点ID"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
status: int = field(
|
||||||
|
default=None,
|
||||||
|
metadata={
|
||||||
|
"required": False,
|
||||||
|
"metadata": {"example": 0, "description": "状态"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
Schema: ClassVar[BaseSchema] = BaseSchema
|
||||||
|
|
||||||
|
class AlertRuleAddRequest(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警规则信息添加请求
|
||||||
|
"""
|
||||||
|
node_id = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={"example": 1, "description": "节点ID"},
|
||||||
|
)
|
||||||
|
rule_name = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={"example": "告警规则1", "description": "告警规则名称"},
|
||||||
|
)
|
||||||
|
alert_rule = fields.String(
|
||||||
|
required=True,
|
||||||
|
metadata={"example": "x<4", "description": "告警规则表达式"},
|
||||||
|
)
|
||||||
|
alert_text = fields.String(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": "节点{{node.title}}告警内容", "description": "告警内容文本模板"},
|
||||||
|
)
|
||||||
|
alert_level = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 0, "description": "告警级别 0-预警,1-一般,2-紧急,3-严重"},
|
||||||
|
load_default=0,
|
||||||
|
)
|
||||||
|
trigger_count = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 1, "description": "阈值触发次数,超过次数后告警"},
|
||||||
|
load_default=1,
|
||||||
|
)
|
||||||
|
status = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 1, "description": "状态 1-启用,0-禁用"},
|
||||||
|
load_default=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
class AlertRuleUpdateRequest(BaseSchema):
|
||||||
|
"""
|
||||||
|
告警规则信息更新请求
|
||||||
|
"""
|
||||||
|
|
||||||
|
node_id = fields.Integer(
|
||||||
|
required=True,
|
||||||
|
metadata={"example": 1, "description": "节点ID"},
|
||||||
|
)
|
||||||
|
rule_name = fields.String(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": "告警规则1", "description": "告警规则名称"},
|
||||||
|
)
|
||||||
|
alert_rule = fields.String(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": "x<4", "description": "告警规则表达式"},
|
||||||
|
)
|
||||||
|
alert_text = fields.String(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": "节点{{node.title}}告警内容", "description": "告警内容文本模板"},
|
||||||
|
)
|
||||||
|
alert_level = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 0, "description": "告警级别 0-预警,1-一般,2-紧急,3-严重"},
|
||||||
|
)
|
||||||
|
trigger_count = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 1, "description": "阈值触发次数,超过次数后告警"},
|
||||||
|
load_default=1,
|
||||||
|
)
|
||||||
|
status = fields.Integer(
|
||||||
|
required=False,
|
||||||
|
metadata={"example": 1, "description": "状态 1-启用,0-禁用"},
|
||||||
|
load_default=1,
|
||||||
|
)
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
from sqlalchemy.orm import noload
|
||||||
|
from sqlalchemy.sql._typing import ColumnExpressionArgument
|
||||||
|
from typing import List, Dict, Any, Optional, Set
|
||||||
|
from iti.applications.extensions import db
|
||||||
|
from flask import current_app
|
||||||
|
from iti.applications.models import (
|
||||||
|
IotAlertLog,
|
||||||
|
IotAlertRule,
|
||||||
|
IotAlertPush,
|
||||||
|
IotEndpoint,
|
||||||
|
)
|
||||||
|
from sqlalchemy import select, distinct
|
||||||
|
|
||||||
|
def add_endpoint_alert_log(endpoint_id: int):
|
||||||
|
"""
|
||||||
|
添加采集端告警日志
|
||||||
|
Args:
|
||||||
|
endpoint_id: 采集端ID
|
||||||
|
"""
|
||||||
|
endpoint = db.session.scalar(select(IotEndpoint).filter_by(id=endpoint_id))
|
||||||
|
if not endpoint:
|
||||||
|
return "采集端不存在"
|
||||||
|
alert_tag = f"ep{endpoint.id}_nd0"
|
||||||
|
alert_log = db.session.scalar(select(IotAlertLog).filter_by(alert_tag=alert_tag))
|
||||||
|
if alert_log:
|
||||||
|
alert_log.trigger_count += 1
|
||||||
|
if alert_log.trigger_count >= 3:
|
||||||
|
alert_log.status = 1
|
||||||
|
push_alert(alert_log)
|
||||||
|
else:
|
||||||
|
dict_data = dict(
|
||||||
|
alert_tag=alert_tag,
|
||||||
|
alert_target_name=f"{endpoint.endpoint_name}({endpoint.endpoint_number})",
|
||||||
|
alert_level=1,
|
||||||
|
status=0,
|
||||||
|
trigger_count=1,
|
||||||
|
alert_content=f"采集端 {endpoint.endpoint_name}({endpoint.endpoint_number}) 网络不可达",
|
||||||
|
)
|
||||||
|
alert_log = IotAlertLog(**dict_data)
|
||||||
|
|
||||||
|
db.session.add(alert_log)
|
||||||
|
db.session.commit()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def push_alert(alert_log: IotAlertLog):
|
||||||
|
"""
|
||||||
|
推送告警消息
|
||||||
|
Args:
|
||||||
|
alert_log: 告警日志
|
||||||
|
"""
|
||||||
|
|
||||||
|
level = f"{alert_log.alert_level}"
|
||||||
|
alert_push_list = db.session.scalars(select(IotAlertPush).filter(IotAlertPush.alert_level.contains(level))).all()
|
||||||
|
if alert_push_list:
|
||||||
|
for alert_push in alert_push_list:
|
||||||
|
# TODO 调用地址发送告警消息
|
||||||
|
current_app.logger.info(f"推送告警消息到 {alert_push.push_url},内容:{alert_log.alert_content}")
|
||||||
Loading…
Reference in New Issue