コード例 #1
0
        private static void InitializeTelemetry(DependencyTelemetry telemetry, Guid operationId, long timestamp)
        {
            telemetry.Start(timestamp);

            var activity = Activity.Current;

            if (activity != null)
            {
                telemetry.Context.Operation.Id = activity.RootId;

                // SQL Client does NOT create and Activity, i.e.
                // we initialize SQL dependency using request Activity
                // and it is a parent of the SQL dependency
                telemetry.Context.Operation.ParentId = activity.Id;

                foreach (var item in activity.Baggage)
                {
                    if (!telemetry.Properties.ContainsKey(item.Key))
                    {
                        telemetry.Properties[item.Key] = item.Value;
                    }
                }
            }
            else
            {
                telemetry.Context.Operation.Id = operationId.ToStringInvariant("N");
            }
        }
        public void StartTimeIsPrecise()
        {
            double []      timeStampDiff = new double[1000];
            DateTimeOffset prevTimestamp = DateTimeOffset.MinValue;

            for (int i = 0; i < timeStampDiff.Length; i++)
            {
                var telemetry = new DependencyTelemetry();
                telemetry.Start();

                if (i > 0)
                {
                    timeStampDiff[i] = telemetry.Timestamp.Subtract(prevTimestamp).TotalMilliseconds;
                    Debug.WriteLine(timeStampDiff[i]);

                    // if timestamp is NOT precise, we'll get precisely 0 which should not ever happen
                    Assert.IsTrue(timeStampDiff[i] != 0);
                }

                prevTimestamp = telemetry.Timestamp;

                // waste a bit of time, assert result to prevent any optimizations
                Assert.IsTrue(ComputeSomethingHeavy() > 0);
            }
        }
        public void OperationTelemetryCanRecordPreciseDurations()
        {
            var telemetry = new DependencyTelemetry();

            long startTime = Stopwatch.GetTimestamp();

            telemetry.Start(timestamp: startTime);

            // Note: Do not use TimeSpan.FromSeconds because it rounds to the nearest millisecond.
            var expectedDuration = TimeSpan.Parse("00:00:00.1234560");

            // Ensure we choose a time that has a fractional (non-integral) number of milliseconds
            Assert.NotEqual(Math.Round(expectedDuration.TotalMilliseconds), expectedDuration.TotalMilliseconds);

            double durationInStopwatchTicks = Stopwatch.Frequency * expectedDuration.TotalSeconds;

            long stopTime = (long)Math.Round(startTime + durationInStopwatchTicks);

            telemetry.Stop(timestamp: stopTime);

            if (Stopwatch.Frequency == TimeSpan.TicksPerSecond)
            {
                // In this case, the times should match exactly.
                Assert.Equal(expectedDuration, telemetry.Duration);
            }
            else
            {
                // There will be a difference, but it should be less than
                // 1 microsecond (10 ticks)
                var difference = (telemetry.Duration - expectedDuration).Duration();
                Assert.True(difference.Ticks < 10);
            }
        }
コード例 #4
0
        // telemetry implementation
        protected DependencyTelemetry StartSendTelemetry(Message request, string method)
        {
            var             soapAction = request.Headers.Action;
            ClientOperation operation;

            if (!this.ChannelManager.OperationMap.TryLookupByAction(soapAction, out operation))
            {
                return(null);
            }

            try
            {
                var telemetry = new DependencyTelemetry();
                this.ChannelManager.TelemetryClient.Initialize(telemetry);
                telemetry.Start();
                telemetry.Type   = DependencyConstants.WcfClientCall;
                telemetry.Target = this.RemoteAddress.Uri.Host;
                telemetry.Data   = this.RemoteAddress.Uri.ToString();
                telemetry.Name   = operation.Name;
                telemetry.Properties[DependencyConstants.SoapActionProperty] = soapAction;
                if (operation.IsOneWay)
                {
                    telemetry.Properties[DependencyConstants.IsOneWayProperty] = bool.TrueString;
                }

                this.SetCorrelationHeaders(telemetry, request);
                return(telemetry);
            }
            catch (Exception ex)
            {
                WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
                return(null);
            }
        }
        /// <summary>
        /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item.
        /// </summary>
        /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param>
        internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient)
        {
            var telemetry = new DependencyTelemetry();

            telemetry.Start();
            Activity activity;
            Activity currentActivity = Activity.Current;

            // On .NET46 without profiler, outgoing requests are instrumented with reflection hook in DiagnosticSource
            //// see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs
            // it creates an Activity and injects standard 'Request-Id' and 'Correlation-Context' headers itself, so we should not start Activity in this case
            if (currentActivity != null && currentActivity.OperationName == "System.Net.Http.Desktop.HttpRequestOut")
            {
                activity = currentActivity;
            }
            else
            {
                // Every operation must have its own Activity
                // if dependency is tracked with profiler of event source, we need to generate a proper Id for it
                // in case of HTTP it will be propagated into the request header.
                // So, we will create a new Activity for the dependency, just to generate an Id.
                activity = new Activity(DependencyActivityName);
                activity.Start();
            }

            // OperationCorrelationTelemetryInitializer will initialize telemetry as a child of current activity:
            // But we need to initialize dependency telemetry from the current Activity:
            // Activity was created for this dependency in the Http Desktop DiagnosticSource
            if (activity.IdFormat == ActivityIdFormat.W3C)
            {
                var context = telemetry.Context;
                context.Operation.Id = activity.TraceId.ToHexString();

                if (activity.Parent != null || activity.ParentSpanId != default)
                {
                    context.Operation.ParentId = activity.ParentSpanId.ToHexString();
                }

                telemetry.Id = activity.SpanId.ToHexString();
            }
            else
            {
                var context = telemetry.Context;
                context.Operation.Id       = activity.RootId;
                context.Operation.ParentId = activity.ParentId;
                telemetry.Id = activity.Id;
            }

            foreach (var item in activity.Baggage)
            {
                if (!telemetry.Properties.ContainsKey(item.Key))
                {
                    telemetry.Properties.Add(item);
                }
            }

            telemetryClient.Initialize(telemetry);
            PretendProfilerIsAttached = false;
            return(telemetry);
        }
        public void OperationTelemetryStartInitializesTimeStampAndStartTimeToTelemetry()
        {
            var telemetry = new DependencyTelemetry();

            Assert.Equal(DateTimeOffset.MinValue, telemetry.Timestamp);
            telemetry.Start();
            Assert.NotEqual(DateTimeOffset.MinValue, telemetry.Timestamp);
        }
        /// <summary>
        /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item.
        /// </summary>
        /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param>
        internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient)
        {
            var telemetry = new DependencyTelemetry();

            telemetry.Start();
            telemetryClient.Initialize(telemetry);
#if NET45
            Activity activity;
            Activity currentActivity = Activity.Current;

            // On .NET46 without profiler, outgoing requests are instrumented with reflection hook in DiagnosticSource
            //// see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs
            // it creates an Activity and injects standard 'Request-Id' and 'Correlation-Context' headers itself, so we should not start Activity in this case
            if (currentActivity != null && currentActivity.OperationName == "System.Net.Http.Desktop.HttpRequestOut")
            {
                activity = currentActivity;
            }
            else
            {
                // Every operation must have its own Activity
                // if dependency is tracked with profiler of event source, we need to generate a proper hierarchical Id for it
                // in case of HTTP it will be propagated into the requert header.
                // So, we will create a new Activity for the dependency, jut to generate an Id.
                activity = new Activity(DependencyActivityName);

                // This is workaround for the issue https://github.com/Microsoft/ApplicationInsights-dotnet/issues/538
                // if there is no parent Activity, ID Activity generates is not random enough to work well with
                // ApplicationInsights sampling algorithm
                // This code should go away when Activity is fixed: https://github.com/dotnet/corefx/issues/18418
                if (Activity.Current == null)
                {
                    activity.SetParentId(telemetry.Id);
                }

                //// end of workaround

                activity.Start();
                activity.Stop();
            }

            // telemetry is initialized from current Activity (root and parent Id, but not the Id)
            telemetry.Id = activity.Id;

            // set operation root Id in case there was no parent activity (e.g. HttpRequest in background thread)
            if (string.IsNullOrEmpty(telemetry.Context.Operation.Id))
            {
                telemetry.Context.Operation.Id = activity.RootId;
            }
#else
            // telemetry is initialized by Base SDK OperationCorrealtionTelemetryInitializer
            // however it does not know about Activity on .NET40 and does not know how to properly generate Ids
            // let's fix it
            telemetry.Id = ApplicationInsightsActivity.GenerateDependencyId(telemetry.Context.Operation.ParentId);
            telemetry.Context.Operation.Id = ApplicationInsightsActivity.GetRootId(telemetry.Id);
#endif
            PretendProfilerIsAttached = false;
            return(telemetry);
        }
        /// <summary>
        /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item.
        /// </summary>
        /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param>
        internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient)
        {
            var telemetry = new DependencyTelemetry();

            telemetry.Start();
            telemetryClient.Initialize(telemetry);
            PretendProfilerIsAttached = false;
            return(telemetry);
        }
