Remove the MultiFileSec option from EventPipe. (#23777)
authorJosé Rivero <jorive@microsoft.com>
Mon, 8 Apr 2019 18:54:19 +0000 (11:54 -0700)
committerGitHub <noreply@github.com>
Mon, 8 Apr 2019 18:54:19 +0000 (11:54 -0700)
This option was a pseudo mechanism to fake "streaming" events out-of-proc.
The idea was to have EventPipe creating files every N seconds, with event data up to that point. Thus, external processes could read these files in an attempt to get "read-time" data.
Now, we actually have streaming of event through IPC channels, so this option is not needed.

src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs
src/vm/eventpipe.cpp
src/vm/eventpipe.h
src/vm/eventpipeinternal.cpp
src/vm/eventpipeinternal.h
src/vm/eventpipeprotocolhelper.cpp
src/vm/eventpipeprotocolhelper.h

index 9f05540..763e78c 100644 (file)
@@ -87,7 +87,6 @@ namespace System.Diagnostics.Tracing
         private uint m_circularBufferSizeInMB;
         private List<EventPipeProviderConfiguration> m_providers;
         private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1);
-        private ulong m_multiFileTraceLengthInSeconds = 0;
 
         internal EventPipeConfiguration(
             string outputFile,
@@ -116,11 +115,6 @@ namespace System.Diagnostics.Tracing
             get { return m_circularBufferSizeInMB; }
         }
 
-        internal ulong MultiFileTraceLengthInSeconds
-        {
-            get { return m_multiFileTraceLengthInSeconds; }
-        }
-
         internal EventPipeProviderConfiguration[] Providers
         {
             get { return m_providers.ToArray(); }
@@ -168,11 +162,6 @@ namespace System.Diagnostics.Tracing
 
             m_minTimeBetweenSamples = minTimeBetweenSamples;
         }
-
-        internal void SetMultiFileTraceLength(ulong traceLengthInSeconds)
-        {
-            m_multiFileTraceLengthInSeconds = traceLengthInSeconds;
-        }
     }
 
     internal static class EventPipe
@@ -198,8 +187,7 @@ namespace System.Diagnostics.Tracing
                 configuration.CircularBufferSizeInMB,
                 (ulong)configuration.ProfilerSamplingRateInNanoseconds,
                 providers,
-                (uint)providers.Length,
-                configuration.MultiFileTraceLengthInSeconds);
+                (uint)providers.Length);
         }
 
         internal static void Disable()
@@ -219,8 +207,7 @@ namespace System.Diagnostics.Tracing
             uint circularBufferSizeInMB,
             ulong profilerSamplingRateInNanoseconds,
             EventPipeProviderConfiguration[] providers,
-            uint numProviders,
-            ulong multiFileTraceLengthInSeconds);
+            uint numProviders);
 
         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
         internal static extern void Disable(UInt64 sessionID);
index cac4ac1..2711d52 100644 (file)
@@ -46,7 +46,6 @@ namespace System.Diagnostics.Tracing
         private const string ConfigKey_CircularMB = "CircularMB";
         private const string ConfigKey_OutputPath = "OutputPath";
         private const string ConfigKey_ProcessID = "ProcessID";
-        private const string ConfigKey_MultiFileSec = "MultiFileSec";
 
         // The default set of providers/keywords/levels.  Used if an alternative configuration is not specified.
         private static EventPipeProviderConfiguration[] DefaultProviderConfiguration => new EventPipeProviderConfiguration[]
@@ -170,7 +169,6 @@ namespace System.Diagnostics.Tracing
             string strProviderConfig = null;
             string strCircularMB = null;
             string strProcessID = null;
-            string strMultiFileSec = null;
 
             // Split the configuration entries by line.
             string[] configEntries = strConfigContents.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
@@ -200,10 +198,6 @@ namespace System.Diagnostics.Tracing
                     {
                         strProcessID = entryComponents[1];
                     }
-                    else if (key.Equals(ConfigKey_MultiFileSec))
-                    {
-                        strMultiFileSec = entryComponents[1];
-                    }
                 }
             }
 
@@ -224,13 +218,6 @@ namespace System.Diagnostics.Tracing
                 throw new ArgumentNullException(nameof(outputPath));
             }
 
-            // Check to see if MultiFileSec is specified.
-            ulong multiFileSec = 0;
-            if (!string.IsNullOrEmpty(strMultiFileSec))
-            {
-                multiFileSec = Convert.ToUInt64(strMultiFileSec);
-            }
-
             // Build the full path to the trace file.
             string traceFileName = BuildTraceFileName();
             string outputFile = Path.Combine(outputPath, traceFileName);
@@ -244,7 +231,6 @@ namespace System.Diagnostics.Tracing
 
             // Initialize a new configuration object.
             EventPipeConfiguration config = new EventPipeConfiguration(outputFile, circularMB);
-            config.SetMultiFileTraceLength(multiFileSec);
 
             // Set the provider configuration if specified.
             if (!string.IsNullOrEmpty(strProviderConfig))
index 9f45989..1e152bc 100644 (file)
@@ -110,7 +110,7 @@ namespace System.Diagnostics.Tracing
                 new EventPipeProviderConfiguration(NativeRuntimeEventSource.EventSourceName, (ulong) aggregatedKeywords, (uint) highestLevel, null)
             };
 
-            m_sessionID = EventPipeInternal.Enable(null, 1024, 1, providerConfiguration, 1, 0);
+            m_sessionID = EventPipeInternal.Enable(null, 1024, 1, providerConfiguration, 1);
             Debug.Assert(m_sessionID != 0);
 
             // Get the session information that is required to properly dispatch events.
index 92b4793..b730bd8 100644 (file)
@@ -31,14 +31,11 @@ bool EventPipe::s_tracingInitialized = false;
 EventPipeConfiguration *EventPipe::s_pConfig = NULL;
 EventPipeSession *EventPipe::s_pSession = NULL;
 EventPipeBufferManager *EventPipe::s_pBufferManager = NULL;
-LPCWSTR EventPipe::s_pOutputPath = NULL;
 EventPipeFile *EventPipe::s_pFile = NULL;
 EventPipeEventSource *EventPipe::s_pEventSource = NULL;
 LPCWSTR EventPipe::s_pCommandLine = NULL;
-unsigned long EventPipe::s_nextFileIndex;
 HANDLE EventPipe::s_fileSwitchTimerHandle = NULL;
 ULONGLONG EventPipe::s_lastFlushSwitchTime = 0;
-uint64_t EventPipe::s_multiFileTraceLengthInSeconds = 0;
 
 #ifdef FEATURE_PAL
 // This function is auto-generated from /src/scripts/genEventPipe.py
@@ -225,8 +222,6 @@ void EventPipe::Shutdown()
     delete pBufferManager;
     delete s_pEventSource;
     s_pEventSource = NULL;
-    delete[] s_pOutputPath;
-    s_pOutputPath = NULL;
 
     // On Windows, this is just a pointer to the return value from
     // GetCommandLineW(), so don't attempt to free it.
@@ -241,8 +236,7 @@ EventPipeSessionID EventPipe::Enable(
     uint32_t circularBufferSizeInMB,
     uint64_t profilerSamplingRateInNanoseconds,
     const EventPipeProviderConfiguration *pProviders,
-    uint32_t numProviders,
-    uint64_t multiFileTraceLengthInSeconds)
+    uint32_t numProviders)
 {
     CONTRACTL
     {
@@ -256,8 +250,6 @@ EventPipeSessionID EventPipe::Enable(
     // Take the lock before enabling tracing.
     CrstHolder _crst(GetLock());
 
-    s_multiFileTraceLengthInSeconds = multiFileTraceLengthInSeconds;
-
     // Create a new session.
     SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds);
     EventPipeSession *pSession = s_pConfig->CreateSession(
@@ -266,9 +258,6 @@ EventPipeSessionID EventPipe::Enable(
         pProviders,
         numProviders);
 
-    // Initialize the next file index.
-    s_nextFileIndex = 1;
-
     // Initialize the last file switch time.
     s_lastFlushSwitchTime = CLRGetTickCount64();
 
@@ -276,24 +265,8 @@ EventPipeSessionID EventPipe::Enable(
     // A NULL output path means that we should not write the results to a file.
     // This is used in the EventListener streaming case.
     if (strOutputPath != NULL)
-    {
-
-        // Save the output file path.
-        SString outputPath(strOutputPath);
-        SIZE_T outputPathLen = outputPath.GetCount();
-        WCHAR *pOutputPath = new WCHAR[outputPathLen + 1];
-        wcsncpy(pOutputPath, outputPath.GetUnicode(), outputPathLen);
-        pOutputPath[outputPathLen] = '\0';
-        s_pOutputPath = pOutputPath;
-
-        SString nextTraceFilePath;
-        GetNextFilePath(nextTraceFilePath);
-
-        s_pFile = new EventPipeFile(new FileStreamWriter(nextTraceFilePath));
-    }
-
-    const DWORD FileSwitchTimerPeriodMS = 1000;
-    return Enable(pSession, SwitchToNextFileTimerCallback, FileSwitchTimerPeriodMS, FileSwitchTimerPeriodMS);
+        s_pFile = new EventPipeFile(new FileStreamWriter(SString(strOutputPath)));
+    return Enable(pSession);
 }
 
 EventPipeSessionID EventPipe::Enable(
@@ -327,6 +300,9 @@ EventPipeSessionID EventPipe::Enable(
         pProviders,
         numProviders);
 
+    // Initialize the last file switch time.
+    s_lastFlushSwitchTime = CLRGetTickCount64();
+
     // Reply back to client with the SessionId
     uint32_t nBytesWritten = 0;
     EventPipeSessionID sessionId = (EventPipeSessionID) pSession;
@@ -359,9 +335,6 @@ EventPipeSessionID EventPipe::Enable(
         GC_TRIGGERS;
         MODE_ANY;
         PRECONDITION(pSession != nullptr);
-        PRECONDITION(callback != nullptr);
-        PRECONDITION(dueTime > 0);
-        PRECONDITION(period > 0);
         PRECONDITION(GetLock()->OwnedByCurrentThread());
     }
     CONTRACTL_END;
@@ -386,7 +359,8 @@ EventPipeSessionID EventPipe::Enable(
     // Enable the sample profiler
     SampleProfiler::Enable();
 
-    CreateFlushTimerCallback(callback, dueTime, period);
+    if (callback != nullptr)
+        CreateFlushTimerCallback(callback, dueTime, period);
 
     // Return the session ID.
     return (EventPipeSessionID)s_pSession;
@@ -427,8 +401,6 @@ void EventPipe::Disable(EventPipeSessionID id)
         // Disable tracing.
         s_pConfig->Disable(s_pSession);
 
-        s_multiFileTraceLengthInSeconds = 0;
-
         // Delete the session.
         s_pConfig->DeleteSession(s_pSession);
         s_pSession = NULL;
@@ -555,36 +527,6 @@ void EventPipe::DeleteFlushTimerCallback()
         s_fileSwitchTimerHandle = NULL;
 }
 
-void WINAPI EventPipe::SwitchToNextFileTimerCallback(PVOID parameter, BOOLEAN timerFired)
-{
-    CONTRACTL
-    {
-        THROWS;
-        GC_TRIGGERS;
-        MODE_ANY;
-        PRECONDITION(timerFired);
-    }
-    CONTRACTL_END;
-
-    // Take the lock control lock to make sure that tracing isn't disabled during this operation.
-    CrstHolder _crst(GetLock());
-
-    if (s_pSession == nullptr || s_pFile == nullptr)
-        return;
-
-    // Make sure that we should actually switch files.
-    if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::File || s_multiFileTraceLengthInSeconds == 0)
-        return;
-
-    GCX_PREEMP();
-
-    if (CLRGetTickCount64() > (s_lastFlushSwitchTime + (s_multiFileTraceLengthInSeconds * 1000)))
-    {
-        SwitchToNextFile();
-        s_lastFlushSwitchTime = CLRGetTickCount64();
-    }
-}
-
 void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired)
 {
     CONTRACTL
@@ -621,80 +563,6 @@ void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired)
     }
 }
 
-void EventPipe::SwitchToNextFile()
-{
-    CONTRACTL
-    {
-        THROWS;
-        GC_TRIGGERS;
-        MODE_PREEMPTIVE;
-        PRECONDITION(s_pFile != nullptr);
-        PRECONDITION(GetLock()->OwnedByCurrentThread());
-    }
-    CONTRACTL_END
-
-    // Get the current time stamp.
-    // WriteAllBuffersToFile will use this to ensure that no events after the current timestamp are written into the file.
-    LARGE_INTEGER stopTimeStamp;
-    QueryPerformanceCounter(&stopTimeStamp);
-    s_pBufferManager->WriteAllBuffersToFile(s_pFile, stopTimeStamp);
-
-    // Open the new file.
-    SString nextTraceFilePath;
-    GetNextFilePath(nextTraceFilePath);
-
-    StreamWriter *pStreamWriter = new (nothrow) FileStreamWriter(nextTraceFilePath);
-    if (pStreamWriter == nullptr)
-    {
-        // TODO: Add error handling.
-        return;
-    }
-
-    EventPipeFile *pFile = new (nothrow) EventPipeFile(pStreamWriter);
-    if (pFile == NULL)
-    {
-        // TODO: Add error handling.
-        return;
-    }
-
-    // Close the previous file.
-    delete s_pFile;
-
-    // Swap in the new file.
-    s_pFile = pFile;
-}
-
-void EventPipe::GetNextFilePath(SString &nextTraceFilePath)
-{
-    CONTRACTL
-    {
-        THROWS;
-        GC_TRIGGERS;
-        MODE_ANY;
-        PRECONDITION(GetLock()->OwnedByCurrentThread());
-    }
-    CONTRACTL_END;
-
-    // Set the full path to the requested trace file as the next file path.
-    nextTraceFilePath.Set(s_pOutputPath);
-
-    // If multiple files have been requested, then add a sequence number to the trace file name.
-    if (s_multiFileTraceLengthInSeconds > 0)
-    {
-        // Remove the ".netperf" file extension if it exists.
-        SString::Iterator netPerfExtension = nextTraceFilePath.End();
-        if (nextTraceFilePath.FindBack(netPerfExtension, W(".netperf")))
-        {
-            nextTraceFilePath.Truncate(netPerfExtension);
-        }
-
-        // Add the sequence number and the ".netperf" file extension.
-        WCHAR strNextIndex[21];
-        swprintf_s(strNextIndex, 21, W(".%u.netperf"), s_nextFileIndex++);
-        nextTraceFilePath.Append(strNextIndex);
-    }
-}
-
 EventPipeSession *EventPipe::GetSession(EventPipeSessionID id)
 {
     LIMITED_METHOD_CONTRACT;
index 5129baf..e60c493 100644 (file)
@@ -255,8 +255,7 @@ public:
         uint32_t circularBufferSizeInMB,
         uint64_t profilerSamplingRateInNanoseconds,
         const EventPipeProviderConfiguration *pProviders,
-        uint32_t numProviders,
-        uint64_t multiFileTraceLengthInSeconds);
+        uint32_t numProviders);
 
     static EventPipeSessionID Enable(
         IpcStream *pStream,
@@ -313,28 +312,16 @@ private:
     // Enable the specified EventPipe session.
     static EventPipeSessionID Enable(
         EventPipeSession *const pSession,
-        WAITORTIMERCALLBACK callback,
-        DWORD dueTime,
-        DWORD period);
+        WAITORTIMERCALLBACK callback = nullptr,
+        DWORD dueTime = 0,
+        DWORD period = 0);
 
     static void CreateFlushTimerCallback(WAITORTIMERCALLBACK Callback, DWORD DueTime, DWORD Period);
 
     static void DeleteFlushTimerCallback();
 
