X-Admin&ABP框架开发-系统日志
网站正常运行中有时出现异常在所难免,查看系统运行日志分析问题并能够根据错误信息快速解决问题尤为重要,ABP对于系统运行日志这块已经做了很好的处理,默认采用的Log4Net已经足够满足开发过程中的需要了(当然有需要的话也可以更换为其它日志组件)。
ABP官网地址:https://aspnetboilerplate.com/
一、日志文件
ABP框架默认使用了Log4Net日志组件,日志记录在txt文件中,也可以替换成其它日志组件诸如Nlog,方便将日志文件信息直接记录到数据库中,具体情形使用具体组件。
当一个文件达到了在Log4Net配置中设置好的文件大小上限时,在文件名后按照数字倒排后开始继续增加文件。
当需要查看错误信息时,直接在日期最近的文件中找出错误信息即可,但是这个过程比较繁琐,还需要从日志文件中去查看,并且日志文件中虽然做了分类,哪些是正常信息,哪些是错误信息,但是不太直观,因此,可以考虑直接将日志文件在页面中呈现,对信息进一步加工,方便直接查看。
参考了AbpZero中的部分代码并根据实际需要进行整合,开始在页面中设计日志展示层。
二、页面展示日志信息
1、系统日志服务应属于整个系统中相对其他业务模块独立的一部分,因此,首先在应用层中新建一个Logging文件夹并创建一个日志应用层服务接口与其实现。在接口中声明两个方法,直接查看当前最近的日志文件中的日志信息以及从服务器下载所有的日志文件。
/// <summary>
/// 网站运行日志应用层服务
/// </summary>
public interface IWebSiteLogAppService : IApplicationService
{
/// <summary>
/// 获取最近的一个日志文件
/// </summary>
/// <returns></returns>
GetLatestWebLogsOutput GetLatestWebLogs(); /// <summary>
/// 下载所有的日志文件
/// </summary>
/// <returns></returns>
FileDto DownloadWebLogs();
}
首先考虑直接获取最近的日志文件信息,直接读取即可,遵循的规则是读取指定文件夹下指定文件后缀名更改日期为最大的文件然后从中读取日志信息,并返回到前端。
public GetLatestWebLogsOutput GetLatestWebLogs()
{
var directory = new DirectoryInfo(AppConsts.LogFilePath); if (!directory.Exists)
{
return new GetLatestWebLogsOutput
{
LatestWebLogLines = new List<string>()
};
} var lastLogFile = directory.GetFiles("*.txt", SearchOption.AllDirectories)
.OrderByDescending(f => f.LastWriteTime)
.FirstOrDefault(); if (lastLogFile == null)
{
return new GetLatestWebLogsOutput();
} var lines = AppFileHelper.ReadLines(lastLogFile.FullName).Reverse().Take().ToList();
var logLineCount = ;
var lineCount = ; foreach (var line in lines)
{
if (line.StartsWith("DEBUG") ||
line.StartsWith("INFO") ||
line.StartsWith("WARN") ||
line.StartsWith("ERROR") ||
line.StartsWith("FATAL"))
logLineCount++; lineCount++; if (logLineCount == ) break;
} return new GetLatestWebLogsOutput
{
LatestWebLogLines = lines.Take(lineCount).Reverse().ToList()
};
}
2、在前端处理日志信息,Mvc层中新增一个控制器,并写一个方法调用日志服务获取最近的日志文件信息,并处理好权限问题及页面左侧菜单的展示。
/// <summary>
/// 系统维护控制器
/// </summary>
[AbpMvcAuthorize]
public class MaintenanceController : SurroundControllerBase
{
private readonly IWebSiteLogAppService _webSiteLogAppService; public MaintenanceController(IWebSiteLogAppService webSiteLogAppService)
{
_webSiteLogAppService = webSiteLogAppService;
} /// <summary>
/// 首页
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
return View();
} /// <summary>
/// 获取最近日志信息
/// </summary>
/// <returns></returns>
public JsonResult GetLatestWebLogs()
{
var getLatestWebLogsOutput = _webSiteLogAppService.GetLatestWebLogs();
return Json(getLatestWebLogsOutput);
}
}
增加一个视图文件并开始编写前端代码获取日志文件,利用abp前端封装好的ajax请求快速的获取日志文件,然后通过layui中提供的徽章进行加工处理,如此一来,通过颜色快速区分哪些是错误信息,哪些信息权重更大,更值得关注,此处引用了一个lodash.js,该js中提供了许多的辅助方法。
function getFormattedLogs(logLines) {
var resultHtml = '';
$.each(logLines, function (index, logLine) {
resultHtml += '<span>' + _.escape(logLine)
.replace('DEBUG', '<span class="layui-badge layui-bg-gray">DEBUG</span>')
.replace('INFO', '<span class="layui-badge layui-bg-green">INFO</span>')
.replace('WARN', '<span class="layui-badge layui-bg-orange">WARN</span>')
.replace('ERROR', '<span class="layui-badge">ERROR</span>')
.replace('FATAL', '<span class="layui-badge">FATAL</span>') + '</span><br/>';
});
return resultHtml;
}
通过刷新按钮获取最近的日志信息。
三、下载日志文件
也可以直接下载日志文件去分析,当然,从使用频率讲,这个功能的权重远低于直接页面查看,但是细想一下,如果说一个异常发生,没有及时去页面中查看,那么就得去成堆的日志中翻找,反而凸显其作用了。
public FileDto DownloadWebLogs()
{
var logFiles = GetAllLogFiles(); var zipFileDto = new FileDto("WebSiteLogs.zip", MimeTypeNames.ApplicationZip); using (var outputZipFileStream = new MemoryStream())
{
using (var zipStream = new ZipArchive(outputZipFileStream, ZipArchiveMode.Create))
{
foreach (var logFile in logFiles)
{
var entry = zipStream.CreateEntry(logFile.Name);
using (var entryStream = entry.Open())
{
using (var fs = new FileStream(logFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 0x1000, FileOptions.SequentialScan))
{
fs.CopyTo(entryStream);
entryStream.Flush();
}
}
}
} _tempFileCacheManager.SetFile(zipFileDto.FileToken, outputZipFileStream.ToArray());
} return zipFileDto;
} private List<FileInfo> GetAllLogFiles()
{
var directory = new DirectoryInfo(AppConsts.LogFilePath);
return directory.GetFiles("*.*", SearchOption.TopDirectoryOnly).ToList();
}
将日志文件全部读取出来,然后打包存储在缓存中,前端点击下载按钮时后台返回压缩包的标识信息供前端直接下载,此处在控制器中加入一个文件管理的控制器,来作为系统中大部分文件下载的渠道。
var waitIndex = parent.layer.load();
abp.ajax({
type:"Get",
url: "@Url.Action("DownloadWebLogs", "Maintenance")",
abpHandleError: false
}).done(function (file) {
location.href = '@Url.Action("DownloadTempFile", "File")' + abp.utils.formatString("?fileToken={0}&fileType={1}&fileName={2}", file.fileToken, file.fileType, file.fileName);
}).fail(function (jqXHR) {
parent.layer.msg(jqXHR.message, { icon: });
}).always(function () {
parent.layer.close(waitIndex);
});
点击日志下载,浏览器开始执行下载任务。
至此,系统日志的页面查看就完成了,对于加入诸如查询等更加丰富的功能,可以再进行扩展,也可以考虑直接使用已有的组件更方便的呈现的日志信息而无需手动实现,诸如LogDashBoard等,可以很快速的接入到系统中。
代码地址:https://gitee.com/530521314/Partner.Surround.git
2019-08-03,望技术有成后能回来看见自己的脚步
X-Admin&ABP框架开发-系统日志的更多相关文章
- X-Admin&ABP框架开发-消息通知
业务型网站使用过程中,消息通知是一个不可或缺的功能,采用站内通知.短信通知.邮件通知.微信通知等等各种方式都有,ABP框架对这部分工作已经封装的很好了,站在巨人的肩膀上,一览全貌,带来的就是心情舒畅. ...
- X-Admin&ABP框架开发-版本管理
多租户系统中,针对于不同租户开放不同功能,或是按照不同功能进行收费管理,需要从宿主本身去管理租户的版本信息,如同酒店人员对不同房间收取不同费用,依据房间内部设施,房间大小等设置不同收费标准.Abp系统 ...
- X-Admin&ABP框架开发-代码生成器
在日常开发中,有时会遇到一些相似的代码,甚至是只要CV一次,改几个名称,就可以实现功能了,而且总归起来,都可以由一些公用的页面更改而来,因此,结合我日常开发中使用到的页面,封装一个适合自己的代码生成器 ...
- X-Admin&ABP框架开发-设置管理
在网站开发中,设置是不可缺少的一环,如用户设置.系统设置.甚至是租户设置等.ABP对于设置的管理已经做了很好的处理,我们可以借助巨人的力量来完成我们的冒险. ABP官网地址:https://aspne ...
- X-Admin&ABP框架开发-RBAC
在业务系统需求规划过程中,通常对于诸如组织机构.用户和角色等这种基础功能,通常是将这部分功能规划到通用子域中,这也说明了,对于这部分功能来讲,是系统的基石,整个业务体系是建立于这部分基石之上的,当然, ...
- X-Admin&ABP框架开发-数据字典
在业务型的系统开发中,我们需要维护各种个样的类型,比如客户类型.客户行业.商品类型等等,这些类型往往信息量不多,并且相似度极高,如果采用一类型一表去设计,将会造成极大的工作量,通过将这部分类型的信息进 ...
- X-Admin&ABP框架开发-租户管理
软件即服务概念的推动,定制化到通用化的发展,用一套代码完成适应不同企业的需求,利用多租户技术可以去做到这一点.ABP里提供了多租户这一概念并且也在Zero模块中实现了这一概念. 一.多租户的概念 单部 ...
- 高薪诚聘熟悉ABP框架的.NET高级开发工程师(2016年7月28日重发)
招聘单位是ABP架构设计交流群(134710707)群主阳铭所在的公司-上海运图贸易有限公司 招聘岗位:.NET高级开发工程师工作地点:上海-普陀区 [公司情况]上海运图贸易有限公司,是由易迅网的创始 ...
- ABP框架实践基础篇之开发UI层
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 说明 其实最开始写的,就是这个ABP框架实践基础篇.在写这篇博客之前,又回头复习了一下ABP框架的理论,如果你还没学习,请查看AB ...
随机推荐
- 【设计模式】结构型04桥接模式(Bridge Pattern)
学习地址:http://www.runoob.com/design-pattern/bridge-pattern.html 桥接模式(Bridge Pattern) 桥接模式(Bridge patte ...
- CentOS 7出现Failed to start firewalld.service: Unit is masked的解决办法和firewalld 防火墙开关
说明:刚刚使用systemctl start firewalld命令开启防火墙的时候,却开不成功,出现Failed to start firewalld.service: Unit is masked ...
- 从Spring的几个阶段理解其工作过程
Spring框架非常强大,想要彻底弄懂Spring是非常困难的. 为了便于了解Spring的工作原理,我们来研究一下,Spring是怎么加载的,Spring会经过几个阶段. 我们站在Javaweb ...
- linuxprobe培训第1节课笔记2019年7月5日
报了老刘的RHCE培训,这是老刘上课笔记简略版. 老刘在课上介绍了开源共享精神和大胡子(Richard M. Stallman—GNU创始人).linux发展史(Linus Benedict Torv ...
- 微信小程序在ios下Echarts图表不能滑动的解决方案
问题现象 这个问题的现象说起来很简单. 小程序页面中有一篇很长的文章,内部有一个Echarts图表,手指上下滑动观看内容. 但是手指滑动区域在Echarts图表上时,页面却不能滑动了. 如下图: 追踪 ...
- POJ 3680:Intervals(最小费用最大流)***
http://poj.org/problem?id=3680 题意:给出n个区间[Li,Ri],每个区间有一个权值wi,要使得每个点都不被超过k个区间覆盖(最多能被k个区间覆盖),如果选取了第i个区间 ...
- kubeadm安装k8s
软件版本: kubelet:V1.13.3 docker: 18.06.1 实验环境: Centos 7.5.1804 说明: 初学.安装步骤参考了阿良的文档,并做了部分修改. 步骤如下: 1.关闭防 ...
- 不使用 ASR 将虚机还原到另一个数据中心
背景 在 Azure 上可能会遇到一个场景是将一台虚机搬到另一台数据中心,在不借助 ASR 的情况下我们该如何做? 因为 ASR 在云上更多的场景是用于灾备到异地.对于虚机的相关信息主要的是磁盘和网络 ...
- 基于C#的机器学习--深层信念网络
我们都听说过深度学习,但是有多少人知道深度信念网络是什么?让我们从本章开始回答这个问题.深度信念网络是一种非常先进的机器学习形式,其意义正在迅速演变.作为一名机器学习开发人员,对这个概念有一定的了解是 ...
- plot3d网格读取写入与可视化
目录 说明 对于程序的说明 源码 说明 plot3d格式是NASA制定并大量使用的CFD网格文件格式,在CFD编程过程中经常涉及到.本文利用Python语言编写一个读取plot3d文件,写入plot3 ...