Layout.WatchDog.NET.Storages.Sqlite
1.5.0-beta.4
dotnet add package Layout.WatchDog.NET.Storages.Sqlite --version 1.5.0-beta.4
NuGet\Install-Package Layout.WatchDog.NET.Storages.Sqlite -Version 1.5.0-beta.4
<PackageReference Include="Layout.WatchDog.NET.Storages.Sqlite" Version="1.5.0-beta.4" />
<PackageVersion Include="Layout.WatchDog.NET.Storages.Sqlite" Version="1.5.0-beta.4" />
<PackageReference Include="Layout.WatchDog.NET.Storages.Sqlite" />
paket add Layout.WatchDog.NET.Storages.Sqlite --version 1.5.0-beta.4
#r "nuget: Layout.WatchDog.NET.Storages.Sqlite, 1.5.0-beta.4"
#:package Layout.WatchDog.NET.Storages.Sqlite@1.5.0-beta.4
#addin nuget:?package=Layout.WatchDog.NET.Storages.Sqlite&version=1.5.0-beta.4&prerelease
#tool nuget:?package=Layout.WatchDog.NET.Storages.Sqlite&version=1.5.0-beta.4&prerelease
WatchDog
简介
WatchDog 是一个专为 ASP.NET Core Web 应用程序和 API 设计的实时消息、事件、HTTP(请求和响应)和异常记录器和查看器。它允许开发人员记录和查看消息、事件、对其 Web 应用程序的 HTTP 请求以及在运行时捕获的异常,全部实时显示。
WatchDog 利用 SignalR 实现实时通信,默认使用轻量级数据库 LiteDB(无需配置),同时支持扩展至外部数据库(MSSQL, MySQL, PostgreSQL, MongoDB, SQLite)。
主要功能
- 实时 HTTP 监控:记录所有请求和响应的详细信息。
- 异常捕获:自动捕获并记录应用程序运行时的异常。
- 代码内日志:支持在业务代码中手动记录消息和事件。
- 实时仪表盘:提供
Web界面 (/watchdog) 查看日志,支持搜索和过滤。 - 多种数据库支持:内置
LiteDB,支持一键切换至主流关系型数据库、MongoDB与SQLite。 - 日志自动清理:支持配置定时自动清理旧日志。
截图预览
- 登录页面
- 请求与响应查看器
- 异常日志示例
安装
方式一:.NET CLI
你需要安装 Layout.WatchDog.NET 核心包。在终端运行:
dotnet add package Layout.WatchDog.NET --version 1.5.0-beta.4
当前发布的是预发布版
1.5.0-beta.4,必须显式指定版本号(或加--prerelease),否则默认只会装到稳定版。
如需使用外部数据库(MSSQL / MySQL / PostgreSQL / SQLite / MongoDB),额外安装对应的 Storage 扩展包:
# 例如使用 PostgreSQL
dotnet add package Layout.WatchDog.NET.Storages.PostgreSql --version 1.5.0-beta.4
可用 Storage 包:
| 驱动 | 包 ID |
|---|---|
| SQL Server | Layout.WatchDog.NET.Storages.SqlServer |
| MySQL | Layout.WatchDog.NET.Storages.MySql |
| PostgreSQL | Layout.WatchDog.NET.Storages.PostgreSql |
| SQLite | Layout.WatchDog.NET.Storages.Sqlite |
| MongoDB | Layout.WatchDog.NET.Storages.MongoDb |
默认 LiteDB 后端内置于核心包,无需额外安装。各 Storage 包的详细用法见数据库后端接入指南。
方式二:NuGet 包管理器
除了 dotnet cli 安装,还可以通过 nuget 包管理器安装:
Install-Package Layout.WatchDog.NET --version 1.5.0-beta.4
# 如需外部数据库,例如 PostgreSQL:
Install-Package Layout.WatchDog.NET.Storages.PostgreSql --version 1.5.0-beta.4
方式三:源码编译(可选)
本仓库以 Layout.WatchDog.NET 为包 ID 发布持续维护的版本,同时面向 .NET 8 与 .NET 10 编译。上游 WatchDog.NET 的最新公开版本 1.4.12 存在已知依赖安全隐患,请勿继续使用。
如果你需要自行打包(例如发布到内部 NuGet 源),版本号定义在 src/WatchDog/WatchDog.csproj 中:
# 克隆仓库
git clone https://gitee.com/dolayout/watch-dog.git
cd watch-dog
# 打包(核心包 + 5 个 Storage 扩展包)
dotnet pack src/WatchDog/WatchDog.csproj -c Release -o ./artifacts
for p in SqlServer MySql PostgreSql Sqlite MongoDb; do
dotnet pack "src/WatchDog.Storages.$p/WatchDog.Storages.$p.csproj" -c Release -o ./artifacts
done
发布顺序:先推核心包
Layout.WatchDog.NET,再推 Storage 包 —— 后者的 nuspec 依赖Layout.WatchDog.NET >= 1.5.0-beta.4。
快速开始
1. 注册服务
在 Program.cs 中注册 WatchDog 服务。
using WatchDog;
// 在 Program.cs 中 (适用于 .NET 6+)
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "Qwerty@123"));
2. 配置中间件
在 HTTP 请求管道中启用 WatchDog 中间件。建议在 UseRouting, UseAuthentication, UseAuthorization 之后添加。
var app = builder.Build();
app.UseWatchDog();
异常日志中间件已由
UseWatchDog()内部自动挂载,无需手动调用。
3. 查看日志
启动你的应用程序,访问 /watchdog 路径(例如:https://localhost:5000/watchdog),使用配置的用户名和密码登录即可查看实时日志。
进阶配置
从 appsettings.json 读取配置(可选)
除纯代码配置外,WatchDog 还支持从 appsettings.json(或任意 IConfiguration 来源)绑定配置。调用 FromConfiguration 后,再用 With* 方法覆盖个别字段:
{
"WatchDog": {
"Username": "admin",
"Password": "Qwerty@123",
"Blacklist": ["api/auth/login", "Test/testPost"],
"UseRegexForBlacklisting": false,
"IsAutoClear": true,
"ClearTimeSchedule": "Monthly",
"CorsPolicy": "",
"UseOutputCache": false,
"Serializer": "Default",
"WorkerId": null,
"Dashboard": {
"Enabled": true,
"BasePath": "/watchdog",
"LegacyPath": "/watchdog-legacy",
"KeepLegacyPage": true,
"FallbackToEmbeddedPage": true,
"AlwaysExposeApi": false,
"DefaultLocale": "en",
"DefaultTheme": "system",
"Features": {
"Requests": true,
"Exceptions": true,
"InCode": true,
"ClearLogs": true,
"Compact": true,
"Metrics": false,
"SecureHub": false
}
}
}
}
builder.Services.AddWatchDog(wd => wd
.FromConfiguration(builder.Configuration.GetSection("WatchDog"))
.WithAutoClear(WatchDogAutoClearScheduleEnum.Monthly));
各配置项含义(键名大小写不敏感,与 WatchDogOptions 属性同名):
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Username / Password |
string | 空 | 看板登录凭据,必填,为空时启动抛 OptionsValidationException |
Blacklist |
string[] | [] |
不记录日志的路径列表,必须是 JSON 数组;写成 "a, b" 只会得到一条字面量路径 |
UseRegexForBlacklisting |
bool | false |
Blacklist 条目按正则解释(等价 UseRegexBlacklist()) |
IsAutoClear |
bool | false |
启用后台定时清理日志 |
ClearTimeSchedule |
string | Weekly |
Daily / Weekly / Monthly / Quarterly / Hourly / Every6Hours / Every12Hours |
CorsPolicy |
string | 空 | 在 WatchDog 管道内应用的 CORS 策略名 |
UseOutputCache |
bool | false |
启用输出缓存中间件(仅 .NET 8+ 生效) |
Serializer |
string | Default |
Newtonsoft 仅为源码兼容保留,行为与 Default 一致 |
WorkerId |
int? | null |
雪花 ID 的 Worker ID,0-1023;多进程写同一库时必填且互不相同 |
Dashboard.* |
object | 见下 | 独立看板配置,字段含义见启用独立看板 |
Dashboard.Features.* |
bool | 见下 | 看板能力开关,字段含义见看板能力开关 |
绑定是"打底",
With*是"覆盖":先FromConfiguration读 JSON,再用With*改个别字段,不会丢失 JSON 里其余配置。TimeProvider无法从 JSON 绑定,保持 null 即使用系统时钟。不要把
ExternalDbConnString/DbDriverOption写进 JSON:这两个字段由 Storage 包的Use*()写入,不是"选择后端"的开关。只写这两项而不调Use*(),AddWatchDog会直接抛InvalidOperationException(不会静默退回 LiteDB)。详见数据库后端接入指南。
AddWatchDog只能调用一次:它每次都会创建一套全新的WatchDogOptions并注册为单例。写成两次调用(例如一次只做FromConfiguration、另一次只做WithAuth)时,后一次的注册会覆盖前一次——JSON 里配的Blacklist/Dashboard/IsAutoClear等会静默丢失;若配置节里没有账号密码,第一次调用还会因校验失败直接抛OptionsValidationException。beta.4 起重复调用会在启动时抛InvalidOperationException。所有配置必须写在同一个回调里,顺序为「先FromConfiguration,后With*」。
设置外部数据库(可选)
WatchDog 默认使用 LiteDB(零配置,内置于核心包)。如需切换到 MSSQL / MySQL / PostgreSQL / MongoDB / SQLite,需引用对应的 Storage 扩展包并调用 Use*() 方法:
// 1. 安装 NuGet 包:Layout.WatchDog.NET.Storages.PostgreSql
// 2. using WatchDog.Storages.PostgreSql;
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "Qwerty@123")
.UsePostgreSql("Server=localhost;Database=WatchDogDb;User Id=postgres;Password=root;"));
1.5.0-beta.4 破坏性变更:
WithExternalDb(driver, connStr)方法已移除,改为各 Storage 包提供独立的Use*()方法。核心包不再传递依赖数据库驱动 NuGet 包,用户按需引用。
各数据库的连接串示例、表结构、分页与清表行为、压缩支持、依赖版本等详见 数据库后端接入指南。
设置自动清除日志(可选)
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "Qwerty@123")
.WithAutoClear(WatchDogAutoClearScheduleEnum.Weekly)); // 默认每周
手动压缩数据文件(LiteDB / SQLite)
LiteDB 的 DeleteAll 只是把数据页标记为空闲,数据文件本身不会变小。清空日志后如果不重写文件,watchdog.db 会一直保持它曾经达到的最大体积。SQLite 的 DELETE 同理,文件不会自动缩小,需要 VACUUM 重写文件。
ClearLogs 与后台自动清理在删除成功后会各自自动压缩一次(LiteDB 调 Compact、SQLite 调 VACUUM),因此日常使用无需干预。下面这个端点用于手动触发,仅在 LiteDB 与 SQLite 后端有效:
GET /WTCHDwatchpage/Compact
需要先登录查看器(与日志页面共用会话),返回 JSON 布尔值。压缩只重写数据文件,不会删除任何日志记录。
# 1. 登录并保存会话 Cookie
curl -c cookies.txt -X POST "https://localhost:5000/WTCHDwatchpage/Auth" \
--data-urlencode "username=admin" \
--data-urlencode "password=Qwerty@123"
# 2. 触发压缩
curl -b cookies.txt "https://localhost:5000/WTCHDwatchpage/Compact"
# => true
返回 false 的常见原因:
- 数据文件不存在(还没有写入过日志)。
- 有其它进程以非共享方式占用了文件,例如
LiteDB Studio直接打开了watchdog.db,或另一个应用实例正在运行。关掉占用方后重试即可。 - 使用的是
MSSQL / MySQL / PostgreSQL或MongoDB后端。这几种后端不需要压缩,该端点恒返回false。
调用前请注意:压缩期间会阻塞所有日志读写,数据库越大耗时越长(几十 MB 级别为秒级)。
LiteDB压缩还会生成一个约等于原库大小的备份文件、完成后自动删除,因此瞬时磁盘占用接近翻倍;SQLite的VACUUM则在临时文件中重写后替换原文件。建议在业务低峰执行。
适用场景:
- 升级后一次性治理:旧版本清空日志不压缩,长期运行过的实例文件已经膨胀。升级后可调用一次回收这部分空间,且无需丢弃当前日志。
- 磁盘空间告急:需要立即腾出空间,同时希望保留最近的日志用于排查。
实测参考:50 条日志的数据库清空前后均为
90112bytes,压缩后降至40960bytes。
多实例部署:设置 Worker ID(可选)
日志记录的 Id 不再由数据库自增,而是由应用生成一个 64 位整数(雪花算法:41 位毫秒时间 + 10 位 Worker ID + 12 位序列号)。因此即使清空日志或压缩 LiteDB 数据文件,新记录的 Id 依然大于旧记录,排序不会错乱。
单进程、单机部署无需配置:默认的 Worker ID 由机器名哈希与进程号推导得到。
只有多个进程写入同一个数据库时(同一个 LiteDB 文件的多个共享连接,或多个实例连同一个 MongoDB 库),才需要显式指定,以保证 Id 全局有序:
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "Qwerty@123")
.WithWorkerId(1)); // 0-1023,同一个库上的每个进程必须不同
也可以不改代码,用环境变量为每个实例注入:
# Linux / macOS
WATCHDOG_WORKER_ID=2 dotnet MyApp.dll
# Windows PowerShell
$env:WATCHDOG_WORKER_ID = 2
说明:
- 取值范围
0-1023,超出会被限制到该区间;代码中的显式配置优先于环境变量。 - 所有后端(LiteDB / SQLite / MSSQL / MySQL / PostgreSQL / MongoDB)均使用雪花算法生成
Id,配置此项对所有后端生效。 Worker ID冲突的后果仅限于两个进程之间的Id排序可能交错,日志本身不会丢失或错乱。Id是 64 位整数,超过JavaScript的安全整数范围(2^53)。如果需要在浏览器端读取Id,请按字符串传输,否则会丢精度。WatchDog自带页面不读取该字段。- 需要从
Id反推生成时间时,id >> 22即为相对2024-01-01 UTC的毫秒数。
从旧版本升级:
LiteDB中Id为Int32的历史记录会在首次打开数据库时自动宽化为Int64,数据不丢失;旧记录的Id数值本身不变,因此会排在新记录之后。SQL 的旧INT自增列与MongoDB的存量数据均无需迁移。
可选配置项
所有配置项都在 AddWatchDog 阶段用 Fluent Builder 声明,UseWatchDog() 无参调用:
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "Qwerty@123")
// 黑名单:路径数组,不记录这些指定 Endpoint 端点/接口
.WithBlacklist("Test/testPost", "api/auth/login")
// CORS 策略名称
.WithCorsPolicy("MyCorsPolicy")
// 应用程序使用 asp.net core8+ 输出缓存
.WithOutputCache()
// 启用正则表达式黑名单
.UseRegexBlacklist());
JSON 序列化器:WatchDog 默认使用内置的 System.Text.Json(无需额外配置)。
WatchDogSerializerEnum.Newtonsoft仅为源码兼容保留,行为与默认一致。
启用独立看板(可选)
包里内置一个可选的独立看板(Vue 实现),可替代原来的内嵌页面。默认关闭,关闭时行为与之前完全一致。
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "******")
// 打开独立看板
.WithDashboard(d => d.Enabled = true));
- 入口:
/watchdog(看板)、/watchdog-legacy(原内嵌页面) - 数据接口:
/watchdog-api/v1/*,与旧端点共用同一数据库与登录会话 - 前端资源随程序集内嵌,无需额外部署前端,也不需要单独起服务
- 若打包时未包含看板产物,运行时会自动降级回内嵌页面并记一条 warning
其他可选配置:
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "******")
.WithDashboard(d =>
{
d.Enabled = true;
d.BasePath = "/wd"; // 自定义挂载路径
d.KeepLegacyPage = false; // 不再暴露原页面
d.FallbackToEmbeddedPage = false; // 产物缺失时直接抛异常,而不是降级
d.DefaultLocale = "zh-Hans"; // 首次访问的默认语言:en / zh-Hans
d.DefaultTheme = "dark"; // 首次访问的默认主题:system / dark / light
}));
看板能力开关(Features)
看板通过 Features 声明启用哪些能力,未开启的入口在界面上直接隐藏:
builder.Services.AddWatchDog(wd => wd
.WithAuth("admin", "******")
.WithDashboard(d =>
{
d.Enabled = true;
d.Features.Requests = true; // HTTP 请求/响应(默认开)
d.Features.Exceptions = true; // 异常日志(默认开)
d.Features.InCode = true; // 代码内日志(默认开)
d.Features.ClearLogs = true; // 清空日志(默认开)
d.Features.Compact = true; // 手动压缩(默认开)
d.Features.Metrics = true; // 节点资源监控(默认关)
d.Features.SecureHub = true; // SignalR 强制会话鉴权(默认关)
}));
节点资源监控(可选)
开启 Features.Metrics 后,看板提供 Infra 总览页(/infra/overview),并对外提供节点级资源快照接口:
GET /watchdog-api/v1/metrics
- 节点级:CPU、内存、磁盘、网络、load average(Windows / Linux / macOS 各自实现;缺失项以
unavailable声明,不用 0 冒充真实值) - 进程级:CPU、内存、GC、线程、句柄、线程池、运行时长
- 首次采样没有速率基线时返回
null并登记unavailable;进程 CPU 沿用单核口径,可超过 100% - 未开启
Features.Metrics时该接口返回 404
看板内提供主题(跟随系统 / 深色 / 浅色)与语言(EN / 中文)切换,选择存在浏览器里;
上面的默认值只在用户从未选择过时生效。原内嵌页面 /watchdog-legacy 不受影响。
记录自定义日志
你可以在代码的任何位置调用 WatchLogger 来记录日志:
using WatchDog;
// 记录普通信息
WatchLogger.Log("用户登录成功");
// 记录警告
WatchLogger.LogWarning("请求频率过高");
// 记录错误
WatchLogger.LogError("处理订单失败", eventId: "Order_001");
集成 Microsoft ILogger
你还可以将标准的 ILogger 日志汇总到 WatchDog 中:
// .NET 6+ 在 Program.cs 中配置
builder.Logging.AddWatchDogLogger();
项目结构
该项目主要包含以下模块:
src/WatchDog/:核心库源码(Layout.WatchDog.NET,内置 LiteDB 后端与看板嵌入资源宿主)。Extensions/:AddWatchDog/UseWatchDog入口与 Fluent Builder。Validation/:启动期配置校验。src/Controllers/:包含处理日志查看请求的控制器。src/Storages/:默认 LiteDB 存储实现(IWatchDogStorage)。src/Helpers/:日志 ID 生成器、分页、节点指标采集等工具。src/Hubs/:SignalR集线器,用于实时推送日志。src/Models/:数据模型定义与统一配置模型WatchDogOptions。src/Services/:后台自动清理服务等。src/WatchPage/:内嵌前端页面(由/WTCHDGstatics提供)。src/Dashboard/:Vue 看板构建产物(内嵌为资源)。
src/WatchDog.Storages.SqlServer/、.MySql/、.PostgreSql/、.Sqlite/、.MongoDb/:外部数据库 Storage 扩展包,各自只依赖一个驱动。src/WatchDog.Dashboard/:独立看板前端源码(Vue 3 + Vite + Tailwind)。tests/Test.WatchDog.API/:API项目演示。tests/Test.WatchDog.MVC/:MVC项目演示。
贡献
如果你发现了 Bug 或者希望增加新功能:
Fork本仓库。- 创建你的特性分支 (
git checkout -b feature/AmazingFeature)。 - 提交你的更改 (
git commit -m 'Add some AmazingFeature')。 - 推送到分支 (
git push origin feature/AmazingFeature)。 - 发起
Pull Request。
致谢
许可证:本项目采用 MIT 许可证。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Dapper (>= 2.1.89)
- Layout.WatchDog.NET (>= 1.5.0-beta.4)
- Microsoft.Data.Sqlite (>= 10.0.14)
-
net8.0
- Dapper (>= 2.1.89)
- Layout.WatchDog.NET (>= 1.5.0-beta.4)
- Microsoft.Data.Sqlite (>= 8.0.33)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.5.0-beta.4 | 42 | 10/31/2026 |