コード例 #9
0
        public void OperationTelemetryStopComputesDurationAfterStart()
        {
            var telemetry = new DependencyTelemetry();

            telemetry.Start();
            Thread.Sleep(2000);
            Assert.Equal(TimeSpan.Zero, telemetry.Duration);
            telemetry.Stop();
            Assert.True(telemetry.Duration.TotalMilliseconds > 0);
        }
        public void OperationTelemetryStopDoesNotAffectTimeStampAndStartTimeAfterStart()
        {
            var telemetry = new DependencyTelemetry();

            telemetry.Start();
            DateTimeOffset actualTime = telemetry.Timestamp;

            telemetry.Stop();
            Assert.Equal(telemetry.Timestamp, actualTime);
        }
        public void OperationTelemetryStopWithTimestampComputesDurationAfterStartWithTimestamp()
        {
            var telemetry = new DependencyTelemetry();

            long startTime        = 123456789012345L;
            long ticksInOneSecond = Stopwatch.Frequency;
            long stopTime         = startTime + ticksInOneSecond;

            telemetry.Start(timestamp: startTime);
            telemetry.Stop(timestamp: stopTime);

            Assert.Equal(TimeSpan.FromSeconds(1), telemetry.Duration);
        }
コード例 #12
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            [Queue("control-queue-ai", Connection = "ConnectionString")] IAsyncCollector <Context> contexts,
            ILogger log)
        {
            log.LogInformation("Accept the request. Incoming request doesn't have correlation info.");
            var requestActivity = new Activity("ActivitySpike: HttpTrigger Request");
            var current         = Activity.Current; // You can refer the current Activity. That is automatically created by HttpTrigger.

            // No parent from the start
            requestActivity.Start();

            var requestTelemetry = new RequestTelemetry {
                Name = "ActivitySpike: HttpTrigger Request"
            };

            requestTelemetry.SetActivity(requestActivity);

            requestTelemetry.Start();

            requestTelemetry.Stop();
            client.Track(requestTelemetry);

            var dependencyActivity = new Activity("HttpTrigger Dependency Queue output");

            dependencyActivity.SetParentId(requestActivity.Id); // You can omit this code
            dependencyActivity.Start();
            var context = new Context()
            {
                ActivityId = dependencyActivity.Id,
                ParentId   = dependencyActivity.ParentId,
            };
            var dependencyTelemetry = new DependencyTelemetry {
                Name = "ActivitySpike:: Enqueue"
            };

            dependencyTelemetry.SetActivity(dependencyActivity);
            dependencyTelemetry.Start();
            client.StartOperation(requestTelemetry);

            await contexts.AddAsync(context);

            dependencyActivity.Stop();

            requestActivity.Stop();

            dependencyTelemetry.Stop();
            client.Track(dependencyTelemetry);

            return(new OkObjectResult($"Orchestration has been started."));
        }
コード例 #13
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            [Queue("control-queue-ai", Connection = "ConnectionString")] IAsyncCollector <TraceContext> contexts,
            ILogger log)
        {
            log.LogInformation("Accept the request. Incoming request doesn't have correlation info.");
            var requestActivity = new Activity("W3CActivitySpike: HttpTrigger Request");

            requestActivity.GenerateW3CContext();
            // No parent from the start
            requestActivity.Start();
            var requestTelemetry = new RequestTelemetry {
                Name = "W3CActivitySpike: HttpTrigger Request"
            };

            requestTelemetry.SetActivity(requestActivity);

            requestTelemetry.Start();

            requestTelemetry.Stop();
            client.Track(requestTelemetry);

            var dependencyActivity = new Activity("HttpTrigger Dependency Queue output");

            dependencyActivity.SetTraceparent(requestActivity.GetTraceparent());
            dependencyActivity.SetTracestate(requestActivity.GetTracestate());
            // dependencyActivity.SetParentId(requestActivity.Id); // maybe not necessary
            dependencyActivity.Start();
            var context = dependencyActivity.CreateTraceContext();

            var dependencyTelemetry = new DependencyTelemetry {
                Name = "W3CActivitySpike:: Enqueue"
            };

            dependencyTelemetry.SetActivity(dependencyActivity);
            dependencyTelemetry.Start();


            await contexts.AddAsync(context);

            dependencyActivity.Stop();

            requestActivity.Stop();

            dependencyTelemetry.Stop();
            client.Track(dependencyTelemetry);

            return(new OkObjectResult($"Orchestration has been started."));
        }
コード例 #14
0
        /// <summary>
        /// Create DependencyTelemetry from the Activity.
        /// </summary>
        /// <param name="context">TraceContext.</param>
        /// <returns>DependencyTelemetry.</returns>
        public static DependencyTelemetry CreateDependencyTelemetry(this TraceContextBase context)
        {
            var telemetry = new DependencyTelemetry {
                Name = context.OperationName
            };

            telemetry.Start();
            telemetry.Duration                   = context.Duration;
            telemetry.Timestamp                  = context.StartTime; // TimeStamp is the time of ending the Activity.
            telemetry.Id                         = context.TelemetryId;
            telemetry.Context.Operation.Id       = context.TelemetryContextOperationId;
            telemetry.Context.Operation.ParentId = context.TelemetryContextOperationParentId;

            return(telemetry);
        }
コード例 #15
0
        public static async Task ActivityFunction([QueueTrigger("work-item-queue-ai", Connection = "ConnectionString")] Context context,
                                                  [Queue("control-queue-ai", Connection = "ConnectionString")] IAsyncCollector <Context> contexts,
                                                  ILogger log)
        {
            log.LogInformation($"Activity Functions Started.");
            var requestActivity = new Activity("Activity Spike: Activity Function Request");

            requestActivity.SetParentId(context.ActivityId);
            requestActivity.Start();

            var requestTelemetry = new RequestTelemetry {
                Name = "Activity Spike: Activity Function Request"
            };

            requestTelemetry.SetActivity(requestActivity);

            requestTelemetry.Start();

            var dependencyActivity = new Activity("Activity FUnction Dependency");

            dependencyActivity.SetParentId(requestActivity.Id);  // You can omit this.
            dependencyActivity.Start();

            var dependencyTelemetry = new DependencyTelemetry {
                Name = "Activity Spike: Activity Function Dependency"
            };

            dependencyTelemetry.SetActivity(dependencyActivity);
            dependencyTelemetry.Start();

            var c = new Context()
            {
                ActivityId            = dependencyActivity.Id,
                ParentId              = dependencyActivity.ParentId,
                OrchestrationActivity = context.OrchestrationActivity,    // I skip the code for stack for the activity.
                Completed             = true
            };
            await contexts.AddAsync(c);

            dependencyActivity.Stop();
            dependencyTelemetry.Stop();
            client.Track(dependencyTelemetry);
            requestActivity.Stop();
            requestTelemetry.Stop();
            client.Track(requestTelemetry);
        }
 // telemetry implementation
 private DependencyTelemetry StartOpenTelemetry(String method)
 {
     try
     {
         var telemetry = new DependencyTelemetry();
         telemetry.Start();
         telemetry.Type   = DependencyConstants.WcfChannelOpen;
         telemetry.Target = RemoteAddress.Uri.Host;
         telemetry.Data   = RemoteAddress.Uri.ToString();
         telemetry.Name   = ChannelManager.OperationMap.ContractType.Name;
         return(telemetry);
     } catch (Exception ex)
     {
         WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
         return(null);
     }
 }
