From 8ee28a015ee275fd26a0b0b3769421d96b961f49 Mon Sep 17 00:00:00 2001 From: Naresh Kumar Date: Thu, 24 Oct 2024 01:05:04 +0530 Subject: [PATCH 1/4] add serilog request logging and ilogger wiring --- TinyUrl/Program.cs | 63 +++++++++++++++++++--------- TinyUrl/TinyUrl.csproj | 6 +++ TinyUrl/appsettings.Development.json | 30 ++++++++++--- 3 files changed, 75 insertions(+), 24 deletions(-) diff --git a/TinyUrl/Program.cs b/TinyUrl/Program.cs index 579dc7e..d39c63c 100644 --- a/TinyUrl/Program.cs +++ b/TinyUrl/Program.cs @@ -1,30 +1,55 @@ +using Serilog; using TinyUrl.Controllers; using TinyUrl.Logic; using TinyUrl.Repository; -var builder = WebApplication.CreateBuilder(args); -var configuration = builder.Configuration; - -// Add services to the container. +try +{ -var services = builder.Services; -services.AddDataDependencies(configuration); -services.AddApiDependencies(); -services.AddBusinessLogicDependencies(); -var app = builder.Build(); + var builder = WebApplication.CreateBuilder(args); + var configuration = builder.Configuration; + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .Enrich.FromLogContext() + .WriteTo.Console() + .WriteTo.File("logs.txt") + .CreateLogger(); + + + // Add services to the container. + + var services = builder.Services; + services.AddSerilog(); + services.AddDataDependencies(configuration); + services.AddApiDependencies(); + services.AddBusinessLogicDependencies(); + var app = builder.Build(); + + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + // Configure the HTTP request pipeline. + + app.UseSerilogRequestLogging(); + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); + return 0; +} +catch (Exception e) +{ + Log.Fatal(e, "Host terminated unexpectedly"); + return 1; -if (app.Environment.IsDevelopment()) +} +finally { - app.UseSwagger(); - app.UseSwaggerUI(); + await Log.CloseAndFlushAsync(); } -// Configure the HTTP request pipeline. - -app.UseAuthorization(); - -app.MapControllers(); - -app.Run(); // to test using web application factory public partial class Program { } \ No newline at end of file diff --git a/TinyUrl/TinyUrl.csproj b/TinyUrl/TinyUrl.csproj index 7799f14..a1e0bed 100644 --- a/TinyUrl/TinyUrl.csproj +++ b/TinyUrl/TinyUrl.csproj @@ -17,6 +17,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/TinyUrl/appsettings.Development.json b/TinyUrl/appsettings.Development.json index e6a79f0..a9f1d02 100644 --- a/TinyUrl/appsettings.Development.json +++ b/TinyUrl/appsettings.Development.json @@ -1,9 +1,29 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } + "Serilog": { + "MinimumLevel": { + "Default": "Information", // Default log level + "Override": { + "Microsoft": "Warning", // Override Microsoft logs to Warning level + "System": "Warning" + } + }, + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], // Enrichment + "WriteTo": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/log-.txt", + "rollingInterval": "Day", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ] }, "ConnectionStrings": { "Sql": "Server=localhost,1433;Database=TinyUrl;User Id=sa;Password=111111111111111@Q;TrustServerCertificate=True;", From 1eac20967f2679da19e696cb2d676144dec397a5 Mon Sep 17 00:00:00 2001 From: Naresh Kumar Date: Thu, 24 Oct 2024 01:13:47 +0530 Subject: [PATCH 2/4] add application logs --- TinyUrl/Controllers/UrlController.cs | 11 +++++++++-- TinyUrl/Repository/SqlRepository.cs | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/TinyUrl/Controllers/UrlController.cs b/TinyUrl/Controllers/UrlController.cs index 309cfc8..4b76176 100644 --- a/TinyUrl/Controllers/UrlController.cs +++ b/TinyUrl/Controllers/UrlController.cs @@ -13,13 +13,19 @@ public class UrlController : ControllerBase private readonly IUrlRepository _urlRepository; private readonly IUnitOfWork _unitOfWork; private readonly IDistributedCache _cache; + private readonly ILogger _logger; - public UrlController(IUrlConverter urlConverter, IUrlRepository urlRepository, IUnitOfWork unitOfWork, IDistributedCache cache) + public UrlController(IUrlConverter urlConverter, + IUrlRepository urlRepository, + IUnitOfWork unitOfWork, + IDistributedCache cache, + ILogger logger) { this._urlConverter = urlConverter; this._urlRepository = urlRepository; this._unitOfWork = unitOfWork; this._cache = cache; + this._logger = logger; } [HttpPost("shorten")] @@ -48,9 +54,10 @@ public async Task RedirectToLongUrl(string shortUrlHash, Cancella var urlString = await this._cache.GetStringAsync(shortUrlHash, cancellationToken); if (!string.IsNullOrEmpty(urlString)) { + this._logger.LogInformation("Cache hit for {shortUrlHash}", shortUrlHash); return this.Redirect(urlString); } - + this._logger.LogInformation("Cache miss for {shortUrlHash}", shortUrlHash); var url = await this._urlRepository.TryGetUrlByCodeAsync(shortUrlHash, cancellationToken); urlString = url?.ToString(); if (string.IsNullOrEmpty(urlString)) diff --git a/TinyUrl/Repository/SqlRepository.cs b/TinyUrl/Repository/SqlRepository.cs index 10aa7e4..9264a29 100644 --- a/TinyUrl/Repository/SqlRepository.cs +++ b/TinyUrl/Repository/SqlRepository.cs @@ -5,10 +5,12 @@ namespace TinyUrl.Repository public class SqlRepository : IUrlRepository { private readonly ApplicationDbContext _dbContext; + private readonly ILogger _logger; - public SqlRepository(ApplicationDbContext dbContext) + public SqlRepository(ApplicationDbContext dbContext, ILogger logger) { this._dbContext = dbContext; + this._logger = logger; } public async Task GenerateIdAsync(Uri url, CancellationToken cancellationToken) @@ -17,6 +19,7 @@ public async Task GenerateIdAsync(Uri url, CancellationToken cancellationTo var urlMappings = new UrlMappings { Url = url.ToString() }; this._dbContext.Urls.Add(urlMappings); await this._dbContext.SaveChangesAsync(cancellationToken); + this._logger.LogInformation("Generated id {id} for {url}", urlMappings.Id, url); return urlMappings.Id; } @@ -30,12 +33,14 @@ public async Task TryUpdateCodeAsync(int id, string code, CancellationToke urlMappings.Code = code; await this._dbContext.SaveChangesAsync(cancellationToken); + this._logger.LogInformation("Updated code {code} for id {id}", code, id); return true; } public async Task TryGetUrlByCodeAsync(string code, CancellationToken cancellationToken) { var urlMappings = await this._dbContext.Urls.FirstOrDefaultAsync(x => x.Code == code, cancellationToken); + this._logger.LogInformation("Retrieved url {url} for code {code}", urlMappings?.Url, code); return urlMappings == null ? null : new Uri(urlMappings.Url!); } } From b121b85c8dc2237c2c924af1bf17d5b964ff161d Mon Sep 17 00:00:00 2001 From: Naresh Kumar Date: Thu, 24 Oct 2024 01:14:05 +0530 Subject: [PATCH 3/4] avoid double logging in console --- TinyUrl/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/TinyUrl/Program.cs b/TinyUrl/Program.cs index d39c63c..c3c4202 100644 --- a/TinyUrl/Program.cs +++ b/TinyUrl/Program.cs @@ -11,7 +11,6 @@ Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .Enrich.FromLogContext() - .WriteTo.Console() .WriteTo.File("logs.txt") .CreateLogger(); From b119172f5731c4e63d162c236e6977deadf33c3c Mon Sep 17 00:00:00 2001 From: Naresh Kumar Date: Thu, 24 Oct 2024 01:16:14 +0530 Subject: [PATCH 4/4] nit --- TinyUrl/Program.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/TinyUrl/Program.cs b/TinyUrl/Program.cs index c3c4202..e4a44ef 100644 --- a/TinyUrl/Program.cs +++ b/TinyUrl/Program.cs @@ -13,7 +13,6 @@ .Enrich.FromLogContext() .WriteTo.File("logs.txt") .CreateLogger(); - // Add services to the container. @@ -29,7 +28,6 @@ app.UseSwagger(); app.UseSwaggerUI(); } - // Configure the HTTP request pipeline. app.UseSerilogRequestLogging(); app.UseAuthorization();