基于 NLog 实现 ASP.NET Core 日志 JSON 化输出与浏览器端在线查看
基于 NLog 实现 ASP.NET Core 日志 JSON 化输出与浏览器端在线查看
在实际项目运维中,我们经常面临需要快速查看线上服务日志的场景,传统方式需登录服务器或容器,操作繁琐且存在安全风险。本文将介绍如何利用 NLog 将 ASP.NET Core 日志以 JSON Lines 格式输出到 wwwroot/logs/ 目录,再配合静态文件中间件,实现 直接通过浏览器在线查看,方便高效且轻量。
1. 访问方式
启动服务后,可通过以下 URL 模板访问日志文件:
http://<host>:<port>/<pathPrefix>/logs/<yyyy-MM-dd>_<Level>.json
示例:
# 本地开发(假设 pathPrefix = "myapp")
http://localhost:30093/myapp/logs/2026-07-08_Info.json
http://localhost:30093/myapp/logs/2026-07-08_Error.json
# 生产环境(假设 pathPrefix = "api")
http://prod.example.com/api/logs/2026-07-08_Warn.json
1.1 URL 参数说明
| 占位符 | 说明 |
|---|---|
<host>:<port> |
服务地址,如 localhost:30093 或生产域名 |
<pathPrefix> |
URL 前缀,与 Program.cs 中 pathPrefix 常量保持一致,如 myapp / api / logs 等 |
<yyyy-MM-dd> |
日志日期,由 NLog 的 ${shortdate} 生成,格式如 2026-07-08 |
<Level> |
日志级别,首字母大写,可选值:Info / Warn / Error / Fatal |
⚠️ 注意:Linux 文件系统区分大小写,URL 中的级别名必须严格首字母大写,否则返回 404。
2. NLog 配置详解
2.1 配置文件 nlog.config 核心片段
<target xsi:type="File"
name="wwwrootlogfile"
fileName="${basedir}/wwwroot/logs/${shortdate}_${level}.json"
maxArchiveDays="3">
<layout xsi:type="JsonLayout">
<attribute name="timestamp" layout="${longdate}" />
<attribute name="level" layout="${level:uppercase=true}" />
<attribute name="message" layout="${message}" />
<attribute name="exception" layout="${exception:format=tostring}" />
<attribute name="logger" layout="${logger}" />
</layout>
</target>
<rules>
<logger name="*" minlevel="Info" writeTo="wwwrootlogfile" />
</rules>
2.2 关键配置项说明
| 配置项 | 说明 |
|---|---|
${basedir} |
应用基目录(dll 所在位置),容器环境下通常为 /app |
fileName |
按日期 + 级别分文件存储,例如 2026-07-08_Info.json |
JsonLayout |
每条日志输出为独立 JSON 对象,包含 timestamp、level、message、exception、logger 字段 |
maxArchiveDays="3" |
仅保留最近 3 天的日志文件,NLog 自动清理更早的旧文件 |
minlevel="Info" |
仅记录 Info 及以上级别(Info / Warn / Error / Fatal),Debug 仅输出至控制台 |
3. JSON 格式与查看方式
3.1 输出格式(JSON Lines)
每行一条独立的 JSON 记录,便于流式解析或使用 jq 处理:
{"timestamp":"2026-07-08 10:23:45.1234","level":"INFO","message":"Consumed 100 events","exception":"","logger":"YourApp.Service.Consumers.ExampleSubscriber"}
{"timestamp":"2026-07-08 10:24:01.5678","level":"ERROR","message":"Kafka connect failed","exception":"System.TimeoutException: ...","logger":"YourApp.Service.Consumers.KafkaConsumer"}
📌 整个文件不是标准 JSON 数组,而是 JSON Lines 格式。浏览器直接打开会显示多行原始 JSON,建议配合 JSON Viewer 浏览器插件或使用
jq进行结构化查看。
3.2 使用 jq 美化查看
# 假设 pathPrefix = "myapp"
curl http://localhost:30093/myapp/logs/2026-07-08_Info.json | jq '.'
4. 静态文件服务配置
4.1 Program.cs 核心代码
const string pathPrefix = "myapp"; // 可改为任意值,如 "api"、"logs" 等
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
WebRootPath = "wwwroot", // 显式指定,确保目录存在
});
// ... 其他服务注册
var app = builder.Build();
app.UseStaticFiles($"/{pathPrefix}"); // 将 wwwroot 挂载到 /{pathPrefix} 路径
app.Run();
4.2 为何要显式指定 WebRootPath
- ASP.NET Core 默认要求
wwwroot目录在启动时必须存在,否则静态文件中间件会使用NullFileProvider,导致所有静态请求返回 404。 dotnet publish不会打包空目录,容器中/app/wwwroot初始不存在。- 显式指定
WebRootPath会触发 WebHost 初始化时的兜底逻辑,自动调用Directory.CreateDirectory,保证目录存在;随后 NLog 首次写入时会自动创建logs/子目录。
5. 常见问题与解决方案
Q1:本地可访问,Linux 部署后 404?
原因:未显式指定 WebRootPath,导致容器中 wwwroot 目录缺失,静态文件服务未生效。
解决:如第 4 节所示,在 WebApplicationOptions 中显式指定 WebRootPath = "wwwroot"。
Q2:文件名大小写导致访问失败?
Linux 文件系统区分大小写,NLog 生成的文件名中 ${level} 为首字母大写(Info / Warn / Error / Fatal),URL 必须完全匹配。
Q3:能否在浏览器中列出所有日志文件?
默认 UseStaticFiles 不支持目录浏览。如需启用(谨慎),可在 Program.cs 中添加:
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, "wwwroot", "logs")),
RequestPath = $"/{pathPrefix}/logs",
});
⚠️ 生产环境慎用,建议配合身份验证或 IP 白名单,避免日志信息泄露。
Q4:Debug 级别日志能否通过浏览器查看?
不能。nlog.config 中 wwwrootlogfile 的规则为 minlevel="Info",Debug 日志仅输出至控制台。如需记录 Debug,可修改规则或新增 target。
Q5:日志文件占用磁盘空间怎么办?
配置中 maxArchiveDays="3" 使 NLog 在每次写入时扫描 wwwroot/logs/ 下匹配模式的文件,自动删除 3 天前的旧文件,当日活跃文件不受影响。
若单日日志量极大,可减小 maxArchiveDays,或配合 archiveAboveSize 按大小切分。
📖 历史说明:此前曾使用
archiveEvery="Day"+maxArchiveFiles="3",但由于fileName已包含${shortdate},NLog 视为每日新文件,归档逻辑未触发,导致旧文件堆积。现已改用maxArchiveDays,正确清理历史文件。
6. 相关文件清单
| 文件路径 | 作用 |
|---|---|
nlog.config |
NLog 日志配置,定义输出格式与清理策略 |
Program.cs |
配置静态文件服务、指定 WebRootPath |
wwwroot/logs/ |
日志输出目录(运行时自动创建) |
7. 总结
通过以上方案,我们实现了:
- ✅ 日志按日期+级别自动分文件存储
- ✅ JSON Lines 格式,便于程序解析与工具处理
- ✅ 浏览器直接访问,无需登录服务器
- ✅ 自动清理过期日志,控制磁盘占用
- ✅ 容器环境适配良好
该方案适用于中小型微服务项目,提供了一种轻量、高效的日志查看途径,值得在开发与测试环境中推广使用。生产环境下若需暴露日志文件,请务必做好访问控制与安全审计。

浙公网安备 33010602011771号