تعقب العمليات المخصصة باستخدام Application Insights .NET SDK

تتعقب Application Insights SDKs تلقائيا طلبات HTTP الواردة والمكالمات إلى الخدمات التابعة، مثل طلبات HTTP واستعلامات SQL. تتبع وارتباط الطلبات والتبعيات يعطيك رؤية في استجابة التطبيق كله والموثوقية عبر جميع microservices التي تجمع بين هذا التطبيق.

هناك فئة من أنماط التطبيق التي لا يمكن دعمها بشكل عام. يتطلب الرصد السليم لهذه الأنماط أدوات التعليمات البرمجية اليدوية. تغطي هذه المقالة بعض الأنماط التي قد تتطلب أدوات يدوية، مثل معالجة قوائم الانتظار المخصصة وتشغيل مهام الخلفية طويلة الأمد.

توفر هذه المقالة إرشادات حول كيفية تعقب العمليات المخصصة باستخدام Application Insights SDK. هذه الوثائق ذات صلة بما يلي:

  • Application Insights SDK.(المعروف أيضًا باسم SDK الأساسي) الإصدار 2.4+.
  • Application Insights لتطبيقات الويب (تشغيل ASP.NET) الإصدار 2.4 +.
  • Application Insights لإصدار ASP.NET الأساسية 2.1+.

إشعار

تعتمد الوثائق التالية على واجهة برمجة تطبيقات Application Insights الكلاسيكية. الخطة طويلة الأجل ل Application Insights هي جمع البيانات باستخدام OpenTelemetry. لمزيد من المعلومات، راجع تمكين Azure Monitor OpenTelemetry لتطبيقات .NET Node.js وPython وJava.

نظرة عامة

العملية هي جزء منطقي من العمل الذي يديره أحد التطبيقات. لها اسم ووقت بدء ومدة ونتيجة وسياق تنفيذ مثل اسم المستخدم والخصائص والنتيجة. إذا تم بدء العملية A بواسطة العملية B، يتم تعيين العملية B كأحد الوالدين لـ A. يمكن أن يكون لعملية أصل واحد فقط، ولكن يمكن أن يكون لها العديد من العمليات التابعة. لمزيد من المعلومات حول العمليات وارتباط بيانات تتبع الاستخدام، راجع ارتباط بيانات تتبع الاستخدام ل Application Insights.

في Application Insights .NET SDK، يتم وصف العملية بواسطة فئة مجردة OperationTelemetry و descendants RequestTelemetry و DependencyTelemetry.

تتبع العمليات الواردة

التطبيق Insights ويب SDK تلقائيًا يجمع طلبات HTTP للتطبيقات ASP.NET التي تعمل في خط أنابيب IIS وكافة التطبيقات الأساسية ASP.NET. هناك حلول مدعومة من المجتمع المحلي لمنصات وأطر أخرى. إذا لم يكن التطبيق مدعوما من قبل أي من الحلول القياسية أو المدعومة من المجتمع، يمكنك استخدامه يدويا.

مثال آخر يتطلب تعقبًا مخصصًا هو العامل الذي يتلقى عناصر من قائمة الانتظار. بالنسبة لبعض قوائم الانتظار، يتم تعقب المكالمة لإضافة رسالة إلى قائمة الانتظار هذه كتبعية. لا يتم جمع العملية عالية المستوى التي تصف معالجة الرسائل تلقائيا.

دعونا نرى كيف يمكن تتبع مثل هذه العمليات.

على مستوى عالٍ، المهمة هي إنشاء RequestTelemetry وتعيين خصائص معروفة. بعد انتهاء العملية، يمكنك تعقب القياس عن بُعد. يوضح المثال التالي هذه المهمة.

طلب HTTP في التطبيق المضيف ذاتيًا Owin

في هذا المثال، يتم نشر سياق التتبع وفقًا لبروتوكول HTTP للارتباط. يجب أن تتوقع تلقي الرؤوس الموضحة هناك.

public class ApplicationInsightsMiddleware : OwinMiddleware
{
    // You may create a new TelemetryConfiguration instance, reuse one you already have,
    // or fetch the instance created by Application Insights SDK.
    private readonly TelemetryConfiguration telemetryConfiguration = TelemetryConfiguration.CreateDefault();
    private readonly TelemetryClient telemetryClient = new TelemetryClient(telemetryConfiguration);
    
    public ApplicationInsightsMiddleware(OwinMiddleware next) : base(next) {}

    public override async Task Invoke(IOwinContext context)
    {
        // Let's create and start RequestTelemetry.
        var requestTelemetry = new RequestTelemetry
        {
            Name = $"{context.Request.Method} {context.Request.Uri.GetLeftPart(UriPartial.Path)}"
        };

        // If there is a Request-Id received from the upstream service, set the telemetry context accordingly.
        if (context.Request.Headers.ContainsKey("Request-Id"))
        {
            var requestId = context.Request.Headers.Get("Request-Id");
            // Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
            requestTelemetry.Context.Operation.Id = GetOperationId(requestId);
            requestTelemetry.Context.Operation.ParentId = requestId;
        }

        // StartOperation is a helper method that allows correlation of 
        // current operations with nested operations/telemetry
        // and initializes start time and duration on telemetry items.
        var operation = telemetryClient.StartOperation(requestTelemetry);

        // Process the request.
        try
        {
            await Next.Invoke(context);
        }
        catch (Exception e)
        {
            requestTelemetry.Success = false;
            requestTelemetry.ResponseCode;
            telemetryClient.TrackException(e);
            throw;
        }
        finally
        {
            // Update status code and success as appropriate.
            if (context.Response != null)
            {
                requestTelemetry.ResponseCode = context.Response.StatusCode.ToString();
                requestTelemetry.Success = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
            }
            else
            {
                requestTelemetry.Success = false;
            }

            // Now it's time to stop the operation (and track telemetry).
            telemetryClient.StopOperation(operation);
        }
    }
    
    public static string GetOperationId(string id)
    {
        // Returns the root ID from the '|' to the first '.' if any.
        int rootEnd = id.IndexOf('.');
        if (rootEnd < 0)
            rootEnd = id.Length;

        int rootStart = id[0] == '|' ? 1 : 0;
        return id.Substring(rootStart, rootEnd - rootStart);
    }
}

يقوم بروتوكول HTTP للارتباط أيضًا بتعريف Correlation-Context الرأس. تم حذفه هنا للتبسيط.

أجهزة قائمة الانتظار

سياق تتبع W3C وبروتوكول HTTP للارتباط يمران بتفاصيل الارتباط مع طلبات HTTP، ولكن يجب على كل بروتوكول قائمة انتظار تحديد كيفية تمرير نفس التفاصيل على طول رسالة قائمة الانتظار. تسمح بعض بروتوكولات قائمة الانتظار، مثل AMQP، بتمرير المزيد من بيانات التعريف. تتطلب البروتوكولات الأخرى، مثل Azure Storage Queue، ترميز السياق في حمولة الرسالة.

إشعار

لا يتم دعم التتبع عبر المكونات لقوائم الانتظار حتى الآن.

باستخدام HTTP، إذا أرسل المنتج والمستهلك بيانات تتبع الاستخدام إلى موارد Application Insights مختلفة، فإن تجربة تشخيص المعاملات وApplication Map تعرض المعاملات وخريطة شاملة. في حالة قوائم الانتظار، هذه الإمكانية غير مدعومة حتى الآن.

قائمة انتظار حافلة الخدمة

للحصول على معلومات التتبع، راجع التتبع الموزع والارتباط من خلال المراسلة ناقل خدمة Azure.

قائمة انتظار التخزين Azure

يوضح المثال التالي كيفية تعقب عمليات قائمة انتظار التخزين Azure وربط القياس عن بُعد بين المنتج والمستهلك وتخزين Azure.

قائمة انتظار التخزين على واجهة برمجة تطبيقات HTTP. يتم تعقب كافة المكالمات إلى قائمة الانتظار بواسطة "مجمع التبعية Insights التطبيق" لطلبات HTTP. يتم تكوينه بشكل افتراضي على تطبيقات ASP.NET و ASP.NET Core. مع أنواع أخرى من التطبيقات، راجع وثائق تطبيقات وحدة التحكم.

قد تحتاج أيضًا إلى ربط معرف العملية التطبيق Insights مع معرف طلب التخزين. للحصول على معلومات حول كيفية تعيين عميل طلب تخزين ومعرف طلب خادم والحصول عليه، راجع مراقبة التخزين Azure وتشخيصه واستكشافه وإصلاحه.

Enqueue

لأن قوائم التخزين تدعم واجهة برمجة تطبيقات HTTP، يتم تعقب كافة العمليات مع قائمة الانتظار تلقائيًا بواسطة تطبيق Insights. وفي كثير من الحالات، ينبغي أن تكون هذه الأجهزة كافية. لربط التتبعات على جانب المستهلك بتتبعات المنتج، يجب تمرير بعض سياق الارتباط بشكل مشابه لكيفية القيام بذلك في بروتوكول HTTP للارتباط.

يوضح هذا المثال كيفية تعقب Enqueue العملية. يمكنك:

  • ربط إعادة المحاولة (إن وجدت):لديهم جميعًا أصل واحد مشترك هو Enqueue العملية. خلاف ذلك، يتم تعقبهم كتوابع للطلب الوارد. إذا كان هناك طلبات منطقية متعددة إلى قائمة الانتظار، قد يكون من الصعب العثور على أي استدعاء نتج عنه إعادة المحاولة.
  • سجلات التخزين المترابطة (إذا لزم الأمر وعند الحاجة):ترتبط مع التطبيق Insights القياس عن بُعد.

Enqueue العملية هي تابعة لعملية أصل. مثال على ذلك هو طلب HTTP وارد. استدعاء تبعية HTTP هو تابع للعملية Enqueue وحفيد الطلب الوارد.

public async Task Enqueue(CloudQueue queue, string message)
{
    var operation = telemetryClient.StartOperation<DependencyTelemetry>("enqueue " + queue.Name);
    operation.Telemetry.Type = "Azure queue";
    operation.Telemetry.Data = "Enqueue " + queue.Name;

    // MessagePayload represents your custom message and also serializes correlation identifiers into payload.
    // For example, if you choose to pass payload serialized to JSON, it might look like
    // {'RootId' : 'some-id', 'ParentId' : '|some-id.1.2.3.', 'message' : 'your message to process'}
    var jsonPayload = JsonConvert.SerializeObject(new MessagePayload
    {
        RootId = operation.Telemetry.Context.Operation.Id,
        ParentId = operation.Telemetry.Id,
        Payload = message
    });
    
    CloudQueueMessage queueMessage = new CloudQueueMessage(jsonPayload);

    // Add operation.Telemetry.Id to the OperationContext to correlate Storage logs and Application Insights telemetry.
    OperationContext context = new OperationContext { ClientRequestID = operation.Telemetry.Id};

    try
    {
        await queue.AddMessageAsync(queueMessage, null, null, new QueueRequestOptions(), context);
    }
    catch (StorageException e)
    {
        operation.Telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
        operation.Telemetry.Success = false;
        operation.Telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
        telemetryClient.TrackException(e);
    }
    finally
    {
        // Update status code and success as appropriate.
        telemetryClient.StopOperation(operation);
    }
}  

لتقليل مقدار القياس عن بُعد لتقارير التطبيق أو إذا كنت لا تريد تعقب Enqueue العملية لأسباب أخرى، استخدم Activity واجهة برمجة التطبيقات مباشرة:

  • إنشاء (وبدء) جديد Activity بدلاً من بدء تشغيل عملية Insights التطبيق. لا تحتاج إلى تعيين أية خصائص عليه باستثناء اسم العملية.
  • قم بعمل تسلسل yourActivity.Id في حمولة الرسالة بدلاً من operation.Telemetry.Id. يمكنك أيضًا استخدام Activity.Current.Id.

Dequeue

Enqueueوبالمثل، يتم تعقب طلب HTTP الفعلي إلى قائمة انتظار التخزين تلقائيًا بواسطة تطبيق Insights. Enqueue من المفترض أن تحدث العملية في السياق الأصل، مثل سياق طلب وارد. تربط Application Insights SDKs تلقائيا مثل هذه العملية، وجزء HTTP الخاص بها، مع الطلب الأصل وبيانات تتبع الاستخدام الأخرى التي تم الإبلاغ عنها في نفس النطاق.

Dequeueالعملية صعبة. التطبيق Insights SDK تلقائيًا المسارات طلبات HTTP. ولكنه لا يعرف سياق الارتباط حتى يتم تحليل الرسالة. لا يمكن ربط طلب HTTP للحصول على الرسالة ببقية بيانات تتبع الاستخدام، خاصة عند تلقي أكثر من رسالة واحدة.

public async Task<MessagePayload> Dequeue(CloudQueue queue)
{
    var operation = telemetryClient.StartOperation<DependencyTelemetry>("dequeue " + queue.Name);
    operation.Telemetry.Type = "Azure queue";
    operation.Telemetry.Data = "Dequeue " + queue.Name;
    
    try
    {
        var message = await queue.GetMessageAsync();
    }
    catch (StorageException e)
    {
        operation.telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
        operation.telemetry.Success = false;
        operation.telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
        telemetryClient.TrackException(e);
    }
    finally
    {
        // Update status code and success as appropriate.
        telemetryClient.StopOperation(operation);
    }

    return null;
}

معالجة

في المثال التالي، يتم تعقب رسالة واردة بطريقة مشابهة لطلب HTTP الوارد:

public async Task Process(MessagePayload message)
{
    // After the message is dequeued from the queue, create RequestTelemetry to track its processing.
    RequestTelemetry requestTelemetry = new RequestTelemetry { Name = "process " + queueName };
    
    // It might also make sense to get the name from the message.
    requestTelemetry.Context.Operation.Id = message.RootId;
    requestTelemetry.Context.Operation.ParentId = message.ParentId;

    var operation = telemetryClient.StartOperation(requestTelemetry);

    try
    {
        await ProcessMessage();
    }
    catch (Exception e)
    {
        telemetryClient.TrackException(e);
        throw;
    }
    finally
    {
        // Update status code and success as appropriate.
        telemetryClient.StopOperation(operation);
    }
}

وبالمثل، يمكن استخدام أدوات عمليات قائمة انتظار أخرى. وينبغي أن تكون عملية نظرة خاطفة في صك بطريقة مماثلة لعملية dequeue. عمليات إدارة قائمة الانتظار الآلية ليست ضرورية. يتتبع التطبيق Insights عمليات مثل HTTP، وفي معظم الحالات، يكفي.

عند حذف رسالة أداة، تأكد من تعيين معرفات العملية (الارتباط). بدلاً من ذلك، يمكنك استخدام Activity API. ثم لا تحتاج إلى تعيين معرفات العملية على عناصر القياس عن بُعد لأن تطبيق Insights SDK يفعل ذلك بالنسبة لك:

  • إنشاء عنصر جديد Activity بعد محاولة تهيئة عنصر من قائمة الانتظار.
  • يستخدم Activity.SetParentId(message.ParentId) لربط سجلات المستهلكين والمنتجين.
  • ابدأActivity.
  • تعقب عمليات الإزالة، والعملية، والحذف باستخدام Start/StopOperation المساعدين. قم بذلك من نفس تدفق عنصر التحكم غير المتزامن (سياق التنفيذ). بهذه الطريقة، يتم ربطها بشكل صحيح.
  • قم بإيقاف Activity.
  • استخدام Start/StopOperation بيانات تتبع الاستخدام أو الاتصال Track بها يدويا.

