diff --git a/src/Services/LibraryManagement/LibraryManagement.API/LibraryManagement.API.csproj b/src/Services/LibraryManagement/LibraryManagement.API/LibraryManagement.API.csproj index 643a398a..6fbcaa9c 100644 --- a/src/Services/LibraryManagement/LibraryManagement.API/LibraryManagement.API.csproj +++ b/src/Services/LibraryManagement/LibraryManagement.API/LibraryManagement.API.csproj @@ -3,6 +3,11 @@ net5.0 + + + + + \ No newline at end of file diff --git a/src/Services/LibraryManagement/LibraryManagement.API/Program.cs b/src/Services/LibraryManagement/LibraryManagement.API/Program.cs index b6b805b6..b9e2491a 100644 --- a/src/Services/LibraryManagement/LibraryManagement.API/Program.cs +++ b/src/Services/LibraryManagement/LibraryManagement.API/Program.cs @@ -1,26 +1,81 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Diagnostics; +using System.IO; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Enrichers.Span; namespace LibraryManagement.API { - public class Program + public static class Program { - public static void Main(string[] args) + public static readonly string Namespace = typeof(Program).Namespace!; + public static readonly string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); + + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Top level all exception catcher")] + public static int Main(string[] args) { - CreateHostBuilder(args).Build().Run(); + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + + var configuration = GetConfiguration(); + Log.Logger = CreateSerilogLogger(configuration); + + try + { + Log.Information("Configuring web host ({ApplicationContext})...", AppName); + var host = CreateHostBuilder(configuration, args).Build(); + + Log.Information("Starting web host ({ApplicationContext})...", AppName); + host.Run(); + + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } } - public static IHostBuilder CreateHostBuilder(string[] args) => + public static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); + webBuilder.UseConfiguration(configuration); + webBuilder.UseSerilog(); }); + + private static ILogger CreateSerilogLogger(IConfiguration configuration) + { + return new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("ApplicationContext", AppName) + .Enrich.FromLogContext() + .Enrich.WithSpan() + .WriteTo.Console() + .WriteTo.Seq("http://seq") + .ReadFrom.Configuration(configuration) + .CreateLogger(); + } + + private static IConfiguration GetConfiguration() + { + var builder = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddEnvironmentVariables(); + + return builder.Build(); + } } } diff --git a/src/Services/LibraryManagement/LibraryManagement.API/Startup.cs b/src/Services/LibraryManagement/LibraryManagement.API/Startup.cs index 2b24d1aa..a239974a 100644 --- a/src/Services/LibraryManagement/LibraryManagement.API/Startup.cs +++ b/src/Services/LibraryManagement/LibraryManagement.API/Startup.cs @@ -1,16 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.HttpsPolicy; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; +using Serilog; namespace LibraryManagement.API { @@ -26,21 +21,35 @@ public Startup(IConfiguration configuration) // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - services.AddControllers(); services.AddSwaggerGen(c => { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "LibraryManagement.API", Version = "v1" }); + c.SwaggerDoc( + "v1", + new OpenApiInfo + { + Title = "LibraryManagement.API", + Version = "v1", + }); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { + var pathBase = Configuration["PATH_BASE"]; + if (!string.IsNullOrEmpty(pathBase)) + { + loggerFactory.CreateLogger().LogInformation("Using PATH BASE '{pathBase}'", pathBase); + app.UsePathBase(pathBase); + } + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } + + app.UseSerilogRequestLogging(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "LibraryManagement.API v1"));