From 7687e18efc4193b2d158394a46c7bc6ad14273ed Mon Sep 17 00:00:00 2001 From: Fredi Machado Date: Sun, 19 May 2024 12:08:41 +1000 Subject: [PATCH] Use record's ToString to improve event logs --- .../appsettings.Development.json | 3 ++- .../Events/ProductCreated.cs | 2 +- .../appsettings.Development.json | 3 ++- .../Events/OrderPlaced.cs | 6 +++--- .../Events/OrderPrepared.cs | 2 +- .../Projections/ProductCreated.cs | 2 +- .../appsettings.Development.json | 3 ++- .../Events/OrderPaidFor.cs | 2 +- .../Events/OrderPlaced.cs | 6 +++--- src/Common/NCafe.Core/Domain/Event.cs | 2 +- .../EventStore/EventStoreRepository.cs | 19 ++++++++++++++++++- 11 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/Admin/NCafe.Admin.Api/appsettings.Development.json b/src/Admin/NCafe.Admin.Api/appsettings.Development.json index 3e1a225..3dae546 100644 --- a/src/Admin/NCafe.Admin.Api/appsettings.Development.json +++ b/src/Admin/NCafe.Admin.Api/appsettings.Development.json @@ -2,7 +2,8 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Information" + "Microsoft.AspNetCore": "Information", + "NCafe.Infrastructure": "Trace" } } } diff --git a/src/Admin/NCafe.Admin.Domain/Events/ProductCreated.cs b/src/Admin/NCafe.Admin.Domain/Events/ProductCreated.cs index 3381189..482fd52 100644 --- a/src/Admin/NCafe.Admin.Domain/Events/ProductCreated.cs +++ b/src/Admin/NCafe.Admin.Domain/Events/ProductCreated.cs @@ -2,7 +2,7 @@ namespace NCafe.Admin.Domain.Events; -public sealed class ProductCreated : Event +public sealed record ProductCreated : Event { public ProductCreated(Guid id, string name, decimal price) { diff --git a/src/Barista/NCafe.Barista.Api/appsettings.Development.json b/src/Barista/NCafe.Barista.Api/appsettings.Development.json index 3e1a225..3dae546 100644 --- a/src/Barista/NCafe.Barista.Api/appsettings.Development.json +++ b/src/Barista/NCafe.Barista.Api/appsettings.Development.json @@ -2,7 +2,8 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Information" + "Microsoft.AspNetCore": "Information", + "NCafe.Infrastructure": "Trace" } } } diff --git a/src/Barista/NCafe.Barista.Domain/Events/OrderPlaced.cs b/src/Barista/NCafe.Barista.Domain/Events/OrderPlaced.cs index 2d2f865..0e11023 100644 --- a/src/Barista/NCafe.Barista.Domain/Events/OrderPlaced.cs +++ b/src/Barista/NCafe.Barista.Domain/Events/OrderPlaced.cs @@ -2,13 +2,13 @@ namespace NCafe.Barista.Domain.Events; -public sealed class OrderPlaced : Event +public sealed record OrderPlaced : Event { public OrderPlaced(Guid id) { Id = id; } - public Guid ProductId { get; set; } - public int Quantity { get; set; } + public Guid ProductId { get; init; } + public int Quantity { get; init; } } diff --git a/src/Barista/NCafe.Barista.Domain/Events/OrderPrepared.cs b/src/Barista/NCafe.Barista.Domain/Events/OrderPrepared.cs index 062f98b..9a26a42 100644 --- a/src/Barista/NCafe.Barista.Domain/Events/OrderPrepared.cs +++ b/src/Barista/NCafe.Barista.Domain/Events/OrderPrepared.cs @@ -2,7 +2,7 @@ namespace NCafe.Barista.Domain.Events; -public sealed class OrderPrepared : Event +public sealed record OrderPrepared : Event { public OrderPrepared(Guid id) { diff --git a/src/Cashier/NCafe.Cashier.Api/Projections/ProductCreated.cs b/src/Cashier/NCafe.Cashier.Api/Projections/ProductCreated.cs index 8e354d6..45c9b59 100644 --- a/src/Cashier/NCafe.Cashier.Api/Projections/ProductCreated.cs +++ b/src/Cashier/NCafe.Cashier.Api/Projections/ProductCreated.cs @@ -2,7 +2,7 @@ namespace NCafe.Cashier.Api.Projections; -public class ProductCreated : IEvent +public record ProductCreated : IEvent { public Guid Id { get; init; } public string Name { get; init; } diff --git a/src/Cashier/NCafe.Cashier.Api/appsettings.Development.json b/src/Cashier/NCafe.Cashier.Api/appsettings.Development.json index 3e1a225..3dae546 100644 --- a/src/Cashier/NCafe.Cashier.Api/appsettings.Development.json +++ b/src/Cashier/NCafe.Cashier.Api/appsettings.Development.json @@ -2,7 +2,8 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Information" + "Microsoft.AspNetCore": "Information", + "NCafe.Infrastructure": "Trace" } } } diff --git a/src/Cashier/NCafe.Cashier.Domain/Events/OrderPaidFor.cs b/src/Cashier/NCafe.Cashier.Domain/Events/OrderPaidFor.cs index 38ed515..b0cff54 100644 --- a/src/Cashier/NCafe.Cashier.Domain/Events/OrderPaidFor.cs +++ b/src/Cashier/NCafe.Cashier.Domain/Events/OrderPaidFor.cs @@ -2,7 +2,7 @@ namespace NCafe.Cashier.Domain.Events; -public sealed class OrderPaidFor : Event +public sealed record OrderPaidFor : Event { public OrderPaidFor(Guid id) { diff --git a/src/Cashier/NCafe.Cashier.Domain/Events/OrderPlaced.cs b/src/Cashier/NCafe.Cashier.Domain/Events/OrderPlaced.cs index b9fcc8a..b94413d 100644 --- a/src/Cashier/NCafe.Cashier.Domain/Events/OrderPlaced.cs +++ b/src/Cashier/NCafe.Cashier.Domain/Events/OrderPlaced.cs @@ -2,13 +2,13 @@ namespace NCafe.Cashier.Domain.Events; -public sealed class OrderPlaced : Event +public sealed record OrderPlaced : Event { public OrderPlaced(Guid id) { Id = id; } - public Guid ProductId { get; set; } - public int Quantity { get; set; } + public Guid ProductId { get; init; } + public int Quantity { get; init; } } diff --git a/src/Common/NCafe.Core/Domain/Event.cs b/src/Common/NCafe.Core/Domain/Event.cs index 1b218df..125d0cb 100644 --- a/src/Common/NCafe.Core/Domain/Event.cs +++ b/src/Common/NCafe.Core/Domain/Event.cs @@ -1,6 +1,6 @@ namespace NCafe.Core.Domain; -public abstract class Event : IEvent +public abstract record Event : IEvent { public Guid Id { get; protected set; } diff --git a/src/Common/NCafe.Infrastructure/EventStore/EventStoreRepository.cs b/src/Common/NCafe.Infrastructure/EventStore/EventStoreRepository.cs index 8f5e08c..fc13dfe 100644 --- a/src/Common/NCafe.Infrastructure/EventStore/EventStoreRepository.cs +++ b/src/Common/NCafe.Infrastructure/EventStore/EventStoreRepository.cs @@ -1,15 +1,19 @@ using EventStore.Client; +using Microsoft.Extensions.Logging; using NCafe.Core.Domain; using NCafe.Core.Repositories; namespace NCafe.Infrastructure.EventStore; -internal class EventStoreRepository(EventStoreClient eventStoreClient) : IRepository +internal class EventStoreRepository(EventStoreClient eventStoreClient, ILogger logger) : IRepository { private readonly EventStoreClient _eventStoreClient = eventStoreClient; + private readonly ILogger _logger = logger; public async Task GetById(Guid id) where TAggregate : AggregateRoot { + _logger.LogInformation("Loading aggregate {AggregateType} with ID {AggregateId}", typeof(TAggregate).Name, id); + var streamName = ToStreamName(id, typeof(TAggregate)); var aggregate = (TAggregate)Activator.CreateInstance(typeof(TAggregate), nonPublic: true); @@ -20,12 +24,17 @@ public async Task GetById(Guid id) where TAggregate : Ag StreamPosition.Start); var events = await result.ToListAsync(); + _logger.LogTrace("Applying {EventCount} events for aggregate {AggregateType} with ID {AggregateId}", + events.Count, typeof(TAggregate).Name, id); foreach (var @event in events) { var state = @event.AsAggregateEvent(); aggregate.ApplyEvent(state); + + _logger.LogTrace("Applied event {EventType} to aggregate {AggregateType} with ID {AggregateId}. Event: {@Event}", + state.GetType().Name, typeof(TAggregate).Name, id, state); } return aggregate; @@ -33,6 +42,8 @@ public async Task GetById(Guid id) where TAggregate : Ag public async Task Save(AggregateRoot aggregate) { + _logger.LogInformation("Saving aggregate {AggregateType} with ID {AggregateId}", aggregate.GetType().Name, aggregate.Id); + var streamName = ToStreamName(aggregate.Id, aggregate.GetType()); var pendingEvents = aggregate.GetPendingEvents().ToArray(); @@ -43,11 +54,17 @@ public async Task Save(AggregateRoot aggregate) .Select(e => e.AsEventData()) .ToArray(); + _logger.LogTrace("Appending {EventCount} events to aggregate {AggregateType} with ID {AggregateId}. Events: {@Events}.", + eventsToAppend.Length, aggregate.GetType().Name, aggregate.Id, pendingEvents); + var result = await _eventStoreClient.AppendToStreamAsync( streamName, StreamRevision.FromInt64(expectedVersion), eventsToAppend); + _logger.LogInformation("Saved aggregate {AggregateType} with ID {AggregateId}. Version: {Version}", + aggregate.GetType().Name, aggregate.Id, result.NextExpectedStreamRevision.ToInt64()); + aggregate.ClearPendingEvents(); }