基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)
系列文章
- 基于.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,这俩开源的工具可以很好的完成这些工作,详情可以看我之前写的这俩篇文章:
然后状态监测我是基于GitHub上的一个开源项目来魔改的:CLRStats
这个组件可以实时查看CPU、GC、线程的状态,不过原版的实现是作为一个中间件嵌入AspNetCore项目,并且访问的地址只能用Basic认证,不适用。
于是我把代码clone下来之后魔改了一下,变成一个可以调用的服务,并且重新写了API接口,终于方便起来了~
这个接口拿到的数据是这样的,后续在管理后台里面做成可视化图表也比较方便。
{
"server": {
"machineName": "machineName",
"systemDateTime": "7/26/2022 11:30:22 PM"
},
"application": {
"cpu": {
"usagePercent": 0
},
"gc": {
"gen0CollectCount": 24,
"gen1CollectCount": 23,
"gen2CollectCount": 22,
"heapMemory": 38328872,
"heapMemoryFormat": "36 M",
"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的人觉得很不适应 = =..
这个接口计算总访问量、今日访问量、昨日访问量,方便做对比(受知乎的创作者中心启发)
public object Overview() {
ISelect<VisitRecord> GetQuerySet() => _repo.Where(a => !a.RequestPath.StartsWith("/Api"));
return new {
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#的日期处理还是比较舒服的
public object Trend(int days = 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()
});
}
按日期统计
这个简单粗暴不用多说
public object Stats(DateTime date) {
var data = _repo.Where(a => a.Time.Date == date.Date && !a.RequestPath.StartsWith("/Api"));
return new { Count = data.Count() };
}
注意这里面所有的统计我都过滤了以/Api开头的地址,因为我只需要统计博客前台的访问量就行了。
配置管理
博客还是有很多需要配置的东西,比如说Host
之前我是写在appsettings.json文件里的,按理说也可以,修改这文件之后也能hot reload,不过问题是没法实现在管理后台中修改并保存
所以我打算实现一个配置管理的功能
一开始是把目光瞄准了KV数据库,甚至要求找一个嵌入式的、C#实现的开源项目,叠了这么多buff,果然没找到合适的
(不过前几天好像看到有个大佬发了篇文章介绍用C#手写一个KV数据库的,大赞!)
于是还是用博客本身的数据来实现好了,也不难
老规矩,继续写Service:StarBlog.Web/Services/ConfigService.cs
这里只把关键代码放出来,完整代码可以看GitHub
public class ConfigService {
private readonly IConfiguration _conf;
private readonly IBaseRepository<ConfigItem> _repo;
public ConfigItem? GetByKey(string key) {
var item = _repo.Where(a => a.Key == key).First();
if (item == null) {
// 尝试读取初始化配置
var section = _conf.GetSection($"StarBlog:Initial:{key}");
if (!section.Exists()) return null;
item = new ConfigItem { Key = key, Value = section.Value, Description = "Initial" };
item = AddOrUpdate(item);
}
return item;
}
public ConfigItem AddOrUpdate(ConfigItem item) {
return _repo.InsertOrUpdate(item);
}
public int? Update(string key, string value, string? description = default) {
var item = GetByKey(key);
if (item == null) return null;
item.Value = value;
if (description != null) item.Description = description;
return _repo.Update(item);
}
public string this[string key] {
get {
var item = GetByKey(key);
return item == null ? "" : item.Value;
}
set {
var item = GetByKey(key) ?? new ConfigItem { Key = key };
item.Value = value;
AddOrUpdate(item);
}
}
}
这个ConfigService实现了索引器,可以比较方便的实现配置的读取和保存
比如这样
var conf = xxx; // 注入 ConfigService
// 读取配置
Console.WriteLine(conf["host"]);
// 修改配置
conf["host"] = "http://dealiaxy.com";
同时我也写了几个接口,可以通过HTTP的方式管理配置,代码就不放了~
初始化
在我的设计中,这个功能是依赖于配置管理的
所以把配置管理做完之后,我的初始化页面也做出来了
看起来是这样的

也就是首次运行本项目的时候,会进入这个页面,目前的初始化配置就只有创建管理、设置Host两个,后续应该会慢慢增加其他的
后台是通过is_init这个字段来判断是否有初始化的
直接上Controller代码
[HttpGet]
public IActionResult Init([FromServices] ConfigService conf) {
if (conf["is_init"] == "true") {
_messages.Error("已经完成初始化!");
return RedirectToAction(nameof(Index));
}
return View(new InitViewModel {
Host = conf["host"]
});
}
[HttpPost]
public IActionResult Init([FromServices] ConfigService conf, [FromServices] IBaseRepository<User> userRepo, InitViewModel vm) {
if (!ModelState.IsValid) return View();
// 保存配置
conf["host"] = vm.Host;
conf["is_init"] = "true";
// 创建用户
// todo 这里暂时存储明文密码,后期要换成MD5加密存储
userRepo.Insert(new User {
Id = Guid.NewGuid().ToString(),
Name = vm.Username,
Password = vm.Password
});
_messages.Success("初始化完成!");
return RedirectToAction(nameof(Index));
}
同时还要实现一个View页面,这个就比较简单,代码不放了
基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)的更多相关文章
- 基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传
前言 九月太忙,只更新了三篇文章,本来这个功能是从九月初就开始做的,结果一直拖到现在国庆假期才有时间完善并且写文章~ 之前我更新了几篇关于 Python 的文章,有朋友留言问是不是不更新 .Net 了 ...
- 基于.NetCore开发博客项目 StarBlog - (19) Markdown渲染方案探索
前言 笔者认为,一个博客网站,最核心的是阅读体验. 在开发StarBlog的过程中,最耗时的恰恰也是文章的展示部分功能. 最开始还没研究出来如何很好的使用后端渲染,所以只能先用Editor.md组件做 ...
- 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 ... 基于. ...
- 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
随机推荐
- .NET混合开发解决方案10 WebView2控件调用网页JS方法
系列目录 [已更新最新开发文章,点击查看详细] WebView2控件应用详解系列博客 .NET桌面程序集成Web网页开发的十种解决方案 .NET混合开发解决方案1 WebView2简介 .NE ...
- 用 Python 远程控制 Windows 服务器,太好用了!
在很多企业会使用闲置的 Windows 机器作为临时服务器,有时候我们想远程调用里面的程序或查看日志文件 Windows 内置的服务「 winrm 」可以满足我们的需求 它是一种基于标准简单对象访问协 ...
- Web Api源码(路由注册)
这篇文章只是我学习Web API框架的输出,学习方法还是输出倒逼输入比较行得通,所以不管写的好不好,坚持下去,肯定有收获.篇幅比较长,仔细思考阅读下来大约需要几分钟. 做.NET开发有好几年时间了,从 ...
- 简易版 vue实现
Vue-mini 完整的Demo示例:git@github.com:xsk-walter/Vue-mini.git 一.Vue实例 构造函数: $option\ $el\ $data 判断是否存在 通 ...
- kvm 虚拟化技术 1.2 之配置网络桥接
实验一:配置网路桥接模式 默认kvm的网络是NAT模式,一般生产环境用桥接模式,把虚拟机改成桥接模式 1.查看是否安装网桥设备 [root@kibana opt]# rpm -qa|grep brid ...
- 在 Git 提交信息中使用 Emoji
Gitmoji 旨在解释如何在 Git 提交消息时使用表情符号.在提交信息时使用表情符号,可以更容易地识别提交的目的或意图. Emoji 列表 :优化项目结构 / 代码格式 :art: ️ :性能提升 ...
- 手把手教你使用 Spring Boot 3 开发上线一个前后端分离的生产级系统(一) - 介绍
项目简介 novel 是一套基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发的前后端分离的学习型小说项目,配备详细的项目教程手把手教你从零开始开发上线一个生产级别的 J ...
- git 无法拉取最新代码
删除本地文件后,想从远程仓库中重新新Pull最新代码,但是执行了git pull origin develop 命令后始终无法拉取下来 提示 Already up-to-date. 原因:当前本地库处 ...
- C# 类继承中的私有字段都去了哪里?
最近在看 C++ 类继承中的字段内存布局,我就很好奇 C# 中的继承链那些 private 字段都哪里去了? 在内存中是如何布局的,毕竟在子类中是无法访问的. 一:举例说明 为了方便讲述,先上一个例子 ...
- PyTorch保存模型、冻结参数等
此外可以参考PyTorch模型保存.https://zhuanlan.zhihu.com/p/73893187 查看模型每层输出详情 Keras有一个简洁的API来查看模型的每一层输出尺寸,这在调试网 ...