diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj index 077d6c624..a4bb5566c 100644 --- a/src/Services/Identity/Identity.API/Identity.API.csproj +++ b/src/Services/Identity/Identity.API/Identity.API.csproj @@ -13,25 +13,28 @@ - - - + + + - + + + + - - - + + + + - + - diff --git a/src/Services/Identity/Identity.API/Program.cs b/src/Services/Identity/Identity.API/Program.cs index d06d49492..1398f87db 100644 --- a/src/Services/Identity/Identity.API/Program.cs +++ b/src/Services/Identity/Identity.API/Program.cs @@ -14,69 +14,100 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API { public class Program { - public static void Main(string[] args) + public static readonly string AppName = typeof(Program).Namespace; + public static readonly string ShortAppName = AppName.Substring(AppName.LastIndexOf('.', AppName.LastIndexOf('.') - 1) + 1); + + public static int Main(string[] args) { - BuildWebHost(args) - .MigrateDbContext((_, __) => { }) - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var logger = services.GetService>(); - var settings = services.GetService>(); - - new ApplicationDbContextSeed() - .SeedAsync(context, env, logger, settings) - .Wait(); - }) - .MigrateDbContext((context,services)=> - { - var configuration = services.GetService(); - - new ConfigurationDbContextSeed() - .SeedAsync(context, configuration) - .Wait(); - }).Run(); - } + var configuration = GetConfiguration(); - public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseStartup() - .ConfigureAppConfiguration((builderContext, config) => - { - var builtConfig = config.Build(); + Log.Logger = CreateSerilogLogger(configuration); + + try + { + Log.Information("Configuring web host ({Application})...", AppName); + var host = BuildWebHost(configuration, args); - var configurationBuilder = new ConfigurationBuilder(); + Log.Information("Applying migrations ({Application})...", AppName); + host.MigrateDbContext((_, __) => { }) + .MigrateDbContext((context, services) => + { + var env = services.GetService(); + var logger = services.GetService>(); + var settings = services.GetService>(); - if (Convert.ToBoolean(builtConfig["UseVault"])) + new ApplicationDbContextSeed() + .SeedAsync(context, env, logger, settings) + .Wait(); + }) + .MigrateDbContext((context, services) => { - 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(); - }) + new ConfigurationDbContextSeed() + .SeedAsync(context, configuration) + .Wait(); + }); + + Log.Information("Starting web host ({Application})...", AppName); + host.Run(); + + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Program terminated unexpectedly ({Application})!", AppName); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } + + private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) => + WebHost.CreateDefaultBuilder(args) + .CaptureStartupErrors(false) + .UseStartup() .UseApplicationInsights() - .UseSerilog((builderContext, config) => - { - config - .MinimumLevel.Information() - .Enrich.FromLogContext() - .WriteTo.Console(); - }) + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseWebRoot("Pics") + .UseConfiguration(configuration) + .UseSerilog() .Build(); + + private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) + { + var seqServerUrl = configuration["Serilog:SeqServerUrl"]; + + return new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Application", AppName) + .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/Identity/Identity.API/Startup.cs b/src/Services/Identity/Identity.API/Startup.cs index aa390779e..e6a257ccf 100644 --- a/src/Services/Identity/Identity.API/Startup.cs +++ b/src/Services/Identity/Identity.API/Startup.cs @@ -42,12 +42,12 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API // Add framework services. services.AddDbContext(options => options.UseSqlServer(Configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - })); + sqlServerOptionsAction: sqlOptions => + { + sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); + //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + })); services.AddIdentity() .AddEntityFrameworkStores() @@ -90,22 +90,22 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API .AddConfigurationStore(options => { options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(migrationsAssembly); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); + sqlServerOptionsAction: sqlOptions => + { + sqlOptions.MigrationsAssembly(migrationsAssembly); + //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }); }) .AddOperationalStore(options => { options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(migrationsAssembly); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); + sqlServerOptionsAction: sqlOptions => + { + sqlOptions.MigrationsAssembly(migrationsAssembly); + //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }); }) .Services.AddTransient(); @@ -118,10 +118,10 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - loggerFactory.AddAzureWebAppDiagnostics(); - loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); + //loggerFactory.AddConsole(Configuration.GetSection("Logging")); + //loggerFactory.AddDebug(); + //loggerFactory.AddAzureWebAppDiagnostics(); + //loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); if (env.IsDevelopment()) { diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index c5a109218..74d8e826c 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -5,12 +5,15 @@ "SpaClient": "http://localhost:5104", "XamarinCallback": "http://localhost:5105/xamarincallback", "UseCustomizationData": false, - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Trace", - "System": "Information", - "Microsoft": "Information" + "Serilog": { + "SeqServerUrl": null, + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Microsoft.eShopOnContainers": "Information", + "System": "Warning" + } } }, "ApplicationInsights": {