简体   繁体   English

Microsoft Service Fabric 和日志记录

[英]Microsoft Service Fabric and logging

I am investigating the best way to implement logging for my Service Fabric Stateless API and have been somewhat overwhelmed by the varying different solutions for what appears to be a relatively simple requirement.我正在研究为我的 Service Fabric 无状态 API 实现日志记录的最佳方法,并且对于看似相对简单的需求的各种不同解决方案感到有些不知所措。

I have implemented logging using the WebHostBuilder().ConfigureLogging and have successfully logged my trace messages to the Debug window and via Serilog.Extensions.Logging.File I have also managed to dump this log to a file, this all being controlled via a #if DEBUG directive and this I was happy with.我已经使用WebHostBuilder().ConfigureLogging实现了日志记录并成功地将我的跟踪消息记录到调试窗口并通过Serilog.Extensions.Logging.File我还设法将此日志转储到一个文件中,这一切都通过#if DEBUG控制#if DEBUG指令和我很满意。

Then I needed to configure what would happen when deployed to a cluster within Azure and this is when I became overwhelmed!!!然后我需要配置部署到 Azure 中的集群时会发生什么,这让我不知所措!!!

I thought that I could register ServiceEventSource type logger in the same manner as I did with AddDebug however it was not this simple.我认为我可以像使用AddDebug一样注册ServiceEventSource类型记录器,但它并不是那么简单。

So I have managed to get my logs to appear within the diagnostic window using the ServiceEventSource.Current.Message but these logs are not integrated within the ASP.NET logging framework :/因此,我设法使用ServiceEventSource.Current.Message使我的日志出现在诊断窗口中,但这些日志未集成在 ASP.NET 日志记录框架中:/

My continued investigation has led me to understand that Service Fabric logging should be directed towards Application Insights albeit many, many articles having varying degrees of detail and applicability to the latest framework.我的持续调查使我明白,Service Fabric 日志记录应该针对 Application Insights,尽管很多文章具有不同程度的详细信息和对最新框架的适用性。

My current thinking is that I need to remove the ASP.NET logging and implement something such as EventFlow to allow my trace messages to be generated and subsequently piped through to Application Insights for interrogation at a later date, is my thinking correct??我目前的想法是我需要删除 ASP.NET 日志记录并实现诸如EventFlow东西,以允许生成我的跟踪消息,然后通过管道传输到 Application Insights 以供日后查询,我的想法是否正确?

Or am I currently going off at a tangent?或者我目前正在切线?

UPDATE 15/05/2019更新 15/05/2019
After deploying this to Azure Service Fabric the log files were not populated, this appears to be an incompatibility between the Serilog.Sinks.AzureBlobStorage NUGET package and the .NET Core version 2.2.0 that my project was targeting.将此部署到 Azure Service Fabric 后,未填充日志文件,这似乎是Serilog.Sinks.AzureBlobStorage NUGET 包与我的项目面向的 .NET Core 版本 2.2.0 之间的不兼容。

I have posted a ticket on the GitHub page and await a response, in the short term you can download the source code and migrate the project to a Microsoft.NETCore.App 2.2.0 project and directly reference this and everything works perfectly.我已经在 GitHub 页面上发布了一张票并等待回复,短期内您可以下载源代码并将项目迁移到Microsoft.NETCore.App 2.2.0 项目并直接引用它,一切正常。

ORIGINAL ANSWER原答案
I seem to do this quite a lot, answering my own question but here goes again.我似乎经常这样做,回答我自己的问题,但又来了。 It's taken me a day or two to get to the bottom of this so I thought I would share my findings and solution with the community in-case it might help somebody else in the future and/or somebody might have something to add or even contradict me which I'd welcome any input.我花了一两天的时间才弄明白这件事的真相,所以我想我会与社区分享我的发现和解决方案,以防将来它可能会帮助其他人和/或有人可能要添加甚至矛盾的东西我欢迎任何意见。

My development environment is as follows: -我的开发环境如下:-

Microsoft Visual Studio 15.9.11
Windows 10 Professional SDK: Microsoft.NETCore.App 2.2.0 Windows 10 Professional SDK: Microsoft.NETCore.App 2.2.0

