使用 .NET Core 2 进行控制台日志记录和读取 Excel 文件






4.39/5 (8投票s)
.NET Core 2 控制台应用程序中的正确日志记录
引言
在本文中,我只关注两件事
- 正确日志记录:主要目标是在 .NET Core 2 中拥有一个具有可配置且良好日志记录的控制台应用程序,并且我们希望使用文件进行日志持久化。
- 读取 Excel 文件:这个概念验证的第二个目的是,的确,它让我在一个星期六的早上坐在键盘前,我需要使用 .NET Core 从 Excel 文件中读取信息。
背景
我今天写这篇文章是因为我一直在尝试查找关于这个主题的有用信息,我不得不多次浏览互联网,在一个大型的相关文章组中来回查找,但没有一篇文章可以完全帮助我实现我的目标。
Using the Code
代码是不言自明的,只需将其视为我为自己启动的 POC。这将是我们团队和我需要在下周开发的一个小型实用程序的起点,但请随意保留这些概念并将其用作您的 .NET Core 实用程序的起点。
注意:我不希望您对历史感到厌烦,所以我只会分享给我带来结果的源代码,并在最后进行一些解释。 我希望它可以帮助到您。
使用 .NET Core 2 进行正确日志记录
此代码片段适用于 .NET Core 控制台应用程序,但也可能稍作修改并用于 ASP NET Core 项目中。 如前所述,目标是拥有良好的控制台日志记录,但我们也希望配置日志级别并拥有单独的机制来记录到文件,从而为我们的应用程序添加日志持久性。
解决方案结构和依赖项
Program.cs
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Events;
using System;
namespace ExcelDataReaderPoc
{
class Program
{
static void Main(string[] args)
{
// Create service collection
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// Create service provider
var serviceProvider = serviceCollection.BuildServiceProvider();
// Run app
serviceProvider.GetService<App>().Run();
}
private static void ConfigureServices(IServiceCollection serviceCollection)
{
// Build configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", false)
.Build();
// Add console logging
serviceCollection.AddSingleton(new LoggerFactory()
.AddConsole(configuration.GetSection("Logging"))
.AddSerilog()
.AddDebug());
serviceCollection.AddLogging();
// Add Serilog logging
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.WriteTo.RollingFile(configuration["Serilog:LogFile"])
.CreateLogger();
// Add access to generic IConfigurationRoot
serviceCollection.AddSingleton(configuration);
// Add the App
serviceCollection.AddTransient<App>();
}
}
}
App.cs
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using OfficeOpenXml;
using System;
using System.IO;
using System.Text;
namespace ExcelDataReaderPoc
{
public class App
{
private readonly ILogger<App> _logger;
private readonly IConfigurationRoot _config;
public App(ILogger<App> logger, IConfigurationRoot config)
{
_logger = logger;
_config = config;
}
public void Run()
{
// Let's test log levels:
_logger.LogTrace("LogTrace");
_logger.LogDebug("LogDebug");
_logger.LogInformation("LogInformation");
_logger.LogWarning("LogWarning");
_logger.LogError("LogError");
_logger.LogCritical("LogCritical");
}
}
}
appsettings.json
{
"Configuration": {
"Title": "Excel Data Reader POC Application"
},
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Trace"
}
},
"Console": {
"LogLevel": {
"Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
"Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
"Microsoft.AspNetCore.Mvc.Razor": "Error",
"Default": "Trace"
}
},
"LogLevel": {
"Default": "Trace"
}
},
"Serilog": {
"LogFile": "C:/Logs/ExcelDataReaderPoc.log",
"MinimumLevel": "Verbose"
}
}
仅凭这一点,我们就可以在控制台中进行适当的日志记录,记录所有内容,因为 debug 的日志级别在 appsetttings.json 文件中设置为 Trace
。
在 .NET Core 2 中读取 Excel 文件
此外,由于我们配置了 Serilog 写入滚动文件,我们可以在配置的文件中看到其结果。 请注意,使用 Serilog 命名法的最低级别是 Verbose
。
该文件在其名称中添加了一个小的日期
并且内容输出具有足够的 POC 细节。
.NET Core 中的 Excel 读取
互联网上有很多关于此主题的文章,但没有一个能解决这个问题,经过多次尝试,我可以使用 EPPlus.Core
库(.NET Core 的非官方端口)获得良好的结果。 为此,我添加了最新的稳定 NuGet 包并修改了 App.cs 以尝试读取现代 Excel 文件 (.xlsx => 2007 或更高版本)。
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using OfficeOpenXml;
using System;
using System.IO;
using System.Text;
namespace ExcelDataReaderPoc
{
public class App
{
private readonly ILogger<App> _logger;
private readonly IConfigurationRoot _config;
public App(ILogger<App> logger, IConfigurationRoot config)
{
_logger = logger;
_config = config;
}
public void Run()
{
// Let's test log levels:
_logger.LogTrace("LogTrace");
_logger.LogDebug("LogDebug");
_logger.LogInformation("LogInformation");
_logger.LogWarning("LogWarning");
_logger.LogError("LogError");
_logger.LogCritical("LogCritical");
// TODO: Extract this to a service class
// load from excel
var filePath = @"D:/test.xlsx";
FileInfo file = new FileInfo(filePath);
using (ExcelPackage package = new ExcelPackage(file))
{
StringBuilder sb = new StringBuilder();
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int rowCount = worksheet.Dimension.Rows;
int ColCount = worksheet.Dimension.Columns;
var rawText = string.Empty;
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= ColCount; col++)
{
rawText += worksheet.Cells[row, col].Value.ToString() + "\t";
}
rawText+="\r\n";
}
_logger.LogInformation(rawText);
}
Console.ReadKey();
}
}
}
让我们运行它……这是控制台输出
这正是我所需要的,考虑到输入 Excel 文件是这样的
关注点
我发现的大部分关于 .NET Core 中日志记录的信息都集中在 ASP NET Core 应用程序上,并且令人讨厌的是,根据这些信息,在代码中调用适当的方法来设置最小级别对我不起作用。 不仅如此,很难找到将 LoggerFactory
(通过使用依赖注入注入 ILogger<T>
)与使用设置文件进行日志记录配置相结合的文章,因此,我希望本文能够帮助像我这样的开发人员在不久的将来节省时间,并在他们的 .NET Core 控制台应用程序和实用程序中获得快速的结果和良好的输出。
如需进一步阅读(Serilog 和 EPPlus 值得一看),以下是一些在 POC 开发期间对我有帮助的 URL 列表
- https://github.com/VahidN/EPPlus.Core
- https://github.com/aspnet/Logging/issues/437
- https://jonhilton.net/2016/09/21/log-different-levels-in-asp-net-core-app/
- https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?tabs=aspnetcore2x
- https://stackoverflow.com/questions/38114761/asp-net-core-configuration-for-net-core-console-application
- https://github.com/serilog/serilog-settings-configuration
- https://github.com/serilog/serilog
历史
- 2017年11月26日 -> 文章创建