web-dev-qa-db-ja.com

ASP.NET CoreアプリケーションでNLogを使用する

CodeProject を見つけて、これを機能させる方法の例を示しましたが、機能しません。主な問題は、"Microsoft.Framework.Logging.NLog": "1.0.0-*"パッケージはNugetに存在しないようです。 このStackOverflowの質問 を見て、それが参照するGitHubの例を見てきましたが、同じ問題が含まれているようです。

私はそれを自分で動作させようとしましたが、私が思いついた最高のものは次のとおりです:

public class NLogLogger : ILogger
{
    public NLogLogger()
    {
        new WebLoggerConfigurer().ConfigureDefault();
    }

    public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
    {
        // currently need the global:: for LogLevels because our namespace contains NLog in it. Is there a better naming convention we could use instead?
        var ll = logLevel == LogLevel.Debug ? global::NLog.LogLevel.Debug
                : logLevel == LogLevel.Verbose ? global::NLog.LogLevel.Trace
                : logLevel == LogLevel.Critical ? global::NLog.LogLevel.Fatal
                : logLevel == LogLevel.Error ? global::NLog.LogLevel.Error
                : logLevel == LogLevel.Information ? global::NLog.LogLevel.Info
                : logLevel == LogLevel.Warning ? global::NLog.LogLevel.Warn
                : global::NLog.LogLevel.Off;

        LogManager.GetCurrentClassLogger().Log(ll, formatter(state, exception));
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return true;
    }

    public IDisposable BeginScopeImpl(object state)
    {
        return new Disposable(() => { });
    }
}

public class NLogLoggerProvider : ILoggerProvider
{
    public void Dispose()
    {
    }

    public ILogger CreateLogger(string categoryName)
    {
        return new NLogLogger();
    }
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddProvider(new NLogLoggerProvider());
    ..
}

BeginScopeImplの実装はハックのように見えますが、どのように実装するのが最善かはわかりませんでした。

  1. これは有効な実装オプションのように見えますか?
  2. BeginScopeImplを実装するより良い方法はありますか?
  3. NLogをASP.NET 5で動作させる別の方法はありますか?
28

Microsoft.Framework.Logging.NLogは NGetのNLog.Extensions.Logging に置き換えられました。これはNLogチームによって管理されています。

ASP.NET Coreの場合、 NLog.Web.AspNetCore (NLog.Extensions.Loggingに依存します)が必要です

使い方:

セットアップ

NLogを有効にして、ASP.NET CoreのDIおよびログAPIに統合する必要があります。これにより、外部(Microsoftなど)によって書き込まれたすべてのログもNLogに送信されます-NLogの構成でそれをフィルタリングできます(パフォーマンスへの影響なし)

ASP.NET Core 1とASP.NET Core 2には、異なるアプローチがあります。

ASP.NET Core 1

ASP.NET Coreでは、ConfigureおよびオプションでConfigureServicesを更新する必要があります。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //add NLog to .NET Core
    loggerFactory.AddNLog();

    //Enable ASP.NET Core features (NLog.web) - only needed for ASP.NET Core users
    app.AddNLogWeb();

    //configure nlog.config in your project root. 
    env.ConfigureNLog("nlog.config");
    ...
    //you could use LogManager.Configuration from here


public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    // e.g. services.AddMvc();

    //needed for NLog.Web
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

ASP.NET Core 2

ASP.NET Core 2の場合、セットアップはASP.NET Core 1とは異なります

Program.csでNLogをセットアップします。

using NLog.Web;
using Microsoft.Extensions.Logging;

public static void Main(string[] args)
{
    // NLog: setup the logger first to catch all errors
    var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
        logger.Debug("init main");
        CreateWebHostBuilder(args).Build().Run(); 
    }
    catch (Exception ex)
    {
        //NLog: catch setup errors
        logger.Error(ex, "Stopped program because of exception");
        throw;
    }
    finally
    {
        // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
        NLog.LogManager.Shutdown();
    }
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
        })
        .UseNLog();  // NLog: setup NLog for Dependency injection

ログを書き込む

