Browse Source

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.
pull/25059/head
SALİH ÖZKARA 7 months ago
parent
commit
de1dc75f58
  1. 7
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AnonymousJobExecutorAsyncBackgroundJob.cs
  2. 49
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpDashboardOptionsProvider.cs
  3. 9
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs
  4. 9
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs
  5. 9
      framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/RabbitMqBackgroundJobManager.cs
  6. 9
      framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpTickerQBackgroundJobManager.cs
  7. 9
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/DefaultBackgroundJobManager.cs

7
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AnonymousJobExecutorAsyncBackgroundJob.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundJobs; namespace Volo.Abp.BackgroundJobs;
@ -20,6 +21,12 @@ public class AnonymousJobExecutorAsyncBackgroundJob : AsyncBackgroundJob<Anonymo
public override async Task ExecuteAsync(AnonymousJobArgs args) public override async Task ExecuteAsync(AnonymousJobArgs args)
{ {
Logger.LogInformation(
"Executing anonymous transport job. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}",
AnonymousJobArgs.JobNameConstant,
args.JobName
);
var handler = HandlerRegistry.Get(args.JobName); var handler = HandlerRegistry.Get(args.JobName);
if (handler == null) if (handler == null)
{ {

49
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpDashboardOptionsProvider.cs

@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using System.Text.Json;
using System.Threading; using System.Threading;
using Hangfire; using Hangfire;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -22,13 +23,59 @@ public class AbpDashboardOptionsProvider : ITransientDependency
DisplayNameFunc = (_, job) => DisplayNameFunc = (_, job) =>
{ {
var jobName = job.ToString(); var jobName = job.ToString();
if (job.Args.Count == 3 && job.Args.Last() is CancellationToken) 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; 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; 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;
}
} }

9
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs

@ -3,6 +3,8 @@ using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire; using Hangfire;
using Hangfire.States; using Hangfire.States;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Hangfire; using Volo.Abp.Hangfire;
@ -17,6 +19,7 @@ public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDep
protected IOptions<AbpHangfireOptions> HangfireOptions { get; } protected IOptions<AbpHangfireOptions> HangfireOptions { get; }
protected IJsonSerializer JsonSerializer { get; } protected IJsonSerializer JsonSerializer { get; }
protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; }
public ILogger<HangfireBackgroundJobManager> Logger { get; set; }
public HangfireBackgroundJobManager( public HangfireBackgroundJobManager(
IOptions<AbpBackgroundJobOptions> backgroundJobOptions, IOptions<AbpBackgroundJobOptions> backgroundJobOptions,
@ -28,6 +31,7 @@ public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDep
HangfireOptions = hangfireOptions; HangfireOptions = hangfireOptions;
JsonSerializer = jsonSerializer; JsonSerializer = jsonSerializer;
AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry;
Logger = NullLogger<HangfireBackgroundJobManager>.Instance;
} }
public virtual Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, public virtual Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
@ -48,6 +52,11 @@ public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDep
{ {
if (ShouldWrapAsAnonymousJob(jobName)) if (ShouldWrapAsAnonymousJob(jobName))
{ {
Logger.LogInformation(
"Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}",
AnonymousJobArgs.JobNameConstant,
jobName
);
var jsonData = JsonSerializer.Serialize(args); var jsonData = JsonSerializer.Serialize(args);
var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData);
return EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); return EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay);

9
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Quartz; using Quartz;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -20,6 +22,7 @@ public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDepen
protected IJsonSerializer JsonSerializer { get; } protected IJsonSerializer JsonSerializer { get; }
protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; }
public ILogger<QuartzBackgroundJobManager> Logger { get; set; }
public QuartzBackgroundJobManager(IScheduler scheduler, IOptions<AbpBackgroundJobQuartzOptions> options, IJsonSerializer jsonSerializer, IAnonymousJobHandlerRegistry anonymousJobHandlerRegistry) public QuartzBackgroundJobManager(IScheduler scheduler, IOptions<AbpBackgroundJobQuartzOptions> options, IJsonSerializer jsonSerializer, IAnonymousJobHandlerRegistry anonymousJobHandlerRegistry)
{ {
@ -27,6 +30,7 @@ public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDepen
JsonSerializer = jsonSerializer; JsonSerializer = jsonSerializer;
Options = options.Value; Options = options.Value;
AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry;
Logger = NullLogger<QuartzBackgroundJobManager>.Instance;
} }
public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
@ -40,6 +44,11 @@ public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDepen
{ {
if (ShouldWrapAsAnonymousJob(jobName)) if (ShouldWrapAsAnonymousJob(jobName))
{ {
Logger.LogInformation(
"Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}",
AnonymousJobArgs.JobNameConstant,
jobName
);
var jsonData = JsonSerializer.Serialize(args); var jsonData = JsonSerializer.Serialize(args);
var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData);
return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay);

9
framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/RabbitMqBackgroundJobManager.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Json; using Volo.Abp.Json;
@ -11,12 +13,14 @@ public class RabbitMqBackgroundJobManager : IBackgroundJobManager, ITransientDep
protected IJobQueueManager JobQueueManager { get; } protected IJobQueueManager JobQueueManager { get; }
protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; }
protected IJsonSerializer JsonSerializer { get; } protected IJsonSerializer JsonSerializer { get; }
public ILogger<RabbitMqBackgroundJobManager> Logger { get; set; }
public RabbitMqBackgroundJobManager(IJobQueueManager jobQueueManager, IAnonymousJobHandlerRegistry anonymousJobHandlerRegistry, IJsonSerializer jsonSerializer) public RabbitMqBackgroundJobManager(IJobQueueManager jobQueueManager, IAnonymousJobHandlerRegistry anonymousJobHandlerRegistry, IJsonSerializer jsonSerializer)
{ {
JobQueueManager = jobQueueManager; JobQueueManager = jobQueueManager;
AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry;
JsonSerializer = jsonSerializer; JsonSerializer = jsonSerializer;
Logger = NullLogger<RabbitMqBackgroundJobManager>.Instance;
} }
public virtual async Task<string> EnqueueAsync<TArgs>( public virtual async Task<string> EnqueueAsync<TArgs>(
@ -36,6 +40,11 @@ public class RabbitMqBackgroundJobManager : IBackgroundJobManager, ITransientDep
{ {
if (ShouldWrapAsAnonymousJob(jobName)) if (ShouldWrapAsAnonymousJob(jobName))
{ {
Logger.LogInformation(
"Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}",
AnonymousJobArgs.JobNameConstant,
jobName
);
var jsonData = JsonSerializer.Serialize(args); var jsonData = JsonSerializer.Serialize(args);
var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData);
return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay);

9
framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpTickerQBackgroundJobManager.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using TickerQ.Utilities; using TickerQ.Utilities;
using TickerQ.Utilities.Entities; using TickerQ.Utilities.Entities;
@ -20,6 +22,7 @@ public class AbpTickerQBackgroundJobManager : IBackgroundJobManager, ITransientD
protected AbpBackgroundJobsTickerQOptions TickerQOptions { get; } protected AbpBackgroundJobsTickerQOptions TickerQOptions { get; }
protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; }
protected IJsonSerializer JsonSerializer { get; } protected IJsonSerializer JsonSerializer { get; }
public ILogger<AbpTickerQBackgroundJobManager> Logger { get; set; }
public AbpTickerQBackgroundJobManager( public AbpTickerQBackgroundJobManager(
ITimeTickerManager<TimeTickerEntity> timeTickerManager, ITimeTickerManager<TimeTickerEntity> timeTickerManager,
@ -33,6 +36,7 @@ public class AbpTickerQBackgroundJobManager : IBackgroundJobManager, ITransientD
TickerQOptions = tickerQOptions.Value; TickerQOptions = tickerQOptions.Value;
AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry; AnonymousJobHandlerRegistry = anonymousJobHandlerRegistry;
JsonSerializer = jsonSerializer; JsonSerializer = jsonSerializer;
Logger = NullLogger<AbpTickerQBackgroundJobManager>.Instance;
} }
public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null)
@ -45,6 +49,11 @@ public class AbpTickerQBackgroundJobManager : IBackgroundJobManager, ITransientD
{ {
if (ShouldWrapAsAnonymousJob(jobName)) if (ShouldWrapAsAnonymousJob(jobName))
{ {
Logger.LogInformation(
"Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}",
AnonymousJobArgs.JobNameConstant,
jobName
);
var jsonData = JsonSerializer.Serialize(args); var jsonData = JsonSerializer.Serialize(args);
var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData);
return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay);

9
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/DefaultBackgroundJobManager.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -21,6 +23,7 @@ public class DefaultBackgroundJobManager : IBackgroundJobManager, ITransientDepe
protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; } protected IAnonymousJobHandlerRegistry AnonymousJobHandlerRegistry { get; }
protected IOptions<AbpBackgroundJobOptions> BackgroundJobOptions { get; } protected IOptions<AbpBackgroundJobOptions> BackgroundJobOptions { get; }
protected IOptions<AbpBackgroundJobWorkerOptions> BackgroundJobWorkerOptions { get; } protected IOptions<AbpBackgroundJobWorkerOptions> BackgroundJobWorkerOptions { get; }
public ILogger<DefaultBackgroundJobManager> Logger { get; set; }
public DefaultBackgroundJobManager( public DefaultBackgroundJobManager(
IClock clock, IClock clock,
@ -38,6 +41,7 @@ public class DefaultBackgroundJobManager : IBackgroundJobManager, ITransientDepe
BackgroundJobOptions = backgroundJobOptions; BackgroundJobOptions = backgroundJobOptions;
BackgroundJobWorkerOptions = backgroundJobWorkerOptions; BackgroundJobWorkerOptions = backgroundJobWorkerOptions;
Store = store; Store = store;
Logger = NullLogger<DefaultBackgroundJobManager>.Instance;
} }
public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null)
@ -50,6 +54,11 @@ public class DefaultBackgroundJobManager : IBackgroundJobManager, ITransientDepe
{ {
if (ShouldWrapAsAnonymousJob(jobName)) if (ShouldWrapAsAnonymousJob(jobName))
{ {
Logger.LogInformation(
"Wrapping job into anonymous transport. TransportJobName: {TransportJobName}, EffectiveJobName: {EffectiveJobName}",
AnonymousJobArgs.JobNameConstant,
jobName
);
var jsonData = Serializer.Serialize(args); var jsonData = Serializer.Serialize(args);
var anonymousArgs = new AnonymousJobArgs(jobName, jsonData); var anonymousArgs = new AnonymousJobArgs(jobName, jsonData);
return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay); return await EnqueueAsync(AnonymousJobArgs.JobNameConstant, anonymousArgs, priority, delay);

Loading…
Cancel
Save