أنواع التبعية

يستخدم Insights التطبيق نوع التبعية لتخصيص تجارب واجهة المستخدم. بالنسبة لقوائم الانتظار، فإنه يتعرف على الأنواع التالية من DependencyTelemetry التي تحسن تجربة تشخيص المعاملات:

  • Azure queue لقوائم انتظار Azure Storage
  • Azure Event Hubs لمراكز الأحداث Azure
  • Azure Service Bus ناقل خدمة Azure

معالجة الدُفعات

مع بعض قوائم الانتظار، يمكنك إلغاء صرير رسائل متعددة مع طلب واحد. معالجة مثل هذه الرسائل مستقلة وتنتمي إلى العمليات المنطقية المختلفة. من غير الممكن ربط Dequeue العملية برسالة معينة تتم معالجتها.

يجب معالجة كل رسالة في تدفق التحكم غير المتزامن الخاص بها. لمزيدٍ من المعلومات، راجع قسم تتبع التبعيات الصادرة.

مهام خلفية طويلة الأمد

بعض التطبيقات بدء تشغيل عمليات التشغيل الطويلة التي قد تكون ناجمة عن طلبات المستخدم. من منظور التتبع/الأجهزة، فإنه لا يختلف عن الطلب أو أدوات التبعية:

async Task BackgroundTask()
{
    var operation = telemetryClient.StartOperation<DependencyTelemetry>(taskName);
    operation.Telemetry.Type = "Background";
    try
    {
        int progress = 0;
        while (progress < 100)
        {
            // Process the task.
            telemetryClient.TrackTrace($"done {progress++}%");
        }
        // Update status code and success as appropriate.
    }
    catch (Exception e)
    {
        telemetryClient.TrackException(e);
        // Update status code and success as appropriate.
        throw;
    }
    finally
    {
        telemetryClient.StopOperation(operation);
    }
}

في هذا المثال، telemetryClient.StartOperation ينشئ DependencyTelemetry ويملأ سياق الارتباط. لنفترض أن لديك عملية أصل تم إنشاؤها بواسطة الطلبات الواردة التي قامت بجدولة العملية. طالما BackgroundTask يبدأ في نفس تدفق عنصر التحكم غير المتزامن مثل طلب وارد، فإنه يرتبط بتلك العملية الأصل. BackgroundTask وجميع عناصر القياس عن بُعد المتداخلة ترتبط تلقائيًا بالطلب الذي تسبب في ذلك، حتى بعد انتهاء الطلب.

عندما تبدأ المهمة من مؤشر ترابط الخلفية التي لا تحتوي على أية عملية ( Activity ) المقترنة به، BackgroundTask لا يكون لها أي أصل. ومع ذلك، يمكن أن يكون تداخل العمليات. ترتبط كافة عناصر القياس عن بُعد التي تم الإبلاغ عنها من المهمة بعناصر DependencyTelemetry تم إنشاؤها في BackgroundTask.

تتبع التبعيات الصادرة

يمكنك تعقب نوع التبعية الخاص بك أو عملية غير معتمدة من قِبل تطبيق Insights.

Enqueueالأسلوب في قائمة انتظار "ناقل الخدمة" أو قائمة انتظار التخزين يمكن أن تكون بمثابة أمثلة للتعقب المخصصة.