I created a new Service Fabric Stateless Service the purpose of this service is to provide RESTful endpoints to a Angular 7 front end web application.我创建了一个新的 Service Fabric 无状态服务,该服务的目的是为 Angular 7 前端 Web 应用程序提供 RESTful 端点。

My requirement was to provide logging information in both my development environment via the Debug window and to also provide similar logging information whilst my apps are being hosted within a Service Fabric Cluster on Azure.我的要求是通过调试窗口在我的开发环境中提供日志信息,并在我的应用程序托管在 Azure 上的 Service Fabric 群集中时提供类似的日志信息。

NUGET Package Installations 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)

Controlling Development & Production Environments控制开发和生产环境
I control the development & production environments using the DEBUG pre-processor directive to include either the appsettings.json or appsettings.Development.json file.我使用DEBUG预处理器指令控制开发和生产环境,以包含appsettings.jsonappsettings.Development.json文件。

My appSettings.Development.json file is like this: -我的 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"]
  } 
}

My appSettings.json file is like this: -我的 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" ]
  }
}

As you can see from the above settings files I output to the Debug window when in development and I have chosen to output to Azure Blob Storage when deployed to a Service Fabric Cluster in Azure.从上面的设置文件可以看出,我在开发时输出到调试窗口,当部署到 Azure 中的 Service Fabric 群集时,我选择输出到 Azure Blob 存储。

To implement the Serilog logging simple review my Stateless Service class implementation below, which shows how to toggle the two different appSettings.json files dependent upon the environment and also how the Serilog logger is inserted into the dependency injection system via the use of the UseSerilog extension method.要实现 Serilog 日志记录,请简单查看下面我的无状态服务类实现,它显示了如何根据环境切换两个不同的 appSettings.json 文件,以及如何通过使用UseSerilog扩展将 Serilog 记录器插入到依赖注入系统中方法。

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();
        }
    }
}

Using the Logger within a controller在控制器中使用 Logger
Because the ILogger instance is configured as a Dependency Injected instance it can simply be accessed within your Controller classes like any other dependency eg因为 ILogger 实例被配置为一个依赖注入的实例,它可以像任何其他依赖一样在你的控制器类中简单地访问,例如

    [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);
        }
    }

I got very sidetracked with the ServiceEventSource.cs class but with the usage of Serilog I have now ignored this aspect of the project template.我对ServiceEventSource.cs类感到非常偏颇,但随着 Serilog 的使用,我现在忽略了项目模板的这一方面。

If you wish to output your logs to other data consumers or simply into different formats then just review the Serilog website here for a complete list of the Sinks available, with Application Insights being one of the many.如果您希望将您的日志输出给其他数据使用者或简单地输出为不同的格式,那么只需在此处查看 Serilog 网站以获取可用接收器的完整列表,Application Insights 就是其中之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Microsoft Service Fabric状态服务将无法启动 - Microsoft Service Fabric Stateful Service will not start Microsoft Service Fabric 主机服务 (FabricHostSvc) 在启动时挂起 - Microsoft Service Fabric Host Service (FabricHostSvc) Hangs on Start 从内部部署Service Fabric应用程序登录到Azure存储模拟器 - Logging to Azure Storage Emulator from on premise Service Fabric application 在服务结构中登录时,NService总线访问被拒绝 - NService Bus Access Denied when logging within service Fabric 日志仅在本地有效,但在部署到Microsoft Azure App Service时无效 - Logging only works localy, but not when deployed to Microsoft Azure App Service 没有注册“Microsoft.Extensions.Logging.ILoggingBuilder”类型的服务 - No service for type 'Microsoft.Extensions.Logging.ILoggingBuilder' has been registered 服务结构服务远程处理 - Service Fabric Service Remoting 如何从Microsoft Azure的Service Fabric中获取资源组名称 - How can I get the resource group name from within Service Fabric on Microsoft Azure 登录Microsoft Azure TableController - Logging in Microsoft Azure TableController 无法解析“Microsoft.Extensions.Logging.ILogger`1[WebApplication1.Startup]”类型的服务 - Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger`1[WebApplication1.Startup]'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM