Add Seq as sink and some integration event traces

This commit is contained in:
Miguel Veloso 2019-01-31 13:33:36 +00:00
parent 6d2c1fc717
commit 3a22e2f35b
7 changed files with 119 additions and 71 deletions

View File

@ -13,25 +13,29 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" /> <PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" /> <PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.6" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" /> <PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.6" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,8 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events;
using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,15 +11,23 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even
{ {
public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler<ProductPriceChangedIntegrationEvent> public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler<ProductPriceChangedIntegrationEvent>
{ {
private readonly ILogger<ProductPriceChangedIntegrationEventHandler> _logger;
private readonly IBasketRepository _repository; private readonly IBasketRepository _repository;
public ProductPriceChangedIntegrationEventHandler(IBasketRepository repository) public ProductPriceChangedIntegrationEventHandler(
ILogger<ProductPriceChangedIntegrationEventHandler> logger,
IBasketRepository repository)
{ {
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_repository = repository ?? throw new ArgumentNullException(nameof(repository)); _repository = repository ?? throw new ArgumentNullException(nameof(repository));
} }
public async Task Handle(ProductPriceChangedIntegrationEvent @event) public async Task Handle(ProductPriceChangedIntegrationEvent @event)
{ {
using (LogContext.PushProperty("IntegrationEventId", @event.Id))
{
_logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Handling integration event: {IntegrationEventId} ({@IntegrationEvent})", @event.Id, @event);
var userIds = _repository.GetUsers(); var userIds = _repository.GetUsers();
foreach (var id in userIds) foreach (var id in userIds)
@ -27,6 +37,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even
await UpdatePriceInBasketItems(@event.ProductId, @event.NewPrice, @event.OldPrice, basket); await UpdatePriceInBasketItems(@event.ProductId, @event.NewPrice, @event.OldPrice, basket);
} }
} }
}
private async Task UpdatePriceInBasketItems(int productId, decimal newPrice, decimal oldPrice, CustomerBasket basket) private async Task UpdatePriceInBasketItems(int productId, decimal newPrice, decimal oldPrice, CustomerBasket basket)
{ {
@ -35,6 +46,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even
if (itemsToUpdate != null) if (itemsToUpdate != null)
{ {
_logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Updating items in basket for user: {BuyerId} ({@Items})", basket.BuyerId, itemsToUpdate);
foreach (var item in itemsToUpdate) foreach (var item in itemsToUpdate)
{ {
if (item.UnitPrice == oldPrice) if (item.UnitPrice == oldPrice)

View File

@ -12,51 +12,79 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
{ {
public class Program public class Program
{ {
public static void Main(string[] args) private static readonly string ApplicationName = typeof(Program).Namespace;
public static int Main(string[] args)
{ {
BuildWebHost(args).Run(); var configuration = GetConfiguration();
Log.Logger = CreateSerilogLogger(configuration);
try
{
Log.Information("Configuring web host ({Application})...", ApplicationName);
var host = BuildWebHost(configuration, args);
Log.Information("Starting web host ({Application})...", ApplicationName);
host.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({Application})!", ApplicationName);
return 1;
}
finally
{
Log.CloseAndFlush();
}
} }
public static IWebHost BuildWebHost(string[] args) => private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(false)
.UseFailing(options => .UseFailing(options =>
{ options.ConfigPath = "/Failing")
options.ConfigPath = "/Failing";
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>() .UseStartup<Startup>()
.ConfigureAppConfiguration((builderContext, config) =>
{
var builtConfig = config.Build();
var configurationBuilder = new ConfigurationBuilder();
if (Convert.ToBoolean(builtConfig["UseVault"]))
{
configurationBuilder.AddAzureKeyVault(
$"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
builtConfig["Vault:ClientId"],
builtConfig["Vault:ClientSecret"]);
}
configurationBuilder.AddEnvironmentVariables();
config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseSerilog((builderContext, config) =>
{
config
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console();
})
.UseApplicationInsights() .UseApplicationInsights()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(configuration)
.UseSerilog()
.Build(); .Build();
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.WithProperty("Application", ApplicationName)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
var config = builder.Build();
if (config.GetValue<bool>("UseVault", false))
{
builder.AddAzureKeyVault(
$"https://{config["Vault:Name"]}.vault.azure.net/",
config["Vault:ClientId"],
config["Vault:ClientSecret"]);
}
return builder.Build();
}
} }
} }

View File

@ -1,10 +1,13 @@
{ {
"Logging": { "Serilog": {
"IncludeScopes": false, "SeqServerUrl": null,
"LogLevel": { "MinimumLevel": {
"Default": "Debug", "Default": "Information",
"System": "Information", "Override": {
"Microsoft": "Information" "Microsoft": "Warning",
"Microsoft.eShopOnContainers": "Information",
"System": "Warning"
}
} }
}, },
"IdentityUrl": "http://localhost:5105", "IdentityUrl": "http://localhost:5105",

View File

@ -34,22 +34,22 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureStorage" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureStorage" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" /> <PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" /> <PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.1.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.0" /> <PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" /> <PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />

View File

@ -58,7 +58,7 @@ namespace Catalog.API.IntegrationEvents
{ {
using (LogContext.PushProperty("IntegrationEventId", evt.Id)) using (LogContext.PushProperty("IntegrationEventId", evt.Id))
{ {
_logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEvent}", evt.Id); _logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id);
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction(): //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency