diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index 4add803b6..0a1b5f581 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -13,25 +13,29 @@ - - + + + + + + - - - - + + + + + - diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs index 546483b40..aeadc9674 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs @@ -1,6 +1,8 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Basket.API.Model; +using Microsoft.Extensions.Logging; +using Serilog.Context; using System; using System.Linq; using System.Threading.Tasks; @@ -9,22 +11,31 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even { public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler { + private readonly ILogger _logger; private readonly IBasketRepository _repository; - public ProductPriceChangedIntegrationEventHandler(IBasketRepository repository) + public ProductPriceChangedIntegrationEventHandler( + ILogger logger, + IBasketRepository repository) { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _repository = repository ?? throw new ArgumentNullException(nameof(repository)); } public async Task Handle(ProductPriceChangedIntegrationEvent @event) { - var userIds = _repository.GetUsers(); - - foreach (var id in userIds) + using (LogContext.PushProperty("IntegrationEventId", @event.Id)) { - var basket = await _repository.GetBasketAsync(id); + _logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Handling integration event: {IntegrationEventId} ({@IntegrationEvent})", @event.Id, @event); - await UpdatePriceInBasketItems(@event.ProductId, @event.NewPrice, @event.OldPrice, basket); + var userIds = _repository.GetUsers(); + + foreach (var id in userIds) + { + var basket = await _repository.GetBasketAsync(id); + + await UpdatePriceInBasketItems(@event.ProductId, @event.NewPrice, @event.OldPrice, basket); + } } } @@ -35,17 +46,19 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even if (itemsToUpdate != null) { + _logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Updating items in basket for user: {BuyerId} ({@Items})", basket.BuyerId, itemsToUpdate); + foreach (var item in itemsToUpdate) { - if(item.UnitPrice == oldPrice) - { + if (item.UnitPrice == oldPrice) + { var originalPrice = item.UnitPrice; item.UnitPrice = newPrice; item.OldUnitPrice = originalPrice; } } await _repository.UpdateBasketAsync(basket); - } + } } } } diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index e4328645e..6b7387c55 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -12,51 +12,79 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API { 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) + .CaptureStartupErrors(false) .UseFailing(options => - { - options.ConfigPath = "/Failing"; - }) - .UseContentRoot(Directory.GetCurrentDirectory()) + options.ConfigPath = "/Failing") .UseStartup() - .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() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseConfiguration(configuration) + .UseSerilog() .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("UseVault", false)) + { + builder.AddAzureKeyVault( + $"https://{config["Vault:Name"]}.vault.azure.net/", + config["Vault:ClientId"], + config["Vault:ClientSecret"]); + } + + return builder.Build(); + } } } diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index eecc8bdd4..9ae6822f8 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -50,7 +50,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API // This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { - RegisterAppInsights(services); + RegisterAppInsights(services); // Add framework services. services.AddMvc(options => @@ -66,7 +66,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API services.AddCustomHealthCheck(Configuration); - services.Configure(Configuration); + services.Configure(Configuration); //By connecting here we are making sure that our service //cannot start until redis is ready. This might slow down startup, diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 4bff4d70d..33f1c299f 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -1,10 +1,13 @@ { - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" + "Serilog": { + "SeqServerUrl": null, + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Microsoft.eShopOnContainers": "Information", + "System": "Warning" + } } }, "IdentityUrl": "http://localhost:5105", diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 962f03ade..a413745dd 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -34,22 +34,22 @@ - + - - - + + + diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs index dd4e5b20e..6b7a65968 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs @@ -58,7 +58,7 @@ namespace Catalog.API.IntegrationEvents { 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(): //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency