예제 #1
0
        public void SendEventToValidateEndpoint()
        {
            EventTelemetry              telemetry1  = new EventTelemetry();
            MetricTelemetry             telemetry2  = new MetricTelemetry();
            DependencyTelemetry         telemetry3  = new DependencyTelemetry();
            ExceptionTelemetry          telemetry4  = new ExceptionTelemetry();
            MetricTelemetry             telemetry5  = new MetricTelemetry();
            PageViewTelemetry           telemetry6  = new PageViewTelemetry();
            PerformanceCounterTelemetry telemetry7  = new PerformanceCounterTelemetry();
            RequestTelemetry            telemetry8  = new RequestTelemetry();
            SessionStateTelemetry       telemetry9  = new SessionStateTelemetry();
            TraceTelemetry              telemetry10 = new TraceTelemetry();

            var telemetryItems = new List <ITelemetry>
            {
                telemetry1,
                telemetry2,
                telemetry3,
                telemetry4,
                telemetry5,
                telemetry6,
                telemetry7,
                telemetry8,
                telemetry9,
                telemetry10
            };

            // ChuckNorrisTeamUnitTests resource in Prototypes5
            var config = new TelemetryConfiguration {
                InstrumentationKey = "fafa4b10-03d3-4bb0-98f4-364f0bdf5df8"
            };
            var telemetryClient = new TelemetryClient(config);

            telemetryClient.Initialize(telemetry1);
            telemetryClient.Initialize(telemetry2);
            telemetryClient.Initialize(telemetry3);
            telemetryClient.Initialize(telemetry4);
            telemetryClient.Initialize(telemetry5);
            telemetryClient.Initialize(telemetry6);
            telemetryClient.Initialize(telemetry7);
            telemetryClient.Initialize(telemetry8);
            telemetryClient.Initialize(telemetry9);
            telemetryClient.Initialize(telemetry10);

            string json = JsonSerializer.SerializeAsString(telemetryItems);

            HttpClient client = new HttpClient();
            var        result = client.PostAsync(
                "https://dc.services.visualstudio.com/v2/validate",
                new ByteArrayContent(Encoding.UTF8.GetBytes(json))).GetAwaiter().GetResult();

            if (result.StatusCode != HttpStatusCode.OK)
            {
                var response = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                Trace.WriteLine(response);
            }

            Assert.Equal(HttpStatusCode.OK, result.StatusCode);
        }
예제 #2
0
        /// <summary>
        /// Creates an operation object with a respective telemetry item using <see cref="Activity"/> instance that holds tracing context. 
        /// </summary>
        /// <example>
        /// <code>
        ///   // receive message from a queue service (or any kind of the request/message from external service)
        ///   var message = queue.Receive();
        /// 
        ///   // Extract tracing context from the message before processing it
        ///   // Note that some protocols may define how Activity should be serialized into the message,
        ///   // and some client SDKs implementing them may provide Extract method.
        ///   // For other protocols/libraries, serialization has to be agreed between producer and consumer
        ///   // and Inject/Extract pattern to be implemented
        ///   var activity = message.ExtractActivity();
        /// 
        ///   // Track processing of the message
        ///   using (telemetryClient.StartOperation&lt;RequestTelemetry&gt;(activity))
        ///   {
        ///     // process message
        ///   }
        ///  // telemetry is reported when operation is disposed.
        /// </code>
        /// </example>
        /// <remarks><para>Activity represents tracing context; it contains correlation identifiers and extended properties that are propagated to external calls.
        /// See <a href="https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/ActivityUserGuide.md"/> for more details.</para>
        /// <para>When Activity instance is passed to StartOperation, it is expected that Activity has ParentId (if it was provided by upstream service), but has not been started yet.
        /// It may also have additional Tags and Baggage to augment telemetry.</para>
        /// </remarks>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="activity">Activity to get tracing context and telemetry properties from.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder<T> StartOperation<T>(this TelemetryClient telemetryClient, Activity activity) where T : OperationTelemetry, new()
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException(nameof(telemetryClient));
            }

            if (activity == null)
            {
                throw new ArgumentNullException(nameof(activity));
            }

            activity.Start();
            T operationTelemetry = ActivityToTelemetry<T>(activity);

            // We initialize telemetry here AND in Track method because of RichPayloadEventSource.
            // It sends Start and Stop events for OperationTelemetry. During Start event telemetry
            // has to contain essential telemetry properties such as correlations ids and ikey.
            // Also, examples in our documentation rely on the fact that correlation Ids are set
            // after StartOperation call and before operation is stopped.
            // Before removing this call (for optimization), make sure:
            // 1) correlation ids are set before method leaves
            // 2) RichPayloadEventSource is re-factored to work without ikey in Start event (or ikey is set)
            //    and does not require other properties in telemetry
            telemetryClient.Initialize(operationTelemetry);

            operationTelemetry.Start();

            return new OperationHolder<T>(telemetryClient, operationTelemetry);
        }
예제 #3
0
        /// <summary>
        /// Creates an operation object with a given telemetry item.
        /// </summary>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="operationTelemetry">Operation to start.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder <T> StartOperation <T>(this TelemetryClient telemetryClient, T operationTelemetry) where T : OperationTelemetry
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException("Telemetry client cannot be null.");
            }

            if (operationTelemetry == null)
            {
                throw new ArgumentNullException("operationTelemetry cannot be null.");
            }

            var operationHolder = new AsyncLocalBasedOperationHolder <T>(telemetryClient, operationTelemetry)
            {
                // Parent context store is assigned to operation that is used to restore call context.
                ParentContext = AsyncLocalHelpers.GetCurrentOperationContext()
            };

            telemetryClient.Initialize(operationTelemetry);

            // Initialize operation id if it wasn't initialized by telemetry initializers
            if (string.IsNullOrEmpty(operationTelemetry.Id))
            {
                operationTelemetry.GenerateOperationId();
            }

            // If the operation is not executing in the context of any other operation
            // set its name and id as a context (root) operation name and id
            if (string.IsNullOrEmpty(operationTelemetry.Context.Operation.Id))
            {
                operationTelemetry.Context.Operation.Id = operationTelemetry.Id;
            }

            if (string.IsNullOrEmpty(operationTelemetry.Context.Operation.Name))
            {
                operationTelemetry.Context.Operation.Name = operationTelemetry.Name;
            }

            operationTelemetry.Start();

            // Update the call context to store certain fields that can be used for subsequent operations.
            var operationContext = new OperationContextForAsyncLocal();

            operationContext.ParentOperationId = operationTelemetry.Id;
            operationContext.RootOperationId   = operationTelemetry.Context.Operation.Id;
            operationContext.RootOperationName = operationTelemetry.Context.Operation.Name;
            AsyncLocalHelpers.SaveOperationContext(operationContext);

            return(operationHolder);
        }
