Browse Source

Add source-generated logging methods

pull/1318/head
copilot-swe-agent[bot] 2 weeks ago
committed by GitHub
parent
commit
19cff623e5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 27
      backend/src/Squidex.Infrastructure/Commands/LogCommandMiddleware.cs
  2. 28
      backend/src/Squidex.Infrastructure/EventSourcing/Consume/EventConsumerProcessor.cs
  3. 7
      backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs
  4. 22
      backend/src/Squidex.Infrastructure/Migrations/Migrator.cs
  5. 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;
public sealed class LogCommandMiddleware(ILogger<LogCommandMiddleware> log) : ICommandMiddleware
public sealed partial class LogCommandMiddleware(ILogger<LogCommandMiddleware> log) : ICommandMiddleware
{
public async Task HandleAsync(CommandContext context, NextDelegate next,
CancellationToken ct)
@ -20,7 +20,7 @@ public sealed class LogCommandMiddleware(ILogger<LogCommandMiddleware> log) : IC
{
if (log.IsEnabled(LogLevel.Debug))
{
log.LogDebug("Command {command} with ID {id} started.", type, context.ContextId);
LogCommandStarted(log, type, context.ContextId);
}
var watch = ValueStopwatch.StartNew();
@ -28,22 +28,37 @@ public sealed class LogCommandMiddleware(ILogger<LogCommandMiddleware> log) : IC
{
await next(context, ct);
log.LogInformation("Command {command} with ID {id} succeeded.", type, context.ContextId);
LogCommandSucceeded(log, type, context.ContextId);
}
finally
{
log.LogInformation("Command {command} with ID {id} completed after {time}ms.", type, context.ContextId, watch.Stop());
LogCommandCompleted(log, type, context.ContextId, watch.Stop());
}
}
catch (Exception ex)
{
log.LogError(ex, "Command {command} with ID {id} failed.", type, context.ContextId);
LogCommandFailed(log, type, context.ContextId, ex);
throw;
}
if (!context.IsCompleted)
{
log.LogCritical("Command {command} with ID {id} not handled.", type, context.ContextId);
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, Guid id);
[LoggerMessage(EventId = 2, Level = LogLevel.Information, Message = "Command {command} with ID {id} succeeded.")]
private static partial void LogCommandSucceeded(ILogger logger, Type command, Guid 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, Guid 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, Guid 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, Guid id);
}

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

@ -13,7 +13,7 @@ using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.EventSourcing.Consume;
public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
public partial class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
{
private readonly SimpleState<EventConsumerState> state;
private readonly IEventFormatter eventFormatter;
@ -69,7 +69,7 @@ public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
}
catch (Exception ex)
{
log.LogCritical(ex, "Failed to complete consumer.");
LogFailedToCompleteConsumer(log, ex);
}
}
@ -107,7 +107,7 @@ public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
if (logWindow.CanRetryAfterFailure())
{
log.LogError(exception, "Failed to handle event.");
LogFailedToHandleEvent(log, exception);
}
}, State.Position);
}
@ -215,8 +215,7 @@ public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
ex = new AggregateException(ex, unsubscribeException);
}
log.LogCritical(ex, "Failed to update consumer {consumer} at position {position} from {caller}.",
eventConsumer.Name, position, caller);
LogFailedToUpdateConsumer(log, eventConsumer.Name, position, caller, ex);
State = previousState.Stopped(ex);
}
@ -233,7 +232,7 @@ public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
{
if (log.IsEnabled(LogLevel.Debug))
{
log.LogDebug("Event consumer {consumer} reset started", eventConsumer.Name);
LogEventConsumerResetStarted(log, eventConsumer.Name);
}
var watch = ValueStopwatch.StartNew();
@ -243,7 +242,7 @@ public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
}
finally
{
log.LogDebug("Event consumer {consumer} reset completed after {time}ms.", eventConsumer.Name, watch.Stop());
LogEventConsumerResetCompleted(log, eventConsumer.Name, watch.Stop());
}
}
@ -282,4 +281,19 @@ public class EventConsumerProcessor : IEventSubscriber<ParsedEvents>
{
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;
public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLogStore
public sealed partial class BackgroundRequestLogStore : DisposableObjectBase, IRequestLogStore
{
private readonly IRequestLogRepository logRepository;
private readonly ILogger<BackgroundRequestLogStore> log;
@ -88,7 +88,7 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
}
catch (Exception ex)
{
log.LogError(ex, "Failed to track usage in background.");
LogTrackUsageFailed(log, ex);
}
finally
{
@ -127,4 +127,7 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
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);
}

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

@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging;
namespace Squidex.Infrastructure.Migrations;
public sealed class Migrator(
public sealed partial class Migrator(
IMigrationStatus migrationStatus,
IMigrationPath migrationPath,
ILogger<Migrator> log)
@ -41,7 +41,7 @@ public sealed class Migrator(
{
var name = migration.ToString()!;
log.LogInformation("Migration {migration} started.", name);
LogMigrationStarted(log, name);
try
{
@ -49,11 +49,11 @@ public sealed class Migrator(
await migration.UpdateAsync(ct);
log.LogInformation("Migration {migration} completed after {time}ms.", name, watch.Stop());
LogMigrationCompleted(log, name, watch.Stop());
}
catch (Exception ex)
{
log.LogCritical(ex, "Migration {migration} failed.", name);
LogMigrationFailed(log, name, ex);
throw new MigrationFailedException(name, ex);
}
}
@ -76,7 +76,7 @@ public sealed class Migrator(
{
while (!await migrationStatus.TryLockAsync(ct))
{
log.LogInformation("Could not acquire lock to start migrating. Trying again in {time}ms.", LockWaitMs);
LogMigrationLockRetry(log, LockWaitMs);
await Task.Delay(LockWaitMs, ct);
}
}
@ -92,4 +92,16 @@ public sealed class Migrator(
{
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);
}

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

@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace Squidex.Web.Pipeline;
public sealed class RequestExceptionMiddleware(RequestDelegate next)
public sealed partial class RequestExceptionMiddleware(RequestDelegate next)
{
private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor();
private static readonly RouteData EmptyRouteData = new RouteData();
@ -37,7 +37,7 @@ public sealed class RequestExceptionMiddleware(RequestDelegate next)
}
catch (Exception ex)
{
log.LogError(ex, "An unexpected exception has occurred.");
LogUnexpectedException(log, ex);
if (!context.Response.HasStarted)
{
@ -77,4 +77,7 @@ public sealed class RequestExceptionMiddleware(RequestDelegate next)
{
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