クラス型をジェネリック引数としてILoggerを注入します。

public class HomeController : Controller
{
    public HomeController(ILogger<HomeController> logger)
    {
        logger.LogInformation("created homeController");
    }

NLogルールを構成する

設定、ログ記録、フィルタリングの方法の例。

Nlog.configを作成します(nlog.configの詳細については、 docs を参照してください)

この例では、2つのファイルを作成します。1つはすべてのログ(Microsoftを含む)と、ログのみを含むファイルです。

<?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="Warn"
        internalLogFile="c:\temp\internal.txt">


    <extensions>
        <!--enable NLog.Web for ASP.NET Core-->
        <add Assembly="NLog.Web.AspNetCore"/>
    </extensions>

    <!-- define various log targets -->
    <targets>
        <!-- write logs to file -->
        <target xsi:type="File" name="allfile" fileName="c:\temp\nlog-all-${shortdate}.log"
                        layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />

        <target xsi:type="File" name="ownFile" fileName="c:\temp\nlog-own-${shortdate}.log"
                    layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />

    </targets>

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

        <!--Skip Microsoft logs - no writeTo attribute-->
        <logger name="Microsoft.*" minlevel="Trace" final="true" />
        <logger name="*" minlevel="Trace" writeTo="ownFile" />
    </rules>
</nlog>

Nlog.configを公開する

Nlog.configがcsprojファイルなどで公開されることを確認します。

<ItemGroup>
    <Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

出力

「nlog-own-2018-02-14.log」には次が含まれます。

2018-02-14 16:27:04.0547 | aspnetCoreApplication.Controllers | INFO | created homeController

2018-02-14 16:27:04.0547 | aspnetCoreApplication.Controllers | INFO | created homeController

トラブルシューティング

ASP.NET Core 2にデバッグログメッセージがありませんか? program.csでSetMinimumLevelを使用していますが、appsettings.jsonもこれを合流させることができます。

次のように変更できます。

Appsettings.jsonを変更します。

{
    "Logging": {
        "LogLevel": {
            "Default": "Trace"
        }
    }
}

ここでMicrosoftのログをフィルタリングすることもできます。

{
    "Logging": {
        "LogLevel": {
            "Default": "Trace",
            "Microsoft": "Information"
        }
    }
}

その他の問題については、このステッププランを参照して原因を見つけてください。 NLogでのロギングトラブルシューティング

乾杯、

ジュリアン(NLog)

編集:NLog.Web.AspNetCore 4.3用に更新

編集2:ASP.NET Core 2および最新の推奨事項のために更新

46
Julian

Julian's answer の更新: NLog.Framework.Logging は廃止とマークされています。代わりに NLog.Extensions.Logging を使用してください(ただし、パッケージの名前を変更するだけです) 。また、env.ConfigureNLog("nlog.config");はVisual Studio(IIS Express)でのデバッグに対してのみ正常に機能します。テスト環境で通常のIIS=にサービスを公開した後、500 internal server errorで開始できませんでした。サービスが起動時にnlog.configを見つけることができなかった。 NLogの問題

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationEnvironment appEnv)
{
    ...
    env.ConfigureNLog(Path.Combine(appEnv.ApplicationBasePath, "nlog.config"));
    ...
}

問題は、ローカルでデバッグする場合、作業ディレクトリはnlog.configを含むプロジェクトのディレクトリですが、IISに発行した後、作業ディレクトリが%PATH_TO_PUBLISHED_SERVICE%\approot\src\%PROJECT_NAME%\である間、すべてのソースファイルは%PATH_TO_PUBLISHED_SERVICE%\にあります。

6
Denis

.netコアコンソールアプリケーションにも使用できます。

private static void ConfigureNlogConfig(string configFile){
  LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationBasePath,configFile), true);
}
4
Ersin Tarhan

現在、ASP.NET CoreでNLogを使用する方法に関する公式のWikiページがあります。

NLog.Web.AspNetCore-Wiki-ASP.NET Core 2.0入門

NLog.Web.AspNetCore-Wiki-ASP.NET Core 1.0入門

3
Rolf Kristensen