Layout.WatchDog.NET 1.5.0-beta.2

This is a prerelease version of Layout.WatchDog.NET.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Layout.WatchDog.NET --version 1.5.0-beta.2
                    
NuGet\Install-Package Layout.WatchDog.NET -Version 1.5.0-beta.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Layout.WatchDog.NET" Version="1.5.0-beta.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Layout.WatchDog.NET" Version="1.5.0-beta.2" />
                    
Directory.Packages.props
<PackageReference Include="Layout.WatchDog.NET" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Layout.WatchDog.NET --version 1.5.0-beta.2
                    
#r "nuget: Layout.WatchDog.NET, 1.5.0-beta.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Layout.WatchDog.NET@1.5.0-beta.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Layout.WatchDog.NET&version=1.5.0-beta.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Layout.WatchDog.NET&version=1.5.0-beta.2&prerelease
                    
Install as a Cake Tool

WatchDog

WatchDog 版本 下载量 MIT 许可证

简介

WatchDog 是一个专为 ASP.NET Core Web 应用程序和 API 设计的实时消息、事件、HTTP(请求和响应)和异常记录器和查看器。它允许开发人员记录和查看消息、事件、对其 Web 应用程序的 HTTP 请求以及在运行时捕获的异常,全部实时显示。

WatchDog 利用 SignalR 实现实时通信,默认使用轻量级数据库 LiteDB(无需配置),同时支持扩展至外部数据库(MSSQL, MySQL, PostgreSQL, MongoDB, SQLite)。

主要功能

  • 实时 HTTP 监控:记录所有请求和响应的详细信息。
  • 异常捕获:自动捕获并记录应用程序运行时的异常。
  • 代码内日志:支持在业务代码中手动记录消息和事件。
  • 实时仪表盘:提供 Web 界面 (/watchdog) 查看日志,支持搜索和过滤。
  • 多种数据库支持:内置 LiteDB,支持一键切换至主流关系型数据库、MongoDB 与 SQLite。
  • 日志自动清理:支持配置定时自动清理旧日志。

截图预览

  • 登录页面

Login

  • 请求与响应查看器

请求和响应查看器

  • 异常日志示例

异常示例详情

安装

方式一:.NET CLI

你需要安装 Layout.WatchDog.NET 包。在终端运行:

dotnet add package Layout.WatchDog.NET --version 1.5.0-beta.1

当前发布的是预发布版 1.5.0-beta.1,必须显式指定版本号(或加 --prerelease),否则默认只会装到稳定版。

方式二:NuGet 包管理器

除了 dotnet cli 安装,还可以通过 nuget 包管理器安装:

Install-Package Layout.WatchDog.NET --version 1.5.0-beta.1

方式三:源码编译(可选)

本仓库以 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
# 打包
dotnet pack src/WatchDog/WatchDog.csproj -c Release -o ./artifacts

快速开始

1. 注册服务

在 Program.cs 中注册 WatchDog 服务。

using WatchDog;

// 在 Program.cs 中 (适用于 .NET 6+)
builder.Services.AddWatchDogServices();

2. 配置中间件

在 HTTP 请求管道中启用 WatchDog 中间件。注意顺序非常重要。

var app = builder.Build();

// 使用 WatchDog 异常记录器
app.UseWatchDogExceptionLogger();
...

// 建议在 UseRouting, UseAuthentication, UseAuthorization 之后添加
app.UseWatchDog(opt =>
{
   // 设置查看器的登录账号
   opt.WatchPageUsername = "admin";
   opt.WatchPagePassword = "Qwerty@123";
});

注意:在主要 WatchDog 中间件之前添加异常记录器,最好是在中间件层次结构的顶部,以便捕获可能的早期异常。

3. 查看日志

