From 574b321aeab2a4f9ac9ab7f6c6fd675f36224056 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 30 Jan 2025 08:14:41 -0600 Subject: [PATCH] Normalized Structured Logging Parts. --- .../Billing/StripeEventHandler.cs | 2 +- .../Extensions/LogBuilderExtensions.cs | 4 +- .../Extensions/LoggerExtensions.cs | 26 +- src/Exceptionless.Core/Jobs/CleanupDataJob.cs | 6 +- .../Jobs/CleanupOrphanedDataJob.cs | 4 +- .../Jobs/DailySummaryJob.cs | 2 +- .../Jobs/EventNotificationsJob.cs | 6 +- src/Exceptionless.Core/Jobs/EventPostsJob.cs | 270 +++++++++--------- .../Jobs/EventUserDescriptionsJob.cs | 8 +- src/Exceptionless.Core/Jobs/MailMessageJob.cs | 2 +- ...OrganizationNotificationWorkItemHandler.cs | 2 +- .../RemoveBotEventsWorkItemHandler.cs | 2 +- .../RemoveStacksWorkItemHandler.cs | 15 +- .../SetProjectIsConfiguredWorkItemHandler.cs | 3 +- .../Migrations/FixDuplicateStacks.cs | 6 +- .../Migrations/UpdateEventUsage.cs | 6 +- .../Pipeline/035_CopySimpleDataToIdxAction.cs | 5 +- .../Pipeline/070_QueueNotificationAction.cs | 4 +- .../Default/0_ThrottleBotsPlugin.cs | 2 +- .../EventUpgrader/Default/V2_EventUpgrade.cs | 2 +- .../Formatting/FormattingPluginManager.cs | 8 +- .../WebHook/WebHookDataPluginManager.cs | 2 +- .../Services/OrganizationService.cs | 6 +- .../Services/SlackService.cs | 2 +- .../Services/StackService.cs | 4 +- .../Services/UsageService.cs | 4 +- .../Extensions/LoggerExtensions.cs | 2 +- .../Repositories/EventRepositoryTests.cs | 12 +- 28 files changed, 209 insertions(+), 208 deletions(-) diff --git a/src/Exceptionless.Core/Billing/StripeEventHandler.cs b/src/Exceptionless.Core/Billing/StripeEventHandler.cs index 7d51e94c79..ce849905cb 100644 --- a/src/Exceptionless.Core/Billing/StripeEventHandler.cs +++ b/src/Exceptionless.Core/Billing/StripeEventHandler.cs @@ -52,7 +52,7 @@ public async Task HandleEventAsync(Stripe.Event stripeEvent) } default: { - _logger.LogTrace("Unhandled stripe webhook called. Type: {Type} Id: {Id} Account: {Account}", stripeEvent.Type, stripeEvent.Id, stripeEvent.Account); + _logger.LogTrace("Unhandled stripe webhook called. Type: {StripeType} Id: {StripeId} Account: {StripeAccount}", stripeEvent.Type, stripeEvent.Id, stripeEvent.Account); break; } } diff --git a/src/Exceptionless.Core/Extensions/LogBuilderExtensions.cs b/src/Exceptionless.Core/Extensions/LogBuilderExtensions.cs index 045af8413c..496ad99101 100644 --- a/src/Exceptionless.Core/Extensions/LogBuilderExtensions.cs +++ b/src/Exceptionless.Core/Extensions/LogBuilderExtensions.cs @@ -5,7 +5,7 @@ public class ExceptionlessState : Dictionary public ExceptionlessState Project(string projectId) { if (!String.IsNullOrEmpty(projectId)) - base["project"] = projectId; + base["Project"] = projectId; return this; } @@ -13,7 +13,7 @@ public ExceptionlessState Project(string projectId) public ExceptionlessState Organization(string organizationId) { if (!String.IsNullOrEmpty(organizationId)) - base["organization"] = organizationId; + base["Organization"] = organizationId; return this; } diff --git a/src/Exceptionless.Core/Extensions/LoggerExtensions.cs b/src/Exceptionless.Core/Extensions/LoggerExtensions.cs index 53237e4473..50c8190ac8 100644 --- a/src/Exceptionless.Core/Extensions/LoggerExtensions.cs +++ b/src/Exceptionless.Core/Extensions/LoggerExtensions.cs @@ -10,7 +10,7 @@ internal static class LoggerExtensions LoggerMessage.Define( LogLevel.Trace, new EventId(0, nameof(RecordWebHook)), - "Process web hook call: id={Id} project={ProjectId} url={Url}"); + "Process web hook call: id={WebHook} project={Project} url={Url}"); private static readonly Action _webHookCancelled = LoggerMessage.Define( @@ -28,25 +28,25 @@ internal static class LoggerExtensions LoggerMessage.Define( LogLevel.Error, new EventId(3, nameof(WebHookTimeout)), - "Timeout calling web hook: status={Status} org={organization} project={ProjectId} url={Url}"); + "Timeout calling web hook: status={Status} organization={Organization} project={Project} url={Url}"); private static readonly Action _webHookError = LoggerMessage.Define( LogLevel.Error, new EventId(4, nameof(WebHookError)), - "Error calling web hook: status={Status} org={organization} project={ProjectId} url={Url}"); + "Error calling web hook: status={Status} organization={Organization} project={Project} url={Url}"); private static readonly Action _webHookComplete = LoggerMessage.Define( LogLevel.Information, new EventId(5, nameof(WebHookError)), - "Web hook POST complete: status={Status} org={organization} project={ProjectId} url={Url}"); + "Web hook POST complete: status={Status} organization={Organization} project={Project} url={Url}"); private static readonly Action _webHookDisabledStatusCode = LoggerMessage.Define( LogLevel.Warning, new EventId(6, nameof(WebHookDisabledStatusCode)), - "Disabling Web hook instance {WebHookId} due to status code: status={Status} org={organization} project={ProjectId} url={Url}"); + "Disabling Web hook instance {WebHookId} due to status code: status={Status} organization={Organization} project={Project} url={Url}"); private static readonly Action _webHookDisabledTooManyErrors = LoggerMessage.Define( @@ -82,25 +82,25 @@ internal static class LoggerExtensions LoggerMessage.Define( LogLevel.Information, new EventId(12, nameof(RemoveOrganizationStart)), - "Removing organization: {Organization} ({OrganizationId})"); + "Removing organization: {OrganizationName} ({Organization})"); private static readonly Action _removeOrganizationComplete = LoggerMessage.Define( LogLevel.Information, new EventId(14, nameof(RemoveOrganizationComplete)), - "Removed organization: {Organization} ({OrganizationId}), Removed {RemovedProjects} Projects, {RemovedStacks} Stacks, {RemovedEvents} Events"); + "Removed organization: {OrganizationName} ({Organization}), Removed {RemovedProjects} Projects, {RemovedStacks} Stacks, {RemovedEvents} Events"); private static readonly Action _removeProjectStart = LoggerMessage.Define( LogLevel.Information, new EventId(15, nameof(RemoveProjectStart)), - "Removing project: {Project} ({ProjectId})"); + "Removing project: {ProjectName} ({Project})"); private static readonly Action _removeProjectComplete = LoggerMessage.Define( LogLevel.Information, new EventId(16, nameof(RemoveProjectComplete)), - "Removed project: {Project} ({ProjectId}), Removed {RemovedStacks} Stacks, {RemovedEvents} Events"); + "Removed project: {ProjectName} ({Project}), Removed {RemovedStacks} Stacks, {RemovedEvents} Events"); private static readonly Action _removeStacksComplete = @@ -113,25 +113,25 @@ internal static class LoggerExtensions LoggerMessage.Define( LogLevel.Information, new EventId(18, nameof(RetentionEnforcementStackStart)), - "Enforcing stack retention period older than {RetentionPeriod:g} for organization {OrganizationName} ({OrganizationId}), Found {TotalStacks} Stacks"); + "Enforcing stack retention period older than {RetentionPeriod:g} for organization {OrganizationName} ({Organization}), Found {TotalStacks} Stacks"); private static readonly Action _retentionEnforcementStackComplete = LoggerMessage.Define( LogLevel.Information, new EventId(19, nameof(RetentionEnforcementStackComplete)), - "Enforced stack retention period for {OrganizationName} ({OrganizationId}), Removed {RemovedStacks} Stacks"); + "Enforced stack retention period for {OrganizationName} ({Organization}), Removed {RemovedStacks} Stacks"); private static readonly Action _retentionEnforcementEventStart = LoggerMessage.Define( LogLevel.Information, new EventId(20, nameof(RetentionEnforcementEventStart)), - "Enforcing event retention period older than {RetentionPeriod:g} for organization {OrganizationName} ({OrganizationId})."); + "Enforcing event retention period older than {RetentionPeriod:g} for organization {OrganizationName} ({Organization})."); private static readonly Action _retentionEnforcementEventComplete = LoggerMessage.Define( LogLevel.Information, new EventId(21, nameof(RetentionEnforcementEventComplete)), - "Enforced event retention period for {OrganizationName} ({OrganizationId}), Removed {RemovedEvents} Events"); + "Enforced event retention period for {OrganizationName} ({Organization}), Removed {RemovedEvents} Events"); public static void RemoveStacksComplete(this ILogger logger, long removedStacks, long removedEvents) => _removeStacksComplete(logger, removedStacks, removedEvents, null); diff --git a/src/Exceptionless.Core/Jobs/CleanupDataJob.cs b/src/Exceptionless.Core/Jobs/CleanupDataJob.cs index 8da1d4d738..46d70bfd2b 100644 --- a/src/Exceptionless.Core/Jobs/CleanupDataJob.cs +++ b/src/Exceptionless.Core/Jobs/CleanupDataJob.cs @@ -113,7 +113,7 @@ private async Task CleanupSoftDeletedOrganizationsAsync(JobContext context) } catch (Exception ex) { - _logger.LogError(ex, "Error removing soft deleted organization {OrganizationId}: {Message}", organization.Id, ex.Message); + _logger.LogError(ex, "Error removing soft deleted organization {Organization}: {Message}", organization.Id, ex.Message); } // Sleep so we are not hammering the backend. @@ -141,7 +141,7 @@ private async Task CleanupSoftDeletedProjectsAsync(JobContext context) } catch (Exception ex) { - _logger.LogError(ex, "Error removing soft deleted project {ProjectId}: {Message}", project.Id, ex.Message); + _logger.LogError(ex, "Error removing soft deleted project {Project}: {Message}", project.Id, ex.Message); } // Sleep so we are not hammering the backend. @@ -246,7 +246,7 @@ private async Task EnforceRetentionAsync(JobContext context) } catch (Exception ex) { - _logger.LogError(ex, "Error enforcing retention for Organization {OrganizationId}: {Message}", organization.Id, ex.Message); + _logger.LogError(ex, "Error enforcing retention for Organization {Organization}: {Message}", organization.Id, ex.Message); } // Sleep so we are not hammering the backend. diff --git a/src/Exceptionless.Core/Jobs/CleanupOrphanedDataJob.cs b/src/Exceptionless.Core/Jobs/CleanupOrphanedDataJob.cs index 49540b0324..995d1ebdbb 100644 --- a/src/Exceptionless.Core/Jobs/CleanupOrphanedDataJob.cs +++ b/src/Exceptionless.Core/Jobs/CleanupOrphanedDataJob.cs @@ -235,7 +235,7 @@ public async Task FixDuplicateStacks(JobContext context) var stacks = await _stackRepository.FindAsync(q => q.Project(projectId).FilterExpression($"signature_hash:{signature}")); if (stacks.Documents.Count < 2) { - _logger.LogError("Did not find multiple stacks with signature {SignatureHash} and project {ProjectId}", signature, projectId); + _logger.LogError("Did not find multiple stacks with signature {SignatureHash} and project {Project}", signature, projectId); continue; } @@ -337,7 +337,7 @@ public async Task FixDuplicateStacks(JobContext context) catch (Exception ex) { error++; - _logger.LogError(ex, "Error fixing duplicate stack {ProjectId} {SignatureHash}", projectId, signature); + _logger.LogError(ex, "Error fixing duplicate stack {Project} {SignatureHash}", projectId, signature); } } diff --git a/src/Exceptionless.Core/Jobs/DailySummaryJob.cs b/src/Exceptionless.Core/Jobs/DailySummaryJob.cs index 1fc0dc1e3c..40b7594556 100644 --- a/src/Exceptionless.Core/Jobs/DailySummaryJob.cs +++ b/src/Exceptionless.Core/Jobs/DailySummaryJob.cs @@ -146,7 +146,7 @@ private async Task SendSummaryNotificationAsync(Project project, SummaryNo return false; } - _logger.LogInformation("Sending daily summary: users={UserCount} project={ProjectId}", users.Count, project.Id); + _logger.LogInformation("Sending daily summary: users={UserCount} project={Project}", users.Count, project.Id); var sf = new AppFilter(project, organization); var systemFilter = new RepositoryQuery().AppFilter(sf).DateRange(data.UtcStartTime, data.UtcEndTime, (PersistentEvent e) => e.Date).Index(data.UtcStartTime, data.UtcEndTime); string filter = "type:error (status:open OR status:regressed)"; diff --git a/src/Exceptionless.Core/Jobs/EventNotificationsJob.cs b/src/Exceptionless.Core/Jobs/EventNotificationsJob.cs index d403ed29bc..359857fb72 100644 --- a/src/Exceptionless.Core/Jobs/EventNotificationsJob.cs +++ b/src/Exceptionless.Core/Jobs/EventNotificationsJob.cs @@ -62,7 +62,7 @@ protected override async Task ProcessQueueEntryAsync(QueueEntryContex bool shouldLog = ev.ProjectId != _appOptions.InternalProjectId; int sent = 0; - if (shouldLog) _logger.LogTrace("Process notification: project={ProjectId} event={Id} stack={Stack}", ev.ProjectId, ev.Id, ev.StackId); + if (shouldLog) _logger.LogTrace("Process notification: project={Project} event={Event} stack={Stack}", ev.ProjectId, ev.Id, ev.StackId); var project = await _projectRepository.GetByIdAsync(ev.ProjectId, o => o.Cache()); if (project is null) @@ -145,7 +145,7 @@ protected override async Task ProcessQueueEntryAsync(QueueEntryContex if (sent > 0) { await _cache.SetAsync(String.Concat("notify:stack-throttle:", ev.StackId), _timeProvider.GetUtcNow().UtcDateTime, _timeProvider.GetUtcNow().UtcDateTime.AddMinutes(15)); - if (shouldLog) _logger.LogInformation("Notifications sent: event={Id} stack={Stack} count={SentCount}", ev.Id, ev.StackId, sent); + if (shouldLog) _logger.LogInformation("Notifications sent: event={Event} stack={Stack} count={SentCount}", ev.Id, ev.StackId, sent); } } return JobResult.Success; @@ -174,7 +174,7 @@ private async Task SendEmailNotificationAsync(string userId, Project proje if (!user.OrganizationIds.Contains(project.OrganizationId)) { - if (shouldLog) _logger.LogError("Unauthorized user: project={ProjectId} user={UserId} organization={Organization} event={Id}", project.Id, userId, project.OrganizationId, ev.Id); + if (shouldLog) _logger.LogError("Unauthorized user: project={Project} user={UserId} organization={Organization} event={Event}", project.Id, userId, project.OrganizationId, ev.Id); return false; } diff --git a/src/Exceptionless.Core/Jobs/EventPostsJob.cs b/src/Exceptionless.Core/Jobs/EventPostsJob.cs index 0e8db33450..c2c2042683 100644 --- a/src/Exceptionless.Core/Jobs/EventPostsJob.cs +++ b/src/Exceptionless.Core/Jobs/EventPostsJob.cs @@ -53,6 +53,8 @@ protected override async Task ProcessQueueEntryAsync(QueueEntryContex { var entry = context.QueueEntry; var ep = entry.Value; + using var _ = _logger.BeginScope(new ExceptionlessState().Organization(ep.OrganizationId).Project(ep.ProjectId)); + string payloadPath = Path.ChangeExtension(entry.Value.FilePath, ".payload"); var payloadTask = AppDiagnostics.PostsMarkFileActiveTime.TimeAsync(() => _eventPostService.GetEventPostPayloadAsync(payloadPath)); var projectTask = _projectRepository.GetByIdAsync(ep.ProjectId, o => o.Cache()); @@ -72,178 +74,176 @@ protected override async Task ProcessQueueEntryAsync(QueueEntryContex return JobResult.FailedWithMessage($"Unable to process payload '{payloadPath}' ({payload.LongLength} bytes): Maximum event post size limit ({_appOptions.MaximumEventPostSize} bytes) reached."); } - using (_logger.BeginScope(new ExceptionlessState().Organization(ep.OrganizationId).Project(ep.ProjectId))) + + AppDiagnostics.PostsCompressedSize.Record(payload.Length); + + bool isDebugLogLevelEnabled = _logger.IsEnabled(LogLevel.Debug); + bool isInternalProject = ep.ProjectId == _appOptions.InternalProjectId; + if (!isInternalProject && _logger.IsEnabled(LogLevel.Information)) { - AppDiagnostics.PostsCompressedSize.Record(payload.Length); + using var processingScope = _logger.BeginScope(new ExceptionlessState().Tag("processing").Tag("compressed").Tag(ep.ContentEncoding).Value(payload.Length)); + _logger.LogInformation("Processing post: id={QueueEntryId} path={FilePath} project={Project} ip={IpAddress} v={ApiVersion} agent={UserAgent}", entry.Id, payloadPath, ep.ProjectId, ep.IpAddress, ep.ApiVersion, ep.UserAgent); + } - bool isDebugLogLevelEnabled = _logger.IsEnabled(LogLevel.Debug); - bool isInternalProject = ep.ProjectId == _appOptions.InternalProjectId; - if (!isInternalProject && _logger.IsEnabled(LogLevel.Information)) - { - using (_logger.BeginScope(new ExceptionlessState().Tag("processing").Tag("compressed").Tag(ep.ContentEncoding).Value(payload.Length))) - _logger.LogInformation("Processing post: id={QueueEntryId} path={FilePath} project={ProjectId} ip={IpAddress} v={ApiVersion} agent={UserAgent}", entry.Id, payloadPath, ep.ProjectId, ep.IpAddress, ep.ApiVersion, ep.UserAgent); - } + var project = await projectTask; + if (project is null) + { + if (!isInternalProject) _logger.LogError("Unable to process EventPost {FilePath}: Unable to load project: {Project}", payloadPath, ep.ProjectId); + await Task.WhenAll(CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime), organizationTask); + return JobResult.Success; + } - var project = await projectTask; - if (project is null) + long maxEventPostSize = _appOptions.MaximumEventPostSize; + byte[] uncompressedData = payload; + if (!String.IsNullOrEmpty(ep.ContentEncoding)) + { + if (!isInternalProject && isDebugLogLevelEnabled) { - if (!isInternalProject) _logger.LogError("Unable to process EventPost {FilePath}: Unable to load project: {Project}", payloadPath, ep.ProjectId); - await Task.WhenAll(CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime), organizationTask); - return JobResult.Success; + using (_logger.BeginScope(new ExceptionlessState().Tag("decompressing").Tag(ep.ContentEncoding))) + _logger.LogDebug("Decompressing EventPost: {QueueEntryId} ({CompressedBytes} bytes)", entry.Id, payload.Length); } - long maxEventPostSize = _appOptions.MaximumEventPostSize; - byte[] uncompressedData = payload; - if (!String.IsNullOrEmpty(ep.ContentEncoding)) + maxEventPostSize = _maximumUncompressedEventPostSize; + try { - if (!isInternalProject && isDebugLogLevelEnabled) - { - using (_logger.BeginScope(new ExceptionlessState().Tag("decompressing").Tag(ep.ContentEncoding))) - _logger.LogDebug("Decompressing EventPost: {QueueEntryId} ({CompressedBytes} bytes)", entry.Id, payload.Length); - } - - maxEventPostSize = _maximumUncompressedEventPostSize; - try + AppDiagnostics.PostsDecompressionTime.Time(() => { - AppDiagnostics.PostsDecompressionTime.Time(() => - { - uncompressedData = uncompressedData.Decompress(ep.ContentEncoding); - }); - } - catch (Exception ex) - { - AppDiagnostics.PostsDecompressionErrors.Add(1); - await Task.WhenAll(CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime), organizationTask); - return JobResult.FailedWithMessage($"Unable to decompress EventPost data '{payloadPath}' ({payload.Length} bytes compressed): {ex.Message}"); - } + uncompressedData = uncompressedData.Decompress(ep.ContentEncoding); + }); } - - AppDiagnostics.PostsUncompressedSize.Record(payload.LongLength); - if (uncompressedData.Length > maxEventPostSize) + catch (Exception ex) { - var org = await organizationTask; - await _usageService.IncrementTooBigAsync(org.Id, project.Id); - await CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime); - return JobResult.FailedWithMessage($"Unable to process decompressed EventPost data '{payloadPath}' ({payload.Length} bytes compressed, {uncompressedData.Length} bytes): Maximum uncompressed event post size limit ({maxEventPostSize} bytes) reached."); + AppDiagnostics.PostsDecompressionErrors.Add(1); + await Task.WhenAll(CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime), organizationTask); + return JobResult.FailedWithMessage($"Unable to decompress EventPost data '{payloadPath}' ({payload.Length} bytes compressed): {ex.Message}"); } + } - if (!isInternalProject && isDebugLogLevelEnabled) - { - using (_logger.BeginScope(new ExceptionlessState().Tag("uncompressed").Value(uncompressedData.Length))) - _logger.LogDebug("Processing uncompressed EventPost: {QueueEntryId} ({UncompressedBytes} bytes)", entry.Id, uncompressedData.Length); - } + AppDiagnostics.PostsUncompressedSize.Record(payload.LongLength); + if (uncompressedData.Length > maxEventPostSize) + { + var org = await organizationTask; + await _usageService.IncrementTooBigAsync(org.Id, project.Id); + await CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime); + return JobResult.FailedWithMessage($"Unable to process decompressed EventPost data '{payloadPath}' ({payload.Length} bytes compressed, {uncompressedData.Length} bytes): Maximum uncompressed event post size limit ({maxEventPostSize} bytes) reached."); + } - var createdUtc = _timeProvider.GetUtcNow().UtcDateTime; - var events = ParseEventPost(ep, createdUtc, uncompressedData, entry.Id, isInternalProject); - if (events is null || events.Count == 0) - { - await Task.WhenAll(CompleteEntryAsync(entry, ep, createdUtc), organizationTask); - return JobResult.Success; - } + if (!isInternalProject && isDebugLogLevelEnabled) + { + using (_logger.BeginScope(new ExceptionlessState().Tag("uncompressed").Value(uncompressedData.Length))) + _logger.LogDebug("Processing uncompressed EventPost: {QueueEntryId} ({UncompressedBytes} bytes)", entry.Id, uncompressedData.Length); + } - if (context.CancellationToken.IsCancellationRequested) - { - await Task.WhenAll(AbandonEntryAsync(entry), organizationTask); - return JobResult.Cancelled; - } + var createdUtc = _timeProvider.GetUtcNow().UtcDateTime; + var events = ParseEventPost(ep, createdUtc, uncompressedData, entry.Id, isInternalProject); + if (events is null || events.Count == 0) + { + await Task.WhenAll(CompleteEntryAsync(entry, ep, createdUtc), organizationTask); + return JobResult.Success; + } - var organization = await organizationTask; - if (organization is null) - { - if (!isInternalProject) - _logger.LogError("Unable to process EventPost {FilePath}: Unable to load organization: {OrganizationId}", payloadPath, project.OrganizationId); + if (context.CancellationToken.IsCancellationRequested) + { + await Task.WhenAll(AbandonEntryAsync(entry), organizationTask); + return JobResult.Cancelled; + } - await CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime); - return JobResult.Success; - } + var organization = await organizationTask; + if (organization is null) + { + if (!isInternalProject) + _logger.LogError("Unable to process EventPost {FilePath}: Unable to load organization: {Organization}", payloadPath, project.OrganizationId); - // Don't process all the events if it will put the account over its limits. - int eventsToProcess = await _usageService.GetEventsLeftAsync(organization.Id); - if (eventsToProcess < 1) - { - if (!isInternalProject) - _logger.LogDebug("Unable to process EventPost {FilePath}: Over plan limits", payloadPath); + await CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime); + return JobResult.Success; + } - await _usageService.IncrementBlockedAsync(organization.Id, project.Id, events.Count); + // Don't process all the events if it will put the account over its limits. + int eventsToProcess = await _usageService.GetEventsLeftAsync(organization.Id); + if (eventsToProcess < 1) + { + if (!isInternalProject) + _logger.LogDebug("Unable to process EventPost {FilePath}: Over plan limits", payloadPath); - await CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime); - return JobResult.Success; - } + await _usageService.IncrementBlockedAsync(organization.Id, project.Id, events.Count); + + await CompleteEntryAsync(entry, ep, _timeProvider.GetUtcNow().UtcDateTime); + return JobResult.Success; + } - // Keep track of the original event payload size, we can save some processing for retries in the case it was a massive batch. - bool isSingleEvent = events.Count == 1; + // Keep track of the original event payload size, we can save some processing for retries in the case it was a massive batch. + bool isSingleEvent = events.Count == 1; - // Discard any events over the plan limit. - if (eventsToProcess < events.Count) - { - int discarded = events.Count - eventsToProcess; - events = events.Take(eventsToProcess).ToList(); + // Discard any events over the plan limit. + if (eventsToProcess < events.Count) + { + int discarded = events.Count - eventsToProcess; + events = events.Take(eventsToProcess).ToList(); - await _usageService.IncrementBlockedAsync(organization.Id, project.Id, discarded); - } + await _usageService.IncrementBlockedAsync(organization.Id, project.Id, discarded); + } - int errorCount = 0; - var eventsToRetry = new List(); - try + int errorCount = 0; + var eventsToRetry = new List(); + try + { + var contexts = await _eventPipeline.RunAsync(events, organization, project, ep); + if (!isInternalProject && isDebugLogLevelEnabled) { - var contexts = await _eventPipeline.RunAsync(events, organization, project, ep); - if (!isInternalProject && isDebugLogLevelEnabled) - { - using (_logger.BeginScope(new ExceptionlessState().Value(contexts.Count))) - _logger.LogDebug("Ran {@Value} events through the pipeline: id={QueueEntryId} success={SuccessCount} error={ErrorCount}", contexts.Count, entry.Id, contexts.Count(r => r.IsProcessed), contexts.Count(r => r.HasError)); - } + using (_logger.BeginScope(new ExceptionlessState().Value(contexts.Count))) + _logger.LogDebug("Ran {@Value} events through the pipeline: id={QueueEntryId} success={SuccessCount} error={ErrorCount}", contexts.Count, entry.Id, contexts.Count(r => r.IsProcessed), contexts.Count(r => r.HasError)); + } - // increment the plan usage counters (note: OverageHandler already incremented usage by 1) - int processedEvents = contexts.Count(c => c.IsProcessed); - await _usageService.IncrementTotalAsync(organization.Id, project.Id, processedEvents); + // increment the plan usage counters (note: OverageHandler already incremented usage by 1) + int processedEvents = contexts.Count(c => c.IsProcessed); + await _usageService.IncrementTotalAsync(organization.Id, project.Id, processedEvents); - int discardedEvents = contexts.Count(c => c.IsDiscarded); - await _usageService.IncrementDiscardedAsync(organization.Id, project.Id, discardedEvents); + int discardedEvents = contexts.Count(c => c.IsDiscarded); + await _usageService.IncrementDiscardedAsync(organization.Id, project.Id, discardedEvents); - foreach (var ctx in contexts) - { - if (ctx.IsCancelled) - continue; + foreach (var ctx in contexts) + { + if (ctx.IsCancelled) + continue; - if (!ctx.HasError) - continue; + if (!ctx.HasError) + continue; - if (!isInternalProject) _logger.LogError(ctx.Exception, "Error processing EventPost {QueueEntryId} {FilePath}: {Message}", entry.Id, payloadPath, ctx.ErrorMessage); - if (ctx.Exception is ValidationException or MiniValidatorException) - continue; + if (!isInternalProject) _logger.LogError(ctx.Exception, "Error processing EventPost {QueueEntryId} {FilePath}: {Message}", entry.Id, payloadPath, ctx.ErrorMessage); + if (ctx.Exception is ValidationException or MiniValidatorException) + continue; - errorCount++; - if (!isSingleEvent) - { - // Put this single event back into the queue so we can retry it separately. - eventsToRetry.Add(ctx.Event); - } + errorCount++; + if (!isSingleEvent) + { + // Put this single event back into the queue so we can retry it separately. + eventsToRetry.Add(ctx.Event); } } - catch (Exception ex) + } + catch (Exception ex) + { + if (!isInternalProject) _logger.LogError(ex, "Error processing EventPost {QueueEntryId} {FilePath}: {Message}", entry.Id, payloadPath, ex.Message); + if (ex is ArgumentException || ex is DocumentNotFoundException) { - if (!isInternalProject) _logger.LogError(ex, "Error processing EventPost {QueueEntryId} {FilePath}: {Message}", entry.Id, payloadPath, ex.Message); - if (ex is ArgumentException || ex is DocumentNotFoundException) - { - await CompleteEntryAsync(entry, ep, createdUtc); - return JobResult.Success; - } - - errorCount++; - if (!isSingleEvent) - eventsToRetry.AddRange(events); + await CompleteEntryAsync(entry, ep, createdUtc); + return JobResult.Success; } - if (eventsToRetry.Count > 0) - await AppDiagnostics.PostsRetryTime.TimeAsync(() => RetryEventsAsync(eventsToRetry, ep, entry, project, isInternalProject)); + errorCount++; + if (!isSingleEvent) + eventsToRetry.AddRange(events); + } - if (isSingleEvent && errorCount > 0) - await AbandonEntryAsync(entry); - else - await CompleteEntryAsync(entry, ep, createdUtc); + if (eventsToRetry.Count > 0) + await AppDiagnostics.PostsRetryTime.TimeAsync(() => RetryEventsAsync(eventsToRetry, ep, entry, project, isInternalProject)); - return JobResult.Success; - } + if (isSingleEvent && errorCount > 0) + await AbandonEntryAsync(entry); + else + await CompleteEntryAsync(entry, ep, createdUtc); + + return JobResult.Success; } private List? ParseEventPost(EventPostInfo ep, DateTime createdUtc, byte[] uncompressedData, string queueEntryId, bool isInternalProject) diff --git a/src/Exceptionless.Core/Jobs/EventUserDescriptionsJob.cs b/src/Exceptionless.Core/Jobs/EventUserDescriptionsJob.cs index b5ddfc3112..f0bde6cc99 100644 --- a/src/Exceptionless.Core/Jobs/EventUserDescriptionsJob.cs +++ b/src/Exceptionless.Core/Jobs/EventUserDescriptionsJob.cs @@ -21,21 +21,21 @@ public EventUserDescriptionsJob(IQueue queue, IEventReposi protected override async Task ProcessQueueEntryAsync(QueueEntryContext context) { - _logger.LogTrace("Processing user description: id={0}", context.QueueEntry.Id); + _logger.LogTrace("Processing user description: id={QueueEntryId}", context.QueueEntry.Id); try { await ProcessUserDescriptionAsync(context.QueueEntry.Value); - _logger.LogInformation("Processed user description: id={Id}", context.QueueEntry.Id); + _logger.LogInformation("Processed user description: id={QueueEntryId}", context.QueueEntry.Id); } catch (DocumentNotFoundException ex) { - _logger.LogError(ex, "An event with this reference id {ReferenceId} has not been processed yet or was deleted. Queue Id: {Id}", ex.Id, context.QueueEntry.Id); + _logger.LogError(ex, "An event with this reference id {ReferenceId} has not been processed yet or was deleted. Queue Id: {QueueEntryId}", ex.Id, context.QueueEntry.Id); return JobResult.FromException(ex); } catch (Exception ex) { - _logger.LogError(ex, "An error occurred while processing the EventUserDescription {Id}: {Message}", context.QueueEntry.Id, ex.Message); + _logger.LogError(ex, "An error occurred while processing the EventUserDescription {QueueEntryId}: {Message}", context.QueueEntry.Id, ex.Message); return JobResult.FromException(ex); } diff --git a/src/Exceptionless.Core/Jobs/MailMessageJob.cs b/src/Exceptionless.Core/Jobs/MailMessageJob.cs index f69423fc34..d8347b1e13 100644 --- a/src/Exceptionless.Core/Jobs/MailMessageJob.cs +++ b/src/Exceptionless.Core/Jobs/MailMessageJob.cs @@ -18,7 +18,7 @@ public MailMessageJob(IQueue queue, IMailSender mailSender, TimePro protected override async Task ProcessQueueEntryAsync(QueueEntryContext context) { - _logger.LogTrace("Processing message {Id}", context.QueueEntry.Id); + _logger.LogTrace("Processing message {QueueEntryId}", context.QueueEntry.Id); try { diff --git a/src/Exceptionless.Core/Jobs/WorkItemHandlers/OrganizationNotificationWorkItemHandler.cs b/src/Exceptionless.Core/Jobs/WorkItemHandlers/OrganizationNotificationWorkItemHandler.cs index 3704f1bf77..9c1201ec74 100644 --- a/src/Exceptionless.Core/Jobs/WorkItemHandlers/OrganizationNotificationWorkItemHandler.cs +++ b/src/Exceptionless.Core/Jobs/WorkItemHandlers/OrganizationNotificationWorkItemHandler.cs @@ -31,7 +31,7 @@ public Task RunAsync(CancellationToken token) { return _subscriber.SubscribeAsync(overage => { - _logger.LogInformation("Enqueueing plan overage work item for organization: {OrganizationId} IsOverHourlyLimit: {IsOverHourlyLimit} IsOverMonthlyLimit: {IsOverMonthlyLimit}", overage.OrganizationId, overage.IsHourly, !overage.IsHourly); + _logger.LogInformation("Enqueueing plan overage work item for organization: {Organization} IsOverHourlyLimit: {IsOverHourlyLimit} IsOverMonthlyLimit: {IsOverMonthlyLimit}", overage.OrganizationId, overage.IsHourly, !overage.IsHourly); return _workItemQueue.EnqueueAsync(new OrganizationNotificationWorkItem { diff --git a/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveBotEventsWorkItemHandler.cs b/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveBotEventsWorkItemHandler.cs index c261d53791..af0aab9cda 100644 --- a/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveBotEventsWorkItemHandler.cs +++ b/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveBotEventsWorkItemHandler.cs @@ -30,7 +30,7 @@ public override async Task HandleItemAsync(WorkItemContext context) { var wi = context.GetData(); using var _ = Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId).Project(wi.ProjectId)); - Log.LogInformation("Received remove bot events work item OrganizationId={OrganizationId} ProjectId={ProjectId}, ClientIpAddress={ClientIpAddress}, UtcStartDate={UtcStartDate}, UtcEndDate={UtcEndDate}", wi.OrganizationId, wi.ProjectId, wi.ClientIpAddress, wi.UtcStartDate, wi.UtcEndDate); + Log.LogInformation("Received remove bot events work item OrganizationId={Organization} ProjectId={Project}, ClientIpAddress={ClientIpAddress}, UtcStartDate={UtcStartDate}, UtcEndDate={UtcEndDate}", wi.OrganizationId, wi.ProjectId, wi.ClientIpAddress, wi.UtcStartDate, wi.UtcEndDate); await context.ReportProgressAsync(0, $"Starting deleting of bot events... OrganizationId={wi.OrganizationId}"); long deleted = await _eventRepository.RemoveAllAsync(wi.OrganizationId, wi.ClientIpAddress, wi.UtcStartDate, wi.UtcEndDate); diff --git a/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveStacksWorkItemHandler.cs b/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveStacksWorkItemHandler.cs index 65f9efe2b2..32c419f260 100644 --- a/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveStacksWorkItemHandler.cs +++ b/src/Exceptionless.Core/Jobs/WorkItemHandlers/RemoveStacksWorkItemHandler.cs @@ -30,13 +30,12 @@ public RemoveStacksWorkItemHandler(IStackRepository stackRepository, ICacheClien public override async Task HandleItemAsync(WorkItemContext context) { var wi = context.GetData(); - using (Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId).Project(wi.ProjectId))) - { - Log.LogInformation("Received remove stacks work item for project: {ProjectId}", wi.ProjectId); - await context.ReportProgressAsync(0, "Starting soft deleting of stacks..."); - long deleted = await _stackRepository.SoftDeleteByProjectIdAsync(wi.OrganizationId, wi.ProjectId); - await _cacheClient.RemoveByPrefixAsync(String.Concat("stack-filter:", wi.OrganizationId, ":", wi.ProjectId)); - await context.ReportProgressAsync(100, $"Stacks soft deleted: {deleted}"); - } + using var _ = Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId).Project(wi.ProjectId)); + + Log.LogInformation("Received remove stacks work item for project: {Project}", wi.ProjectId); + await context.ReportProgressAsync(0, "Starting soft deleting of stacks..."); + long deleted = await _stackRepository.SoftDeleteByProjectIdAsync(wi.OrganizationId, wi.ProjectId); + await _cacheClient.RemoveByPrefixAsync(String.Concat("stack-filter:", wi.OrganizationId, ":", wi.ProjectId)); + await context.ReportProgressAsync(100, $"Stacks soft deleted: {deleted}"); } } diff --git a/src/Exceptionless.Core/Jobs/WorkItemHandlers/SetProjectIsConfiguredWorkItemHandler.cs b/src/Exceptionless.Core/Jobs/WorkItemHandlers/SetProjectIsConfiguredWorkItemHandler.cs index e4c65abaf2..b80b4882fa 100644 --- a/src/Exceptionless.Core/Jobs/WorkItemHandlers/SetProjectIsConfiguredWorkItemHandler.cs +++ b/src/Exceptionless.Core/Jobs/WorkItemHandlers/SetProjectIsConfiguredWorkItemHandler.cs @@ -31,7 +31,8 @@ public SetProjectIsConfiguredWorkItemHandler(IProjectRepository projectRepositor public override async Task HandleItemAsync(WorkItemContext context) { var workItem = context.GetData(); - Log.LogInformation("Setting Is Configured for project: {ProjectId}", workItem.ProjectId); + using var _ = Log.BeginScope(new ExceptionlessState().Project(workItem.ProjectId)); + Log.LogInformation("Setting Is Configured for project: {Project}", workItem.ProjectId); var project = await _projectRepository.GetByIdAsync(workItem.ProjectId); if (project is null || project.IsConfigured.GetValueOrDefault()) diff --git a/src/Exceptionless.Core/Migrations/FixDuplicateStacks.cs b/src/Exceptionless.Core/Migrations/FixDuplicateStacks.cs index c0c5b64c73..0b90ad1bf7 100644 --- a/src/Exceptionless.Core/Migrations/FixDuplicateStacks.cs +++ b/src/Exceptionless.Core/Migrations/FixDuplicateStacks.cs @@ -54,7 +54,7 @@ public override async Task RunAsync(MigrationContext context) while (buckets.Count > 0) { - _logger.LogInformation($"Found {total} duplicate stacks in batch #{batch}."); + _logger.LogInformation("Found {Total} duplicate stacks in batch #{Batch}", total, batch); foreach (var duplicateSignature in buckets) { @@ -74,7 +74,7 @@ public override async Task RunAsync(MigrationContext context) var stacks = await _stackRepository.FindAsync(q => q.Project(projectId).FilterExpression($"signature_hash:{signature}")); if (stacks.Documents.Count < 2) { - _logger.LogError("Did not find multiple stacks with signature {SignatureHash} and project {ProjectId}", signature, projectId); + _logger.LogError("Did not find multiple stacks with signature {SignatureHash} and project {Project}", signature, projectId); continue; } @@ -173,7 +173,7 @@ public override async Task RunAsync(MigrationContext context) catch (Exception ex) { error++; - _logger.LogError(ex, "Error fixing duplicate stack {ProjectId} {SignatureHash}", projectId, signature); + _logger.LogError(ex, "Error fixing duplicate stack {Project} {SignatureHash}", projectId, signature); } } diff --git a/src/Exceptionless.Core/Migrations/UpdateEventUsage.cs b/src/Exceptionless.Core/Migrations/UpdateEventUsage.cs index 29ad67713a..1ba20a7ac6 100644 --- a/src/Exceptionless.Core/Migrations/UpdateEventUsage.cs +++ b/src/Exceptionless.Core/Migrations/UpdateEventUsage.cs @@ -90,7 +90,7 @@ private async Task UpdateOrganizationsUsageAsync(MigrationContext context) } catch (Exception ex) { - _logger.LogError(ex, "Error updating organization {OrganizationId}: {Message}", organization.Id, ex.Message); + _logger.LogError(ex, "Error updating organization {Organization}: {Message}", organization.Id, ex.Message); error++; } } @@ -129,7 +129,7 @@ private async Task UpdateProjectsUsageAsync(MigrationContext context, Organizati long eventTotal = dateHistogramBucket.Total.GetValueOrDefault(); if (eventTotal > usage.Total) { - _logger.LogInformation("Updating {ProjectName} ({ProjectId}) {UsageDate} usage total from {UsageTotalFrom} to {UsageTotal}", project.Name, project.Id, usage.Date, usage.Total, eventTotal); + _logger.LogInformation("Updating {ProjectName} ({Project}) {UsageDate} usage total from {UsageTotalFrom} to {UsageTotal}", project.Name, project.Id, usage.Date, usage.Total, eventTotal); usage.Total = (int)eventTotal; } @@ -141,7 +141,7 @@ private async Task UpdateProjectsUsageAsync(MigrationContext context, Organizati } catch (Exception ex) { - _logger.LogError(ex, "Error updating project {ProjectId}: {Message}", project.Id, ex.Message); + _logger.LogError(ex, "Error updating project {Project}: {Message}", project.Id, ex.Message); } } diff --git a/src/Exceptionless.Core/Pipeline/035_CopySimpleDataToIdxAction.cs b/src/Exceptionless.Core/Pipeline/035_CopySimpleDataToIdxAction.cs index ab4deab79d..04b839d075 100644 --- a/src/Exceptionless.Core/Pipeline/035_CopySimpleDataToIdxAction.cs +++ b/src/Exceptionless.Core/Pipeline/035_CopySimpleDataToIdxAction.cs @@ -1,4 +1,5 @@ -using Exceptionless.Core.Plugins.EventProcessor; +using Exceptionless.Core.Extensions; +using Exceptionless.Core.Plugins.EventProcessor; using Microsoft.Extensions.Logging; namespace Exceptionless.Core.Pipeline; @@ -20,7 +21,7 @@ public override Task ProcessAsync(EventContext ctx) if (fieldCount > 20 && _logger.IsEnabled(LogLevel.Warning)) { var ev = ctx.Event; - using (_logger.BeginScope(new ExceptionlessState().Organization(ctx.Organization.Id).Property("Event", new { ev.Date, ev.StackId, ev.Type, ev.Source, ev.Message, ev.Value, ev.Geo, ev.ReferenceId, ev.Tags, ev.Idx }))) + using (_logger.BeginScope(new ExceptionlessState().Organization(ctx.Organization.Id).Project(ev.ProjectId).Property("Event", new { ev.Date, ev.StackId, ev.Type, ev.Source, ev.Message, ev.Value, ev.Geo, ev.ReferenceId }))) _logger.LogWarning("Event has {FieldCount} indexed fields", fieldCount); } diff --git a/src/Exceptionless.Core/Pipeline/070_QueueNotificationAction.cs b/src/Exceptionless.Core/Pipeline/070_QueueNotificationAction.cs index 9c9a6b8fa4..d91f57dbbd 100644 --- a/src/Exceptionless.Core/Pipeline/070_QueueNotificationAction.cs +++ b/src/Exceptionless.Core/Pipeline/070_QueueNotificationAction.cs @@ -62,12 +62,12 @@ await _notificationQueue.EnqueueAsync(new EventNotification if (notification.Data is null) { - _logger.LogTrace("Skipping Web hook: invalid data payload: project={ProjectId} url={Url}", ctx.Event.ProjectId, hook.Url); + _logger.LogTrace("Skipping Web hook: invalid data payload: project={Project} url={Url}", ctx.Event.ProjectId, hook.Url); continue; } await _webHookNotificationQueue.EnqueueAsync(notification); - _logger.LogTrace("Web hook queued: project={ProjectId} url={Url}", ctx.Event.ProjectId, hook.Url); + _logger.LogTrace("Web hook queued: project={Project} url={Url}", ctx.Event.ProjectId, hook.Url); } } diff --git a/src/Exceptionless.Core/Plugins/EventProcessor/Default/0_ThrottleBotsPlugin.cs b/src/Exceptionless.Core/Plugins/EventProcessor/Default/0_ThrottleBotsPlugin.cs index f3396215a7..097dd25d23 100644 --- a/src/Exceptionless.Core/Plugins/EventProcessor/Default/0_ThrottleBotsPlugin.cs +++ b/src/Exceptionless.Core/Plugins/EventProcessor/Default/0_ThrottleBotsPlugin.cs @@ -59,7 +59,7 @@ public override async Task EventBatchProcessingAsync(ICollection c continue; var utcNow = _timeProvider.GetUtcNow().UtcDateTime; - _logger.LogInformation("Bot throttle triggered. IP: {IP} Time: {ThrottlingPeriod} Project: {ProjectId}", clientIpAddressGroup.Key, utcNow.Floor(_throttlingPeriod), firstContext.Event.ProjectId); + _logger.LogInformation("Bot throttle triggered. IP: {IP} Time: {ThrottlingPeriod} Project: {Project}", clientIpAddressGroup.Key, utcNow.Floor(_throttlingPeriod), firstContext.Event.ProjectId); // The throttle was triggered, go and delete all the errors that triggered the throttle to reduce bot noise in the system await _workItemQueue.EnqueueAsync(new RemoveBotEventsWorkItem diff --git a/src/Exceptionless.Core/Plugins/EventUpgrader/Default/V2_EventUpgrade.cs b/src/Exceptionless.Core/Plugins/EventUpgrader/Default/V2_EventUpgrade.cs index 5611ccb5b4..700fb2ce15 100644 --- a/src/Exceptionless.Core/Plugins/EventUpgrader/Default/V2_EventUpgrade.cs +++ b/src/Exceptionless.Core/Plugins/EventUpgrader/Default/V2_EventUpgrade.cs @@ -132,7 +132,7 @@ private void RenameAndValidateExtraExceptionProperties(string? id, JObject error if (json.Length > 200000) { - _logger.LogError("__ExceptionInfo on {Id} is Too Big: {Length}", id, json.Length); + _logger.LogError("__ExceptionInfo on {Event} is Too Big: {Length}", id, json.Length); return; } diff --git a/src/Exceptionless.Core/Plugins/Formatting/FormattingPluginManager.cs b/src/Exceptionless.Core/Plugins/Formatting/FormattingPluginManager.cs index 26f2fa6fa1..04fe179e35 100644 --- a/src/Exceptionless.Core/Plugins/Formatting/FormattingPluginManager.cs +++ b/src/Exceptionless.Core/Plugins/Formatting/FormattingPluginManager.cs @@ -48,7 +48,7 @@ public SummaryData GetEventSummaryData(PersistentEvent ev) } catch (Exception ex) { - _logger.LogError(ex, "Error calling GetEventSummaryHtml for Event {Id} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); + _logger.LogError(ex, "Error calling GetEventSummaryHtml for Event {Event} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); } } @@ -72,7 +72,7 @@ public string GetStackTitle(PersistentEvent ev) } catch (Exception ex) { - _logger.LogError(ex, "Error calling GetStackTitle for Event {Id} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); + _logger.LogError(ex, "Error calling GetStackTitle for Event {Event} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); } } @@ -96,7 +96,7 @@ public MailMessageData GetEventNotificationMailMessageData(PersistentEvent ev, b } catch (Exception ex) { - _logger.LogError(ex, "Error calling GetEventNotificationMailMessage for Event {Id} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); + _logger.LogError(ex, "Error calling GetEventNotificationMailMessage for Event {Event} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); } } @@ -120,7 +120,7 @@ public SlackMessage GetSlackEventNotificationMessage(PersistentEvent ev, Project } catch (Exception ex) { - _logger.LogError(ex, "Error calling GetSlackEventNotificationMessage for Event {Id} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); + _logger.LogError(ex, "Error calling GetSlackEventNotificationMessage for Event {Event} in plugin {PluginName}: {Message}", ev.Id, plugin.Name, ex.Message); } } diff --git a/src/Exceptionless.Core/Plugins/WebHook/WebHookDataPluginManager.cs b/src/Exceptionless.Core/Plugins/WebHook/WebHookDataPluginManager.cs index 2dba789770..84c307586b 100644 --- a/src/Exceptionless.Core/Plugins/WebHook/WebHookDataPluginManager.cs +++ b/src/Exceptionless.Core/Plugins/WebHook/WebHookDataPluginManager.cs @@ -59,7 +59,7 @@ public WebHookDataPluginManager(IServiceProvider serviceProvider, AppOptions opt } catch (Exception ex) { - _logger.LogError(ex, "Error calling create from stack {StackId} in plugin {PluginName}: {Message}", context.Stack.Id, plugin.Name, ex.Message); + _logger.LogError(ex, "Error calling create from stack {Stack} in plugin {PluginName}: {Message}", context.Stack.Id, plugin.Name, ex.Message); } } diff --git a/src/Exceptionless.Core/Services/OrganizationService.cs b/src/Exceptionless.Core/Services/OrganizationService.cs index 185c6b0482..06ee5eee4d 100644 --- a/src/Exceptionless.Core/Services/OrganizationService.cs +++ b/src/Exceptionless.Core/Services/OrganizationService.cs @@ -83,7 +83,7 @@ public async Task RemoveUsersAsync(Organization organization, string? curr } else { - _logger.LogInformation("Removing user {User} from organization: {OrganizationName} ({OrganizationId})", user.Id, organization.Name, organization.Id); + _logger.LogInformation("Removing user {User} from organization: {OrganizationName} ({Organization})", user.Id, organization.Name, organization.Id); user.OrganizationIds.Remove(organization.Id); await _userRepository.SaveAsync(user, o => o.Cache()); @@ -95,13 +95,13 @@ public async Task RemoveUsersAsync(Organization organization, string? curr public Task RemoveTokensAsync(Organization organization) { - _logger.LogInformation("Removing tokens for {OrganizationName} ({OrganizationId})", organization.Name, organization.Id); + _logger.LogInformation("Removing tokens for {OrganizationName} ({Organization})", organization.Name, organization.Id); return _tokenRepository.RemoveAllByOrganizationIdAsync(organization.Id); } public Task RemoveWebHooksAsync(Organization organization) { - _logger.LogInformation("Removing web hooks for {OrganizationName} ({OrganizationId})", organization.Name, organization.Id); + _logger.LogInformation("Removing web hooks for {OrganizationName} ({Organization})", organization.Name, organization.Id); return _webHookRepository.RemoveAllByOrganizationIdAsync(organization.Id); } diff --git a/src/Exceptionless.Core/Services/SlackService.cs b/src/Exceptionless.Core/Services/SlackService.cs index c41ec984c4..a921ba533e 100644 --- a/src/Exceptionless.Core/Services/SlackService.cs +++ b/src/Exceptionless.Core/Services/SlackService.cs @@ -119,7 +119,7 @@ public async Task SendEventNoticeAsync(PersistentEvent ev, Project project var message = _pluginManager.GetSlackEventNotificationMessage(ev, project, isCritical, isNew, isRegression); if (message is null) { - _logger.LogWarning("Unable to create event notification slack message for event {Id}", ev.Id); + _logger.LogWarning("Unable to create event notification slack message for event {Event}", ev.Id); return false; } diff --git a/src/Exceptionless.Core/Services/StackService.cs b/src/Exceptionless.Core/Services/StackService.cs index 1b88ca8936..8aaa62043c 100644 --- a/src/Exceptionless.Core/Services/StackService.cs +++ b/src/Exceptionless.Core/Services/StackService.cs @@ -88,12 +88,12 @@ await Task.WhenAll( } else { - _logger.LogTrace("Increment event count {OccurrenceCount} for organization:{OrganizationId} project:{ProjectId} stack:{StackId} with Min Date:{OccurrenceMinDate} Max Date:{OccurrenceMaxDate}", occurrenceCount, organizationId, projectId, stackId, occurrenceMinDate, occurrenceMaxDate); + _logger.LogTrace("Increment event count {OccurrenceCount} for organization:{Organization} project:{Project} stack:{Stack} with Min Date:{OccurrenceMinDate} Max Date:{OccurrenceMaxDate}", occurrenceCount, organizationId, projectId, stackId, occurrenceMinDate, occurrenceMaxDate); } } catch (Exception ex) { - _logger.LogError(ex, "Error incrementing event count for organization: {OrganizationId} project:{ProjectId} stack:{StackId}", organizationId, projectId, stackId); + _logger.LogError(ex, "Error incrementing event count for organization: {Organization} project:{Project} stack:{Stack}", organizationId, projectId, stackId); if (!shouldRetry) { await IncrementStackUsageAsync(organizationId, projectId, stackId, occurrenceMinDate, occurrenceMaxDate, occurrenceCount); diff --git a/src/Exceptionless.Core/Services/UsageService.cs b/src/Exceptionless.Core/Services/UsageService.cs index fb7cb4436d..3647005175 100644 --- a/src/Exceptionless.Core/Services/UsageService.cs +++ b/src/Exceptionless.Core/Services/UsageService.cs @@ -75,7 +75,7 @@ private async Task SavePendingOrganizationUsageAsync(DateTime utcNow) if (organization is null) continue; - _logger.LogInformation("Saving org ({OrganizationId}-{OrganizationName}) event usage for time bucket: {BucketUtc}...", organizationId, organization.Name, bucketUtc); + _logger.LogInformation("Saving org ({Organization}-{OrganizationName}) event usage for time bucket: {BucketUtc}...", organizationId, organization.Name, bucketUtc); var bucketTotal = await _cache.GetAsync(GetBucketTotalCacheKey(bucketUtc, organizationId)); var bucketBlocked = await _cache.GetAsync(GetBucketBlockedCacheKey(bucketUtc, organizationId)); @@ -153,7 +153,7 @@ private async Task SavePendingProjectUsageAsync(DateTime utcNow) if (project is null) continue; - _logger.LogInformation("Saving project ({ProjectId}-{ProjectName}) event usage for time bucket: {BucketUtc}...", projectId, project.Name, bucketUtc); + _logger.LogInformation("Saving project ({Project}-{ProjectName}) event usage for time bucket: {BucketUtc}...", projectId, project.Name, bucketUtc); var bucketTotal = await _cache.GetAsync(GetBucketTotalCacheKey(bucketUtc, project.OrganizationId, projectId)); var bucketBlocked = await _cache.GetAsync(GetBucketBlockedCacheKey(bucketUtc, project.OrganizationId, projectId)); diff --git a/src/Exceptionless.Web/Extensions/LoggerExtensions.cs b/src/Exceptionless.Web/Extensions/LoggerExtensions.cs index 22ee809de9..95296dc92d 100644 --- a/src/Exceptionless.Web/Extensions/LoggerExtensions.cs +++ b/src/Exceptionless.Web/Extensions/LoggerExtensions.cs @@ -36,7 +36,7 @@ internal static class LoggerExtensions LoggerMessage.Define( LogLevel.Information, new EventId(5, nameof(UserDeletingOrganization)), - "User {User} deleting organization: {OrganizationName} ({OrganizationId})"); + "User {User} deleting organization: {OrganizationName} ({Organization})"); private static readonly Action _userLoggedIn = LoggerMessage.Define( diff --git a/tests/Exceptionless.Tests/Repositories/EventRepositoryTests.cs b/tests/Exceptionless.Tests/Repositories/EventRepositoryTests.cs index 79e2bd8066..44fec3db6d 100644 --- a/tests/Exceptionless.Tests/Repositories/EventRepositoryTests.cs +++ b/tests/Exceptionless.Tests/Repositories/EventRepositoryTests.cs @@ -100,13 +100,13 @@ public async Task GetPreviousEventIdInStackTestAsync() _logger.LogDebug("Actual order:"); foreach (var t in _ids) - _logger.LogDebug("{Id}: {Date}", t.Item1, t.Item2.ToLongTimeString()); + _logger.LogDebug("{Event}: {Date}", t.Item1, t.Item2.ToLongTimeString()); _logger.LogDebug(""); _logger.LogDebug("Sorted order:"); var sortedIds = _ids.OrderBy(t => t.Item2.Ticks).ThenBy(t => t.Item1).ToList(); foreach (var t in sortedIds) - _logger.LogDebug("{Id}: {Date}", t.Item1, t.Item2.ToLongTimeString()); + _logger.LogDebug("{Event}: {Date}", t.Item1, t.Item2.ToLongTimeString()); _logger.LogDebug(""); _logger.LogDebug("Tests:"); @@ -114,7 +114,7 @@ public async Task GetPreviousEventIdInStackTestAsync() Assert.Equal(_ids.Count, await _repository.CountAsync()); for (int i = 0; i < sortedIds.Count; i++) { - _logger.LogDebug("Current - {Id}: {Date}", sortedIds[i].Item1, sortedIds[i].Item2.ToLongTimeString()); + _logger.LogDebug("Current - {Event}: {Date}", sortedIds[i].Item1, sortedIds[i].Item2.ToLongTimeString()); if (i == 0) Assert.Null((await _repository.GetPreviousAndNextEventIdsAsync(sortedIds[i].Item1)).Previous); else @@ -129,20 +129,20 @@ public async Task GetNextEventIdInStackTestAsync() _logger.LogDebug("Actual order:"); foreach (var t in _ids) - _logger.LogDebug("{Id}: {Date}", t.Item1, t.Item2.ToLongTimeString()); + _logger.LogDebug("{Event}: {Date}", t.Item1, t.Item2.ToLongTimeString()); _logger.LogDebug(""); _logger.LogDebug("Sorted order:"); var sortedIds = _ids.OrderBy(t => t.Item2.Ticks).ThenBy(t => t.Item1).ToList(); foreach (var t in sortedIds) - _logger.LogDebug("{Id}: {Date}", t.Item1, t.Item2.ToLongTimeString()); + _logger.LogDebug("{Event}: {Date}", t.Item1, t.Item2.ToLongTimeString()); _logger.LogDebug(""); _logger.LogDebug("Tests:"); Assert.Equal(_ids.Count, await _repository.CountAsync()); for (int i = 0; i < sortedIds.Count; i++) { - _logger.LogDebug("Current - {Id}: {Date}", sortedIds[i].Item1, sortedIds[i].Item2.ToLongTimeString()); + _logger.LogDebug("Current - {Event}: {Date}", sortedIds[i].Item1, sortedIds[i].Item2.ToLongTimeString()); string? nextId = (await _repository.GetPreviousAndNextEventIdsAsync(sortedIds[i].Item1)).Next; if (i == sortedIds.Count - 1) Assert.Null(nextId);