/// <summary> /// When a thread starts work that is on behalf of 'something else' (typically another /// thread or network request) it should mark the thread as working on that other work. /// This API marks the current thread as working on activity 'activityID'. It returns /// whatever activity the thread was previously marked with. There is a convention that /// callers can assume that callees restore this activity mark before the callee returns. /// To encourage this, this API returns the old activity, so that it can be restored later. /// /// All events created with the EventSource on this thread are also tagged with the /// activity ID of the thread. /// /// It is common, and good practice after setting the thread to an activity to log an event /// with a 'start' opcode to indicate that precise time/thread where the new activity /// started. /// </summary> /// <param name="activityId">A Guid that represents the new activity with which to mark /// the current thread</param> /// <param name="oldActivityThatWillContinue">The Guid that represents the current activity /// which will continue at some point in the future, on the current thread</param> public static void SetCurrentThreadActivityId(Guid activityId, out Guid oldActivityThatWillContinue) { oldActivityThatWillContinue = activityId; #if FEATURE_MANAGED_ETW // We ignore errors to keep with the convention that EventSources do not throw errors. // Note we can't access m_throwOnWrites because this is a static method. #if FEATURE_PERFTRACING && PLATFORM_WINDOWS EventPipeInternal.EventActivityIdControl( (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID, ref oldActivityThatWillContinue); #elif FEATURE_PERFTRACING EventPipeInternal.EventActivityIdControl( (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID, ref oldActivityThatWillContinue); #endif // FEATURE_PERFTRACING && PLATFORM_WINDOWS #if PLATFORM_WINDOWS UnsafeNativeMethods.ManifestEtw.EventActivityIdControl( UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID, ref oldActivityThatWillContinue); #endif // PLATFORM_WINDOWS #endif // FEATURE_MANAGED_ETW // We don't call the activityDying callback here because the caller has declared that // it is not dying. if (TplEtwProvider.Log != null) { TplEtwProvider.Log.SetActivityId(activityId); } }
// ActivityID support (see also WriteEventWithRelatedActivityIdCore) /// <summary> /// When a thread starts work that is on behalf of 'something else' (typically another /// thread or network request) it should mark the thread as working on that other work. /// This API marks the current thread as working on activity 'activityID'. This API /// should be used when the caller knows the thread's current activity (the one being /// overwritten) has completed. Otherwise, callers should prefer the overload that /// return the oldActivityThatWillContinue (below). /// /// All events created with the EventSource on this thread are also tagged with the /// activity ID of the thread. /// /// It is common, and good practice after setting the thread to an activity to log an event /// with a 'start' opcode to indicate that precise time/thread where the new activity /// started. /// </summary> /// <param name="activityId">A Guid that represents the new activity with which to mark /// the current thread</param> public static void SetCurrentThreadActivityId(Guid activityId) { if (TplEtwProvider.Log != null) { TplEtwProvider.Log.SetActivityId(activityId); } #if FEATURE_MANAGED_ETW #if FEATURE_ACTIVITYSAMPLING Guid newId = activityId; #endif // FEATURE_ACTIVITYSAMPLING // We ignore errors to keep with the convention that EventSources do not throw errors. // Note we can't access m_throwOnWrites because this is a static method. #if FEATURE_PERFTRACING && PLATFORM_WINDOWS // Set the activity id via EventPipe. EventPipeInternal.EventActivityIdControl( (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID, ref activityId); // Set the activity id via ETW and fetch the previous id. if (UnsafeNativeMethods.ManifestEtw.EventActivityIdControl( UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID, ref activityId) == 0) #elif FEATURE_PERFTRACING if (EventPipeInternal.EventActivityIdControl( (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID, ref activityId) == 0) #elif PLATFORM_WINDOWS if (UnsafeNativeMethods.ManifestEtw.EventActivityIdControl( UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID, ref activityId) == 0) #endif // FEATURE_PERFTRACING && PLATFORM_WINDOWS { #if FEATURE_ACTIVITYSAMPLING var activityDying = s_activityDying; if (activityDying != null && newId != activityId) { if (activityId == Guid.Empty) { activityId = FallbackActivityId; } // OutputDebugString(string.Format("Activity dying: {0} -> {1}", activityId, newId)); activityDying(activityId); // This is actually the OLD activity ID. } #endif // FEATURE_ACTIVITYSAMPLING } #endif // FEATURE_MANAGED_ETW }
// ActivityID support (see also WriteEventWithRelatedActivityIdCore) /// <summary> /// When a thread starts work that is on behalf of 'something else' (typically another /// thread or network request) it should mark the thread as working on that other work. /// This API marks the current thread as working on activity 'activityID'. This API /// should be used when the caller knows the thread's current activity (the one being /// overwritten) has completed. Otherwise, callers should prefer the overload that /// return the oldActivityThatWillContinue (below). /// /// All events created with the EventSource on this thread are also tagged with the /// activity ID of the thread. /// /// It is common, and good practice after setting the thread to an activity to log an event /// with a 'start' opcode to indicate that precise time/thread where the new activity /// started. /// </summary> /// <param name="activityId">A Guid that represents the new activity with which to mark /// the current thread</param> public static void SetCurrentThreadActivityId(Guid activityId) { if (TplEventSource.Log != null) { TplEventSource.Log.SetActivityId(activityId); } // We ignore errors to keep with the convention that EventSources do not throw errors. // Note we can't access m_throwOnWrites because this is a static method. #if FEATURE_MANAGED_ETW #if FEATURE_PERFTRACING // Set the activity id via EventPipe. EventPipeInternal.EventActivityIdControl( (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID, ref activityId); #endif // FEATURE_PERFTRACING #if PLATFORM_WINDOWS // Set the activity id via ETW. UnsafeNativeMethods.ManifestEtw.EventActivityIdControl( UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID, ref activityId); #endif // PLATFORM_WINDOWS #endif // FEATURE_MANAGED_ETW }
// Get or set the per-thread activity ID. int IEventProvider.EventActivityIdControl(UnsafeNativeMethods.ManifestEtw.ActivityControl ControlCode, ref Guid ActivityId) { return(EventPipeInternal.EventActivityIdControl((uint)ControlCode, ref ActivityId)); }