-    // Performs one polling operation to determine if it is necessary to switch to a new file.
-    // If the polling operation decides it is time, it will perform the switch.
-    // Called directly from the timer when the timer is triggered.
-    static void WINAPI SwitchToNextFileTimerCallback(PVOID parameter, BOOLEAN timerFired);
-
     static void WINAPI FlushTimer(PVOID parameter, BOOLEAN timerFired);
 
-    // If event pipe has been configured to write multiple files, switch to the next file.
-    static void SwitchToNextFile();
-
-    // Generate the file path for the next trace file.
-    // This is used when event pipe has been configured to create multiple trace files with a specified maximum length of time.
-    static void GetNextFilePath(SString &nextTraceFilePath);
-
     // Callback function for the stack walker.  For each frame walked, this callback is invoked.
     static StackWalkAction StackWalkCallback(CrawlFrame *pCf, StackContents *pData);
 
@@ -358,14 +345,11 @@ private:
     static EventPipeConfiguration *s_pConfig;
     static EventPipeSession *s_pSession;
     static EventPipeBufferManager *s_pBufferManager;
-    static LPCWSTR s_pOutputPath;
-    static unsigned long s_nextFileIndex;
     static EventPipeFile *s_pFile;
     static EventPipeEventSource *s_pEventSource;
     static LPCWSTR s_pCommandLine;
     static HANDLE s_fileSwitchTimerHandle;
     static ULONGLONG s_lastFlushSwitchTime;
-    static uint64_t s_multiFileTraceLengthInSeconds;
 };
 
 struct EventPipeProviderConfiguration
index 30a1464..17efeb3 100644 (file)
@@ -22,8 +22,7 @@ UINT64 QCALLTYPE EventPipeInternal::Enable(
     UINT32 circularBufferSizeInMB,
     INT64 profilerSamplingRateInNanoseconds,
     EventPipeProviderConfiguration *pProviders,
-    UINT32 numProviders,
-    UINT64 multiFileTraceLengthInSeconds)
+    UINT32 numProviders)
 {
     QCALL_CONTRACT;
 
@@ -36,8 +35,7 @@ UINT64 QCALLTYPE EventPipeInternal::Enable(
             circularBufferSizeInMB,
             profilerSamplingRateInNanoseconds,
             pProviders,
-            numProviders,
-            multiFileTraceLengthInSeconds);
+            numProviders);
     }
     END_QCALL;
 
index bbd4ad6..e4252c7 100644 (file)
@@ -49,8 +49,7 @@ public:
         UINT32 circularBufferSizeInMB,
         INT64 profilerSamplingRateInNanoseconds,
         EventPipeProviderConfiguration *pProviders,
-        UINT32 numProviders,
-        UINT64 multiFileTraceLengthInSeconds);
+        UINT32 numProviders);
 
     //! TODO: Add a ListActiveSessions to get the live SessionID in order to Disable?
 
index c1fe613..24eb2b0 100644 (file)
@@ -74,7 +74,7 @@ void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream)
 
     // The protocol buffer is defined as:
     // X, Y, Z means encode bytes for X followed by bytes for Y followed by bytes for Z
-    // message = uint circularBufferMB, ulong multiFileTraceLength, string outputPath, array<provider_config> providers
+    // message = uint circularBufferMB, string outputPath, array<provider_config> providers
     // uint = 4 little endian bytes
     // ulong = 8 little endian bytes
     // wchar = 2 little endian bytes, UTF16 encoding