예제 #4
0
        /// <summary>
        /// Start operation creates an operation object with a respective telemetry item.
        /// </summary>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="operationName">Name of the operation that customer is planning to propagate.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder <T> StartOperation <T>(this TelemetryClient telemetryClient, string operationName) where T : OperationTelemetry, new()
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException("Telemetry client cannot be null.");
            }

            var operation = new CallContextBasedOperationHolder <T>(telemetryClient, new T());

            operation.Telemetry.Start();

            // Parent context store is assigned to operation that is used to restore call context.
            operation.ParentContext = CallContextHelpers.GetCurrentOperationContext();

            if (string.IsNullOrEmpty(operation.Telemetry.Name) && !string.IsNullOrEmpty(operationName))
            {
                operation.Telemetry.Name = operationName;
            }

            telemetryClient.Initialize(operation.Telemetry);

            // Initialize operation id if it wasn't initialized by telemetry initializers
            if (string.IsNullOrEmpty(operation.Telemetry.Id))
            {
                operation.Telemetry.GenerateOperationId();
            }

            // If operation do not executes in a context of any other operaiton -
            // set it's name and id as a context (root) operation name and id
            if (string.IsNullOrEmpty(operation.Telemetry.Context.Operation.Id))
            {
                operation.Telemetry.Context.Operation.Id = operation.Telemetry.Id;
            }

            if (string.IsNullOrEmpty(operation.Telemetry.Context.Operation.Name))
            {
                operation.Telemetry.Context.Operation.Name = operation.Telemetry.Name;
            }

            // Update the call context to store certain fields that can be used for subsequent operations.
            var operationContext = new OperationContextForCallContext();

            operationContext.ParentOperationId = operation.Telemetry.Id;
            operationContext.RootOperationId   = operation.Telemetry.Context.Operation.Id;
            operationContext.RootOperationName = operation.Telemetry.Context.Operation.Name;
            CallContextHelpers.SaveOperationContext(operationContext);

            return(operation);
        }
예제 #5
0
        /// <summary>
        /// Creates an operation object with a given telemetry item.
        /// </summary>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="operationTelemetry">Operation to start.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder <T> StartOperation <T>(this TelemetryClient telemetryClient, T operationTelemetry) where T : OperationTelemetry
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException("Telemetry client cannot be null.");
            }

            if (operationTelemetry == null)
            {
                throw new ArgumentNullException("operationTelemetry cannot be null.");
            }

            telemetryClient.Initialize(operationTelemetry);

            var telemetryContext = operationTelemetry.Context.Operation;

            // Initialize operation id if it wasn't initialized by telemetry initializers
            if (string.IsNullOrEmpty(operationTelemetry.Id))
            {
                operationTelemetry.GenerateOperationId();
            }

            // If the operation is not executing in the context of any other operation
            // set its name and id as a context (root) operation name and id
            if (string.IsNullOrEmpty(telemetryContext.Id))
            {
                telemetryContext.Id = operationTelemetry.Id;
            }

            if (string.IsNullOrEmpty(telemetryContext.Name))
            {
                telemetryContext.Name = operationTelemetry.Name;
            }

            bool isActivityAvailable = false;

            isActivityAvailable = ActivityExtensions.TryRun(() =>
            {
                var parentActivity    = Activity.Current;
                var operationActivity = new Activity(ChildActivityName);

                string operationName = telemetryContext.Name;
                if (string.IsNullOrEmpty(operationName))
                {
                    operationName = parentActivity?.GetOperationName();
                }

                if (!string.IsNullOrEmpty(operationName))
                {
                    operationActivity.SetOperationName(operationName);
                }

                if (parentActivity == null)
                {
                    // telemetryContext.Id is always set: if it was null, it is set to opTelemetry.Id and opTelemetry.Id is never null
                    operationActivity.SetParentId(telemetryContext.Id);
                }

                operationActivity.Start();
                operationTelemetry.Id = operationActivity.Id;
            });

            var operationHolder = new OperationHolder <T>(telemetryClient, operationTelemetry);

            if (!isActivityAvailable)
            {
                // Parent context store is assigned to operation that is used to restore call context.
                operationHolder.ParentContext = CallContextHelpers.GetCurrentOperationContext();
            }

            operationTelemetry.Start();

            if (!isActivityAvailable)
            {
                // Update the call context to store certain fields that can be used for subsequent operations.
                var operationContext = new OperationContextForCallContext
                {
                    ParentOperationId = operationTelemetry.Id,
                    RootOperationId   = operationTelemetry.Context.Operation.Id,
                    RootOperationName = operationTelemetry.Context.Operation.Name
                };
                CallContextHelpers.SaveOperationContext(operationContext);
            }

            return(operationHolder);
        }
