我的Programm.cs:

var logger = LogManager.Setup()
    .RegisterNLogWeb()
    .LoadConfigurationFromFile("nlog.config")
    .GetCurrentClassLogger();

try
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddControllers(options => { options.Filters.Add<LogResponseFilterAttribute>(); 
    });
    
    builder.Services.AddScoped<LogResponseFilterAttribute>();

    builder.Logging.ClearProviders();
    builder.Logging.SetMinimumLevel(LogLevel.Information);

    builder.Host.UseNLog();

    var app = builder.Build();

    app.UseHttpsRedirection();

    app.UseAuthorization();

    app.MapControllers();

    app.Run();
}
catch (Exception e)
{
    logger.Error(e, "Stopped program because of exception");
    throw;
}
finally
{
    LogManager.Shutdown();
}

我的nlog.config分:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Error"
      throwExceptions="false"
      internalLogFile="c:\logs\internal-log.txt">

    <variable name="iis_sitename" value="${gdc:item=iis_sitename}"/>
    <variable name="logDirectory" value="c:/logs/${iis_sitename}"/>
    <variable name="logSourceName" value="dpc"/>

    <targets async="true">
        <target xsi:type="File"
                name="jsonFile"
                fileName="${logDirectory}/${logSourceName}-${lowercase:${level}}.jsonl"
                archiveFileName="${logDirectory}/archives/${logSourceName}-${lowercase:${level}}_${date:format=yyyy-MM-dd}.jsonl"
                archiveAboveSize="1000240"
                archiveNumbering="Sequence"
                archiveEvery="Day"
                concurrentWrites="true"
                keepFileOpen="true"
                maxArchiveFiles="1"
                encoding="UTF-8">
            <layout xsi:type="JsonLayout"
                    includeAllProperties="true"
                    maxRecursionLimit="2"
                    suppressSpaces="true">
                <attribute name="timestamp" layout="${longdate}"/>
                <attribute name="message" layout="${message}"/>
            </layout>
        </target>
    </targets>

    <rules>
        <logger name="*" minlevel="Info" writeTo="jsonFile" />
    </rules>
</nlog>

在一次行动中,我怎么称呼它:

[HttpGet("products")]
    public Task<object?> Get(CancellationToken cancellationToken, [FromQuery] Filter filter)
    {
        _logger.LogInformation("Hello world!");
         ... other stuff
    }

我得到的是:

enter image description here

我很困惑!这是什么?我能不能要回我的"Hello world"?所有这些聪明的东西看起来很酷,可能会用于新一季的"机器人先生",但我没有 需要它!我只需要我的"Hello world"!

推荐答案

所有日志(log)库的一个基本概念是,当您指定要捕获的日志(log)的详细程度时,Log Severity Level是主要的筛选标准.

nlog.config中,100的主过滤器由minlevel属性定义,这是要记录的最低日志(log)级别.在您的例子中,您指定了Info,这对应于所有Information that highlights progress or application lifetime events.

  • 正如您在日志(log)输出中看到的那样,来自运行时的许多smart stuff与您的http操作端点的生存期特别相关.

用来区分日志(log)和标准Info日志(log)消息的第一种机制是在代码中使用_logger.LogWarning而不是LogInformation.想想警告的意思是,"more important than the standard 103, but less than an 104".而不是字典中的解释,意思是某些东西可能出错,或者你接近了某种错误阈值或状态.

  • 一些日志(log)记录框架定义了高于Info但小于WarningNotice级别,这似乎更合适,但MS日志(log)记录扩展和NLog都不显式地支持这一点.

因此,了解到框架和其他系统工具将使用Info报告生存期事件,默认情况下,您应该在应用程序逻辑中使用LogWarning()来轻松区分既不是Critical也不是Error的重要消息

 _logger.LogWarning("Hello world!");

然后在您的配置规则中,您可以指定Warn作为日志(log)详细程度:

<rules>
    <logger name="*" minlevel="Warn" writeTo="jsonFile" />
</rules>

您还可以使用Rules来定位可能在运行时处于活动状态的特定记录器(如果您知道它们的话).按照约定,内部.NET记录器使用完全限定的类名作为记录器名称.知道这一点的你

如果您将其作为属性包含在layout中,则不必在记录器名称looks cool, but you think is redundant处使用guess

  <layout xsi:type="JsonLayout"
          includeAllProperties="true"
          maxRecursionLimit="2"
          suppressSpaces="true">
      <attribute name="timestamp" layout="${longdate}"/>
      <attribute name="logger" layout="${logger}"/>
      <attribute name="message" layout="${message}"/>
  </layout>

然后,您可以为符合您的名称模式条件的记录器指定不同的minLevel.由于NLog5我们可以使用finalMinLevel来简化组合日志(log)记录规则的语法,下面的示例将只记录通用系统和Microsoft框架记录器的Warn或更高版本,但仍然允许在日志(log)输出中捕获来self 们的应用程序运行时的Info条消息.

<rules>
    <logger name="System.*" finalMinLevel="Warn" />
    <logger name="Microsoft.*" finalMinLevel="Warn" />
    <logger name="Microsoft.Hosting.Lifetime*" finalMinLevel="Warn" />
    <logger name="*" minlevel="Info" writeTo="jsonFile" />
</rules>

NOTE:
It is often tempting to silence logs from outside of our application logic using finalMinLevel="None" but this could lead to you missing critical information if your application fails due to external hosting or environmental events. finalMinLevel="Warn" is a conventional standard that means the standard lifetime events will be excluded but any more important information will still be logged.

Csharp相关问答推荐

如何使用Unity和MRTK3将手网添加到Hololens 2应用程序中

. NET 8 HttpClient post参数将其情况更改为camel'

处理. netstandard2.0项目中HttpClient.SslProtocol的PlatformNotSupportedException问题""

将列表字符串映射为逗号分隔字符串<>

一种安全的方式来存储SSH凭证(MAUI/C#应用程序)

Unity 2D自顶向下弓旋转

图形API基于appid列表检索多个应用程序

Nuget包Serilog.Sinks.AwsCloudwatch引发TypeLoadExceptions,因为父类型是密封的

Take()方法如何与IAsyncEnumerable一起使用

如何使用自定义负载均衡器管理Ocelot负载均衡器中的多线程和批读取

如何在CSharp中将json字符串转换为DataTable?

C#按名称从类获取属性值类型<;t>;,我需要反射吗?

C#LINQ子字符串

MudBlazor Textfield已禁用,但其验证工作正常

C#System.Commandline:如何向命令添加参数以便向其传递值?

数据库操作预计影响1行,但实际影响0行; after _dbContext.SaveChanges();

如何消除Visual Studio错误,因为它不识别集合表达式的新C#12语法?

根据优先级整理合同列表

ASP.NET核心MVC|如何在控制器方法之间传递值

如何对列表<;列表>;使用集合表达式?