2019 年 5 月 15 日更新
将其部署到 Azure Service Fabric 后,未填充日志文件,这似乎是 Serilog.Sinks.AzureBlobStorage NUGET 包与我的项目所针对的 .NET Core 版本 2.2.0 之间的不兼容。
我已经在 GitHub 页面上发了一张票,等待回复,短期内你可以下载源代码并将项目迁移到 Microsoft.NETCore.App 2.2.0 项目并直接引用此项目,一切正常。
原始答案
我似乎经常这样做,回答我自己的问题,但又来了。我花了一两天的时间才弄清楚这一点,所以我想我会与社区分享我的发现和解决方案,以防它可能在未来帮助其他人和/或有人可能有什么要补充甚至是矛盾的我欢迎任何意见。
我的开发环境如下:-
Microsoft Visual Studio 15.9.11
Windows 10 Professional
SDK:Microsoft.NETCore.App 2.2.0
我创建了一个新的 Service Fabric 无状态服务,该服务的目的是为 Angular 7 前端 Web 应用程序提供 RESTful 端点。
我的要求是通过调试窗口在我的开发环境中提供日志信息,并在我的应用托管在 Azure 上的 Service Fabric 集群中时提供类似的日志信息。
NUGET 包安装
Microsoft.Extensions.Logging (2.2.0)
Serilog.AspNetCore (2.1.1)
Serilog.Enrichers.Environment (2.1.3)
Serilog.Settings.Configuration (3.0.1)
Serilog.Sinks.Debug (1.0.1)
Serilog.Sinks.AzureBlobStorage (1.3.0)
控制开发和生产环境
我使用DEBUG 预处理器指令控制开发和生产环境,以包含appsettings.json 或appsettings.Development.json 文件。
我的 appSettings.Development.json 文件是这样的:-
{
"AppSettings": {
// My app settings not applicable to this
},
"Serilog": {
"Using": [ "Serilog.Sinks.Debug" ],
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {MachineName} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": ["WithMachineName"]
}
}
我的 appSettings.json 文件是这样的:-
{
"AppSettings": {
// My app settings not applicable to this
},
"Serilog": {
"Using": [ "Serilog.Sinks.AzureBlobStorage" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "AzureBlobStorage",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {MachineName} {Level:u3}] {Message:lj}{NewLine}{Exception}",
"connectionString": "[Connection String]",
"storageContainerName": "app",
"storageFileName": "{yyyy}-{MM}-{dd}.log"
}
}
],
"Enrich": [ "WithMachineName" ]
}
}
从上面的设置文件可以看出,我在开发时输出到调试窗口,并且我选择在部署到 Azure 中的 Service Fabric 群集时输出到 Azure Blob 存储。
要实现 Serilog 日志记录,请查看下面的 Stateless Service 类实现,它显示了如何根据环境切换两个不同的 appSettings.json 文件,以及如何通过使用将 Serilog 记录器插入到依赖注入系统中UseSerilog 扩展方法。
using System.Collections.Generic;
using System.Fabric;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.ServiceFabric.Services.Communication.AspNetCore;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
using Serilog;
namespace Caboodal.Manatee.ServiceFabric.Api.Identity
{
internal sealed class Identity : StatelessService
{
public Identity(StatelessServiceContext context)
: base(context)
{
}
private string AppSettingsFilename
{
get
{
#if DEBUG
return "appsettings.Development.json";
#else
return "appsettings.json";
#endif
}
}
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
var appSettings = GetAppSettings();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(appSettings)
.CreateLogger();
return new[]
{
new ServiceInstanceListener(
serviceContext =>
new KestrelCommunicationListener(
serviceContext,
"ServiceEndpoint",
(url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel()
.ConfigureAppConfiguration(
(builderContext, config) =>
{
config.AddJsonFile(AppSettingsFilename, false, true);
})
.ConfigureServices(
services => services
.AddSingleton(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseSerilog()
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
private IConfigurationRoot GetAppSettings()
{
return new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(AppSettingsFilename)
.Build();
}
}
}
在控制器中使用记录器
因为 ILogger 实例被配置为依赖注入实例,所以它可以像任何其他依赖项一样在您的 Controller 类中简单地访问,例如
[Authorize]
[ApiController]
[Route("[controller]")]
public class UserController : ApiController
{
private readonly IUserService _userService;
private readonly ILogger<UserController> _logger;
public UserController(IUserService userService, ILogger<UserController> logger)
{
_userService = userService;
_logger = logger;
}
[AllowAnonymous]
[HttpPost("authenticate")]
public IActionResult Authenticate([FromBody] DtoAuthenticateRequest request)
{
// Adding log entries
_logger.Log(LogLevel.Debug, "Here is a log entry");
// Some code in here
return Ok(response);
}
}
我对 ServiceEventSource.cs 类非常感兴趣,但使用 Serilog 我现在忽略了项目模板的这一方面。
如果您希望将日志输出给其他数据消费者或只是以不同的格式输出,那么只需查看 Serilog 网站here 以获取可用接收器的完整列表,Application Insights 就是其中之一。