예제 #6
0
        /// <summary>
        /// Creates an operation object with a given telemetry item. 
        /// </summary>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="operationTelemetry">Operation to start.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder<T> StartOperation<T>(this TelemetryClient telemetryClient, T operationTelemetry) where T : OperationTelemetry
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException(nameof(telemetryClient));
            }

            if (operationTelemetry == null)
            {
                throw new ArgumentNullException(nameof(operationTelemetry));
            }

            // We initialize telemetry here AND in Track method because of RichPayloadEventSource.
            // It sends Start and Stop events for OperationTelemetry. During Start event telemetry
            // has to contain essential telemetry properties such as correlations ids and ikey.
            // Also, examples in our documentation rely on the fact that correlation Ids are set
            // after StartOperation call and before operation is stopped.
            // Before removing this call (for optimization), make sure:
            // 1) correlation ids are set before method leaves
            // 2) RichPayloadEventSource is re-factored to work without ikey in Start event (or ikey is set)
            //    and does not require other properties in telemetry
            telemetryClient.Initialize(operationTelemetry);

            var telemetryContext = operationTelemetry.Context.Operation;

            // Initialize operation id if it wasn't initialized by telemetry initializers
            if (string.IsNullOrEmpty(operationTelemetry.Id))
            {
                operationTelemetry.GenerateOperationId();
            }

            // If the operation is not executing in the context of any other operation
            // set its name and id as a context (root) operation name and id
            if (string.IsNullOrEmpty(telemetryContext.Id))
            {
                telemetryContext.Id = operationTelemetry.Id;
            }

            if (string.IsNullOrEmpty(telemetryContext.Name))
            {
                telemetryContext.Name = operationTelemetry.Name;
            }

            bool isActivityAvailable = false;

            isActivityAvailable = ActivityExtensions.TryRun(() =>
            {
                var parentActivity = Activity.Current;
                var operationActivity = new Activity(ChildActivityName);

                string operationName = telemetryContext.Name;
                if (string.IsNullOrEmpty(operationName))
                {
                    operationName = parentActivity?.GetOperationName();
                }

                if (!string.IsNullOrEmpty(operationName))
                {
                    operationActivity.SetOperationName(operationName);
                }

                if (parentActivity == null)
                {
                    // telemetryContext.Id is always set: if it was null, it is set to opTelemetry.Id and opTelemetry.Id is never null
                    operationActivity.SetParentId(telemetryContext.Id);
                }

                operationActivity.Start();
                operationTelemetry.Id = operationActivity.Id;
            });

            var operationHolder = new OperationHolder<T>(telemetryClient, operationTelemetry);
            if (!isActivityAvailable)
            {
                // Parent context store is assigned to operation that is used to restore call context.
                operationHolder.ParentContext = CallContextHelpers.GetCurrentOperationContext();
            }

            operationTelemetry.Start();

            if (!isActivityAvailable)
            {
                // Update the call context to store certain fields that can be used for subsequent operations.
                var operationContext = new OperationContextForCallContext
                {
                    ParentOperationId = operationTelemetry.Id,
                    RootOperationId = operationTelemetry.Context.Operation.Id,
                    RootOperationName = operationTelemetry.Context.Operation.Name
                };
                CallContextHelpers.SaveOperationContext(operationContext);
            }

            return operationHolder;
        }
        public void SendEventToValidateEndpoint()
        {
            string unicodeString = "русский\\#/\x0000\x0001\x0002\x0003\x0004\x0005\x0006\x0007\x0008\x009Farabicشلاؤيثبلاهتنمةىخحضقسفعشلاؤيصثبل c\n\r\t";

            EventTelemetry      telemetry1 = new EventTelemetry(unicodeString);
            MetricTelemetry     telemetry2 = new MetricTelemetry("name", 100);
            DependencyTelemetry telemetry3 = new DependencyTelemetry("name", "commandName", DateTimeOffset.UtcNow, TimeSpan.FromHours(3), true);
            ExceptionTelemetry  telemetry4 = new ExceptionTelemetry(new ArgumentException("Test"));
            MetricTelemetry     telemetry5 = new MetricTelemetry("name", 100);
            PageViewTelemetry   telemetry6 = new PageViewTelemetry("name");

#pragma warning disable 618
            PerformanceCounterTelemetry telemetry7 = new PerformanceCounterTelemetry("category", "name", "instance", 100);
#pragma warning restore 618
            RequestTelemetry telemetry8 = new RequestTelemetry("name", DateTimeOffset.UtcNow, TimeSpan.FromHours(2), "200", true);
#pragma warning disable 618
            SessionStateTelemetry telemetry9 = new SessionStateTelemetry(SessionState.Start);
#pragma warning restore 618
            TraceTelemetry        telemetry10 = new TraceTelemetry("text");
            AvailabilityTelemetry telemetry11 = new AvailabilityTelemetry("name", DateTimeOffset.UtcNow, TimeSpan.FromHours(10), "location", true, "message");

            var telemetryItems = new List <ITelemetry>
            {
                telemetry1,
                telemetry2,
                telemetry3,
                telemetry4,
                telemetry5,
                telemetry6,
                telemetry7,
                telemetry8,
                telemetry9,
                telemetry10,
                telemetry11
            };

            // ChuckNorrisTeamUnitTests resource in Prototypes5
            var config          = new TelemetryConfiguration("fafa4b10-03d3-4bb0-98f4-364f0bdf5df8");
            var telemetryClient = new TelemetryClient(config);
            telemetryClient.Context.Properties.Add(unicodeString, unicodeString);

            telemetryClient.Initialize(telemetry1);
            telemetryClient.Initialize(telemetry2);
            telemetryClient.Initialize(telemetry3);
            telemetryClient.Initialize(telemetry4);
            telemetryClient.Initialize(telemetry5);
            telemetryClient.Initialize(telemetry6);
            telemetryClient.Initialize(telemetry7);
            telemetryClient.Initialize(telemetry8);
            telemetryClient.Initialize(telemetry9);
            telemetryClient.Initialize(telemetry10);
            telemetryClient.Initialize(telemetry11);

            string json = JsonSerializer.SerializeAsString(telemetryItems);

            HttpClient client = new HttpClient();
            var        result = client.PostAsync(
                "https://dc.services.visualstudio.com/v2/validate",
                new ByteArrayContent(Encoding.UTF8.GetBytes(json))).GetAwaiter().GetResult();

            if (result.StatusCode != HttpStatusCode.OK)
            {
                var response = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                Trace.WriteLine(response);
            }

            Assert.Equal(HttpStatusCode.OK, result.StatusCode);
        }
        /// <summary>
        /// Creates an operation object with a respective telemetry item using <see cref="Activity"/> instance that holds tracing context.
        /// </summary>
        /// <example>
        /// <code>
        ///   // receive message from a queue service (or any kind of the request/message from external service)
        ///   var message = queue.Receive();
        ///
        ///   // Extract tracing context from the message before processing it
        ///   // Note that some protocols may define how Activity should be serialized into the message,
        ///   // and some client SDKs implementing them may provide Extract method.
        ///   // For other protocols/libraries, serialization has to be agreed between producer and consumer
        ///   // and Inject/Extract pattern to be implemented
        ///   var activity = message.ExtractActivity();
        ///
        ///   // Track processing of the message
        ///   using (telemetryClient.StartOperation&lt;RequestTelemetry&gt;(activity))
        ///   {
        ///     // process message
        ///   }
        ///  // telemetry is reported when operation is disposed.
        /// </code>
        /// </example>
        /// <remarks><para>Activity represents tracing context; it contains correlation identifiers and extended properties that are propagated to external calls.
        /// See <a href="https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/ActivityUserGuide.md"/> for more details.</para>
        /// <para>When Activity instance is passed to StartOperation, it is expected that Activity has ParentId (if it was provided by upstream service), but has not been started yet.
        /// It may also have additional Tags and Baggage to augment telemetry.</para>
        /// </remarks>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="activity">Activity to get tracing context and telemetry properties from.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder <T> StartOperation <T>(this TelemetryClient telemetryClient, Activity activity) where T : OperationTelemetry, new()
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException(nameof(telemetryClient));
            }

            if (activity == null)
            {
                throw new ArgumentNullException(nameof(activity));
            }

            Activity originalActivity = null;

            // not started activity, default case
            if (activity.Id == null)
            {
                originalActivity = Activity.Current;
            }

            string legacyRoot   = null;
            string legacyParent = null;

            if (Activity.DefaultIdFormat == ActivityIdFormat.W3C)
            {
                // if parent is not  W3C
                if (activity.ParentId != null &&
                    !activity.ParentId.StartsWith("00-", StringComparison.Ordinal))
                {
                    // save parent
                    legacyParent = activity.ParentId;

                    if (W3CUtilities.IsCompatibleW3CTraceId(activity.RootId))
                    {
                        // reuse root id when compatible with trace ID
                        activity = CopyFromCompatibleRoot(activity);
                    }
                    else
                    {
                        // or store legacy root in custom property
                        legacyRoot = activity.RootId;
                    }
                }
            }

            activity.Start();
            T operationTelemetry = ActivityToTelemetry <T>(activity);

            if (legacyRoot != null)
            {
                operationTelemetry.Properties.Add(W3CConstants.LegacyRootIdProperty, legacyRoot);
            }

            if (legacyParent != null)
            {
                operationTelemetry.Context.Operation.ParentId = legacyParent;
            }

            // We initialize telemetry here AND in Track method because of RichPayloadEventSource.
            // It sends Start and Stop events for OperationTelemetry. During Start event telemetry
            // has to contain essential telemetry properties such as correlations ids and ikey.
            // Also, examples in our documentation rely on the fact that correlation Ids are set
            // after StartOperation call and before operation is stopped.
            // Before removing this call (for optimization), make sure:
            // 1) correlation ids are set before method leaves
            // 2) RichPayloadEventSource is re-factored to work without ikey in Start event (or ikey is set)
            //    and does not require other properties in telemetry
            telemetryClient.Initialize(operationTelemetry);

            operationTelemetry.Start();

            return(new OperationHolder <T>(telemetryClient, operationTelemetry, originalActivity));
        }
        /// <summary>
        /// Creates an operation object with a given telemetry item.
        /// </summary>
        /// <typeparam name="T">Type of the telemetry item.</typeparam>
        /// <param name="telemetryClient">Telemetry client object.</param>
        /// <param name="operationTelemetry">Operation to start.</param>
        /// <returns>Operation item object with a new telemetry item having current start time and timestamp.</returns>
        public static IOperationHolder <T> StartOperation <T>(this TelemetryClient telemetryClient, T operationTelemetry) where T : OperationTelemetry
        {
            if (telemetryClient == null)
            {
                throw new ArgumentNullException(nameof(telemetryClient));
            }

            if (operationTelemetry == null)
            {
                throw new ArgumentNullException(nameof(operationTelemetry));
            }

            var  telemetryContext  = operationTelemetry.Context.Operation;
            bool idsAssignedByUser = !string.IsNullOrEmpty(telemetryContext.Id);

            // We initialize telemetry here AND in Track method because of RichPayloadEventSource.
            // It sends Start and Stop events for OperationTelemetry. During Start event telemetry
            // has to contain essential telemetry properties such as correlations ids and ikey.
            // Also, examples in our documentation rely on the fact that correlation Ids are set
            // after StartOperation call and before operation is stopped.
            // Before removing this call (for optimization), make sure:
            // 1) correlation ids are set before method leaves
            // 2) RichPayloadEventSource is re-factored to work without ikey in Start event (or ikey is set)
            //    and does not require other properties in telemetry
            telemetryClient.Initialize(operationTelemetry);

            // Initialize operation id if it wasn't initialized by telemetry initializers
            if (string.IsNullOrEmpty(operationTelemetry.Id))
            {
                operationTelemetry.GenerateOperationId();
            }

            // If the operation is not executing in the context of any other operation
            // set its name as a context (root) operation name.
            if (string.IsNullOrEmpty(telemetryContext.Name))
            {
                telemetryContext.Name = operationTelemetry.Name;
            }

            OperationHolder <T> operationHolder = null;

            var isActivityAvailable = ActivityExtensions.TryRun(() =>
            {
                var parentActivity    = Activity.Current;
                var operationActivity = new Activity(ChildActivityName);

                string operationName = telemetryContext.Name;
                if (string.IsNullOrEmpty(operationName))
                {
                    operationName = parentActivity?.GetOperationName();
                }

                if (!string.IsNullOrEmpty(operationName))
                {
                    operationActivity.SetOperationName(operationName);
                }

                if (idsAssignedByUser)
                {
                    if (Activity.DefaultIdFormat == ActivityIdFormat.W3C)
                    {
                        if (W3CUtilities.IsCompatibleW3CTraceId(telemetryContext.Id))
                        {
                            // If the user provided operationId is W3C Compatible, use it.
                            operationActivity.SetParentId(ActivityTraceId.CreateFromString(telemetryContext.Id.AsSpan()),
                                                          default(ActivitySpanId), ActivityTraceFlags.None);
                        }
                        else
                        {
                            // If user provided operationId is not W3C compatible, generate a new one instead.
                            // and store supplied value inside custom property.
                            operationTelemetry.Properties.Add(W3CConstants.LegacyRootIdProperty, telemetryContext.Id);
                            telemetryContext.Id = null;
                        }
                    }
                    else
                    {
                        operationActivity.SetParentId(telemetryContext.Id);
                    }
                }

                operationActivity.Start();

                if (operationActivity.IdFormat == ActivityIdFormat.W3C)
                {
                    if (string.IsNullOrEmpty(telemetryContext.Id))
                    {
                        telemetryContext.Id = operationActivity.TraceId.ToHexString();
                    }

                    // ID takes the form |TraceID.SpanId.
                    // TelemetryContext.Id used instead of TraceID.ToHexString() for perf.
                    operationTelemetry.Id = W3CUtilities.FormatTelemetryId(telemetryContext.Id, operationActivity.SpanId.ToHexString());
                }
                else
                {
                    if (string.IsNullOrEmpty(telemetryContext.Id))
                    {
                        telemetryContext.Id = operationActivity.RootId;
                    }

                    operationTelemetry.Id = operationActivity.Id;
                }

                operationHolder = new OperationHolder <T>(telemetryClient, operationTelemetry, parentActivity == operationActivity.Parent ? null : parentActivity);
            });

            if (!isActivityAvailable)
            {
                // Parent context store is assigned to operation that is used to restore call context.
                operationHolder = new OperationHolder <T>(telemetryClient, operationTelemetry)
                {
                    ParentContext = CallContextHelpers.GetCurrentOperationContext(),
                };
                telemetryContext.Id = operationTelemetry.Id;
            }

            operationTelemetry.Start();

            if (!isActivityAvailable)
            {
                // Update the call context to store certain fields that can be used for subsequent operations.
                var operationContext = new OperationContextForCallContext
                {
                    ParentOperationId = operationTelemetry.Id,
                    RootOperationId   = operationTelemetry.Context.Operation.Id,
                    RootOperationName = operationTelemetry.Context.Operation.Name,
                };
                CallContextHelpers.SaveOperationContext(operationContext);
            }

            return(operationHolder);
        }