netcore在linux写日志,在.NET Core控制台应用程序中使用日志

原标题:在.NET Core控制台应用程序中使用日志

假设在某个框架中有以下服务:

public interface ICalculationService

{

int Add( int x, int y);

}

public class CalculationService : ICalculationService

{

private readonly ILogger logger;

public CalculationService(ILogger logger)

=> this .logger = logger;

public int Add( int x, int y)

{

var result = x + y;

this .logger.LogDebug($ "{x}+{y}={result}" );

return result;

}

}

该服务很简单,就是计算两个整数的和,并在返回结果的时候打印一条日志。如果在ASP.NET Core应用程序中使用这个服务,方法非常简单,只需要在Startup.cs中注册服务,然后在Controller中直接通过构造器注入即可:

// Startup.cs

public void ConfigureServices(IServiceCollection services)

{

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

services.AddSingleton();

}

// Controller

[Route( "api/[controller]" )]

[ApiController]

public class CalculationController : ControllerBase

{

private readonly ICalculationService service;

public CalculationController(ICalculationService service)

{

this .service = service;

}

[HttpGet( "{x}/{y}" )]

public ActionResult< int > Get( int x, int y)

=> this .service.Add(x, y);

}

执行起来可以看到,日志可被正常输出:

那么,如果希望在一个控制台应用程序中使用这个CalculationService服务,又该如何提供这个ILogger构造函数的参数呢?

在.NET Core控制台应用程序中,如需使用标准的日志机制(Microsoft.Extensions.Logging),最合适的做法就是使用依赖注入,通过依赖注入框架来完成ILogger对象的解析。使用标准的日志机制的一个最大好处是,你可以选择不同的日志解决方案,来决定你的应用程序的日志输出方式。比如,Serilog提供了非常强大的扩展,可以很方便地将Serilog集成到应用程序中,以快速地实现将日志输出到几十种不同的日志服务平台。

下面,我使用dotnet CLI和Visual Studio Code来展示如何在.NET Core控制台应用程序中,使用上面的CalculationService服务。

首先,在本地目录中,使用dotnet new命令创建一个控制台应用程序:

1

dotnet new console -n CalcServiceApp

0b191023348408dc850d0a7ec45ac596.png

然后,使用dotnet add命令,添加NuGet包的引用:

dotnet add package Microsoft.Extensions.DependencyInjection

dotnet add package Microsoft.Extensions.Configuration

dotnet add package Microsoft.Extensions.Configuration.Json

dotnet add package Microsoft.Extensions.Logging

dotnet add package Microsoft.Extensions.Logging.Configuration

dotnet add package Microsoft.Extensions.Logging.Console

现在,基于CalcServiceApp目录,启动Visual Studio Code,如果已经安装了OmniSharp插件,Visual Studio Code会自动安装C#依赖项、更新代码引用,并提示会在当前目录下新建一个.vscode的隐藏目录,以存放项目调试的配置信息。我们暂时还不涉及到调试的问题,所以可以暂时放一放。

下面要做的就是在Program类的Main方法中,使用CalculationService提供的服务。Main方法的代码如下:

static void Main( string [] args)

{

// 从appsettings.json文件中读入日志的配置信息

var configuration = new ConfigurationBuilder()

.AddJsonFile( "appsettings.json" )

.Build();

using ( var serviceProvider = new ServiceCollection()

.AddLogging(loggingBuilder => {

loggingBuilder.AddConfiguration(configuration.GetSection( "Logging" ));

loggingBuilder.AddConsole(); // 将日志输出到控制台

})

.AddSingleton()

.BuildServiceProvider())

{

var calcService = serviceProvider.GetService();

Console.WriteLine(calcService.Add(3, 4));

}

}

上面的代码中,通过向ServiceCollection对象添加Logging配置,指定日志输出的配置文件将采用appsettings.json文件,同时使用该文件中的Logging节点所提供的配置信息。目前为了测试,appsettings.json文件内容如下:

{

"Logging" : {

"LogLevel" : {

"Default" : "Debug" ,

"System" : "Information" ,

"Microsoft" : "Information"

}

}

}

接下来,就是要确保appsettings.json文件在代码编译时,能够正确复制到输出目录,以便程序运行时能够找到该文件,因此,可以修改项目的csproj文件,指定appsettings.json文件能够在编译的时候复制到输出目录:

< Project Sdk = "Microsoft.NET.Sdk" >

< PropertyGroup >

< OutputType >Exe OutputType >

< TargetFramework >netcoreapp2.2 TargetFramework >

PropertyGroup >

< ItemGroup >

< PackageReference Include = "Microsoft.Extensions.Configuration" Version = "2.2.0" />

< PackageReference Include = "Microsoft.Extensions.Configuration.Json" Version = "2.2.0" />

< PackageReference Include = "Microsoft.Extensions.DependencyInjection" Version = "2.2.0" />

< PackageReference Include = "Microsoft.Extensions.Logging" Version = "2.2.0" />

< PackageReference Include = "Microsoft.Extensions.Logging.Configuration" Version = "2.2.0" />

< PackageReference Include = "Microsoft.Extensions.Logging.Console" Version = "2.2.0" />

ItemGroup >

< ItemGroup >

< None Update = "appsettings.json" >

< CopyToOutputDirectory >Always CopyToOutputDirectory >

None >

ItemGroup >

Project >

OK,在命令行通过dotnet run命令启动应用程序,可以看到日志能够被正常输出:

ead168e43c9289de40630418c93351e8.png

细心的朋友会发现,为什么日志的输出会在计算结果输出之后,不是应该在计算的时候才输出日志,而此时计算结果还没有返回吗?没错,看起来像是日志的输出会在单独的线程中进行。如果在Main函数中没有使用using来合理释放serviceProvider的资源,那么日志的输出内容会非常奇怪,有时候甚至看不到日志信息的输出。有关这一问题可以参考这篇帖子:https://github.com/aspnet/Logging/issues/631,解决方案就是需要dispose serviceProvider对象,但日志的输出仍然是异步的。

好了,有关在.NET Core控制台应用程序中使用日志,就介绍这么多,有关日志配置和使用的详细信息,可以参考微软的官方文档。微软官方文档内容非常给力,微软也花了很大的功夫启动了Docs项目,来推动文档本地化的工作进程。本文另一个目的是为了展示使用Visual Studio Code进行.NET Core应用程序的开发,为了撰写博客方便,我是在Windows下使用的Visual Studio Code和.NET Core SDK。事实上,在Linux或者MacOS下,都可以很好地使用Visual Studio Code进行.NET应用程序的开发(之前我也有一篇英文文章介绍这个话题:http://sunnycoding.cn/2018/11/07/developing-asp-net-core-apps-by-using-visual-studio-code/)。最后,贴一张Visual Studio Code的图,供大家参考:

70271a20f3d1de0263dab9bc23f59e19.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值