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

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: 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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
监控 JavaScript 前端开发
Sentry 监控 - Environments 区分不同部署环境的事件数据
Sentry 监控 - Environments 区分不同部署环境的事件数据
315 0
Sentry 监控 - Environments 区分不同部署环境的事件数据
|
监控 网络协议 关系型数据库
zabbix自动化监控---自动注册机制(二十三)
zabbix自动监控之自动注册 1.自动注册介绍 zabbix自动发现的效率非常慢,每次自动发现的时候都需要对所有的主机进行扫描,也类似与zabbix被动模式,每次都需要向机器进行一次探测,比如这次某个主机没有存在,下次上线了又要重新扫描一次,效率非常低下。 而zabbix自动注册的原理就类似主动模式,每次都是由zabbix-agent主动去向zabbix-server说我上线了,需要加入监控,这时zabbix-server同意后立马就加入监控了,这个效率是非常高的 zabbix自动注册只需要配置四个地方即可生效
340 0
zabbix自动化监控---自动注册机制(二十三)
|
监控 Linux
zabbix自动化监控---自动发现机制(二十二)
zabbix自动监控之自动发现 1.自动发现介绍 当我们有上千台主机都需要加监控的时候用自动发现会非常方便,只需要我们创建一个自动发现规则,设置自动发现的范围,在根据设置的动作就可以将已经安装好agent的Linux服务器自动的添加到监控上
859 0
zabbix自动化监控---自动发现机制(二十二)
|
存储 缓存 资源调度
Hooks + TS 搭建一个任务管理系统(终)-- 项目总结
Hooks + TS 搭建一个任务管理系统(终)-- 项目总结
288 0
Hooks + TS 搭建一个任务管理系统(终)-- 项目总结
[ABP实战开源项目]---ABP实时服务-通知系统.发布模式
简介 在ABP中,提供了通知服务。它是一个基于实时通知的基础设施。分为订阅模式和发布模式。 本次会在项目中使用发布模式来演示一个用户注册后,收到的欢迎信息。
1363 0

热门文章

最新文章