Adhesive框架系列文章--报警服务模块使用和实现

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
日志服务 SLS,月写入数据量 50GB 1个月
简介: Adhesive框架的Mongodb数据服务模块提供了大量数据的存储功能。在有的时候,我们希望对数据量或是数据的某个值进行一个监控,并且在达到某个阀值之后进行报警。此时,可以使用报警服务模块进行邮件报警和短信报警。

Adhesive框架的Mongodb数据服务模块提供了大量数据的存储功能。在有的时候,我们希望对数据量或是数据的某个值进行一个监控,并且在达到某个阀值之后进行报警。此时,可以使用报警服务模块进行邮件报警和短信报警。报警服务的实现其实很简单,定期检测数据量或数据的值,然后根据配置决定是否要报警,如果要的话,根据配置获取报警的接收者,然后进行相应的报警。现在先来看一下报警服务的配置,同样,打开配置后台可以在全局配置中找到报警服务的配置节点:

image

点击进去:

image

在这里依次介绍一下每一个配置:

1、状态数据的报警配置:这里配置了基于状态数据的报警配置。所谓状态信息,就是始终只有一条最新的数据代表了一个状态,报警也就是查看其中某个列的值,根据这个值来判断是否需要报警。

2、统计数据的报警配置:这里配置了基于统计数据的报警配置。所谓统计数据,就是一个时间间隔内有多少条数据写入,报警取决于数据量,而不是其中某一条数据的某个列的值。

3、接收者的配置:在这里把报警数据接收者分了组,使用组的概念来管理这些信息接收者。

4、短信服务的类别ID:这个是我们公司特有的短信通道的类别ID,不具有普适性。

5、邮件服务器的地址和帐号:在这里发送邮件使用的是Common模块中提供的JMail发送邮件的功能。

6、邮件标题和正文以及短信和日志消息的模板:这里配置的是,发送邮件的标题和正文、发消息的内容以及日志记录的内容的一个模板。其中有很多占位符:

1)配置的名字

2)列名

3)报警时间间隔

4)数据量

5)条件类型

6)阀值

一个典型的数据如下:

Adhesive.Test.Mvc错误日志监控 ItemCount 60秒 1400 MoreThan 100

7、发送邮件和短消息的时间间隔,发送邮件和短消息出错后的时间间隔:在这里我们还是使用了内存队列服务模块来发送邮件和短消息,这里配置的是正常情况下多少毫秒发送一次邮件或短消息,以及错误情况下多少时间后再一次尝试进行短消息和邮件的发送。

 

先来看一下报警接收者分组的配置:

image

在这里我们添加了一个名为测试的组:

image

对于每一个组都有如下的配置:

1、组名

2、是否开启邮件消息

3、是否开启手机短信消息

4、发送邮件消息的间隔,也就是在一定时间内只会发送一次消息

5、发送手机消息的间隔,同上。在有的时候我们可能会对相同的报警信息发送到两个组,第一个组允许1秒收一次消息,而第二个组是领导组,不希望有很多骚扰,那么可以配置时间长一点。

6、组内的接收者明细:

image

这里配置了一个用户,再点击进去查看明细:

image

对于每一个用户配置帐号、真实姓名、手机号码和邮箱地址。

 

然后,来看一下两种报警模式的配置,第一个是基于数据量的报警:

image

点击进入数据量统计配置节点之后可以看到在这里我们配置了一个叫错误日志监控的报警。也就是希望监控Adhesive.Test.Mvc这个表中错误日志的数据量,现在来看一下怎么通过灵活的配置完成这个功能:

image

首先,我们知道错误日志是存在Aic__Log这个数据库中的,那么我们指定数据库名为Aic__Log。然后我们希望针对Adhesive.Test.Mvc这个表进行报警,那么也需要配置相应的表名。然后我们希望配置1分钟内数据量超过100条则报警,那么需要把时间间隔配置为1分钟,把数据量阀值配置成100,把条件类型配置为MoreThan,这是一个枚举:

    internal enum AlarmConditionType
    {
        LessThan = 1,
        LessThanAndEqualTo = 2,
        MoreThan = 3,
        MoreThanAndEqualTo = 4,
    }

并且配置10秒进行一次检查,前1分钟是不是达到阀值。这里还有一个问题,就是我们希望只针对错误级别的日志进行报警,那么我们需要进一步配置数据过滤:image

在这里配置Lev为4。可以对比下LogInfo的定义:

   [MongodbPersistenceItem(MongodbIndexOption = MongodbIndexOption.Ascending, ColumnName = "Lev")]
        [MongodbPresentationItem(MongodbFilterOption = MongodbFilterOption.DropDownListFilter, DisplayName = "日志级别", ShowInTableView = true)]
        public LogLevel LogLevel { get; set; }

其中看到,日志级别的列名为Lev,并且LogLevel值为4的级别是Error:

    public enum LogLevel
    {
        None = 99,
        Debug = 1,
        Info = 2,
        Warning = 3,
        Error = 4
    }

 

最后,看一下基于状态的配置:

image

在这里我们希望监控Mongodb服务端内存队列中当前项的数量,如果数量超过100则报警(内存中有100条剩余的数据来不及提交到数据库)。

image

基本的配置和统计量的配置差不多,只不过注意这里的列名是模糊匹配的:

image

对比一下State__MongodbServer的定义,也就是任意一个内存队列的CurrentItemConut超过100都会报警。之所以能这样是因为我们Mongodb存储字典是树形结构的。

 

介绍了报警服务的配置之后,我们来看其中的一个最关键的实现,也就是服务的初始化过程:

       internal static void Init()
        {
            mailService.Init(AlarmConfiguration.GetConfig().MailSmtp, AlarmConfiguration.GetConfig().MailUsername, AlarmConfiguration.GetConfig().MailPassword);
            mobileService.Init(AlarmConfiguration.GetConfig().MobileCategoryId);

            mailMemoryQueueService.Init(new MemoryQueueServiceConfiguration("AlarmService_MailQueue", mailService.Send)
            {
                ConsumeItemCountInOneBatch = 1,
                ConsumeIntervalMilliseconds = AlarmConfiguration.GetConfig().MailMessageInerval,
                ConsumeIntervalWhenErrorMilliseconds = AlarmConfiguration.GetConfig().MailMessageErrorInerval,
                ConsumeErrorAction = MemoryQueueServiceConsumeErrorAction.EnqueueTwiceAndLogException
            });
            mobileMemoryQueueService.Init(new MemoryQueueServiceConfiguration("AlarmService_MobileQueue", mobileService.Send)
            {
                ConsumeItemCountInOneBatch = 1,
                ConsumeIntervalMilliseconds = AlarmConfiguration.GetConfig().MobileMessageInerval,
                ConsumeIntervalWhenErrorMilliseconds = AlarmConfiguration.GetConfig().MobileMessageErrorInerval,
                ConsumeErrorAction = MemoryQueueServiceConsumeErrorAction.EnqueueTwiceAndLogException
            });
            var config = AlarmConfiguration.GetConfig();
            foreach (var item in config.AlarmConfigurationByStatistics)
            {
                var alarmServiceState = new AlarmServiceState
                {
                    AlarmConfigurationItemName = item.Key,
                    AlarmServiceStateItems = new Dictionary<string, AlarmServiceStateItem>(),
                };
                item.Value.AlarmReceiverGroupNames.Values.Each(groupName =>
                {
                    alarmServiceState.AlarmServiceStateItems.Add(groupName, new AlarmServiceStateItem
                    {
                        ReceiverGroupName = groupName,
                        AlarmReceiverGroupLastMailMessageTime = DateTime.MinValue,
                        AlarmReceiverGroupLastMobileMessageTime = DateTime.MinValue,
                    });
                });
                var interval = item.Value.CheckTimeSpan;
                var timer = new System.Threading.Timer(CheckActionForStatistics, item.Key, interval, interval);
                alarmServiceState.CheckTimer = timer;
                alarmServiceStates.Add(alarmServiceState);
            }

            foreach (var item in config.AlarmConfigurationByStates)
            {
                var alarmServiceState = new AlarmServiceState
                {
                    AlarmConfigurationItemName = item.Key,
                    AlarmServiceStateItems = new Dictionary<string, AlarmServiceStateItem>(),
                };
                item.Value.AlarmReceiverGroupNames.Values.Each(groupName =>
                {
                    alarmServiceState.AlarmServiceStateItems.Add(groupName, new AlarmServiceStateItem
                    {
                        ReceiverGroupName = groupName,
                        AlarmReceiverGroupLastMailMessageTime = DateTime.MinValue,
                        AlarmReceiverGroupLastMobileMessageTime = DateTime.MinValue,
                    });
                });
                var interval = item.Value.CheckTimeSpan;
                var timer = new System.Threading.Timer(CheckActionForState, item.Key, interval, interval);
                alarmServiceState.CheckTimer = timer;
                alarmServiceStates.Add(alarmServiceState);
            }
        }
    }

