您的位置:首页 >聚焦 >

热门看点:基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)

2022-07-30 19:30:08    来源:程序员客栈
系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)前言

最近好几天都忙着写代码,没更新文章,近期给博客增加了一些功能,本文一次性介绍~

新增的功能如下:


(相关资料图)

系统监控:sentry、exceptionless、CLRStats访问统计配置管理初始化系统监控

PS:其实前面两篇关于日志收集工具介绍的文章也是为了给本文做铺垫

系统监控这块包括日志收集、性能监测和系统状态监测。

日志收集和性能监测我交给了ExceptionLess和Sentry,这俩开源的工具可以很好的完成这些工作,详情可以看我之前写的这俩篇文章:

Sentry的安装、配置、使用ExceptionLess的安装、配置、使用

然后状态监测我是基于GitHub上的一个开源项目来魔改的:CLRStats

这个组件可以实时查看CPU、GC、线程的状态,不过原版的实现是作为一个中间件嵌入AspNetCore项目,并且访问的地址只能用Basic认证,不适用。

于是我把代码clone下来之后魔改了一下,变成一个可以调用的服务,并且重新写了API接口,终于方便起来了~

这个接口拿到的数据是这样的,后续在管理后台里面做成可视化图表也比较方便。

{"server":{"machineName":"machineName","systemDateTime":"7/26/202211:30:22PM"},"application":{"cpu":{"usagePercent":0},"gc":{"gen0CollectCount":24,"gen1CollectCount":23,"gen2CollectCount":22,"heapMemory":38328872,"heapMemoryFormat":"36M","isServerGC":true},"thread":{"availableCompletionPortThreads":1000,"availableWorkerThreads":32766,"usedCompletionPortThreads":0,"usedWorkerThreads":1,"usedThreadCount":29,"maxCompletionPortThreads":1000,"maxWorkerThreads":32767}}}

具体代码就不复制粘贴了,我把它放在StarBlog.Contrib项目中,作为一个独立的组件方便调用。

访问统计

虽然前面这篇文章有介绍访问统计的实现:基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计

不过只是单纯讲了通过中间件实现访问记录,这些数据存在数据库之后并没有被利用起来

现在就实现了一些简单的统计,目前主要实现了总览数据(总访问、今日、昨日访问)、趋势数据、指定日期统计,这几个功能。

逻辑代码在StarBlog.Web/Services/VisitRecordService.cs中

总览数据代码在这

PS:我发现FreeSQL的ISelect对象在链式操作时候的行为很奇怪,我知道是懒加载,但是已经执行了.Count()似乎还没执行,下一行调用的代码甚至会把前面的筛选条件加上,无奈我之内在方法内又写了一个嵌套的方法……

也就是这个GetQuerySet,这点让我这种用习惯DjangoORM的人觉得很不适应 = =..

这个接口计算总访问量、今日访问量、昨日访问量,方便做对比(受知乎的创作者中心启发)

publicobjectOverview(){ISelectGetQuerySet()=>_repo.Where(a=>!a.RequestPath.StartsWith("/Api"));returnnew{TotalVisit=GetQuerySet().Count(),TodayVisit=GetQuerySet().Where(a=>a.Time.Date==DateTime.Today).Count(),YesterdayVisit=GetQuerySet().Where(a=>a.Time.Date==DateTime.Today.AddDays(-2).Date).Count(),};}

趋势数据

也就是统计最近n天的访问量

PS:C#的日期处理还是比较舒服的

publicobjectTrend(intdays=7){return_repo.Where(a=>!a.RequestPath.StartsWith("/Api")).Where(a=>a.Time.Date>DateTime.Today.AddDays(-days).Date).GroupBy(a=>a.Time.Date).ToList(a=>new{time=a.Key,date=$"{a.Key.Month}-{a.Key.Day}",count=a.Count()});}

按日期统计

这个简单粗暴不用多说

publicobjectStats(DateTimedate){vardata=_repo.Where(a=>a.Time.Date==date.Date&&!a.RequestPath.StartsWith("/Api"));returnnew{Count=data.Count()};}

注意这里面所有的统计我都过滤了以/Api开头的地址,因为我只需要统计博客前台的访问量就行了。

配置管理

博客还是有很多需要配置的东西,比如说Host

之前我是写在appsettings.json文件里的,按理说也可以,修改这文件之后也能hot reload,不过问题是没法实现在管理后台中修改并保存

所以我打算实现一个配置管理的功能

一开始是把目光瞄准了KV数据库,甚至要求找一个嵌入式的、C#实现的开源项目,叠了这么多buff,果然没找到合适的

(不过前几天好像看到有个大佬发了篇文章介绍用C#手写一个KV数据库的,大赞!)

于是还是用博客本身的数据来实现好了,也不难

老规矩,继续写Service:StarBlog.Web/Services/ConfigService.cs

这里只把关键代码放出来,完整代码可以看GitHub

publicclassConfigService{privatereadonlyIConfiguration_conf;privatereadonlyIBaseRepository_repo;publicConfigItem?GetByKey(stringkey){varitem=_repo.Where(a=>a.Key==key).First();if(item==null){//尝试读取初始化配置varsection=_conf.GetSection($"StarBlog:Initial:{key}");if(!section.Exists())returnnull;item=newConfigItem{Key=key,Value=section.Value,Description="Initial"};item=AddOrUpdate(item);}returnitem;}publicConfigItemAddOrUpdate(ConfigItemitem){return_repo.InsertOrUpdate(item);}publicint?Update(stringkey,stringvalue,string?description=default){varitem=GetByKey(key);if(item==null)returnnull;item.Value=value;if(description!=null)item.Description=description;return_repo.Update(item);}publicstringthis[stringkey]{get{varitem=GetByKey(key);returnitem==null?"":item.Value;}set{varitem=GetByKey(key)??newConfigItem{Key=key};item.Value=value;AddOrUpdate(item);}}}

这个ConfigService实现了索引器,可以比较方便的实现配置的读取和保存

比如这样

varconf=xxx;//注入ConfigService//读取配置Console.WriteLine(conf["host"]);//修改配置conf["host"]="http://dealiaxy.com";

同时我也写了几个接口,可以通过HTTP的方式管理配置,代码就不放了~

初始化

在我的设计中,这个功能是依赖于配置管理的

所以把配置管理做完之后,我的初始化页面也做出来了

看起来是这样的

image

也就是首次运行本项目的时候,会进入这个页面,目前的初始化配置就只有创建管理、设置Host两个,后续应该会慢慢增加其他的

后台是通过is_init这个字段来判断是否有初始化的

直接上Controller代码

[HttpGet]publicIActionResultInit([FromServices]ConfigServiceconf){if(conf["is_init"]=="true"){_messages.Error("已经完成初始化!");returnRedirectToAction(nameof(Index));}returnView(newInitViewModel{Host=conf["host"]});}[HttpPost]publicIActionResultInit([FromServices]ConfigServiceconf,[FromServices]IBaseRepositoryuserRepo,InitViewModelvm){if(!ModelState.IsValid)returnView();//保存配置conf["host"]=vm.Host;conf["is_init"]="true";//创建用户//todo这里暂时存储明文密码,后期要换成MD5加密存储userRepo.Insert(newUser{Id=Guid.NewGuid().ToString(),Name=vm.Username,Password=vm.Password});_messages.Success("初始化完成!");returnRedirectToAction(nameof(Index));}

同时还要实现一个View页面,这个就比较简单,代码不放了

关键词: 配置管理 访问统计 是这样的

相关阅读