الأسلوب العام لتعقب التبعية المخصصة هو:

  • TelemetryClient.StartOperation استدعاء الأسلوب (الملحق) الذي يملأ الخصائص DependencyTelemetry المطلوبة للارتباط وبعض الخصائص الأخرى، مثل البدء والطابع الزمني والمدة.
  • تعيين خصائص مخصصة أخرى على DependencyTelemetry، مثل الاسم وأي سياق آخر تحتاجه.
  • إجراء مكالمة تبعية وانتظرها.
  • أوقف العملية StopOperation عند انتهائها.
  • معالجة الاستثناءات.
public async Task RunMyTaskAsync()
{
    using (var operation = telemetryClient.StartOperation<DependencyTelemetry>("task 1"))
    {
        try 
        {
            var myTask = await StartMyTaskAsync();
            // Update status code and success as appropriate.
        }
        catch(...) 
        {
            // Update status code and success as appropriate.
        }
    }
}

يؤدي التخلص من عملية إلى إيقاف العملية، لذلك قد تقوم بذلك بدلا من استدعاء StopOperation.

تحذير

في بعض الحالات، قد يمنعfinally استثناء غير معالج استدعاء، لذلك قد لا يتم تعقب العمليات.

عمليات متوازية معالجة وتتبع

يؤدي استدعاء StopOperation فقط إلى إيقاف العملية التي تم تشغيلها. إذا كانت العملية الحالية قيد التشغيل لا تتطابق مع العملية التي تريد إيقافها، StopOperation فلا تفعل شيئًا. قد يحدث هذا الموقف إذا بدأت عمليات متعددة بالتوازي في نفس سياق التنفيذ.

var firstOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 1");
var firstTask = RunMyTaskAsync();

var secondOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 2");
var secondTask = RunMyTaskAsync();

await firstTask;

// FAILURE!!! This will do nothing and will not report telemetry for the first operation
// as currently secondOperation is active.
telemetryClient.StopOperation(firstOperation); 

await secondTask;

تأكد دائما من استدعاء StartOperation العملية ومعالجتها بنفس الأسلوب غير المتزامن لعزل العمليات التي تعمل بالتوازي. إذا كانت العملية متزامنة (أو غير متزامنة)، فلف العملية وتعقبها باستخدام Task.Run.

public void RunMyTask(string name)
{
    using (var operation = telemetryClient.StartOperation<DependencyTelemetry>(name))
    {
        Process();
        // Update status code and success as appropriate.
    }
}

public async Task RunAllTasks()
{
    var task1 = Task.Run(() => RunMyTask("task 1"));
    var task2 = Task.Run(() => RunMyTask("task 2"));
    
    await Task.WhenAll(task1, task2);
}

عمليات ApplicationInsights مقابل System.Diagnostics.Activity

System.Diagnostics.Activity يمثل سياق التتبع الموزع ويستخدم من قِبل الأطر والمكتبات لإنشاء ونشر السياق داخل وخارج العملية وربط عناصر القياس عن بُعد. Activity يعمل مع System.Diagnostics.DiagnosticSource كآلية الإعلام بين إطار العمل/المكتبة للإخطار بالأحداث المثيرة للاهتمام مثل الطلبات والاستثناءات الواردة أو الصادرة.

الأنشطة هم مواطنون من الدرجة الأولى في Application Insights. تعتمد التبعية التلقائية ومجموعة الطلبات بشكل كبير عليها جنبا إلى جنب مع DiagnosticSource الأحداث. إذا قمت بإنشاء Activity في التطبيق الخاص بك، فلن يؤدي ذلك إلى إنشاء بيانات تتبع الاستخدام Application Insights. يحتاج Application Insights إلى تلقي DiagnosticSource الأحداث ومعرفة أسماء الأحداث والحمولات للترجمة Activity إلى بيانات تتبع الاستخدام.

تتضمن كل عملية Application Insights (طلب أو تبعية Activity) . عند StartOperation استدعاء، فإنه يتم إنشاء Activity أسفل. StartOperation هي الطريقة الموصى بها لتتبع القياس عن بُعد للطلب أو التبعية يدويًا وضمان ارتباط كل شيء.

الخطوات التالية