From de1dc75f58326166117d2842da8019a4f69f631f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SAL=C4=B0H=20=C3=96ZKARA?= Date: Tue, 10 Mar 2026 13:42:41 +0300 Subject: [PATCH] Add logging and improve anonymous job naming Add informational logging when jobs are wrapped into the anonymous transport and when anonymous transport jobs are executed to improve observability. Introduce ILogger properties (defaulting to NullLogger) and add LogInformation calls in Hangfire, Quartz, RabbitMQ, TickerQ and Default background job managers, and in AnonymousJobExecutorAsyncBackgroundJob.ExecuteAsync. Improve Hangfire dashboard display by attempting to deserialize serialized AnonymousJobArgs to show the effective (original) job name via a new TryGetEffectiveJobName JSON helper. Add required using directives and safe JSON parsing with fallbacks. --- .../AnonymousJobExecutorAsyncBackgroundJob.cs | 7 +++ .../Hangfire/AbpDashboardOptionsProvider.cs | 49 ++++++++++++++++++- .../Hangfire/HangfireBackgroundJobManager.cs | 9 ++++ .../Quartz/QuartzBackgroundJobManager.cs | 9 ++++ .../RabbitMQ/RabbitMqBackgroundJobManager.cs | 9 ++++ .../TickerQ/AbpTickerQBackgroundJobManager.cs | 9 ++++ .../DefaultBackgroundJobManager.cs | 9 ++++ 7 files changed, 100 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AnonymousJobExecutorAsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AnonymousJobExecutorAsyncBackgroundJob.cs index 51f0515e7e..c076eab337 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AnonymousJobExecutorAsyncBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AnonymousJobExecutorAsyncBackgroundJob.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundJobs; @@ -20,6 +21,12 @@ public class AnonymousJobExecutorAsyncBackgroundJob : AsyncBackgroundJob { var jobName = job.ToString(); + if (job.Args.Count == 3 && job.Args.Last() is CancellationToken) { + if (job.Args[1] is AnonymousJobArgs anonymousJobArgs) + { + return anonymousJobArgs.JobName; + } + jobName = AbpBackgroundJobOptions.GetJob(job.Args[1].GetType()).JobName; } + if (job.Args.Count == 4 && job.Args.Last() is CancellationToken) + { + if (job.Args[1] is string transportJobName) + { + if (transportJobName == AnonymousJobArgs.JobNameConstant && + job.Args[2] is string serializedArgs && + TryGetEffectiveJobName(serializedArgs, out var effectiveJobName)) + { + return effectiveJobName; + } + + return transportJobName; + } + } + return jobName; } }; } + + protected virtual bool TryGetEffectiveJobName(string serializedArgs, out string effectiveJobName) + { + effectiveJobName = string.Empty; + + try + { + using var document = JsonDocument.Parse(serializedArgs); + if (document.RootElement.TryGetProperty(nameof(AnonymousJobArgs.JobName), out var jobNameElement)) + { + var jobName = jobNameElement.GetString(); + if (!string.IsNullOrWhiteSpace(jobName)) + { + effectiveJobName = jobName!; + return true; + } + } + } + catch + { + // Ignore parse errors and fallback to transport job name. + } + + return false; + } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs index fbd1034ecd..67406f2b8d 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs @@ -3,6 +3,8 @@ using System.Reflection; using System.Threading.Tasks; using Hangfire; using Hangfire.States; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Hangfire; @@ -17,6 +19,7 @@ public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDep protected IOptions HangfireOptions { get; } protected IJsonSerializer JsonSerializer { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } + public ILogger Logger { get; set; } public HangfireBackgroundJobManager( IOptions backgroundJobOptions, @@ -28,6 +31,7 @@ public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDep HangfireOptions = hangfireOptions; JsonSerializer = jsonSerializer; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; + Logger = NullLogger.Instance; } public virtual Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, @@ -48,6 +52,11 @@ public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDep { if (ShouldWrapAsAnonymousJob(jobName)) { + Logger.LogInformation( + "Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}", + AnonymousJobArgs.JobNameConstant, + jobName + ); var jsonData = JsonSerializer.Serialize(args); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); return EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); diff --git a/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs index 842f47c78f..4d52498f84 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs @@ -1,5 +1,7 @@ using System; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Quartz; using Volo.Abp.DependencyInjection; @@ -20,6 +22,7 @@ public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDepen protected IJsonSerializer JsonSerializer { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } + public ILogger Logger { get; set; } public QuartzBackgroundJobManager(IScheduler scheduler, IOptions options, IJsonSerializer jsonSerializer, IAnonymousJobHandlerRegistry anonymousJobHandlerRegistry) { @@ -27,6 +30,7 @@ public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDepen JsonSerializer = jsonSerializer; Options = options.Value; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; + Logger = NullLogger.Instance; } public virtual async Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, @@ -40,6 +44,11 @@ public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDepen { if (ShouldWrapAsAnonymousJob(jobName)) { + Logger.LogInformation( + "Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}", + AnonymousJobArgs.JobNameConstant, + jobName + ); var jsonData = JsonSerializer.Serialize(args); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); diff --git a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/RabbitMqBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/RabbitMqBackgroundJobManager.cs index 5c7b420c98..5483a3094e 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/RabbitMqBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/RabbitMqBackgroundJobManager.cs @@ -1,5 +1,7 @@ using System; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.DependencyInjection; using Volo.Abp.Json; @@ -11,12 +13,14 @@ public class RabbitMqBackgroundJobManager : IBackgroundJobManager, ITransientDep protected IJobQueueManager JobQueueManager { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IJsonSerializer JsonSerializer { get; } + public ILogger Logger { get; set; } public RabbitMqBackgroundJobManager(IJobQueueManager jobQueueManager, IAnonymousJobHandlerRegistry anonymousJobHandlerRegistry, IJsonSerializer jsonSerializer) { JobQueueManager = jobQueueManager; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; JsonSerializer = jsonSerializer; + Logger = NullLogger.Instance; } public virtual async Task EnqueueAsync( @@ -36,6 +40,11 @@ public class RabbitMqBackgroundJobManager : IBackgroundJobManager, ITransientDep { if (ShouldWrapAsAnonymousJob(jobName)) { + Logger.LogInformation( + "Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}", + AnonymousJobArgs.JobNameConstant, + jobName + ); var jsonData = JsonSerializer.Serialize(args); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); diff --git a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpTickerQBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpTickerQBackgroundJobManager.cs index a6e1f95e64..54b97adf30 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpTickerQBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpTickerQBackgroundJobManager.cs @@ -1,6 +1,8 @@ using System; using System.Reflection; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using TickerQ.Utilities; using TickerQ.Utilities.Entities; @@ -20,6 +22,7 @@ public class AbpTickerQBackgroundJobManager : IBackgroundJobManager, ITransientD protected AbpBackgroundJobsTickerQOptions TickerQOptions { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IJsonSerializer JsonSerializer { get; } + public ILogger Logger { get; set; } public AbpTickerQBackgroundJobManager( ITimeTickerManager timeTickerManager, @@ -33,6 +36,7 @@ public class AbpTickerQBackgroundJobManager : IBackgroundJobManager, ITransientD TickerQOptions = tickerQOptions.Value; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; JsonSerializer = jsonSerializer; + Logger = NullLogger.Instance; } public virtual async Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) @@ -45,6 +49,11 @@ public class AbpTickerQBackgroundJobManager : IBackgroundJobManager, ITransientD { if (ShouldWrapAsAnonymousJob(jobName)) { + Logger.LogInformation( + "Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}", + AnonymousJobArgs.JobNameConstant, + jobName + ); var jsonData = JsonSerializer.Serialize(args); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/DefaultBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/DefaultBackgroundJobManager.cs index 1760342ef1..5669525db9 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/DefaultBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/DefaultBackgroundJobManager.cs @@ -1,5 +1,7 @@ using System; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.BackgroundWorkers; using Volo.Abp.DependencyInjection; @@ -21,6 +23,7 @@ public class DefaultBackgroundJobManager : IBackgroundJobManager, ITransientDepe protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IOptions BackgroundJobOptions { get; } protected IOptions BackgroundJobWorkerOptions { get; } + public ILogger Logger { get; set; } public DefaultBackgroundJobManager( IClock clock, @@ -38,6 +41,7 @@ public class DefaultBackgroundJobManager : IBackgroundJobManager, ITransientDepe BackgroundJobOptions = backgroundJobOptions; BackgroundJobWorkerOptions = backgroundJobWorkerOptions; Store = store; + Logger = NullLogger.Instance; } public virtual async Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) @@ -50,6 +54,11 @@ public class DefaultBackgroundJobManager : IBackgroundJobManager, ITransientDepe { if (ShouldWrapAsAnonymousJob(jobName)) { + Logger.LogInformation( + "Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}", + AnonymousJobArgs.JobNameConstant, + jobName + ); var jsonData = Serializer.Serialize(args); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay);