-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add serilog logging #31
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe Dotnet Foundation's API project has embraced enhanced logging capabilities by integrating Serilog, a popular .NET logging library. This upgrade includes the addition of several Serilog packages to enrich logging functionality, alongside the configuration of both file and console logging with a custom template. This ensures a robust logging mechanism, further augmented by request logging middleware for comprehensive monitoring. Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 0
Configuration used: CodeRabbit UI
Files ignored due to path filters (1)
DotnetFoundation/DotnetFoundation.Api/appsettings.Development.jsonis excluded by:!**/*.json
Files selected for processing (2)
- DotnetFoundation/DotnetFoundation.Api/DotnetFoundation.Api.csproj (1 hunks)
- DotnetFoundation/DotnetFoundation.Api/Program.cs (3 hunks)
Additional comments: 5
DotnetFoundation/DotnetFoundation.Api/DotnetFoundation.Api.csproj (3)
- 11-11: The addition of the
Serilog.AspNetCorepackage reference is correct and necessary for integrating Serilog with ASP.NET Core.- 12-12: The addition of the
Serilog.Expressionspackage reference is correct and supports advanced log event filtering and transformation.- 13-13: The addition of the
Serilog.Formatting.Compactpackage reference is correct and enables compact JSON formatting for logs, aligning with the structured logging approach.DotnetFoundation/DotnetFoundation.Api/Program.cs (2)
- 57-70: The Serilog setup and configuration for both file and console logging are correctly implemented, following best practices for structured logging. However, consider making the log file path configurable through
appsettings.jsonor environment variables to enhance flexibility in different environments.- 94-94: The integration of Serilog with request logging middleware using
UseSerilogRequestLoggingis correctly implemented and placed within the request pipeline configuration.
Description
Add console and file logging using serilog
Log file is present in
./DotnetFoundation.Api/Logs/log-{timestamp}.ndjsonFollowed recommended format
Reference for expressionTemplate: https://nblumhardt.com/2021/06/customize-serilog-json-output/#:~:text=Tip%3A%20output,.Code
Osmosys coding standards: https://github.com/OsmosysSoftware/dev-standards/blob/main/coding-standards/log-format.md
Log output using serilog expressionTemplate
{"Timestamp":"2024-03-26T19:51:04.1683766+05:30","Level":"Information","TracebackId":"6e8b492067a8908b680e9520092a765f","RequestPath":"/swagger/v1/swagger.json","StatusCode":200,"SourceContext":"Microsoft.AspNetCore.Hosting.Diagnostics","Data":{"EventId":1948596947,"RequestId":"0HN2DJVRNB7QH:00000003"},"Message":"Request finished HTTP/1.1 GET http://localhost:5000/swagger/v1/swagger.json - 200 null application/json;charset=utf-8 260.5326ms"} {"Timestamp":"2024-03-26T19:51:11.2268782+05:30","Level":"Information","TracebackId":"6f06532a7cba78ddd9b6bc25c5f479d7","RequestPath":"/api/tasks","SourceContext":"Microsoft.AspNetCore.Hosting.Diagnostics","Data":{"EventId":3574200426,"RequestId":"0HN2DJVRNB7QH:00000004"},"Message":"Request starting HTTP/1.1 GET http://localhost:5000/api/tasks - null null"} {"Timestamp":"2024-03-26T19:51:11.2658494+05:30","Level":"Warning","TracebackId":"6f06532a7cba78ddd9b6bc25c5f479d7","RequestPath":"/api/tasks","SourceContext":"Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware","Data":{"EventId":3396783137,"RequestId":"0HN2DJVRNB7QH:00000004"},"Message":"Failed to determine the https port for redirect."} {"Timestamp":"2024-03-26T19:51:20.0705410+05:30","Level":"Error","TracebackId":"6f06532a7cba78ddd9b6bc25c5f479d7","RequestMethod":"GET","RequestPath":"/api/tasks","StatusCode":500,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","Data":{"EventId":1657833564},"Message":"HTTP GET /api/tasks responded 500 in 8792.4283 ms","Exception":"MySqlConnector.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.\r\n at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, MySqlConnection connection, Int64 startingTimestamp, ILoadBalancer loadBalancer, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 437\r\n at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, Action`4 logMessage, Int64 startingTimestamp, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 428\r\n at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, Action`4 logMessage, Int64 startingTimestamp, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 433\r\n at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int64 startingTimestamp, Int32 timeoutMilliseconds, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 111\r\n at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int64 startingTimestamp, Int32 timeoutMilliseconds, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 144\r\n at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int64 startingTimestamp, Activity activity, Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 919\r\n at MySqlConnector.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 419\r\n at MySqlConnector.MySqlConnection.Open() in /_/src/MySqlConnector/MySqlConnection.cs:line 381\r\n at Microsoft.EntityFrameworkCore.ServerVersion.AutoDetect(String connectionString)\r\n at DotnetFoundation.Infrastructure.DependencyInjection.<>c__DisplayClass0_0.<AddInfrastructure>b__0(DbContextOptionsBuilder options) in d:\\Osmosys\\R&D-X\\dotnet-foundation\\DotnetFoundation\\DotnetFoundation.Infrastructure\\DependencyInjection.cs:line 26\r\n at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass1_0`2.<AddDbContext>b__0(IServiceProvider _, DbContextOptionsBuilder b)\r\n at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.CreateDbContextOptions[TContext](IServiceProvider applicationServiceProvider, Action`2 optionsAction)\r\n at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass17_0`1.<AddCoreServices>b__0(IServiceProvider p)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)\r\n at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)\r\n at Microsoft.AspNetCore.Identity.SecurityStampValidator.ValidateAsync[TValidator](CookieValidatePrincipalContext context)\r\n at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.HandleAuthenticateAsync()\r\n at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()\r\n at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)"}Screenshots
logfile
console
Summary by CodeRabbit