Created
November 15, 2024 07:55
-
-
Save odinserj/06e18950b5bf3083a5aed0ed06d3d18a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
using Hangfire.Client; | |
using Hangfire.Server; | |
using Hangfire.States; | |
using Hangfire.Storage; | |
namespace ActivitiesSupport | |
{ | |
public sealed class DiagnosticsActivityFilter : IClientFilter, IServerFilter, IApplyStateFilter | |
{ | |
private const string ActivityItemsKeyName = "Diagnostics.Activity"; | |
private const string ParentIdParameterName = "My.Activity.ParentId"; | |
private readonly ActivitySource _activitySource; | |
public DiagnosticsActivityFilter(ActivitySource activitySource) | |
{ | |
_activitySource = activitySource ?? throw new ArgumentNullException(nameof(activitySource)); | |
} | |
public void OnCreating(CreatingContext context) | |
{ | |
using var parentActivity = _activitySource.StartActivity( | |
$"background job '{context.Job.Type.Name}.{context.Job.Method.Name}'"); | |
parentActivity?.SetTag("job.type", context.Job.Type.FullName); | |
parentActivity?.SetTag("job.method", context.Job.Method.Name); | |
parentActivity?.SetTag("job.state", context.InitialState.Name); | |
parentActivity?.SetTag("job.storage", context.Storage.ToString()); | |
if (parentActivity?.Id != null) | |
{ | |
context.SetJobParameter(ParentIdParameterName, parentActivity.Id); | |
} | |
var activity = _activitySource.StartActivity( | |
$"create job '{context.Job.Type.Name}.{context.Job.Method.Name}'", | |
ActivityKind.Producer); | |
context.Items[ActivityItemsKeyName] = activity; | |
} | |
public void OnCreated(CreatedContext context) | |
{ | |
if (context.Items.TryGetValue(ActivityItemsKeyName, out var item) && | |
item is Activity activity) | |
{ | |
if (context.Exception == null) | |
{ | |
activity.SetStatus(ActivityStatusCode.Ok, "Created"); | |
activity.SetTag("job.id", context.BackgroundJob.Id); | |
activity.SetTag("job.created", context.BackgroundJob.CreatedAt.ToString("O")); | |
} | |
else | |
{ | |
activity.SetStatus(ActivityStatusCode.Error, "Exception"); | |
activity.SetTag("exception.type", context.Exception.GetType().FullName); | |
activity.SetTag("exception.message", context.Exception.Message); | |
activity.SetTag("exception.stacktrace", context.Exception.ToString()); | |
} | |
activity.Dispose(); | |
} | |
} | |
public void OnPerforming(PerformingContext context) | |
{ | |
var parentId = context.GetJobParameter<string>(ParentIdParameterName); | |
ActivityContext.TryParse(parentId, null, isRemote: true, out var parentCtx); | |
var activity = _activitySource.StartActivity( | |
$"perform job '{context.BackgroundJob.Job.Type.Name}.{context.BackgroundJob.Job.Method.Name}'", | |
ActivityKind.Consumer, | |
parentCtx); | |
context.Items[ActivityItemsKeyName] = activity; | |
} | |
public void OnPerformed(PerformedContext context) | |
{ | |
if (context.Items.TryGetValue(ActivityItemsKeyName, out var item) && item is Activity activity) | |
{ | |
if (context.Exception == null) | |
{ | |
activity.SetStatus(ActivityStatusCode.Ok, "Performed"); | |
} | |
else | |
{ | |
activity.SetStatus(ActivityStatusCode.Error, "Exception"); | |
activity.SetTag("exception.type", context.Exception.GetType().FullName); | |
activity.SetTag("exception.message", context.Exception.Message); | |
activity.SetTag("exception.stacktrace", context.Exception.ToString()); | |
} | |
activity.Dispose(); | |
} | |
} | |
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction) | |
{ | |
var parentId = context.GetJobParameter<string>(ParentIdParameterName); | |
ActivityContext.TryParse(parentId, null, isRemote: true, out var parentCtx); | |
using var activity = _activitySource.StartActivity( | |
$"state change to '{context.NewState.Name}'", | |
ActivityKind.Consumer, | |
parentCtx); | |
activity?.SetTag("state.old", context.OldStateName); | |
activity?.SetTag("state.new", context.NewState.Name); | |
activity?.SetTag("state.reason", context.NewState.Reason); | |
} | |
public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment