Skip to content

Commit b885d63

Browse files
Merge pull request #324 from CodebreakerApp/copilot/fix-323
Enhance logging: Use strongly typed logging via LoggerExtensions/Log with source generation
2 parents 15eb759 + 483abcc commit b885d63

12 files changed

Lines changed: 117 additions & 19 deletions

File tree

src/services/bot/CodeBreaker.Bot/Infrastructure/Log.cs renamed to src/services/bot/CodeBreaker.Bot/Extensions/LoggerExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace CodeBreaker.Bot;
22

3-
internal static partial class Log
3+
internal static partial class LoggerExtensions
44
{
55
[LoggerMessage(
66
EventId = 3000,

src/services/bot/Codebreaker.BotQ/Endpoints/BotQueueClient.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using static Codebreaker.BotQ.Endpoints.BotQueueClient;
2+
using static CodeBreaker.Bot.Log;
23

34
namespace Codebreaker.BotQ.Endpoints;
45

@@ -25,7 +26,7 @@ private async Task ProcessMessagesAsync(QueueClient queueClient, QueueClient dea
2526
QueueProperties properties = await queueClient.GetPropertiesAsync();
2627
if (properties.ApproximateMessagesCount > 0)
2728
{
28-
logger.LogInformation("Queue has {count} messages", properties.ApproximateMessagesCount);
29+
logger.QueueHasMessages(properties.ApproximateMessagesCount);
2930
QueueMessage[] messages = await queueClient.ReceiveMessagesAsync();
3031
foreach (var encodedMessage in messages)
3132
{
@@ -41,7 +42,7 @@ private async Task ProcessMessagesAsync(QueueClient queueClient, QueueClient dea
4142

4243
byte[] bytes = Convert.FromBase64String(encodedMessage.MessageText);
4344
string message = Encoding.UTF8.GetString(bytes);
44-
logger.LogInformation("Received queue message: {message}", message);
45+
logger.ReceivedQueueMessage(message);
4546

4647
var botMessage = JsonSerializer.Deserialize<BotMessage>(message);
4748
if (botMessage is null)

src/services/bot/Codebreaker.BotQ/Infrastructure/Log.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,16 @@ internal static partial class Log
8585
Level = LogLevel.Information,
8686
Message = "Started playing games with sequence {Id}")]
8787
public static partial void StartedPlayingGames(this ILogger logger, Guid id);
88+
89+
[LoggerMessage(
90+
EventId = 4009,
91+
Level = LogLevel.Information,
92+
Message = "Queue has {Count} messages")]
93+
public static partial void QueueHasMessages(this ILogger logger, int count);
94+
95+
[LoggerMessage(
96+
EventId = 4010,
97+
Level = LogLevel.Information,
98+
Message = "Received queue message: {Message}")]
99+
public static partial void ReceivedQueueMessage(this ILogger logger, string message);
88100
}

src/services/gameapis/Codebreaker.GameAPIs/ApplicationServices.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.Extensions.Diagnostics.HealthChecks;
1+
using Codebreaker.GameAPIs.Extensions;
2+
using Microsoft.Extensions.Diagnostics.HealthChecks;
23

34
using System.Diagnostics;
45

@@ -154,15 +155,15 @@ public static async Task CreateOrUpdateDatabaseAsync(this WebApplication app)
154155
if (repo is GamesSqlServerContext context)
155156
{
156157
await context.Database.MigrateAsync();
157-
app.Logger.LogInformation("Database updated");
158+
app.Logger.DatabaseUpdated();
158159
}
159160

160161
// add a delay to try out /health checks
161162
await Task.Delay(TimeSpan.FromSeconds(25));
162163
}
163164
catch (Exception ex)
164165
{
165-
app.Logger.LogError(ex, "Error updating database");
166+
app.Logger.ErrorUpdatingDatabase(ex);
166167
}
167168
}
168169

src/services/gameapis/Codebreaker.GameAPIs/Infrastructure/Log.cs renamed to src/services/gameapis/Codebreaker.GameAPIs/Extensions/LoggerExtensions.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Codebreaker.GameAPIs.Extensions;
22

3-
public static partial class Log
3+
public static partial class LoggerExtensions
44
{
55
[LoggerMessage(
66
EventId = 3000,
@@ -29,7 +29,7 @@ public static partial class Log
2929
[LoggerMessage(
3030
EventId = 3004,
3131
Level = LogLevel.Error,
32-
Message = "Error writing game completed event, game id: {gameId}")]
32+
Message = "Error writing game completed event, game id: {GameId}")]
3333
public static partial void ErrorWritingGameCompletedEvent(this ILogger logger, Guid gameId, Exception ex);
3434

3535
[LoggerMessage(
@@ -114,4 +114,16 @@ public static void QueryGames(this ILogger logger, IEnumerable<Game> games, stri
114114
Level = LogLevel.Information,
115115
Message = "Game {GameId} completion sent via {Service}")]
116116
public static partial void GameCompletionSent(this ILogger logger, Guid gameId, string service);
117+
118+
[LoggerMessage(
119+
EventId = 4010,
120+
Level = LogLevel.Information,
121+
Message = "Database updated")]
122+
public static partial void DatabaseUpdated(this ILogger logger);
123+
124+
[LoggerMessage(
125+
EventId = 4011,
126+
Level = LogLevel.Error,
127+
Message = "Error updating database")]
128+
public static partial void ErrorUpdatingDatabase(this ILogger logger, Exception ex);
117129
}

src/services/gateway/Codebreaker.ApiGateway.Identities/Codebreaker.ApiGateway.Identities/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Codebreaker.ApiGateway.Identities.Components.Account.Pages;
1010
using Codebreaker.ApiGateway.Identities.Components.Account.Pages.Manage;
1111
using Codebreaker.ApiGateway.Identities.Data;
12+
using Codebreaker.ApiGateway.Identities.Extensions;
1213

1314
namespace Microsoft.AspNetCore.Routing;
1415

@@ -83,7 +84,7 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn
8384
}
8485

8586
var userId = await userManager.GetUserIdAsync(user);
86-
downloadLogger.LogInformation("User with ID '{UserId}' asked for their personal data.", userId);
87+
downloadLogger.UserRequestedPersonalData(userId);
8788

8889
// Only include personal data for download
8990
var personalData = new Dictionary<string, string>();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Codebreaker.ApiGateway.Identities.Extensions;
2+
3+
public static partial class LogExtensions
4+
{
5+
[LoggerMessage(
6+
EventId = 30001,
7+
Level = LogLevel.Information,
8+
Message = "User with ID '{UserId}' asked for their personal data")]
9+
public static partial void UserRequestedPersonalData(this ILogger logger, string userId);
10+
}

src/services/live/Codebreaker.Live/Endpoints/GRPCLiveGameService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Codebreaker.Grpc;
2+
using Codebreaker.Live.Extensions;
23
using Google.Protobuf.WellKnownTypes;
34
using Grpc.Core;
45

@@ -8,7 +9,7 @@ public class GRPCLiveGameService(IHubContext<LiveHub> hubContext, ILogger<GRPCLi
89
{
910
async public override Task<Empty> ReportGameCompleted(ReportGameCompletedRequest request, ServerCallContext context)
1011
{
11-
logger.LogInformation("Received game ended {type} {gameid}", request.GameType, request.Id);
12+
logger.ReceivedGameEnded(request.GameType, request.Id);
1213
await hubContext.Clients.Group(request.GameType).SendAsync("GameCompleted", request.ToGameSummary());
1314
return new Empty();
1415
}

src/services/live/Codebreaker.Live/Extensions/LogExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ public static partial class LogExtensions
2626
Message = "Processing game completion event")]
2727
public static partial void ProcessingGameCompletionEvent(this ILogger logger);
2828

29+
[LoggerMessage(
30+
EventId = 20005,
31+
Level = LogLevel.Information,
32+
Message = "Received game ended {GameType} {GameId}")]
33+
public static partial void ReceivedGameEnded(this ILogger logger, string gameType, string gameId);
34+
2935
[LoggerMessage(
3036
EventId = 40001,
3137
Level = LogLevel.Warning,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
namespace Codebreaker.Ranking.Extensions;
2+
3+
public static partial class LoggerExtensions
4+
{
5+
[LoggerMessage(
6+
EventId = 10001,
7+
Level = LogLevel.Information,
8+
Message = "Processing event")]
9+
public static partial void ProcessingEvent(this ILogger logger);
10+
11+
[LoggerMessage(
12+
EventId = 10002,
13+
Level = LogLevel.Warning,
14+
Message = "Game summary is empty after deserialization")]
15+
public static partial void GameSummaryIsEmpty(this ILogger logger);
16+
17+
[LoggerMessage(
18+
EventId = 10003,
19+
Level = LogLevel.Information,
20+
Message = "Received game completion event for game {GameId}")]
21+
public static partial void ReceivedGameCompletionEvent(this ILogger logger, Guid gameId);
22+
23+
[LoggerMessage(
24+
EventId = 10004,
25+
Level = LogLevel.Error,
26+
Message = "Error processing event: {Error}")]
27+
public static partial void ErrorProcessingEvent(this ILogger logger, Exception ex, string error);
28+
29+
[LoggerMessage(
30+
EventId = 10005,
31+
Level = LogLevel.Error,
32+
Message = "{Error}")]
33+
public static partial void Error(this ILogger logger, Exception ex, string error);
34+
35+
[LoggerMessage(
36+
EventId = 10006,
37+
Level = LogLevel.Error,
38+
Message = "Deserialized null GameSummary")]
39+
public static partial void DeserializedNullGameSummary(this ILogger logger);
40+
41+
[LoggerMessage(
42+
EventId = 10007,
43+
Level = LogLevel.Warning,
44+
Message = "Consume exception: {Message}")]
45+
public static partial void ConsumeException(this ILogger logger, string message);
46+
47+
[LoggerMessage(
48+
EventId = 10008,
49+
Level = LogLevel.Information,
50+
Message = "Processing was cancelled")]
51+
public static partial void ProcessingWasCancelled(this ILogger logger);
52+
}

0 commit comments

Comments
 (0)