@@ -84,13 +84,11 @@ void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream)
 
     LPCWSTR strOutputPath;
     uint32_t circularBufferSizeInMB = EventPipeProtocolHelper::DefaultCircularBufferMB;
-    uint64_t multiFileTraceLengthInSeconds = EventPipeProtocolHelper::DefaultMultiFileTraceLengthInSeconds;
     CQuickArray<EventPipeProviderConfiguration> providerConfigs;
 
     uint8_t *pBufferCursor = buffer;
     uint32_t bufferLen = nNumberOfBytesRead;
     if (!TryParse(pBufferCursor, bufferLen, circularBufferSizeInMB) ||
-        !TryParse(pBufferCursor, bufferLen, multiFileTraceLengthInSeconds) ||
         !TryParseString(pBufferCursor, bufferLen, strOutputPath) ||
         !TryParseProviderConfiguration(pBufferCursor, bufferLen, providerConfigs))
     {
@@ -103,12 +101,11 @@ void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream)
     if (providerConfigs.Size() > 0)
     {
         sessionId = EventPipe::Enable(
-            strOutputPath,                                 // outputFile
-            circularBufferSizeInMB,                        // circularBufferSizeInMB
-            DefaultProfilerSamplingRateInNanoseconds,      // ProfilerSamplingRateInNanoseconds
-            providerConfigs.Ptr(),                         // pConfigs
-            static_cast<uint32_t>(providerConfigs.Size()), // numConfigs
-            multiFileTraceLengthInSeconds);                // multiFileTraceLengthInSeconds
+            strOutputPath,                                  // outputFile
+            circularBufferSizeInMB,                         // circularBufferSizeInMB
+            DefaultProfilerSamplingRateInNanoseconds,       // ProfilerSamplingRateInNanoseconds
+            providerConfigs.Ptr(),                          // pConfigs
+            static_cast<uint32_t>(providerConfigs.Size())); // numConfigs
     }
 
     uint32_t nBytesWritten = 0;
@@ -191,7 +188,7 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream)
 
     // The protocol buffer is defined as:
     // X, Y, Z means encode bytes for X followed by bytes for Y followed by bytes for Z
-    // message = uint circularBufferMB, ulong multiFileTraceLength, string outputPath, array<provider_config> providers
+    // message = uint circularBufferMB, string outputPath, array<provider_config> providers
     // uint = 4 little endian bytes
     // wchar = 2 little endian bytes, UTF16 encoding
     // array<T> = uint length, length # of Ts
@@ -200,13 +197,11 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream)
 
     LPCWSTR strOutputPath;
     uint32_t circularBufferSizeInMB = EventPipeProtocolHelper::DefaultCircularBufferMB;
-    uint64_t multiFileTraceLengthInSeconds = EventPipeProtocolHelper::DefaultMultiFileTraceLengthInSeconds;
     CQuickArray<EventPipeProviderConfiguration> providerConfigs;
 
     uint8_t *pBufferCursor = buffer;
     uint32_t bufferLen = nNumberOfBytesRead;
     if (!TryParse(pBufferCursor, bufferLen, circularBufferSizeInMB) ||
-        !TryParse(pBufferCursor, bufferLen, multiFileTraceLengthInSeconds) ||
         !TryParseString(pBufferCursor, bufferLen, strOutputPath) ||
         !TryParseProviderConfiguration(pBufferCursor, bufferLen, providerConfigs))
     {
index 44192d7..4fc8580 100644 (file)
@@ -23,7 +23,6 @@ public:
 
 private:
     const static uint32_t DefaultCircularBufferMB = 1024; // 1 GB
-    const static uint64_t DefaultMultiFileTraceLengthInSeconds = 0;
     const static uint32_t DefaultProfilerSamplingRateInNanoseconds = 1000000; // 1 msec.
     const static uint32_t IpcStreamReadBufferSize = 8192;