基于 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.cspathPrefix 常量保持一致,如 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 对象,包含 timestamplevelmessageexceptionlogger 字段
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.configwwwrootlogfile 的规则为 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 格式,便于程序解析与工具处理
  • ✅ 浏览器直接访问,无需登录服务器
  • ✅ 自动清理过期日志,控制磁盘占用
  • ✅ 容器环境适配良好

该方案适用于中小型微服务项目,提供了一种轻量、高效的日志查看途径,值得在开发与测试环境中推广使用。生产环境下若需暴露日志文件,请务必做好访问控制与安全审计。

posted @ 2026-08-11 17:53  怀恋小时候  阅读(9)  评论(0)    收藏  举报