Log2Net日志查询网站代码解析
在前面的几节中,我们介绍了Log2Net的使用方法和代码设计。使用这个组件,我们可以方便地将日志记录到数据库中,那么,我们怎么能看到这些日志呢?于是,日志查询网站应运而生。效果图如下:
该代码已开源,地址为 https://github.com/yuchen1030/Log2Net-LgWG.LogQuery 。下面介绍其代码设计。
一、总体介绍
日志查询网站由三部分组成:1、系统监控;2、日志查询;3、权限设计。本系统对应的数据库为读写分离中的读,使用的数据库为LogTrace_R、LogMonitor_R以及LogQuery,项目名称为LgWG.LogQuery。LgWG意为Log2Net Work Group。
本网站采用ABP框架,需要对以下知识有所了解:ASP.NET MVC 5、Web API 2、DDD领域驱动设计 (Entities、Repositories、Domain Services、Domain Events、Application Services、DTOs等)、Ioc/DI、Castle windsor (依赖注入容器)、Entity Framework 6、数据迁移、AutoMapper(实现Dto类与实体类的双向自动转换)、SignalR、Bootstrap 、jQuery等。参考网站:http://www.aspnetboilerplate.com/ 。
使用该框架进行开发时,第一步是从ABP官网http://www.aspnetboilerplate.com/Templates上下载模板,例如本项目起名为LgWG.LogQuery,则下载的模板如下图所示:
该项目需要使用VS2017打开,.net版本为4.6.1,对Nuget的版本要求等请按照提示进行相应安装。还原程序包后,将web项目设为起始项目,在程序包管理器控制台下选择EF项目,运行Update-Database命令,系统会自动为我们创建默认的数据库。然后运行项目就可以得到一个直接运行的网站,可以进行权限管理(租户管理、角色管理、用户管理)等。我们在此基础上添加我们的业务功能实现日志查询。
本网站分为公共方法/工具类、基础设施层、领域层、应用服务层、网站应用层,权限部分的设计ABP已经为我们实现好了,我们需要做的工作是实现监控日志LogMonitor和操作轨迹日志LogTrace这两个领域的实现和应用。
二、领域核心层和基础设施层
ABP框架中,官方推荐使用code first,即先写领域核心层实体,创建数据库迁移,然后生成数据库。对于LogQuery数据库,确实是这样的(对此数据库的实体,ABP已经为我们做好了,我们只需要upodate数据库即可)。然而对于LogTrace_R和LogMonitor_R数据库,他们已经存在了,我们采用Code first from database的方式来生成实体和数据库上下文。具体做法是在EF项目下添加ADO.NET实体数据模型,然后选择Code first from database,选择数据库连接之后就会创建实体模型,然后我们将这里生成的实体剪切到core项目下,即完成了core层的实体创建工作。
LgWG.LogQuery.Core层定义系统的领域,即定义系统使用的实体,定义仓储接口等。本项目定义了LogTrace和LogMonitor两个领域,分别定义了其实体和仓储接口。我们定义了泛型的基础仓储接口IBaseRepository,这两个仓储接口继承之。
LgWG.LogQuery.EntityFramework层为仓储实现,我们分别定义这两个实体接口的实现。一般情况下,我们只需要继承EfRepositoryBase就可以了,EfRepositoryBase已经为我们定义了常见的增删改查方法的实现,只有对一些特殊的方法才需要我们自己来实现。
三、应用服务层
本层(LgWG.LogQuery.Application)调用核心层的接口,对UI层提供服务。在本层中,DTO数据传输对象的主要作用是封装UI层需要的数据,避免数据库实体全部暴露给UI层。这些dto对象被用作服务层方法的参数或返回值。
本层中的服务分为接口和实现,调用时使用接口方法。这些接口继承了IApplicationService接口,ABP框架会自动将这些接口转为为可以以WebAPI形式调用的接口。本系统中定义的服务接口如下图所示:
然后,编写相应的接口的实现代码,分别位于Log_OperateTraceService类和Log_SystemMonitorService类中,具体参见源代码。
它们生成的webpai接口如下图所示(SwaggerUI显示):
在上述方法中,只有GetLogMonitorsEveryServer略为复杂。在GetLogMonitorsEveryServer方法中,根据用户的监控范围、显示点数等条件检索监控数据。若监控范围内的数据量total大于要显示的点数tarNum,则在从0~total-1中取出tarNum个数,尽量做到间隔相等,使用等差数列的算法,具体实现参见代码中的GetDataByInterval方法。
四、网站表现层
本层用于展现网站,是和用户直接打交道的界面。使用的是ASP.NET MVC5.0框架,表格显示采用的是Bootstrap-table,饼图曲线图显示使用的是chart,js,曲线图实时更新采用的是SignalR技术,
界面效果见文章开头所示。
4.1 轨迹日志查询界面及实现
轨迹日志查询就是根据日期、日志类型、用户姓名、模块名、关键词等条件,从数据库中检索出相关数据,显示到界面上。另外还显示了各服务器当前的CPU使用率和内存使用率。该部分所有代码位于LogTraceController及其对应的视图中。如下图所示:
这3个方法都是调用应用服务层的相关方法实现。具体参考代码。
4.2 系统监控界面及实现
系统监控就是实时显示各个服务器的运行情况,并可根据日期、系统名称等条件,从数据库中检索出详细的监控数据,显示到界面上。该部分所有代码位于LogMonitorController及其对应的视图中。如下图所示:
这4个方法都是调用应用服务层的相关方法实现。具体参考代码。
在曲线图显示中,用户可以设置监控范围、显示点数、是否为实时模式、窗口模式等条件,在查询模式和实时更新模式中都会根据这些条件获取响应的数据,进行相应的显示。这些设置可以根据用户级或租户级从数据库中读取(AbpSettings表),暂时实现设置的保存。
为实现实时更新功能,系统中定义了LogMonitorHub 集线器,服务器端定时从数据库中获取最新的监控信息,使用SignalR技术,前台的updateLogMonitorDatas方法被调用,完成前台的同步更新(_clients.Clients(list).updateLogMonitorDatas())。由于在该LogMonitorDal中,直接调用ILog_OperateTraceService 和ILog_SystemMonitorService无效,我们通过WebAPI接口的方法获取到实时的监控数据,具体代码参见GetMonitorChartDataFromAPI方法(这里的/api/services/app/log_SystemMonitorService/GetMonitorChartData就是ABP框架根据我们的服务的接口,自动为我们生成的接口)。
另外,系统是实时更新的过程中,会检测服务器个数和名称是否和上次一致,若不一致,说明有服务器新加入或失去联系,此时会在有上方的消息收件箱中进行提示,并播放音乐报警。
4.3 系统基础功能
1、用户权限管理:系统可进行用户权限管理,包括租户管理、角色管理、用户管理。本系统大部分采用ABP框架自带的权限系统,只是在角色中增加了每个角色的操作范围。具体请参考代码。
2、日志记录:本系统引用Log2Net组件,在Application_Start事件中注册日志系统,在各application和session事件中注册各个日志事件,实现系统监控日志和轨迹日志的记录。
因为本项目的业务比较简单,就是从数据库查询出数据并显示出来,代码逻辑没有太多可以说道的地方。因此没有详细的贴出代码。把界面设计的美观和实用,才是本系统的重点,这非本人所长,因此套用了ABP框架和BootstrapUI,效果看得过去就完工啦。代码参见 https://github.com/yuchen1030/Log2Net-LgWG.LogQuery。
欢迎提出问题,欢迎使用~~