diff --git a/assets/Squidex.Assets.FTP/FTPAssetStore.cs b/assets/Squidex.Assets.FTP/FTPAssetStore.cs index 79f675d..00a586b 100644 --- a/assets/Squidex.Assets.FTP/FTPAssetStore.cs +++ b/assets/Squidex.Assets.FTP/FTPAssetStore.cs @@ -43,7 +43,7 @@ public async Task InitializeAsync( pool.Return(client); } - log.LogInformation("Initialized with {path}", options.Path); + LogMessages.InitializedWithPath(log, options.Path); } public async Task GetSizeAsync(string fileName, diff --git a/assets/Squidex.Assets.FTP/LogMessages.cs b/assets/Squidex.Assets.FTP/LogMessages.cs new file mode 100644 index 0000000..6666be1 --- /dev/null +++ b/assets/Squidex.Assets.FTP/LogMessages.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Assets.FTP; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "Initialized with {path}")] + public static partial void InitializedWithPath(ILogger logger, string path); +} diff --git a/assets/Squidex.Assets.ResizeService/ImageResizer.cs b/assets/Squidex.Assets.ResizeService/ImageResizer.cs index 4d37426..0d59b43 100644 --- a/assets/Squidex.Assets.ResizeService/ImageResizer.cs +++ b/assets/Squidex.Assets.ResizeService/ImageResizer.cs @@ -42,7 +42,7 @@ private async Task BlurAsync(HttpContext context) catch (Exception ex) { var log = context.RequestServices.GetRequiredService>(); - log.LogError(ex, "Failed to orient image."); + LogMessages.FailedToOrientImage(log, ex); context.Response.StatusCode = 400; } @@ -64,7 +64,7 @@ await assetThumbnailGenerator.FixAsync( catch (Exception ex) { var log = context.RequestServices.GetRequiredService>(); - log.LogError(ex, "Failed to orient image."); + LogMessages.FailedToOrientImage(log, ex); context.Response.StatusCode = 400; } @@ -89,7 +89,7 @@ await assetThumbnailGenerator.CreateThumbnailAsync( catch (Exception ex) { var log = context.RequestServices.GetRequiredService>(); - log.LogError(ex, "Failed to resize image."); + LogMessages.FailedToResizeImage(log, ex); context.Response.StatusCode = 400; } diff --git a/assets/Squidex.Assets.ResizeService/LogMessages.cs b/assets/Squidex.Assets.ResizeService/LogMessages.cs new file mode 100644 index 0000000..584ca72 --- /dev/null +++ b/assets/Squidex.Assets.ResizeService/LogMessages.cs @@ -0,0 +1,19 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Assets.ResizeService; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to orient image.")] + public static partial void FailedToOrientImage(ILogger logger, Exception exception); + + [LoggerMessage(EventId = 2, Level = LogLevel.Error, Message = "Failed to resize image.")] + public static partial void FailedToResizeImage(ILogger logger, Exception exception); +} diff --git a/assets/Squidex.Assets/FolderAssetStore.cs b/assets/Squidex.Assets/FolderAssetStore.cs index 918bebe..b4827c3 100644 --- a/assets/Squidex.Assets/FolderAssetStore.cs +++ b/assets/Squidex.Assets/FolderAssetStore.cs @@ -27,7 +27,7 @@ public async Task InitializeAsync( } await this.UploadTestAssetAsync(ct); - log.LogInformation("Initialized with {folder}", directory.FullName); + LogMessages.InitializedWithFolder(log, directory.FullName); } catch (Exception ex) { diff --git a/assets/Squidex.Assets/LogMessages.cs b/assets/Squidex.Assets/LogMessages.cs new file mode 100644 index 0000000..6531748 --- /dev/null +++ b/assets/Squidex.Assets/LogMessages.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Assets; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "Initialized with {folder}")] + public static partial void InitializedWithFolder(ILogger logger, string folder); +} diff --git a/flows/Squidex.Flows/CronJobs/Internal/DefaultCronJobManager.cs b/flows/Squidex.Flows/CronJobs/Internal/DefaultCronJobManager.cs index fd6dea0..384a8e1 100644 --- a/flows/Squidex.Flows/CronJobs/Internal/DefaultCronJobManager.cs +++ b/flows/Squidex.Flows/CronJobs/Internal/DefaultCronJobManager.cs @@ -58,9 +58,7 @@ public async Task UpdateAllAsync( if (!TryGetCronExpression(cronJob.CronExpression, false, out var expression)) { failedJobs.TryAdd(cronJob.Id, true); - log.LogWarning("Failed parse expression '{expression}' for id '{id}'", - cronJob.Id, - cronJob.CronExpression); + LogMessages.FailedToParseExpression(log, cronJob.CronExpression, cronJob.Id); continue; } @@ -85,9 +83,7 @@ public async Task UpdateAllAsync( if (next == default) { - log.LogWarning("Failed to get next occurrency for cron job '{id}' and expression '{expression}'", - cronJob.Id, - cronJob.CronExpression); + LogMessages.FailedToGetNextOccurrency(log, cronJob.Id, cronJob.CronExpression); continue; } @@ -96,7 +92,7 @@ public async Task UpdateAllAsync( catch (Exception ex) { failedJobs.TryAdd(cronJob.Id, true); - log.LogError(ex, "Failed to handle cron job with id '{id}'", cronJob.Id); + LogMessages.FailedToHandleCronJob(log, ex, cronJob.Id); } } @@ -111,7 +107,7 @@ public async Task UpdateAllAsync( } catch (Exception ex) { - log.LogCritical(ex, "Failed to reschedule cron jobs."); + LogMessages.FailedToRescheduleCronJobs(log, ex); foreach (var (id, _) in currentUpdates) { failedJobs.TryAdd(id, true); diff --git a/flows/Squidex.Flows/CronJobs/Internal/LogMessages.cs b/flows/Squidex.Flows/CronJobs/Internal/LogMessages.cs new file mode 100644 index 0000000..6a667c2 --- /dev/null +++ b/flows/Squidex.Flows/CronJobs/Internal/LogMessages.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Flows.CronJobs.Internal; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Warning, Message = "Failed to parse expression '{expression}' for id '{id}'")] + public static partial void FailedToParseExpression(ILogger logger, string expression, string id); + + [LoggerMessage(EventId = 2, Level = LogLevel.Warning, Message = "Failed to get next occurrence for cron job '{id}' and expression '{expression}'")] + public static partial void FailedToGetNextOccurrency(ILogger logger, string id, string expression); + + [LoggerMessage(EventId = 3, Level = LogLevel.Error, Message = "Failed to handle cron job with id '{id}'")] + public static partial void FailedToHandleCronJob(ILogger logger, Exception exception, string id); + + [LoggerMessage(EventId = 4, Level = LogLevel.Critical, Message = "Failed to reschedule cron jobs.")] + public static partial void FailedToRescheduleCronJobs(ILogger logger, Exception exception); +} diff --git a/flows/Squidex.Flows/Internal/Execution/DefaultFlowExecutor.cs b/flows/Squidex.Flows/Internal/Execution/DefaultFlowExecutor.cs index d95dd8c..9a3f058 100644 --- a/flows/Squidex.Flows/Internal/Execution/DefaultFlowExecutor.cs +++ b/flows/Squidex.Flows/Internal/Execution/DefaultFlowExecutor.cs @@ -288,7 +288,7 @@ private async Task HandleCallbacksAsync(FlowExecutionState state, } catch (Exception ex) { - log.LogError(ex, "Failed to execute {callback}.", callback); + LogMessages.FailedToExecuteCallback(log, ex, callback); } } } diff --git a/flows/Squidex.Flows/Internal/Execution/FlowExecutionWorker.cs b/flows/Squidex.Flows/Internal/Execution/FlowExecutionWorker.cs index 96077d8..b424b69 100644 --- a/flows/Squidex.Flows/Internal/Execution/FlowExecutionWorker.cs +++ b/flows/Squidex.Flows/Internal/Execution/FlowExecutionWorker.cs @@ -73,7 +73,7 @@ public async Task QueryAsync( } catch (Exception ex) { - log.LogError(ex, "Failed to query rule events."); + LogMessages.FailedToQueryRuleEvents(log, ex); } } @@ -91,7 +91,7 @@ public async Task HandleAsync(FlowExecutionState state, } catch (Exception ex) { - log.LogError(ex, "Failed to execute flow."); + LogMessages.FailedToExecuteFlow(log, ex); } finally { diff --git a/flows/Squidex.Flows/Internal/Execution/LogMessages.cs b/flows/Squidex.Flows/Internal/Execution/LogMessages.cs new file mode 100644 index 0000000..7a8e0fa --- /dev/null +++ b/flows/Squidex.Flows/Internal/Execution/LogMessages.cs @@ -0,0 +1,22 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Flows.Internal.Execution; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to execute {callback}.")] + public static partial void FailedToExecuteCallback(ILogger logger, Exception exception, object callback); + + [LoggerMessage(EventId = 2, Level = LogLevel.Error, Message = "Failed to query rule events.")] + public static partial void FailedToQueryRuleEvents(ILogger logger, Exception exception); + + [LoggerMessage(EventId = 3, Level = LogLevel.Error, Message = "Failed to execute flow.")] + public static partial void FailedToExecuteFlow(ILogger logger, Exception exception); +} diff --git a/hosting/Squidex.Hosting.Abstractions/LogMessages.cs b/hosting/Squidex.Hosting.Abstractions/LogMessages.cs new file mode 100644 index 0000000..b068297 --- /dev/null +++ b/hosting/Squidex.Hosting.Abstractions/LogMessages.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Hosting; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Warning, Message = "Failed to execute timer.")] + public static partial void FailedToExecuteTimer(ILogger logger, Exception exception); +} diff --git a/hosting/Squidex.Hosting.Abstractions/SimpleTimer.cs b/hosting/Squidex.Hosting.Abstractions/SimpleTimer.cs index af9d1e3..f3fb74d 100644 --- a/hosting/Squidex.Hosting.Abstractions/SimpleTimer.cs +++ b/hosting/Squidex.Hosting.Abstractions/SimpleTimer.cs @@ -39,7 +39,10 @@ public SimpleTimer(Func action, TimeSpan interval, ILog } catch (Exception ex) { - log?.LogWarning(ex, "Failed to execute timer."); + if (log != null) + { + LogMessages.FailedToExecuteTimer(log, ex); + } } } } diff --git a/messaging/Squidex.Messaging.EntityFramework/EFSubscription.cs b/messaging/Squidex.Messaging.EntityFramework/EFSubscription.cs index 5ca552a..290b5d9 100644 --- a/messaging/Squidex.Messaging.EntityFramework/EFSubscription.cs +++ b/messaging/Squidex.Messaging.EntityFramework/EFSubscription.cs @@ -99,7 +99,7 @@ public async Task OnErrorAsync(TransportResult result, if (result.Data is not string id) { - log.LogWarning("Transport message has no MongoDb ID."); + LogMessages.TransportMessageHasNoMongoDbId(log); return; } @@ -115,7 +115,7 @@ await context.Set() } catch (Exception ex) { - log.LogError(ex, "Failed to put the message back into the queue '{queue}'.", channelName); + LogMessages.FailedToPutMessageBackIntoQueue(log, ex, channelName); } } @@ -129,7 +129,7 @@ public async Task OnSuccessAsync(TransportResult result, if (result.Data is not string id) { - log.LogWarning("Transport message has no MongoDb ID."); + LogMessages.TransportMessageHasNoMongoDbId(log); return; } @@ -142,7 +142,7 @@ await context.Set().Where(x => x.Id == id) } catch (Exception ex) { - log.LogError(ex, "Failed to remove message from queue '{queue}'.", channelName); + LogMessages.FailedToRemoveMessageFromQueue(log, ex, channelName); } } } diff --git a/messaging/Squidex.Messaging.EntityFramework/EFTransportCleaner.cs b/messaging/Squidex.Messaging.EntityFramework/EFTransportCleaner.cs index e9b6395..595adf5 100644 --- a/messaging/Squidex.Messaging.EntityFramework/EFTransportCleaner.cs +++ b/messaging/Squidex.Messaging.EntityFramework/EFTransportCleaner.cs @@ -38,7 +38,7 @@ await context.Set() if (updated > 0) { - log.LogInformation("{collectionName}: Items reset: {count}.", channelName, updated); + LogMessages.ItemsReset(log, channelName, updated); } }, updateInterval, log); diff --git a/messaging/Squidex.Messaging.EntityFramework/LogMessages.cs b/messaging/Squidex.Messaging.EntityFramework/LogMessages.cs new file mode 100644 index 0000000..97cc091 --- /dev/null +++ b/messaging/Squidex.Messaging.EntityFramework/LogMessages.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.EntityFramework; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Warning, Message = "Transport message has no database ID.")] + public static partial void TransportMessageHasNoMongoDbId(ILogger logger); + + [LoggerMessage(EventId = 2, Level = LogLevel.Error, Message = "Failed to put the message back into the queue '{queue}'.")] + public static partial void FailedToPutMessageBackIntoQueue(ILogger logger, Exception exception, string queue); + + [LoggerMessage(EventId = 3, Level = LogLevel.Error, Message = "Failed to remove message from queue '{queue}'.")] + public static partial void FailedToRemoveMessageFromQueue(ILogger logger, Exception exception, string queue); + + [LoggerMessage(EventId = 4, Level = LogLevel.Information, Message = "{collectionName}: Items reset: {count}.")] + public static partial void ItemsReset(ILogger logger, string collectionName, int count); +} diff --git a/messaging/Squidex.Messaging.GoogleCloud/GooglePubSubSubscription.cs b/messaging/Squidex.Messaging.GoogleCloud/GooglePubSubSubscription.cs index 4cc0b4e..6a06bfa 100644 --- a/messaging/Squidex.Messaging.GoogleCloud/GooglePubSubSubscription.cs +++ b/messaging/Squidex.Messaging.GoogleCloud/GooglePubSubSubscription.cs @@ -46,7 +46,7 @@ private async Task SubscribeCoreAsync(MessageTransportCallback callback, ILogger } catch (Exception ex) when (ex is not OperationCanceledException) { - log.LogError(ex, "Failed to consume message from subscription '{subscription}'.", subscriberClient.SubscriptionName.SubscriptionId); + LogMessages.FailedToConsumeMessageFromSubscription(log, ex, subscriberClient.SubscriptionName.SubscriptionId); } } diff --git a/messaging/Squidex.Messaging.GoogleCloud/LogMessages.cs b/messaging/Squidex.Messaging.GoogleCloud/LogMessages.cs new file mode 100644 index 0000000..a99bd27 --- /dev/null +++ b/messaging/Squidex.Messaging.GoogleCloud/LogMessages.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.GoogleCloud; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to consume message from subscription '{subscription}'.")] + public static partial void FailedToConsumeMessageFromSubscription(ILogger logger, Exception exception, string subscription); +} diff --git a/messaging/Squidex.Messaging.Kafka/KafkaLogFactory.cs b/messaging/Squidex.Messaging.Kafka/KafkaLogFactory.cs index 3f9d1b8..88dd180 100644 --- a/messaging/Squidex.Messaging.Kafka/KafkaLogFactory.cs +++ b/messaging/Squidex.Messaging.Kafka/KafkaLogFactory.cs @@ -62,24 +62,24 @@ public static Action, LogMessage> ProducerLog(ILogger lo private static void Log(ILogger log, string stats) { - log.LogInformation("Kafka stastics received: {stats}.", stats); + LogMessages.KafkaStatisticsReceived(log, stats); } private static void Log(ILogger log, Error error) { - log.LogInformation("Kafka error with code {code} happened: {details}.", error.Code, error.Reason); + LogMessages.KafkaError(log, error.Code, error.Reason); } private static void Log(ILogger log, LogMessage message) { var level = GetLogLevel(message.Level); - if (log.IsEnabled(level)) + if (!log.IsEnabled(level)) { return; } - log.Log(level, "Kafka log recieved from system {system}: {message}.", message.Name, message.Message); + LogMessages.KafkaLog(log, level, message.Name, message.Message); } private static LogLevel GetLogLevel(SyslogLevel level) diff --git a/messaging/Squidex.Messaging.Kafka/KafkaSubscription.cs b/messaging/Squidex.Messaging.Kafka/KafkaSubscription.cs index 5fa1cdc..c83da63 100644 --- a/messaging/Squidex.Messaging.Kafka/KafkaSubscription.cs +++ b/messaging/Squidex.Messaging.Kafka/KafkaSubscription.cs @@ -64,7 +64,7 @@ public KafkaSubscription(string channelName, MessageTransportCallback callback, } catch (Exception ex) { - log.LogError(ex, "Subscription failed."); + LogMessages.SubscriptionFailed(log, ex); } finally { @@ -91,7 +91,7 @@ public async ValueTask DisposeAsync() } catch (Exception ex) { - log.LogError(ex, "Kafka shutdown failed."); + LogMessages.KafkaShutdownFailed(log, ex); } } @@ -118,7 +118,7 @@ private void Commit(TransportResult result) if (result.Data is not ConsumeResult consumeResult) { - log.LogWarning("Transport message has no consume result."); + LogMessages.TransportMessageHasNoConsumeResult(log); return; } @@ -128,7 +128,7 @@ private void Commit(TransportResult result) } catch (Exception ex) { - log.LogError(ex, "Failed to commit the message."); + LogMessages.FailedToCommitMessage(log, ex); } } } diff --git a/messaging/Squidex.Messaging.Kafka/LogMessages.cs b/messaging/Squidex.Messaging.Kafka/LogMessages.cs new file mode 100644 index 0000000..ecc4270 --- /dev/null +++ b/messaging/Squidex.Messaging.Kafka/LogMessages.cs @@ -0,0 +1,35 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Confluent.Kafka; +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.Kafka; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Subscription failed.")] + public static partial void SubscriptionFailed(ILogger logger, Exception exception); + + [LoggerMessage(EventId = 2, Level = LogLevel.Error, Message = "Kafka shutdown failed.")] + public static partial void KafkaShutdownFailed(ILogger logger, Exception exception); + + [LoggerMessage(EventId = 3, Level = LogLevel.Warning, Message = "Transport message has no consume result.")] + public static partial void TransportMessageHasNoConsumeResult(ILogger logger); + + [LoggerMessage(EventId = 4, Level = LogLevel.Error, Message = "Failed to commit the message.")] + public static partial void FailedToCommitMessage(ILogger logger, Exception exception); + + [LoggerMessage(EventId = 5, Level = LogLevel.Information, Message = "Kafka statistics received: {stats}.")] + public static partial void KafkaStatisticsReceived(ILogger logger, string stats); + + [LoggerMessage(EventId = 6, Level = LogLevel.Information, Message = "Kafka error with code {code} happened: {details}.")] + public static partial void KafkaError(ILogger logger, ErrorCode code, string details); + + [LoggerMessage(EventId = 7, Message = "Kafka log received from system {system}: {message}.")] + public static partial void KafkaLog(ILogger logger, LogLevel level, string system, string message); +} diff --git a/messaging/Squidex.Messaging.Mongo/LogMessages.cs b/messaging/Squidex.Messaging.Mongo/LogMessages.cs new file mode 100644 index 0000000..449e62f --- /dev/null +++ b/messaging/Squidex.Messaging.Mongo/LogMessages.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.Mongo; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Warning, Message = "Transport message has no MongoDb ID.")] + public static partial void TransportMessageHasNoMongoDbId(ILogger logger); + + [LoggerMessage(EventId = 2, Level = LogLevel.Error, Message = "Failed to put the message back into the queue '{queue}'.")] + public static partial void FailedToPutMessageBackIntoQueue(ILogger logger, Exception exception, string? queue); + + [LoggerMessage(EventId = 3, Level = LogLevel.Error, Message = "Failed to remove message from queue '{queue}'.")] + public static partial void FailedToRemoveMessageFromQueue(ILogger logger, Exception exception, string? queue); + + [LoggerMessage(EventId = 4, Level = LogLevel.Information, Message = "{collectionName}: Items reset: {count}.")] + public static partial void ItemsReset(ILogger logger, string collectionName, long count); +} diff --git a/messaging/Squidex.Messaging.Mongo/MongoSubscription.cs b/messaging/Squidex.Messaging.Mongo/MongoSubscription.cs index 94b8413..14d3168 100644 --- a/messaging/Squidex.Messaging.Mongo/MongoSubscription.cs +++ b/messaging/Squidex.Messaging.Mongo/MongoSubscription.cs @@ -165,7 +165,7 @@ public async Task OnErrorAsync(TransportResult result, if (result.Data is not string id) { - log.LogWarning("Transport message has no MongoDb ID."); + LogMessages.TransportMessageHasNoMongoDbId(log); return; } @@ -175,7 +175,7 @@ public async Task OnErrorAsync(TransportResult result, } catch (Exception ex) { - log.LogError(ex, "Failed to put the message back into the queue '{queue}'.", channelName); + LogMessages.FailedToPutMessageBackIntoQueue(log, ex, channelName); } } @@ -189,7 +189,7 @@ public async Task OnSuccessAsync(TransportResult result, if (result.Data is not string id) { - log.LogWarning("Transport message has no MongoDb ID."); + LogMessages.TransportMessageHasNoMongoDbId(log); return; } @@ -199,7 +199,7 @@ public async Task OnSuccessAsync(TransportResult result, } catch (Exception ex) { - log.LogError(ex, "Failed to remove message from queue '{queue}'.", channelName); + LogMessages.FailedToRemoveMessageFromQueue(log, ex, channelName); } } } diff --git a/messaging/Squidex.Messaging.Mongo/MongoTransportCleaner.cs b/messaging/Squidex.Messaging.Mongo/MongoTransportCleaner.cs index 471b117..e272045 100644 --- a/messaging/Squidex.Messaging.Mongo/MongoTransportCleaner.cs +++ b/messaging/Squidex.Messaging.Mongo/MongoTransportCleaner.cs @@ -35,7 +35,7 @@ internal sealed class MongoTransportCleaner( if (update.IsModifiedCountAvailable && update.ModifiedCount > 0) { - log.LogInformation("{collectionName}: Items reset: {count}.", channelName, update.ModifiedCount); + LogMessages.ItemsReset(log, channelName, update.ModifiedCount); } }, updateInterval, log); diff --git a/messaging/Squidex.Messaging.RabbitMq/LogMessages.cs b/messaging/Squidex.Messaging.RabbitMq/LogMessages.cs new file mode 100644 index 0000000..f4413d2 --- /dev/null +++ b/messaging/Squidex.Messaging.RabbitMq/LogMessages.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.RabbitMq; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to handle message from queue {queue}.")] + public static partial void FailedToHandleMessageFromQueue(ILogger logger, Exception exception, string queue); + + [LoggerMessage(EventId = 2, Level = LogLevel.Warning, Message = "Transport message has no RabbitMq delivery tag.")] + public static partial void TransportMessageHasNoRabbitMqDeliveryTag(ILogger logger); + + [LoggerMessage(EventId = 3, Level = LogLevel.Error, Message = "Failed to acknowledge message from queue {queue}.")] + public static partial void FailedToAcknowledgeMessageFromQueue(ILogger logger, Exception exception, string queue); + + [LoggerMessage(EventId = 4, Level = LogLevel.Error, Message = "Failed to reject message from queue {queue}.")] + public static partial void FailedToRejectMessageFromQueue(ILogger logger, Exception exception, string queue); +} diff --git a/messaging/Squidex.Messaging.RabbitMq/RabbitMqSubscription.cs b/messaging/Squidex.Messaging.RabbitMq/RabbitMqSubscription.cs index 229281d..7feb3b5 100644 --- a/messaging/Squidex.Messaging.RabbitMq/RabbitMqSubscription.cs +++ b/messaging/Squidex.Messaging.RabbitMq/RabbitMqSubscription.cs @@ -75,7 +75,7 @@ internal async Task StartAsync(MessageTransportCallback callback, } catch (Exception ex) { - log.LogError(ex, "Failed to handle message from queue {queue}.", queueName); + LogMessages.FailedToHandleMessageFromQueue(log, ex, queueName); } }; @@ -105,7 +105,7 @@ public async Task OnErrorAsync(TransportResult result, if (result.Data is not ulong deliverTag) { - log.LogWarning("Transport message has no RabbitMq delivery tag."); + LogMessages.TransportMessageHasNoRabbitMqDeliveryTag(log); return; } @@ -115,7 +115,7 @@ public async Task OnErrorAsync(TransportResult result, } catch (Exception ex) { - log.LogError(ex, "Failed to acknowledge message from queue {queue}.", queueName); + LogMessages.FailedToAcknowledgeMessageFromQueue(log, ex, queueName); } } @@ -129,7 +129,7 @@ public async Task OnSuccessAsync(TransportResult result, if (result.Data is not ulong deliverTag) { - log.LogWarning("Transport message has no RabbitMq delivery tag."); + LogMessages.TransportMessageHasNoRabbitMqDeliveryTag(log); return; } @@ -139,7 +139,7 @@ public async Task OnSuccessAsync(TransportResult result, } catch (Exception ex) { - log.LogError(ex, "Failed to reject message from queue {queue}.", queueName); + LogMessages.FailedToRejectMessageFromQueue(log, ex, queueName); } } } diff --git a/messaging/Squidex.Messaging.Redis/LogMessages.cs b/messaging/Squidex.Messaging.Redis/LogMessages.cs new file mode 100644 index 0000000..0e813e1 --- /dev/null +++ b/messaging/Squidex.Messaging.Redis/LogMessages.cs @@ -0,0 +1,19 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.Redis; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to deserialize message.")] + public static partial void FailedToDeserializeMessage(ILogger logger, Exception exception); + + [LoggerMessage(EventId = 100, EventName = "RedisConnectionLog", Level = LogLevel.Debug, Message = "{message}")] + public static partial void RedisConnectionLog(ILogger logger, string? message); +} diff --git a/messaging/Squidex.Messaging.Redis/LoggerTextWriter.cs b/messaging/Squidex.Messaging.Redis/LoggerTextWriter.cs index 462e226..515bdb0 100644 --- a/messaging/Squidex.Messaging.Redis/LoggerTextWriter.cs +++ b/messaging/Squidex.Messaging.Redis/LoggerTextWriter.cs @@ -22,9 +22,7 @@ public override void WriteLine(string? value) { if (log.IsEnabled(LogLevel.Debug)) { -#pragma warning disable CA2254 // Template should be a static expression - log.LogDebug(new EventId(100, "RedisConnectionLog"), value); -#pragma warning restore CA2254 // Template should be a static expression + LogMessages.RedisConnectionLog(log, value); } } } diff --git a/messaging/Squidex.Messaging.Redis/RedisTopicSubscription.cs b/messaging/Squidex.Messaging.Redis/RedisTopicSubscription.cs index 850a2f8..f6aa510 100644 --- a/messaging/Squidex.Messaging.Redis/RedisTopicSubscription.cs +++ b/messaging/Squidex.Messaging.Redis/RedisTopicSubscription.cs @@ -28,7 +28,7 @@ public RedisTopicSubscription(string topicName, ISubscriber subscriber, MessageT } catch (Exception ex) { - log.LogError(ex, "Failed to deserialize message."); + LogMessages.FailedToDeserializeMessage(log, ex); } }); diff --git a/messaging/Squidex.Messaging.Subscriptions/Implementation/LogMessages.cs b/messaging/Squidex.Messaging.Subscriptions/Implementation/LogMessages.cs new file mode 100644 index 0000000..2795e35 --- /dev/null +++ b/messaging/Squidex.Messaging.Subscriptions/Implementation/LogMessages.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.Subscriptions.Implementation; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "Received payload of type {type} from {sender}")] + public static partial void ReceivedPayload(ILogger logger, Type? type, string? sender); +} diff --git a/messaging/Squidex.Messaging.Subscriptions/Implementation/SubscriptionService.cs b/messaging/Squidex.Messaging.Subscriptions/Implementation/SubscriptionService.cs index 9f2eb95..083e2d4 100644 --- a/messaging/Squidex.Messaging.Subscriptions/Implementation/SubscriptionService.cs +++ b/messaging/Squidex.Messaging.Subscriptions/Implementation/SubscriptionService.cs @@ -46,7 +46,7 @@ public Task HandleAsync(PayloadMessageBase message, return Task.CompletedTask; } - log.LogDebug("Received payload of type {type} from {sender}", message.GetUntypedPayload()?.GetType(), message.SourceId); + LogMessages.ReceivedPayload(log, message.GetUntypedPayload()?.GetType(), message.SourceId); foreach (var subscriptionId in message.SubscriptionIds) { diff --git a/messaging/Squidex.Messaging/Implementation/DelegatingConsumer.cs b/messaging/Squidex.Messaging/Implementation/DelegatingConsumer.cs index 8f63e00..da468bb 100644 --- a/messaging/Squidex.Messaging/Implementation/DelegatingConsumer.cs +++ b/messaging/Squidex.Messaging/Implementation/DelegatingConsumer.cs @@ -103,7 +103,7 @@ private async Task OnScheduledMessage((SerializedObject source, TransportResult catch (Exception ex) { // The message is broken, we cannot handle it, even if we would retry. - log.LogError(ex, "Failed to deserialize message with type {type}.", source.TypeString); + LogMessages.FailedToDeserializeMessage(log, ex, source.TypeString); return; } @@ -127,7 +127,7 @@ private async Task OnScheduledMessage((SerializedObject source, TransportResult { if (shouldLog) { - log.LogInformation("Handling {message} for {channel} with {handler}.", deserialized.Message, channelName, handler); + LogMessages.HandlingMessage(log, deserialized.Message, channelName, handler); } using (var linked = CancellationTokenSource.CreateLinkedTokenSource(ct)) @@ -139,7 +139,7 @@ private async Task OnScheduledMessage((SerializedObject source, TransportResult if (shouldLog) { - log.LogInformation("Handled {message} for {channel} with {handler}.", deserialized.Message, channelName, handler); + LogMessages.HandledMessage(log, deserialized.Message, channelName, handler); } } catch (OperationCanceledException) @@ -148,13 +148,13 @@ private async Task OnScheduledMessage((SerializedObject source, TransportResult } catch (Exception ex) { - log.LogInformation(ex, "Failed to handle {message} for {channel} with {handler}.", deserialized.Message, channelName, handler); + LogMessages.FailedToHandleMessage(log, ex, deserialized.Message, channelName, handler); } } } catch (Exception ex) { - log.LogError(ex, "Failed to consume message with type {type}.", source.TypeString); + LogMessages.FailedToConsumeMessage(log, ex, source.TypeString); } finally { @@ -192,7 +192,7 @@ private async Task OnMessageAsync(TransportResult transportResult, IMessageAck a // The message is broken, we cannot handle it, even if we would retry. await ack.OnSuccessAsync(transportResult, default); - log.LogWarning("Message has no type header."); + LogMessages.MessageHasNoTypeHeader(log); return; } diff --git a/messaging/Squidex.Messaging/Implementation/LogMessages.cs b/messaging/Squidex.Messaging/Implementation/LogMessages.cs new file mode 100644 index 0000000..a7f51fd --- /dev/null +++ b/messaging/Squidex.Messaging/Implementation/LogMessages.cs @@ -0,0 +1,31 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Logging; + +namespace Squidex.Messaging.Implementation; + +internal static partial class LogMessages +{ + [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to deserialize message with type {type}.")] + public static partial void FailedToDeserializeMessage(ILogger logger, Exception exception, string type); + + [LoggerMessage(EventId = 2, Level = LogLevel.Information, Message = "Handling {message} for {channel} with {handler}.")] + public static partial void HandlingMessage(ILogger logger, object? message, ChannelName channel, object handler); + + [LoggerMessage(EventId = 3, Level = LogLevel.Information, Message = "Handled {message} for {channel} with {handler}.")] + public static partial void HandledMessage(ILogger logger, object? message, ChannelName channel, object handler); + + [LoggerMessage(EventId = 4, Level = LogLevel.Information, Message = "Failed to handle {message} for {channel} with {handler}.")] + public static partial void FailedToHandleMessage(ILogger logger, Exception exception, object? message, ChannelName channel, object handler); + + [LoggerMessage(EventId = 5, Level = LogLevel.Error, Message = "Failed to consume message with type {type}.")] + public static partial void FailedToConsumeMessage(ILogger logger, Exception exception, string type); + + [LoggerMessage(EventId = 6, Level = LogLevel.Warning, Message = "Message has no type header.")] + public static partial void MessageHasNoTypeHeader(ILogger logger); +}