public void StopDependencyTrackingThrowsExceptionWithNullTelemetryClient()
        {
            var             operationItem = new OperationHolder <DependencyTelemetry>(this.telemetryClient, new DependencyTelemetry());
            TelemetryClient tc            = null;

            tc.StopOperation(operationItem);
        }
예제 #2
0
        public void Add()
        {
            var rh = new OperationHolder();

            rh.Add("operation1", "principal1");

            Assert.Equal(1, rh.OperationCount);
        }
예제 #3
0
        public void ContainsPrincipal()
        {
            var rh = new OperationHolder();

            rh.Add("operation1", "principal1");

            Assert.True(rh.ContainsPrincipal("operation1", "principal1"));
        }
        public OperationHolder LogStartOperation(string operationName)
        {
            if (_config.IsEnabled)
            {
            }
            var test = new OperationHolder();

            test.CurrentOperation = new object();
            return(test);
        }
예제 #5
0
        public void StopGetAll(
            )
        {
            WebApiServiceEventSource.Current.StopGetAll(
                _context
                );
            var getAllOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(getAllOperationHolder);
            getAllOperationHolder.Dispose();
        }
        public OperationHolder LogStartOperation(string operationName)
        {
            OperationHolder operationHolder = new OperationHolder();

            if (_config.IsEnabled && ToSeverityLevel(_config.Treshold) <= SeverityLevel.Information)
            {
                operationHolder.CurrentOperation = _telemetryClient.StartOperation <RequestTelemetry>(operationName);
            }

            return(operationHolder);
        }
예제 #7
0
        public void StopActorActive(
            )
        {
            PersonActorServiceEventSource.Current.StopActorActive(
                _actor
                );

            var actorActiveOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(actorActiveOperationHolder);
            actorActiveOperationHolder.Dispose();
        }
        public void StopRequestContext(
            System.Collections.Generic.IEnumerable <CodeEffect.ServiceFabric.Services.Remoting.FabricTransport.ServiceRequestHeader> headers)
        {
            WebApiServiceEventSource.Current.StopRequestContext(
                _context,
                headers
                );
            var requestContextOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(requestContextOperationHolder);
            requestContextOperationHolder.Dispose();
        }
예제 #9
0
        public void StopLoop(
            )
        {
            DefaultEventSource.Current.StopLoop(
                _processId,
                _machineName,
                _actorId
                );
            var loopOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(loopOperationHolder);
            loopOperationHolder.Dispose();
        }
        public void StopActorMessageRecieved(
            string methodName,
            CodeEffect.ServiceFabric.Services.Remoting.FabricTransport.CustomServiceRequestHeader headers)
        {
            WebApiServiceEventSource.Current.StopActorMessageRecieved(
                _context,
                methodName,
                headers
                );
            var actorMessageRecievedOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(actorMessageRecievedOperationHolder);
            actorMessageRecievedOperationHolder.Dispose();
        }
        public void StopMessageSend(
            System.Uri requestUri,
            CodeEffect.ServiceFabric.Services.Remoting.FabricTransport.CustomServiceRequestHeader headers)
        {
            WebApiServiceEventSource.Current.StopMessageSend(
                _context,
                requestUri,
                headers
                );
            var messageSendOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(messageSendOperationHolder);
            messageSendOperationHolder.Dispose();
        }
예제 #12
0
        public void StartHello(
            )
        {
            Sample.Current.StartHello(

                );

            System.Diagnostics.Debug.WriteLine($"[Console] ERR: StartHello");

            _helloStopwatch.Restart();
            var helloOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("hello");

            OperationHolder.StartOperation(helloOperationHolder);
        }
예제 #13
0
        public void StartLoop(
            )
        {
            Sample.Current.StartLoop(

                );

            System.Diagnostics.Debug.WriteLine($"[ConsoleRunner] ERR: StartLoop");

            _loopStopwatch.Restart();
            var loopOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("loop");

            OperationHolder.StartOperation(loopOperationHolder);
        }
예제 #14
0
        public void StopHello(
            )
        {
            Sample.Current.StopHello(

                );

            System.Diagnostics.Debug.WriteLine($"[Console] ERR: StopHello");

            _helloStopwatch.Stop();
            var helloOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(helloOperationHolder);
            helloOperationHolder.Dispose();
        }
예제 #15
0
        public void StopLoop(
            )
        {
            Sample.Current.StopLoop(

                );

            System.Diagnostics.Debug.WriteLine($"[ConsoleRunner] ERR: StopLoop");

            _loopStopwatch.Stop();
            var loopOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(loopOperationHolder);
            loopOperationHolder.Dispose();
        }
예제 #16
0
        public void StartLoop(
            )
        {
            DefaultEventSource.Current.StartLoop(
                _processId,
                _machineName,
                _actorId
                );

            var loopOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("loop");

            loopOperationHolder.Telemetry.Properties.Add("ProcessId", _processId.ToString());
            loopOperationHolder.Telemetry.Properties.Add("MachineName", Environment.MachineName);
            loopOperationHolder.Telemetry.Properties.Add("Actor", _actorId.ToString());
            OperationHolder.StartOperation(loopOperationHolder);
        }
예제 #17
0
        public void StartGetAll(
            )
        {
            WebApiServiceEventSource.Current.StartGetAll(
                _context
                );

            var getAllOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("getAll");

            getAllOperationHolder.Telemetry.Properties.Add("ServiceName", _context.ServiceName.ToString());
            getAllOperationHolder.Telemetry.Properties.Add("ServiceTypeName", _context.ServiceTypeName);
            getAllOperationHolder.Telemetry.Properties.Add("ReplicaOrInstanceId", _context.InstanceId.ToString());
            getAllOperationHolder.Telemetry.Properties.Add("PartitionId", _context.PartitionId.ToString());
            getAllOperationHolder.Telemetry.Properties.Add("ApplicationName", _context.CodePackageActivationContext.ApplicationName);
            getAllOperationHolder.Telemetry.Properties.Add("ApplicationTypeName", _context.CodePackageActivationContext.ApplicationTypeName);
            getAllOperationHolder.Telemetry.Properties.Add("NodeName", _context.NodeContext.NodeName);
            OperationHolder.StartOperation(getAllOperationHolder);
        }
예제 #18
0
        public void StopLoop(
            )
        {
            FGDiagnosticsAutoLoggerSamplesConsoleApplication1EventSource.Current.StopLoop(
                _autogenerated,
                _machineName
                );

            System.Diagnostics.Debug.WriteLine($"[ConsoleRunner] ERR: StopLoop");

            System.Diagnostics.Debug.WriteLine($"\t_autogenerated:\t{_autogenerated}");
            System.Diagnostics.Debug.WriteLine($"\tEnvironment.MachineName:\t{Environment.MachineName}");
            _loopStopwatch.Stop();

            var loopOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(loopOperationHolder);
            loopOperationHolder.Dispose();
        }
예제 #19
0
        public void StartLoop(
            )
        {
            FGDiagnosticsAutoLoggerSamplesConsoleApplication1EventSource.Current.StartLoop(
                _autogenerated,
                _machineName
                );

            System.Diagnostics.Debug.WriteLine($"[ConsoleRunner] ERR: StartLoop");

            System.Diagnostics.Debug.WriteLine($"\t_autogenerated:\t{_autogenerated}");
            System.Diagnostics.Debug.WriteLine($"\tEnvironment.MachineName:\t{Environment.MachineName}");
            _loopStopwatch.Restart();

            var loopOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("loop");

            loopOperationHolder.Telemetry.Properties.Add("Autogenerated", _autogenerated.ToString());
            loopOperationHolder.Telemetry.Properties.Add("MachineName", Environment.MachineName);
            OperationHolder.StartOperation(loopOperationHolder);
        }
        public void StartRequestContext(
            System.Collections.Generic.IEnumerable <CodeEffect.ServiceFabric.Services.Remoting.FabricTransport.ServiceRequestHeader> headers)
        {
            WebApiServiceEventSource.Current.StartRequestContext(
                _context,
                headers
                );

            var requestContextOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("requestContext");

            requestContextOperationHolder.Telemetry.Properties.Add("ServiceName", _context.ServiceName.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("ServiceTypeName", _context.ServiceTypeName);
            requestContextOperationHolder.Telemetry.Properties.Add("ReplicaOrInstanceId", _context.InstanceId.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("PartitionId", _context.PartitionId.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("ApplicationName", _context.CodePackageActivationContext.ApplicationName);
            requestContextOperationHolder.Telemetry.Properties.Add("ApplicationTypeName", _context.CodePackageActivationContext.ApplicationTypeName);
            requestContextOperationHolder.Telemetry.Properties.Add("NodeName", _context.NodeContext.NodeName);
            requestContextOperationHolder.Telemetry.Properties.Add("Headers", headers.ToString());
            OperationHolder.StartOperation(requestContextOperationHolder);
        }
        public void StopLoop(
            )
        {
            Sample.Current.StopLoop(
                _processId,
                _machineName,
                _actorId
                );

            System.Diagnostics.Debug.WriteLine($"[ConsoleRunner] ERR: StopLoop");

            System.Diagnostics.Debug.WriteLine($"\t_processId:\t{_processId}");
            System.Diagnostics.Debug.WriteLine($"\tEnvironment.MachineName:\t{Environment.MachineName}");
            System.Diagnostics.Debug.WriteLine($"\t_actorId.ToString():\t{_actorId.ToString()}");
            System.Diagnostics.Debug.WriteLine($"\t_actorId.Kind.ToString():\t{_actorId.Kind.ToString()}");
            _loopStopwatch.Stop();
            var loopOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(loopOperationHolder);
            loopOperationHolder.Dispose();
        }
        public void StopHello(
            )
        {
            Sample.Current.StopHello(
                _actorId,
                _processId,
                _machineName
                );

            System.Diagnostics.Debug.WriteLine($"[Console] ERR: StopHello");

            System.Diagnostics.Debug.WriteLine($"\t_actorId.ToString():\t{_actorId.ToString()}");
            System.Diagnostics.Debug.WriteLine($"\t_actorId.Kind.ToString():\t{_actorId.Kind.ToString()}");
            System.Diagnostics.Debug.WriteLine($"\t_processId:\t{_processId}");
            System.Diagnostics.Debug.WriteLine($"\tEnvironment.MachineName:\t{Environment.MachineName}");
            _helloStopwatch.Stop();
            var helloOperationHolder = OperationHolder.StopOperation();

            _telemetryClient.StopOperation(helloOperationHolder);
            helloOperationHolder.Dispose();
        }
예제 #23
0
        public void StartRequestContext(
            System.Collections.Generic.IEnumerable <FG.ServiceFabric.Services.Remoting.FabricTransport.ServiceRequestHeader> headers)
        {
            PersonActorServiceEventSource.Current.StartRequestContext(
                _actor,
                headers
                );

            var requestContextOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("requestContext");

            requestContextOperationHolder.Telemetry.Properties.Add("ActorType", _actor.ActorType.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("ActorId", _actor.ActorId.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("ApplicationTypeName", _actor.ApplicationTypeName);
            requestContextOperationHolder.Telemetry.Properties.Add("ApplicationName", _actor.ApplicationName);
            requestContextOperationHolder.Telemetry.Properties.Add("ServiceTypeName", _actor.ServiceTypeName);
            requestContextOperationHolder.Telemetry.Properties.Add("ServiceName", _actor.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("PartitionId", _actor.PartitionId.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("ReplicaOrInstanceId", _actor.ReplicaOrInstanceId.ToString());
            requestContextOperationHolder.Telemetry.Properties.Add("NodeName", _actor.NodeName);
            requestContextOperationHolder.Telemetry.Properties.Add("Headers", headers.ToString());
            OperationHolder.StartOperation(requestContextOperationHolder);
        }
예제 #24
0
        public void StartActorActive(
            bool firstActivation)
        {
            PersonActorServiceEventSource.Current.StartActorActive(
                _actor,
                firstActivation
                );

            var actorActiveOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("actorActive");

            actorActiveOperationHolder.Telemetry.Properties.Add("ActorType", _actor.ActorType.ToString());
            actorActiveOperationHolder.Telemetry.Properties.Add("ActorId", _actor.ActorId.ToString());
            actorActiveOperationHolder.Telemetry.Properties.Add("ApplicationTypeName", _actor.ApplicationTypeName);
            actorActiveOperationHolder.Telemetry.Properties.Add("ApplicationName", _actor.ApplicationName);
            actorActiveOperationHolder.Telemetry.Properties.Add("ServiceTypeName", _actor.ServiceTypeName);
            actorActiveOperationHolder.Telemetry.Properties.Add("ServiceName", _actor.ToString());
            actorActiveOperationHolder.Telemetry.Properties.Add("PartitionId", _actor.PartitionId.ToString());
            actorActiveOperationHolder.Telemetry.Properties.Add("ReplicaOrInstanceId", _actor.ReplicaOrInstanceId.ToString());
            actorActiveOperationHolder.Telemetry.Properties.Add("NodeName", _actor.NodeName);
            actorActiveOperationHolder.Telemetry.Properties.Add("FirstActivation", firstActivation.ToString());
            OperationHolder.StartOperation(actorActiveOperationHolder);
        }
        public void StartHello(
            )
        {
            Sample.Current.StartHello(
                _actorId,
                _processId,
                _machineName
                );

            System.Diagnostics.Debug.WriteLine($"[Console] ERR: StartHello");

            System.Diagnostics.Debug.WriteLine($"\t_actorId.ToString():\t{_actorId.ToString()}");
            System.Diagnostics.Debug.WriteLine($"\t_actorId.Kind.ToString():\t{_actorId.Kind.ToString()}");
            System.Diagnostics.Debug.WriteLine($"\t_processId:\t{_processId}");
            System.Diagnostics.Debug.WriteLine($"\tEnvironment.MachineName:\t{Environment.MachineName}");
            _helloStopwatch.Restart();
            var helloOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("hello");

            helloOperationHolder.Telemetry.Properties.Add("ActorId", _actorId.ToString());
            helloOperationHolder.Telemetry.Properties.Add("ActorIdType", _actorId.Kind.ToString());
            helloOperationHolder.Telemetry.Properties.Add("ProcessId", _processId.ToString());
            helloOperationHolder.Telemetry.Properties.Add("MachineName", Environment.MachineName);
            OperationHolder.StartOperation(helloOperationHolder);
        }
        public void StartActorMessageRecieved(
            string methodName,
            CodeEffect.ServiceFabric.Services.Remoting.FabricTransport.CustomServiceRequestHeader headers)
        {
            WebApiServiceEventSource.Current.StartActorMessageRecieved(
                _context,
                methodName,
                headers
                );

            var actorMessageRecievedOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>("actorMessageRecieved");

            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("ServiceName", _context.ServiceName.ToString());
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("ServiceTypeName", _context.ServiceTypeName);
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("ReplicaOrInstanceId", _context.InstanceId.ToString());
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("PartitionId", _context.PartitionId.ToString());
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("ApplicationName", _context.CodePackageActivationContext.ApplicationName);
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("ApplicationTypeName", _context.CodePackageActivationContext.ApplicationTypeName);
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("NodeName", _context.NodeContext.NodeName);
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("MethodName", methodName);
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("User", headers?.GetHeader("name"));
            actorMessageRecievedOperationHolder.Telemetry.Properties.Add("CorrelationId", headers?.GetHeader("correlation-id"));
            OperationHolder.StartOperation(actorMessageRecievedOperationHolder);
        }
        public void StartMessageSend(
            System.Uri requestUri,
            CodeEffect.ServiceFabric.Services.Remoting.FabricTransport.CustomServiceRequestHeader headers)
        {
            WebApiServiceEventSource.Current.StartMessageSend(
                _context,
                requestUri,
                headers
                );

            var messageSendOperationHolder = _telemetryClient.StartOperation <RequestTelemetry>(requestUri.ToString());

            messageSendOperationHolder.Telemetry.Properties.Add("ServiceName", _context.ServiceName.ToString());
            messageSendOperationHolder.Telemetry.Properties.Add("ServiceTypeName", _context.ServiceTypeName);
            messageSendOperationHolder.Telemetry.Properties.Add("ReplicaOrInstanceId", _context.InstanceId.ToString());
            messageSendOperationHolder.Telemetry.Properties.Add("PartitionId", _context.PartitionId.ToString());
            messageSendOperationHolder.Telemetry.Properties.Add("ApplicationName", _context.CodePackageActivationContext.ApplicationName);
            messageSendOperationHolder.Telemetry.Properties.Add("ApplicationTypeName", _context.CodePackageActivationContext.ApplicationTypeName);
            messageSendOperationHolder.Telemetry.Properties.Add("NodeName", _context.NodeContext.NodeName);
            messageSendOperationHolder.Telemetry.Properties.Add("RequestUri", requestUri.ToString());
            messageSendOperationHolder.Telemetry.Properties.Add("User", headers?.GetHeader("name"));
            messageSendOperationHolder.Telemetry.Properties.Add("CorrelationId", headers?.GetHeader("correlation-id"));
            OperationHolder.StartOperation(messageSendOperationHolder);
        }
예제 #28
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);
        }
예제 #29
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;
        }
        /// <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);
        }