首页 > 解决方案 > 如何使用 Azure 函数注入 NLog

问题描述

我有以下代码来依赖注入 NLog 记录器:

// startup.cs
[assembly: FunctionsStartup(typeof(MyApp.FunctionApp.Startup))]
namespace MyApp.FunctionApp {
    public class Startup : FunctionsStartup {
        public override void Configure(IFunctionsHostBuilder builder) {
            var nLogConfigPath = GetLogPath("nlog.config");
            
            builder.Services.AddLogging(loggingBuilder =>
            {
                var nLogOptions = new NLogAspNetCoreOptions
                {
                    RegisterHttpContextAccessor = true,
                    IgnoreEmptyEventId = true,
                    IncludeScopes = true,
                    ShutdownOnDispose = true
                };

                var logFactory = NLogBuilder.ConfigureNLog(nLogConfigPath);
                logFactory.AutoShutdown = false;

                var nLogConfig = logFactory.Configuration;
                loggingBuilder.AddNLog(nLogConfig, nLogOptions);
            });
        }
    }
}

// actual function code
public class ActualFunctionClass {
    public ActualFunctionClass (ILogger<ActualFunctionClass> logger) {
        logger.LogInformation("log stuff");
    }
}

在 nlog.config 中,我有几个目标。如何确保logger为 ActualFunctionClass 的参数配置了正确的目标?

这些是 nlog.config 的内容。作为记录,我想使用locations-dataload-file目标登录。

<?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"
      throwExceptions="true"
      keepVariablesOnReload="true">

  <variable name="logDirectory" value="${basedir}/logs/locations-dataload" />
  <variable name="commonLayout" value="${longdate}|${logger}|${uppercase:${level}}|${message}, ${all-event-properties:format=[key]=[value]:separator=, } ${exception}" />
  <targets>
    <target xsi:type="ApplicationInsightsTarget"
            name="locations-dataload-ai"
            layout="${commonLayout}" />

    <target xsi:type="File"
            name="locations-dataload-file"
            fileName="${logDirectory}/locations-dataload-file-${shortdate}.log"
            layout="${commonLayout}" />

    <target xsi:type="Null" name="blackhole" />
  </targets>

  <rules>
  <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Trace" writeTo="locations-dataload-ai" />

    <!--All logs, including from Microsoft-->
    <logger name="locations-dataload-local*" minlevel="Trace" writeTo="locations-dataload-ai,locations-dataload-file" />

    <!-- Skip Microsoft logs and so log only own logs -->
    <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
  </rules>

  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
    <add assembly="MyApp.Logging" />
  </extensions>
</nlog>

标签: c#.net.net-coredependency-injectionnlog

解决方案


我认为这是错误的:

<logger name="locations-dataload-local*" ...

记录器名称默认为 Namespace.ClassName

您可以通过以下方式进行测试:

将规则更改为name="*"

 <logger name="*" minlevel="Trace" writeTo="locations-dataload-ai,locations-dataload-file" />

并添加到您的布局${logger}中,例如

layout="${logger}|${commonLayout}" 

名称过滤器将与记录器名称匹配${logger)。因此,如果记录器名称是YourNamespace.ActualFunctionClass thenlocations-dataload-local*将不匹配。


推荐阅读