启动你的应用程序,访问 /watchdog 路径(例如:https://localhost:5000/watchdog),使用配置的用户名和密码登录即可查看实时日志。

进阶配置

设置外部数据库(可选)

WatchDog 默认使用 LiteDB。如果需要使用 MySQL, PostgreSQL, MSSQL、MongoDB 或 SQLite,请按以下方式配置:

services.AddWatchDogServices(opt =>
{
   // 选择数据库驱动类型
   opt.DbDriverOption = WatchDogDbDriverEnum.PostgreSql;
   // 设置外部数据库连接字符串
   opt.SetExternalDbConnString = "Server=localhost;Database=WatchDogDb;User Id=postgres;Password=root;";
});
使用 SQLite(可选)

SQLite 与默认的 LiteDB 同属嵌入式单文件存储,适合不想部署独立数据库服务的场景,同时能用标准 SQL 工具直接查询日志:

services.AddWatchDogServices(opt =>
{
   opt.DbDriverOption = WatchDogDbDriverEnum.Sqlite;
   // 相对路径会自动归一到应用基目录(AppContext.BaseDirectory),与 LiteDB 的 watchdog.db 落点一致;
   // 也可直接写绝对路径。
   opt.SetExternalDbConnString = "Data Source=watchdog.db";
});

说明:

  • 连接打开时会自动设置 journal_mode=WAL、busy_timeout=5000、synchronous=NORMAL,以提升并发写入稳定性。WAL 模式下会生成 watchdog.db-wal、watchdog.db-shm 副产物,备份时需一并带走。
  • 表结构使用 INTEGER PRIMARY KEY AUTOINCREMENT,清空日志后自增 id 不会回退,与 LiteDB/MongoDB 的雪花 id 设计目标一致。
  • 清空日志后可调用 /WTCHDwatchpage/Compact 手动执行 VACUUM 归还磁盘空间;自动清理任务在清空后也会自动触发。
  • 多实例同库在 WAL + busy_timeout 下可承载常规并发,极端高并发仍可能超时,建议单进程使用。

设置自动清除日志(可选)

services.AddWatchDogServices(opt =>
{
   opt.IsAutoClear = true; // 开启自动清除
   opt.ClearTimeSchedule = 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 条日志的数据库清空前后均为 90112 bytes,压缩后降至 40960 bytes。

多实例部署:设置 Worker ID(可选)

日志记录的 Id 不再由数据库自增,而是由应用生成一个 64 位整数(雪花算法:41 位毫秒时间 + 10 位 Worker ID + 12 位序列号)。因此即使清空日志或压缩 LiteDB 数据文件,新记录的 Id 依然大于旧记录,排序不会错乱。

单进程、单机部署无需配置:默认的 Worker ID 由机器名哈希与进程号推导得到。

只有多个进程写入同一个数据库时(同一个 LiteDB 文件的多个共享连接,或多个实例连同一个 MongoDB 库),才需要显式指定,以保证 Id 全局有序:

services.AddWatchDogServices(opt =>
{
   opt.WorkerId = 1; // 0-1023,同一个库上的每个进程必须不同
});

也可以不改代码,用环境变量为每个实例注入:

# Linux / macOS
WATCHDOG_WORKER_ID=2 dotnet MyApp.dll
# Windows PowerShell
$env:WATCHDOG_WORKER_ID = 2

说明:

  • 取值范围 0-1023,超出会被限制到该区间;代码中的显式配置优先于环境变量。
  • 仅 LiteDB 与 MongoDB 使用该生成器;MSSQL / MySQL / PostgreSQL 使用数据库自增列,配置此项不会生效。
  • 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 的存量数据均无需迁移。

可选配置项

在 app.UseWatchDog() 中可以配置更多选项:

app.UseWatchDog(opt =>
{
   opt.WatchPageUsername = "admin";
   opt.WatchPagePassword = "Qwerty@123";

   // 可选配置项:
   // 黑名单:逗号分隔的路径,不记录这些指定 Endpoint 端点/接口
   opt.Blacklist = "Test/testPost, api/auth/login";
   // JSON 序列化器:WatchDog 默认使用内置的 System.Text.Json(无需额外配置)
   // opt.Serializer = WatchDogSerializerEnum.Newtonsoft; // 已废弃,Newtonsoft 不再被使用
   // CORS 策略名称
   opt.CorsPolicy = "MyCorsPolicy";
   // 应用程序使用 asp.net core8+ 输出缓存
   opt.UseOutputCache = true;
   // 启用正则表达式黑名单
   opt.UseRegexForBlacklisting = true;
 });

启用独立看板(可选)

包里内置一个可选的独立看板(Vue 实现),可替代原来的内嵌页面。默认关闭,关闭时行为与之前完全一致。

app.UseWatchDog(opt =>
{
    opt.WatchPageUsername = "admin";
    opt.WatchPagePassword = "******";

    // 打开独立看板
    opt.Dashboard.Enabled = true;
});
  • 入口:/watchdog(看板)、/watchdog-legacy(原内嵌页面)
  • 数据接口:/watchdog-api/v1/*,与旧端点共用同一数据库与登录会话
  • 前端资源随程序集内嵌,无需额外部署前端,也不需要单独起服务
  • 若打包时未包含看板产物,运行时会自动降级回内嵌页面并记一条 warning

其他可选配置:

opt.Dashboard.BasePath = "/wd";            // 自定义挂载路径
opt.Dashboard.KeepLegacyPage = false;      // 不再暴露原页面
opt.Dashboard.FallbackToEmbeddedPage = false; // 产物缺失时直接抛异常,而不是降级
opt.Dashboard.DefaultLocale = "zh-Hans";   // 首次访问的默认语言:en / zh-Hans
opt.Dashboard.DefaultTheme = "dark";       // 首次访问的默认主题:system / dark / light

看板内提供主题(跟随系统 / 深色 / 浅色)与语言(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/:核心库源码。
    • src/Controllers/:包含处理日志查看请求的控制器。
    • src/Helpers/:数据库操作辅助类(支持 LiteDB, SQL, MongoDB),以及日志 ID 生成器等工具。
    • src/Hubs/:SignalR 集线器,用于实时推送日志。
    • src/Models/:数据模型定义。
    • src/Services/:后台自动清理服务等。
    • src/WatchPage/:内嵌前端页面(由 /WTCHDGstatics 提供)。
  • tests/Test.WatchDog.API/:API 项目演示。
  • tests/Test.WatchDog.MVC/:MVC 项目演示。

贡献

如果你发现了 Bug 或者希望增加新功能:

  1. Fork 本仓库。
  2. 创建你的特性分支 (git checkout -b feature/AmazingFeature)。
  3. 提交你的更改 (git commit -m 'Add some AmazingFeature')。
  4. 推送到分支 (git push origin feature/AmazingFeature)。
  5. 发起 Pull Request。

致谢


许可证:本项目采用 MIT 许可证。

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.3 39 10/29/2026
1.5.0-beta.2 40 10/29/2026
1.5.0-beta.1 41 10/28/2026

1.5.0-beta.2 - 预发布版本,新增独立 Dashboard 看板(含服务器资源监控)与 SQLite 驱动支持

基于 1.5.0-beta.1,本版主要新增两块能力:

新增:独立 Dashboard 看板
- 新增可选独立看板(Vue 3.5 + TanStack + Tailwind),默认关闭,启用后挂载到可配 BasePath,未启用或产物缺失时自动降级到内嵌 WatchPage
- 新增服务器资源监控总览页:CPU、内存、磁盘、网络、GC、运行时(线程/句柄/线程池)等节点指标,含 Sparkline / RingGauge / StackedBar 等图表组件
- 后端新增节点指标采集(Helpers/Metrics,按平台分 Windows / Linux / Mac / Portable provider)与进程指标采集
- 新增 Dashboard API(约定式路由 watchdog-api/v1/{action}),供看板消费
- 看板与内嵌页面共存:可配置保留旧版 /watchdog-legacy 页面,并在旧页面注入返回看板的浮动入口
- 旧版页面改为新标签打开,避免覆盖看板上下文

新增:SQLite 数据库驱动支持
- 新增数据库驱动 WatchDogDbDriverEnum.Sqlite(枚举值 5,追加在末尾,不影响已有配置)
- 与默认 LiteDB 同属零运维单文件存储,同时可用标准 SQL 工具直接查询日志
- 连接自动设置 journal_mode=WAL、busy_timeout=5000、synchronous=NORMAL,提升并发写入稳定性
- 相对路径的 Data Source 自动归一到 AppContext.BaseDirectory,与 LiteDB 的 watchdog.db 落点对齐
- 表结构使用 INTEGER PRIMARY KEY AUTOINCREMENT,清空日志后自增 id 不回退
- 清空日志后支持 VACUUM 归还磁盘空间(手动端点 /WTCHDwatchpage/Compact 与自动清理均生效)
- LIKE 搜索对 INTEGER 列显式 CAST 成 TEXT,避免隐式转换行为不可控
- Microsoft.Data.Sqlite 按 TargetFramework 区分版本:net8.0 用 8.0.33、net10.0 用 10.0.14

改进
- Dashboard API 返回的 storage.driver 字符串值统一为全小写(litedb / mssql / mysql / postgresql / mongo / sqlite)
- 依赖版本按 TargetFramework 区分:Microsoft.Data.Sqlite(net8.0 用 8.0.33、net10.0 用 10.0.14)、Npgsql(net8.0 用 8.0.9、net10.0 用 10.0.3)、MySql.Data(net8.0 用 9.7.0、net10.0 用 26.10.0)

1.5.0-beta.1 - 预发布版本,基于上游 1.4.x 继续维护,包 ID 改为 Layout.WatchDog.NET

上游 WatchDog.NET 的最新公开版本 1.4.12 存在已知依赖安全隐患,请勿继续使用。
该版为 1.5.0 的首个预发布包,验证包 ID 切换与数据库层改造。主要含:数据库层分页、
统一 UTC 时间、清空日志后自动压缩 LiteDB、日志 Id 改用雪花算法、SQL 筛选参数化、
支持 net8.0 与 net10.0 双目标等。详细条目见 1.5.0-beta.1 发布说明。