コード例 #17
0
        public async Task Run([TimerTrigger("*/15 * * * * *")] TimerInfo myTimer)
        {
            var dep = new DependencyTelemetry()
            {
                Name = "Dependency Test",
                Type = "Test",
                Data = "C# Timer trigger function executed"
            };

            dep.Start();

            await Task.Delay(3000);

            dep.Stop();
            _telemetryClient.TrackDependency(dep);

            _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        }
コード例 #18
0
        public static async Task ActivityFunction([QueueTrigger("work-item-queue-ai", Connection = "ConnectionString")] TraceContext traceContext,
                                                  [Queue("control-queue-ai", Connection = "ConnectionString")] IAsyncCollector <TraceContext> contexts,
                                                  ILogger log)
        {
            log.LogInformation($"W3CActivity Functions Started.");
            var requestActivity = new Activity("W3CActivity Spike: Activity Function Request");

            requestActivity.SetParentAndStart(traceContext);

            var requestTelemetry = new RequestTelemetry {
                Name = "W3CActivity Spike: Activity Function Request"
            };

            requestTelemetry.SetActivity(requestActivity);

            requestTelemetry.Start();

            var dependencyActivity = new Activity("W3CActivity FUnction Dependency");

            dependencyActivity.SetParentAndStart(requestActivity);

            var dependencyTelemetry = new DependencyTelemetry {
                Name = "W3CActivity Spike: Activity Function Dependency"
            };

            dependencyTelemetry.SetActivity(dependencyActivity);
            dependencyTelemetry.Start();
            var c = dependencyActivity.CreateTraceContext();

            c.OrchestrationContexts = traceContext.OrchestrationContexts;
            c.Completed             = true;

            await contexts.AddAsync(c);

            dependencyActivity.Stop();
            dependencyTelemetry.Stop();
            client.Track(dependencyTelemetry);
            requestActivity.Stop();
            requestTelemetry.Stop();
            client.Track(requestTelemetry);
        }
        private static void InitializeTelemetry(DependencyTelemetry telemetry, Guid operationId, long timestamp)
        {
            telemetry.Start(timestamp);

            var activity = Activity.Current;

            if (activity != null)
            {
                // SQL Client does NOT create Activity.
                // We initialize SQL dependency using Activity from incoming Request
                // and it is the parent of the SQL dependency

                if (activity.IdFormat == ActivityIdFormat.W3C)
                {
                    var traceId = activity.TraceId.ToHexString();
                    telemetry.Context.Operation.Id       = traceId;
                    telemetry.Context.Operation.ParentId = W3CUtilities.FormatTelemetryId(traceId, activity.SpanId.ToHexString());
                }
                else
                {
                    telemetry.Context.Operation.Id       = activity.RootId;
                    telemetry.Context.Operation.ParentId = activity.Id;
                }

                foreach (var item in activity.Baggage)
                {
                    if (!telemetry.Properties.ContainsKey(item.Key))
                    {
                        telemetry.Properties[item.Key] = item.Value;
                    }
                }
            }
            else
            {
                telemetry.Context.Operation.Id = operationId.ToStringInvariant("N");
            }
        }
コード例 #20
0
        private static void InitializeTelemetry(DependencyTelemetry telemetry, Guid operationId, long timestamp)
        {
            telemetry.Start(timestamp);

            var activity = Activity.Current;

            if (activity != null)
            {
                telemetry.Context.Operation.Id       = activity.RootId;
                telemetry.Context.Operation.ParentId = activity.ParentId;

                foreach (var item in activity.Baggage)
                {
                    if (!telemetry.Properties.ContainsKey(item.Key))
                    {
                        telemetry.Properties[item.Key] = item.Value;
                    }
                }
            }
            else
            {
                telemetry.Context.Operation.Id = operationId.ToString("N");
            }
        }
