Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Azure 将Hangfire作业记录到应用程序洞察并将活动与操作Id关联_Azure_Azure Application Insights_Asp.net Core 3.1_Hangfire - Fatal编程技术网

Azure 将Hangfire作业记录到应用程序洞察并将活动与操作Id关联

Azure 将Hangfire作业记录到应用程序洞察并将活动与操作Id关联,azure,azure-application-insights,asp.net-core-3.1,hangfire,Azure,Azure Application Insights,Asp.net Core 3.1,Hangfire,我觉得这应该比实际情况简单得多,或者我只是想得太多了 我有一个.NETCore3.1WebAPI应用程序,它使用HangFire在后台处理一些作业。我还配置了Application Insights,以便从.NET核心API记录遥测 我可以在Application Insights中看到记录事件和依赖项遥测数据。但是,每个事件/日志/依赖项都是根据唯一的OperationId和父Id记录的 我试图确定如何确保记录的任何活动或后台作业上下文中使用的任何依赖项都是根据后台作业排队的原始请求的Oper

我觉得这应该比实际情况简单得多,或者我只是想得太多了

我有一个.NETCore3.1WebAPI应用程序,它使用HangFire在后台处理一些作业。我还配置了Application Insights,以便从.NET核心API记录遥测

我可以在Application Insights中看到记录事件和依赖项遥测数据。但是,每个事件/日志/依赖项都是根据唯一的OperationId和父Id记录的

我试图确定如何确保记录的任何活动或后台作业上下文中使用的任何依赖项都是根据后台作业排队的原始请求的OperationId和/或父Id记录的

当我对作业排队时,我可以获取传入HTTP请求的当前OperationId,并将其与作业一起推送到HangFire队列中。然后执行作业时,我可以取回操作ID。然后,我需要做的是使OperationID在作业执行的整个上下文/生命周期中都可用,以便它连接到发送给Application Insightd的任何遥测数据

我想我可以创建一个IJobContext接口,它可以被注入到执行作业的类中。在这种情况下,我可以推送OperationID。然后,我可以创建一个ITelemetryInitializer,它还将IJobContext作为依赖项。在ITelemetryInitializer中,我可以设置发送到Application Insights的遥测的OperationID和ParentId。下面是一些简单的代码:

public class HangFirePanelMessageQueue : IMessageQueue
{
    private readonly MessageProcessor _messageProcessor;
    private readonly IHangFireJobContext _jobContext;
    private readonly TelemetryClient _telemetryClient;

    public HangFirePanelMessageQueue(MessageProcessor panelMessageProcessor,
        IIoTMessageSerializer iotHubMessageSerialiser,
        IHangFireJobContext jobContext, TelemetryClient telemetryClient)
    {
        _messageProcessor = panelMessageProcessor;
        _jobContext = jobContext;
        _telemetryClient = telemetryClient;
    }

    public async Task ProcessQueuedMessage(string message, string operationId)
    {
        var iotMessage = _iotHubMessageSerialiser.GetMessage(message);

        _jobContext?.Set(iotMessage.CorrelationID, iotMessage.MessageID);

        await _messageProcessor.ProcessMessage(iotMessage);
    }

    public Task QueueMessageForProcessing(string message)
    {
        var dummyTrace = new TraceTelemetry("Queuing message for processing", SeverityLevel.Information);
        _telemetryClient.TrackTrace(dummyTrace);
        string opId = dummyTrace.Context.Operation.Id;

        BackgroundJob.Enqueue(() =>
        ProcessQueuedMessage(message, opId));

        return Task.CompletedTask;
    }
}
IJobContext看起来像这样:

public interface IHangFireJobContext
{
    bool Initialised { get; }

    string OperationId { get; }

    string JobId { get; }

    void Set(string operationId, string jobId);
}
然后我会有一个ITelemetryInitializer,它丰富了任何ITelemetry:

public class EnrichBackgroundJobTelemetry : ITelemetryInitializer
{
    private readonly IHangFireJobContext jobContext;

    public EnrichBackgroundJobTelemetry(IHangFireJobContext jobContext)
    {
        this.jobContext = jobContext;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (!jobContext.Initialised)
        {
            return;
        }

        telemetry.Context.Operation.Id = jobContext.OperationId;
    }
}
然而,我的问题是ITelemetryInitializer是一个单例,因此它将使用IHangFireJobContext实例化一次,而IHangFireJobContext将永远不会更新任何后续的HangFire作业

我确实找到了这个项目,它扩展了。Correlate创建一个相关上下文,可通过类似于IHttpContextAccessor的ICorrelationContextAccessor访问该上下文

然而,相关状态的脚注“请考虑.Net Cype 3现在已经为W3C TraceCeTeX(blog)提供了内置的支持,并且还有其他分布式的跟踪库,其功能比关联性更强。”列出了应用程序的见解作为更高级分布式跟踪的替代方案之一。 那么,有谁能帮助我理解,当在HangFire作业的上下文中创建遥测技术时,我如何能够丰富其应用程序洞察力?我觉得正确的答案是使用ITelemetryInitializer并填充该ITelemetry项上的OperationId,但是,我不确定要将什么依赖性注入ITelemetryInitializer以访问HangFire作业上下文

当我对作业排队时,我可以获取传入HTTP请求的当前OperationId,并将其与作业一起推送到HangFire队列中

那么,我说的对吗,你们有一个控制器动作,它把功推到了火上?如果是这样,您可以在控制器方法内部获取操作id并将其传递给作业。使用该操作id启动使用该操作id的新操作。该操作以及该操作期间生成的所有遥测将链接到原始请求

我没有hangfire集成,但下面的代码显示了总体思路:一些工作在后台排队完成,应该链接到有关遥测的请求:

[HttpGet(“/api/demo5”)]
公共操作结果TrackWorker()
{
var requestTelemetry=HttpContext.Features.Get();
_taskQueue.QueueBackgroundWorkItem(异步ct=>
{
使用(var op=_telemetryClient.startoOperation(“QueuedWork”,requestTelemetry.Context.Operation.Id))
{
_=等待新的HttpClient()。GetStringAsync(“http://blank.org");
等待任务。延迟(250);
op.Telemetry.ResultCode=“200”;
op.Telemetry.Success=true;
}
});
返回已接受();
}
可以找到完整的示例


我刚刚遇到Trace.CorrelationManager,它被记录为“获取此跟踪线程的相关管理器”。我将研究如何利用它来启动和停止关于HangFire作业的逻辑操作,并从ITelemetryInitializer中的Trace.CorrelationManager中检索operationID。