Browse Source

Centralize logger messages per project

pull/1318/head
copilot-swe-agent[bot] 2 weeks ago
committed by GitHub
parent
commit
ca6bbc1e35
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 27
      backend/src/Squidex.Infrastructure/Commands/LogCommandMiddleware.cs
  2. 25
      backend/src/Squidex.Infrastructure/EventSourcing/Consume/EventConsumerProcessor.cs
  3. 7
      backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs
  4. 58
      backend/src/Squidex.Infrastructure/LogMessages.cs
  5. 22
      backend/src/Squidex.Infrastructure/Migrations/Migrator.cs
  6. 19
      backend/src/Squidex.Web/LogMessages.cs
  7. 2
      backend/src/Squidex.Web/Pipeline/FileCallbackResultExecutor.cs
  8. 7
      backend/src/Squidex.Web/Pipeline/RequestExceptionMiddleware.cs

27
backend/src/Squidex.Infrastructure/Commands/LogCommandMiddleware.cs

@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging;
namespace Squidex.Infrastructure.Commands; namespace Squidex.Infrastructure.Commands;
public sealed partial class LogCommandMiddleware(ILogger<LogCommandMiddleware> log) : ICommandMiddleware public sealed class LogCommandMiddleware(ILogger<LogCommandMiddleware> log) : ICommandMiddleware
{ {
public async Task HandleAsync(CommandContext context, NextDelegate next, public async Task HandleAsync(CommandContext context, NextDelegate next,
CancellationToken ct) CancellationToken ct)
@ -20,7 +20,7 @@ public sealed partial class LogCommandMiddleware(ILogger<LogCommandMiddleware> l
{ {
if (log.IsEnabled(LogLevel.Debug)) if (log.IsEnabled(LogLevel.Debug))
{ {
LogCommandStarted(log, type, context.ContextId); LogMessages.LogCommandStarted(log, type, context.ContextId);
} }
var watch = ValueStopwatch.StartNew(); var watch = ValueStopwatch.StartNew();
@ -28,37 +28,22 @@ public sealed partial class LogCommandMiddleware(ILogger<LogCommandMiddleware> l
{ {
await next(context, ct); await next(context, ct);
LogCommandSucceeded(log, type, context.ContextId); LogMessages.LogCommandSucceeded(log, type, context.ContextId);
} }
finally finally
{ {
LogCommandCompleted(log, type, context.ContextId, watch.Stop()); LogMessages.LogCommandCompleted(log, type, context.ContextId, watch.Stop());
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
LogCommandFailed(log, type, context.ContextId, ex); LogMessages.LogCommandFailed(log, type, context.ContextId, ex);
throw; throw;
} }
if (!context.IsCompleted) if (!context.IsCompleted)
{ {
LogCommandNotHandled(log, type, context.ContextId); LogMessages.LogCommandNotHandled(log, type, context.ContextId);
} }
} }
[LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "Command {command} with ID {id} started.")]
private static partial void LogCommandStarted(ILogger logger, Type command, DomainId id);
[LoggerMessage(EventId = 2, Level = LogLevel.Information, Message = "Command {command} with ID {id} succeeded.")]
private static partial void LogCommandSucceeded(ILogger logger, Type command, DomainId id);
[LoggerMessage(EventId = 3, Level = LogLevel.Information, Message = "Command {command} with ID {id} completed after {time}ms.")]
private static partial void LogCommandCompleted(ILogger logger, Type command, DomainId id, long time);
[LoggerMessage(EventId = 4, Level = LogLevel.Error, Message = "Command {command} with ID {id} failed.")]
private static partial void LogCommandFailed(ILogger logger, Type command, DomainId id, Exception exception);
[LoggerMessage(EventId = 5, Level = LogLevel.Critical, Message = "Command {command} with ID {id} not handled.")]
private static partial void LogCommandNotHandled(ILogger logger, Type command, DomainId id);
} }

25
backend/src/Squidex.Infrastructure/EventSourcing/Consume/EventConsumerProcessor.cs

@ -69,7 +69,7 @@ public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
} }
catch (Exception ex) catch (Exception ex)
{ {
LogFailedToCompleteConsumer(log, ex); LogMessages.LogFailedToCompleteConsumer(log, ex);
} }
} }
@ -107,7 +107,7 @@ public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
if (logWindow.CanRetryAfterFailure()) if (logWindow.CanRetryAfterFailure())
{ {
LogFailedToHandleEvent(log, exception); LogMessages.LogFailedToHandleEvent(log, exception);
} }
}, State.Position); }, State.Position);
} }
@ -215,7 +215,7 @@ public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
ex = new AggregateException(ex, unsubscribeException); ex = new AggregateException(ex, unsubscribeException);
} }
LogFailedToUpdateConsumer(log, eventConsumer.Name, position, caller, ex); LogMessages.LogFailedToUpdateConsumer(log, eventConsumer.Name, position, caller, ex);
State = previousState.Stopped(ex); State = previousState.Stopped(ex);
} }
@ -232,7 +232,7 @@ public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
{ {
if (log.IsEnabled(LogLevel.Debug)) if (log.IsEnabled(LogLevel.Debug))
{ {
LogEventConsumerResetStarted(log, eventConsumer.Name); LogMessages.LogEventConsumerResetStarted(log, eventConsumer.Name);
} }
var watch = ValueStopwatch.StartNew(); var watch = ValueStopwatch.StartNew();
@ -242,7 +242,7 @@ public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
} }
finally finally
{ {
LogEventConsumerResetCompleted(log, eventConsumer.Name, watch.Stop()); LogMessages.LogEventConsumerResetCompleted(log, eventConsumer.Name, watch.Stop());
} }
} }
@ -281,19 +281,4 @@ public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
{ {
return eventStore.CreateSubscription(subscriber, eventConsumer.EventsFilter, State.Position); return eventStore.CreateSubscription(subscriber, eventConsumer.EventsFilter, State.Position);
} }
[LoggerMessage(EventId = 1, Level = LogLevel.Critical, Message = "Failed to complete consumer.")]
private static partial void LogFailedToCompleteConsumer(ILogger logger, Exception exception);
[LoggerMessage(EventId = 2, Level = LogLevel.Error, Message = "Failed to handle event.")]
private static partial void LogFailedToHandleEvent(ILogger logger, Exception exception);
[LoggerMessage(EventId = 3, Level = LogLevel.Critical, Message = "Failed to update consumer {consumer} at position {position} from {caller}.")]
private static partial void LogFailedToUpdateConsumer(ILogger logger, string consumer, string? position, string? caller, Exception exception);
[LoggerMessage(EventId = 4, Level = LogLevel.Debug, Message = "Event consumer {consumer} reset started")]
private static partial void LogEventConsumerResetStarted(ILogger logger, string consumer);
[LoggerMessage(EventId = 5, Level = LogLevel.Debug, Message = "Event consumer {consumer} reset completed after {time}ms.")]
private static partial void LogEventConsumerResetCompleted(ILogger logger, string consumer, long time);
} }

7
backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs

@ -13,7 +13,7 @@ using Squidex.Infrastructure.Timers;
namespace Squidex.Infrastructure.Log; namespace Squidex.Infrastructure.Log;
public sealed partial class BackgroundRequestLogStore : DisposableObjectBase, IRequestLogStore public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLogStore
{ {
private readonly IRequestLogRepository logRepository; private readonly IRequestLogRepository logRepository;
private readonly ILogger<BackgroundRequestLogStore> log; private readonly ILogger<BackgroundRequestLogStore> log;
@ -88,7 +88,7 @@ public sealed partial class BackgroundRequestLogStore : DisposableObjectBase, IR
} }
catch (Exception ex) catch (Exception ex)
{ {
LogTrackUsageFailed(log, ex); LogMessages.LogTrackUsageFailed(log, ex);
} }
finally finally
{ {
@ -127,7 +127,4 @@ public sealed partial class BackgroundRequestLogStore : DisposableObjectBase, IR
return Task.CompletedTask; return Task.CompletedTask;
} }
[LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Failed to track usage in background.")]
private static partial void LogTrackUsageFailed(ILogger logger, Exception exception);
} }

58
backend/src/Squidex.Infrastructure/LogMessages.cs

@ -0,0 +1,58 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.Extensions.Logging;
namespace Squidex.Infrastructure;
internal static partial class LogMessages
{
[LoggerMessage(Level = LogLevel.Debug, Message = "Command {command} with ID {id} started.")]
public static partial void LogCommandStarted(ILogger logger, Type command, DomainId id);
[LoggerMessage(Level = LogLevel.Information, Message = "Command {command} with ID {id} succeeded.")]
public static partial void LogCommandSucceeded(ILogger logger, Type command, DomainId id);
[LoggerMessage(Level = LogLevel.Information, Message = "Command {command} with ID {id} completed after {time}ms.")]
public static partial void LogCommandCompleted(ILogger logger, Type command, DomainId id, long time);
[LoggerMessage(Level = LogLevel.Error, Message = "Command {command} with ID {id} failed.")]
public static partial void LogCommandFailed(ILogger logger, Type command, DomainId id, Exception exception);
[LoggerMessage(Level = LogLevel.Critical, Message = "Command {command} with ID {id} not handled.")]
public static partial void LogCommandNotHandled(ILogger logger, Type command, DomainId id);
[LoggerMessage(Level = LogLevel.Critical, Message = "Failed to complete consumer.")]
public static partial void LogFailedToCompleteConsumer(ILogger logger, Exception exception);
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to handle event.")]
public static partial void LogFailedToHandleEvent(ILogger logger, Exception exception);
[LoggerMessage(Level = LogLevel.Critical, Message = "Failed to update consumer {consumer} at position {position} from {caller}.")]
public static partial void LogFailedToUpdateConsumer(ILogger logger, string consumer, string? position, string? caller, Exception exception);
[LoggerMessage(Level = LogLevel.Debug, Message = "Event consumer {consumer} reset started")]
public static partial void LogEventConsumerResetStarted(ILogger logger, string consumer);
[LoggerMessage(Level = LogLevel.Debug, Message = "Event consumer {consumer} reset completed after {time}ms.")]
public static partial void LogEventConsumerResetCompleted(ILogger logger, string consumer, long time);
[LoggerMessage(Level = LogLevel.Information, Message = "Migration {migration} started.")]
public static partial void LogMigrationStarted(ILogger logger, string migration);
[LoggerMessage(Level = LogLevel.Information, Message = "Migration {migration} completed after {time}ms.")]
public static partial void LogMigrationCompleted(ILogger logger, string migration, long time);
[LoggerMessage(Level = LogLevel.Critical, Message = "Migration {migration} failed.")]
public static partial void LogMigrationFailed(ILogger logger, string migration, Exception exception);
[LoggerMessage(Level = LogLevel.Information, Message = "Could not acquire lock to start migrating. Trying again in {time}ms.")]
public static partial void LogMigrationLockRetry(ILogger logger, int time);
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to track usage in background.")]
public static partial void LogTrackUsageFailed(ILogger logger, Exception exception);
}

22
backend/src/Squidex.Infrastructure/Migrations/Migrator.cs

@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging;
namespace Squidex.Infrastructure.Migrations; namespace Squidex.Infrastructure.Migrations;
public sealed partial class Migrator( public sealed class Migrator(
IMigrationStatus migrationStatus, IMigrationStatus migrationStatus,
IMigrationPath migrationPath, IMigrationPath migrationPath,
ILogger<Migrator> log) ILogger<Migrator> log)
@ -41,7 +41,7 @@ public sealed partial class Migrator(
{ {
var name = migration.ToString()!; var name = migration.ToString()!;
LogMigrationStarted(log, name); LogMessages.LogMigrationStarted(log, name);
try try
{ {
@ -49,11 +49,11 @@ public sealed partial class Migrator(
await migration.UpdateAsync(ct); await migration.UpdateAsync(ct);
LogMigrationCompleted(log, name, watch.Stop()); LogMessages.LogMigrationCompleted(log, name, watch.Stop());
} }
catch (Exception ex) catch (Exception ex)
{ {
LogMigrationFailed(log, name, ex); LogMessages.LogMigrationFailed(log, name, ex);
throw new MigrationFailedException(name, ex); throw new MigrationFailedException(name, ex);
} }
} }
@ -76,7 +76,7 @@ public sealed partial class Migrator(
{ {
while (!await migrationStatus.TryLockAsync(ct)) while (!await migrationStatus.TryLockAsync(ct))
{ {
LogMigrationLockRetry(log, LockWaitMs); LogMessages.LogMigrationLockRetry(log, LockWaitMs);
await Task.Delay(LockWaitMs, ct); await Task.Delay(LockWaitMs, ct);
} }
} }
@ -92,16 +92,4 @@ public sealed partial class Migrator(
{ {
return migrationStatus.UnlockAsync(); return migrationStatus.UnlockAsync();
} }
[LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "Migration {migration} started.")]
private static partial void LogMigrationStarted(ILogger logger, string migration);
[LoggerMessage(EventId = 2, Level = LogLevel.Information, Message = "Migration {migration} completed after {time}ms.")]
private static partial void LogMigrationCompleted(ILogger logger, string migration, long time);
[LoggerMessage(EventId = 3, Level = LogLevel.Critical, Message = "Migration {migration} failed.")]
private static partial void LogMigrationFailed(ILogger logger, string migration, Exception exception);
[LoggerMessage(EventId = 4, Level = LogLevel.Information, Message = "Could not acquire lock to start migrating. Trying again in {time}ms.")]
private static partial void LogMigrationLockRetry(ILogger logger, int time);
} }

19
backend/src/Squidex.Web/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.Web;
internal static partial class LogMessages
{
[LoggerMessage(Level = LogLevel.Error, Message = "An unexpected exception has occurred.")]
public static partial void LogUnexpectedException(ILogger logger, Exception exception);
[LoggerMessage(Level = LogLevel.Critical, Message = "Failed to send result.")]
public static partial void LogFailedToSendResult(ILogger logger, Exception exception);
}

2
backend/src/Squidex.Web/Pipeline/FileCallbackResultExecutor.cs

@ -54,7 +54,7 @@ public sealed class FileCallbackResultExecutor(ILoggerFactory loggerFactory) : F
response.Headers.Clear(); response.Headers.Clear();
response.StatusCode = 404; response.StatusCode = 404;
Logger.LogCritical(new EventId(99), e, "Failed to send result."); LogMessages.LogFailedToSendResult(Logger, e);
} }
else else
{ {

7
backend/src/Squidex.Web/Pipeline/RequestExceptionMiddleware.cs

@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace Squidex.Web.Pipeline; namespace Squidex.Web.Pipeline;
public sealed partial class RequestExceptionMiddleware(RequestDelegate next) public sealed class RequestExceptionMiddleware(RequestDelegate next)
{ {
private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor(); private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor();
private static readonly RouteData EmptyRouteData = new RouteData(); private static readonly RouteData EmptyRouteData = new RouteData();
@ -37,7 +37,7 @@ public sealed partial class RequestExceptionMiddleware(RequestDelegate next)
} }
catch (Exception ex) catch (Exception ex)
{ {
LogUnexpectedException(log, ex); LogMessages.LogUnexpectedException(log, ex);
if (!context.Response.HasStarted) if (!context.Response.HasStarted)
{ {
@ -77,7 +77,4 @@ public sealed partial class RequestExceptionMiddleware(RequestDelegate next)
{ {
return statusCode is >= 400 and < 600; return statusCode is >= 400 and < 600;
} }
[LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "An unexpected exception has occurred.")]
private static partial void LogUnexpectedException(ILogger logger, Exception exception);
} }

Loading…
Cancel
Save