コード例 #21
0
        /// <summary>
        /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item.
        /// </summary>
        /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param>
        internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient)
        {
            var telemetry = new DependencyTelemetry();

            telemetry.Start();
            Activity activity;
            Activity currentActivity = Activity.Current;

            // On .NET46 without profiler, outgoing requests are instrumented with reflection hook in DiagnosticSource
            //// see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs
            // it creates an Activity and injects standard 'Request-Id' and 'Correlation-Context' headers itself, so we should not start Activity in this case
            if (currentActivity != null && currentActivity.OperationName == "System.Net.Http.Desktop.HttpRequestOut")
            {
                activity = currentActivity;

                // OperationCorrelationTelemetryInitializer will initialize telemetry as a child of current activity:
                // But we need to initialize dependency telemetry from the current Activity:
                // Activity was created for this dependency in the Http Desktop DiagnosticSource
                var context = telemetry.Context;
                context.Operation.Id       = activity.RootId;
                context.Operation.ParentId = activity.ParentId;
                foreach (var item in activity.Baggage)
                {
                    if (!telemetry.Properties.ContainsKey(item.Key))
                    {
                        telemetry.Properties.Add(item);
                    }
                }

                telemetryClient.Initialize(telemetry);
            }
            else
            {
                telemetryClient.Initialize(telemetry);

                // Every operation must have its own Activity
                // if dependency is tracked with profiler of event source, we need to generate a proper Id for it
                // in case of HTTP it will be propagated into the requert header.
                // So, we will create a new Activity for the dependency, just to generate an Id.
                activity = new Activity(DependencyActivityName);

                // As a first step in supporting W3C protocol in ApplicationInsights,
                // we want to generate Activity Ids in the W3C compatible format.
                // While .NET changes to Activity are pending, we want to ensure trace starts with W3C compatible Id
                // as early as possible, so that everyone has a chance to upgrade and have compatibility with W3C systems once they arrive.
                // So if there is no parent Activity (i.e. this request has happened in the background, without parent scope), we'll override
                // the current Activity with the one with properly formatted Id. This workaround should go away
                // with W3C support on .NET https://github.com/dotnet/corefx/issues/30331 (TODO)
                if (currentActivity == null)
                {
                    activity.SetParentId(StringUtilities.GenerateTraceId());
                }

                // end of workaround

                activity.Start();
            }

            // telemetry is initialized from current Activity (root and parent Id, but not the Id)
            telemetry.Id = activity.Id;

            // set operation root Id in case there was no parent activity (e.g. HttpRequest in background thread)
            if (string.IsNullOrEmpty(telemetry.Context.Operation.Id))
            {
                telemetry.Context.Operation.Id = activity.RootId;
            }

#pragma warning disable 612, 618
            if (IsW3CEnabled)
            {
                W3COperationCorrelationTelemetryInitializer.UpdateTelemetry(telemetry, activity, true);
            }
#pragma warning restore 612, 618

            PretendProfilerIsAttached = false;
            return(telemetry);
        }
コード例 #22
0
        public static async Task Orchestrator([QueueTrigger("control-queue-ai", Connection = "ConnectionString")] Context context,
                                              [Queue("work-item-queue-ai", Connection = "ConnectionString")] IAsyncCollector <Context> contexts,
                                              ILogger log)
        {
            log.LogInformation($"Orchestration Started.");
            Activity requestActivity = null;

            if (context.OrchestrationActivity == null) // In case of the initial execution.
            {
                requestActivity = new Activity("Activity Spike: Orchestration Request");
                requestActivity.SetParentId(context.ActivityId);
            }
            else
            {
                requestActivity = new Activity("Activity Spike: Orchestration Request");
                // After Activity.SetParentId then Start the actvitiy, it will create a new Id. However, it is not Identical as the last execution.
                // This is necessary. Or directly set from SubsetActivity. This is not recommended. However, there is no way for this protocol.
                var property = typeof(Activity).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance);
                property.SetValue(requestActivity, context.OrchestrationActivity.ActivityId);
                requestActivity.SetParentId(context.OrchestrationActivity.ParentId);
            }

            requestActivity.Start();
            var subsetActivity = new SubsetActivity()
            {
                ActivityId = requestActivity.Id,
                ParentId   = requestActivity.ParentId,
                RootId     = requestActivity.RootId
            };
            var requestTelemetry = new RequestTelemetry {
                Name = "Activity Spike: Ochestration Result"
            };

            if (context.OrchestrationActivity == null)
            {
                requestTelemetry.SetActivity(requestActivity);
            }
            else
            {
                requestTelemetry.Id = context.OrchestrationActivity.ActivityId;
                requestTelemetry.Context.Operation.Id       = context.OrchestrationActivity.RootId;
                requestTelemetry.Context.Operation.ParentId = context.OrchestrationActivity.ParentId;
            }

            requestTelemetry.Start();
            // Only the last execution, we track it.
            var dependencyActivity = new Activity("Activity Spike: Orchestration Dependency");

            dependencyActivity.SetParentId(requestActivity.Id); // You can omit this.
            dependencyActivity.Start();

            var dependencyTelemetry = new DependencyTelemetry {
                Name = "Activity Spike: Orchestration Dependency"
            };

            dependencyTelemetry.SetActivity(dependencyActivity);

            dependencyTelemetry.Start();

            var c = new Context()
            {
                ActivityId            = requestActivity.Id,
                ParentId              = requestActivity.ParentId,
                OrchestrationActivity = subsetActivity
            };


            dependencyActivity.Stop();
            dependencyTelemetry.Stop();

            if (context.Completed)
            {
                client.Track(dependencyTelemetry);
            }
            else
            {
                await contexts.AddAsync(c);

                // We don't need to emit telemetry for intermediate execution.
            }

            requestActivity.Stop();

            requestTelemetry.Stop();
            if (context.OrchestrationActivity == null) // In case of the initial execution.
            {
                client.Track(requestTelemetry);
            }
        }
コード例 #23
0
        public static async Task Orchestrator([QueueTrigger("control-queue-ai", Connection = "ConnectionString")]
                                              TraceContext traceContext,
                                              [Queue("work-item-queue-ai", Connection = "ConnectionString")]
                                              IAsyncCollector <TraceContext> contexts,
                                              ILogger log)
        {
            log.LogInformation($"Orchestration Started.");
            Activity requestActivity = null;
            var      isReplay        = traceContext.OrchestrationContexts.Count != 0;

            if (!isReplay)
            {
                requestActivity = new Activity("W3CActivity Spike: Orchestration Request");
                requestActivity.SetParentAndStart(traceContext);

                var requestTelemetry = new RequestTelemetry {
                    Name = "W3CActivity Spike: Orchestration Request"
                };
                requestTelemetry.SetActivity(requestActivity);

                requestTelemetry.Start();

                requestActivity.Stop();

                requestTelemetry.Stop();
                client.Track(requestTelemetry);
            }

            TraceContext c = null;

            if (!isReplay)
            {
                c = requestActivity.CreateTraceContext();
                c.OrchestrationContexts = traceContext.OrchestrationContexts;
                c.OrchestrationContexts.Push(requestActivity.CreateTraceContext());
            }
            else
            {
                c = traceContext.OrchestrationContexts.Peek(); // if necessary. This program doesn't need it.
            }



            if (traceContext.Completed)
            {
                var dependencyActivity = new Activity("W3CActivity Spike: Orchestration Dependency");
                dependencyActivity.SetParentAndStart(traceContext.OrchestrationContexts.Peek());
                var dependencyTelemetry = new DependencyTelemetry {
                    Name = "W3CActivity Spike: Orchestration Dependency"
                };
                dependencyTelemetry.SetActivity(dependencyActivity);

                dependencyTelemetry.Start();
                dependencyActivity.Stop();
                dependencyTelemetry.Stop();

                client.Track(dependencyTelemetry);
            }
            else
            {
                await contexts.AddAsync(c);

                // We don't need to emit telemetry for intermediate execution.
            }
        }