我们知道在报警服务模块中,我们也是通过内存队列服务来进行邮件和短信数据发送的,那么我们首先是初始化两个内存队列。

然后,我们读取配置,分别为基于统计数据的报警和基于状态的报警初始化后台的定时器,每一种配置一个定时器。定时器的执行间隔就是前面提到的CheckTimeSpan。而我们的代码中也定义了alarmServiceStates字段作为根:

 private static List<AlarmServiceState> alarmServiceStates = new List<AlarmServiceState>();
作者: lovecindywang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
7月前
|
机器学习/深度学习 计算机视觉 索引
YOLOv11改进策略【Conv和Transformer】| ECCV-2024 Histogram Transformer 直方图自注意力 适用于噪声大,图像质量低的检测任务
YOLOv11改进策略【Conv和Transformer】| ECCV-2024 Histogram Transformer 直方图自注意力 适用于噪声大,图像质量低的检测任务
345 9
YOLOv11改进策略【Conv和Transformer】| ECCV-2024 Histogram Transformer 直方图自注意力 适用于噪声大,图像质量低的检测任务
|
8月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的高校食堂移动预约点餐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
9月前
|
存储 安全 物联网
未来已来:区块链技术在物联网与虚拟现实中的应用
随着科技的不断进步,新兴技术如区块链、物联网(IoT)和虚拟现实(VR)正在逐渐改变我们的生活和工作方式。本文将探讨这些技术的发展趋势和应用场景,以及它们如何相互融合,为我们带来更便捷、安全和沉浸式的体验。
|
10月前
|
供应链 安全 芯片
台积电7nm芯片断供影响分析:中国大陆半导体产业的挑战与机遇
近日,有关台积电可能断供中国大陆7nm芯片的消息引发了业界的广泛关注。这一事件不仅关系到全球半导体供应链的稳定性,也对中国大陆半导体产业的发展提出了新的挑战。本文将探讨这一事件背后的原因、可能的影响以及中国大陆半导体产业的应对策略。
569 0
|
分布式计算 项目管理 MaxCompute
MaxCompute元数据使用实践--数据权限统计
本文主要介绍通过元数据的相关权限的视图进行数据权限的统计。
101778 2
|
监控 容灾 数据中心
《云上容灾交付服务白皮书》——3交付标准化参考框架——3.3 容灾方案设计(上)
《云上容灾交付服务白皮书》——3交付标准化参考框架——3.3 容灾方案设计(上)
279 0
|
应用服务中间件 C语言 nginx
Nginx Upload Module 上传模块
传统站点在处理文件上传请求时,普遍使用后端编程语言处理,如:Java、PHP、Python、Ruby等。今天给大家介绍Nginx的一个模块,Upload Module上传模块,此模块的原理是先把用户上传的文件保存到临时文件,然后在交由后台页面处理,并且把文件的原名,上传后的名称,文件类型,文件大小set到页面。
2145 0
|
SQL 关系型数据库 MySQL
kingbaseES(人大金仓)数据库语法和常用函数 以及 踩坑记录
最近公司弄了个新项目,数据库指定使用kingbase数据库
|
存储 Ubuntu 数据可视化
在Ubuntu 和 CentOS 中不用密码运行sudo命令
通常,不建议所有没有权限的用户在没有密码的情况下运行 sudo。建议您创建一个新的 sudoers 文件并单独分配命令必须运行没有密码的 sudo 命令!
1024 0
|
存储 Rust JavaScript