ASP.NET Core里让NLog根据环境加载配置文件

2019-07-09 10:09:47 浏览数 (1)

我们知道ASP.NET Core自带了appsettings.环境名.json,天生就能做到根据不同的环境选择不同的配置文件。但是NLog的官方例子里只有一份nlog.config,如何根据不同环境加载不同配置呢?

怎么会有这种想法

首先,这个需求的背景,依然来源于我自己的博客系统(https://edi.wang)。我的博客运行在全球领先的微软智能云Azure国际版的App Services上(真香)。而这个服务有配套的日志文件夹,位于应用程序目录以外。虽然我仍然可以把日志记在网站目录下,但这么做并不是Azure的推荐实践。因此对于生产环境,我需要更改NLog的日志文件路径。

原路径

fileName="${basedir}logs${shortdate}.log"

新路径

fileName="${basedir}....LogFilesApplication${shortdate}.log"

没错,NLog支持用".."的方式表示上一级文件夹。

现在生产环境没问题了,但是开发环境会跟着受影响。日志会写到不合理的文件夹里去,如果没有二级父目录,那么日志就直接没了。因此为了解决这个问题,我们需要一个能判断当前环境,并使用不同NLog配置文件的方法。

新建环境配置文件

首先,复制出一个用于开发环境的配置文件,如:nlog.debug.config,这种命名的好处在于,VS会自动将它nest到nlog.config下。

在我的例子里,只有日志路径是环境独立的。因此我需要在nlog.debug.config里针对开发环境,设置日志路径:

fileName="${basedir}logs${shortdate}.log"

加载环境配置文件

NLog加载配置文件的位置位于ASP.NET Core应用刚启动的时候:

public static void Main(string[] args)

{

var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

// ...

}

然而这时候程序还没有加载依赖注入,用不了IHostingEnvironment,如何获取环境名称呢?

其实呢,ASP.NET Core的环境名称是通过一个名为 ASPNETCORE_ENVIRONMENT 的环境变量配置的,这在VS里可以通过工程属性看到:

所以就算我们还没有DI服务,我们可以这样硬搞:

Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

它会返回环境名称的字符串值。对于最常用的环境名称,ASP.NET Core框架自己有一个预定义的文件:

namespace Microsoft.AspNetCore.Hosting

{

//

// Summary:

// Commonly used environment names.

public static class EnvironmentName

{

public static readonly string Development;

public static readonly string Staging;

public static readonly string Production;

}

}

在我的例子里,只要不是Production环境,我就要让NLog加载nlog.debug.config,所以这样写就OK啦:

public static void Main(string[] args)

{

var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

var isProd = environment == EnvironmentName.Production;

var logger = NLogBuilder.ConfigureNLog(isProd ? "nlog.config" : "nlog.debug.config").GetCurrentClassLogger();

}

现在,网站在Azure上能够将日志写入专用文件夹:

在本地debug的时候,写入网站根目录:

0 人点赞