├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── BuildAndTest.yml │ ├── BuildProfiling_Example.yml │ └── BuildRelease.yml ├── .gitignore ├── BuildScripts └── RemoveStrict.ps1 ├── ETWAnalyzer.sln ├── ETWAnalyzer ├── 3rdParty │ ├── 7-Zip │ │ ├── 7z.dll │ │ ├── 7z.exe │ │ ├── 7z1900-src.7z │ │ └── LICENSE │ ├── Microsoft.Windows.EventTracing.Processing │ │ └── traceprocessing-eula.pdf │ ├── NewtonSoft.Json │ │ └── LICENSE │ └── ReadMeOSS.md ├── Analyzers │ ├── AnalyzerBase.cs │ ├── CPU │ │ ├── FreshBackendAnalyzer.cs │ │ └── StackTagAnalyzer.cs │ ├── Exception │ │ ├── CurrentAndNextNeighboursModuleVersion.cs │ │ ├── Duration │ │ │ └── ExceptionByDurationAnomalieAnalyzer.cs │ │ ├── ExceptionAnalyzerBase.cs │ │ ├── ExceptionDataCleaner.cs │ │ ├── ExceptionDifferenceAnalyzer │ │ │ ├── DetectionSerializeUpdater.cs │ │ │ ├── ExceptionDifferencePersistentAnalyzer.cs │ │ │ ├── ExceptionDifferenceVolatileAnalyzer.cs │ │ │ ├── TimeSeriesDetector.cs │ │ │ └── TimeSeriesExceptionActivities.cs │ │ ├── ExceptionFiltering.cs │ │ ├── ExceptionFilters.cs │ │ ├── ExceptionKeyEvent.cs │ │ ├── ExceptionOccurrence │ │ │ └── ExceptionOccurrenceAnalyzer.cs │ │ ├── ExceptionSourceFileWithNextNeighboursModuleVersion.cs │ │ ├── ResultPrinter │ │ │ ├── ColorConfig.cs │ │ │ ├── ConsoleAsExceptionTableConfig.cs │ │ │ ├── ConsolePrinter.cs │ │ │ ├── ExceptionAnalysisDetailPrinter.cs │ │ │ └── ExceptionDifferenceAnalysisOverviewPrinter.cs │ │ ├── Screenshot │ │ │ └── ScreenshotDatas.cs │ │ ├── TestSpecificCollectionOfUniqueExceptionsWithSource.cs │ │ ├── TimeSeriesToMathematicalFunction.cs │ │ └── UniqueExceptionsWithSourceFiles.cs │ ├── Infrastructure │ │ ├── LinearRegression.cs │ │ ├── TestRunDataAccessor.cs │ │ └── ValueAnomalieDetector.cs │ ├── Problem │ │ ├── Classification.cs │ │ ├── Issue.cs │ │ ├── Severities.cs │ │ ├── TestAnalysisResult.cs │ │ └── TestAnalysisResultCollection.cs │ ├── ProcessExtensions.cs │ ├── ScreenshotBitmapping │ │ └── SampleBitmapGenerator.cs │ └── TestCount │ │ └── TestCountAnalyzer.cs ├── App.config ├── Commands │ ├── AnalyzeCommand.cs │ ├── ArgParser.cs │ ├── CommandFactory.cs │ ├── ConsoleCommand.cs │ ├── ConvertCommand.cs │ ├── ConvertTimeCommand.cs │ ├── DumpCommand.cs │ ├── ExtractCommand.cs │ ├── HelpCommand.cs │ ├── ICommand.cs │ ├── ICommandExecutor.cs │ ├── ICommandLineParser.cs │ ├── LoadSymbolCommand.cs │ ├── MissingInputException.cs │ └── OutDir.cs ├── Configuration │ ├── ConfigFiles.cs │ ├── DllToBuildMap.json │ ├── DllToBuildMappings.cs │ ├── Drivers.cs │ ├── ExceptionFilters.xml │ ├── GCAndJit.stacktags │ ├── ProcessRenameRules.xml │ ├── RequiredPdbs.txt │ ├── Special.stacktags │ ├── TestRunConfiguration.xml │ ├── WellKnownDrivers.json │ └── default.stacktags ├── Converters │ ├── LICENSE │ ├── SpeedScopeWriter.cs │ └── StackSourceWriterHelper.cs ├── Documentation │ ├── AutomatedProfiling.md │ ├── BuildProfiling.md │ ├── Contributing.md │ ├── ConvertCommand.md │ ├── ConvertTimeCommand.md │ ├── DumpCPUCommand.md │ ├── DumpCPUExtended.md │ ├── DumpDNSCommand.md │ ├── DumpDiskCommand.md │ ├── DumpExceptionCommand.md │ ├── DumpFileCommand.md │ ├── DumpLBRCommand.md │ ├── DumpMarkCommand.md │ ├── DumpMemoryCommand.md │ ├── DumpObjectRefCommand.md │ ├── DumpPMCCommand.md │ ├── DumpPower.md │ ├── DumpProcessCommand.md │ ├── DumpTCPCommand.md │ ├── DumpTestRunCommand.md │ ├── DumpThreadPoolCommand.md │ ├── DumpVersionCommand.md │ ├── ExtractCommand.md │ ├── Filters.md │ ├── Images │ │ ├── BuildArtifacts.png │ │ ├── BuildProfiling_AVOverhead.png │ │ ├── BuildProfiling_LoadSymbols.png │ │ ├── BuildProfiling_MethodLevel.png │ │ ├── BuildProfiling_ProfilingDataView.png │ │ ├── BuildProfiling_Stats.png │ │ ├── CPUTimeFirstLast.png │ │ ├── DumpCPUAVShowTotal.png │ │ ├── DumpCPUAV_SortByWait.png │ │ ├── DumpCPUExtended.png │ │ ├── DumpCPUTop10Stacktags.png │ │ ├── DumpCPUTop20Methods.png │ │ ├── DumpCPUTop30Methods.png │ │ ├── DumpCPUTop5.png │ │ ├── DumpCPUTop9.png │ │ ├── DumpCPUTopN2ProcessFmt.png │ │ ├── DumpCPUTopology.png │ │ ├── DumpCPU_All.png │ │ ├── DumpCPU_FirstLastDurationCorrelation.png │ │ ├── DumpCPU_Normalized.png │ │ ├── DumpCPU_ZeroTime.png │ │ ├── DumpDisk.png │ │ ├── DumpDnsCommand.png │ │ ├── DumpDnsTopN15_ShowAdapter.png │ │ ├── DumpException.png │ │ ├── DumpFile.png │ │ ├── DumpFile_Details.png │ │ ├── DumpFile_PerFileClippedAndReversed.png │ │ ├── DumpLBRExample.png │ │ ├── DumpLBRExample_Overview.png │ │ ├── DumpMark.png │ │ ├── DumpMark_ZeroTime.png │ │ ├── DumpMemory_Top5.png │ │ ├── DumpMemory_Total.png │ │ ├── DumpMemory_TotalMemory.png │ │ ├── DumpObjectRef_Filter.png │ │ ├── DumpObjectRef_Inherit.png │ │ ├── DumpObjectRef_Leak.png │ │ ├── DumpObjectRef_LeakStack.png │ │ ├── DumpPMC.png │ │ ├── DumpProcessTree.png │ │ ├── DumpProcess_Clip.png │ │ ├── DumpProcess_Crash.png │ │ ├── DumpProcess_CtrlC.png │ │ ├── DumpProcess_Merge.png │ │ ├── DumpProcess_RenamedSvcHost.png │ │ ├── DumpProcess_TimeFmt.png │ │ ├── DumpProcess_User.png │ │ ├── DumpStatsCommand.png │ │ ├── DumpTCP.png │ │ ├── DumpThreadPool.png │ │ ├── DumpVersion.png │ │ ├── ETWAnalyzer_ClippedOutput.png │ │ ├── EventHorizon20190410-78m.png │ │ ├── ExtractedDataFiles.png │ │ ├── ExtractionCommand.png │ │ ├── IETWExtract.png │ │ ├── PowerPlan.png │ │ ├── ProgramaticAccess.png │ │ ├── Raw │ │ │ └── CPUTimeFirstLast.png │ │ ├── ShowFileOnLine.png │ │ ├── SpeedScope.png │ │ ├── StackTags.png │ │ ├── WPA_DiskIO.png │ │ ├── WPA_FILEIO.png │ │ ├── WPA_Frequency.png │ │ ├── WPA_HandleLeak.png │ │ ├── WPA_HighCPUAnalysis.png │ │ ├── WPA_Memory.png │ │ ├── WPA_PowerSettings.png │ │ ├── WPA_TimeFormat.png │ │ ├── WPA_TraceStatistics.png │ │ ├── WPA_Trace_General.png │ │ ├── WindowsDefender_SMI.png │ │ ├── ZeroShutdownMetric.png │ │ └── ZeroTimeTimeoutExceptions.png │ ├── LoadSymbolCommand.md │ ├── ProgramaticAccess.md │ ├── StatsCommand.md │ └── ZeroTime.md ├── ETWAnalyzer.csproj ├── EventDump │ ├── DumpBase.cs │ ├── DumpBase_T.cs │ ├── DumpCPUMethod.cs │ ├── DumpCommands.cs │ ├── DumpDisk.cs │ ├── DumpDns.cs │ ├── DumpExceptions.cs │ ├── DumpFile.cs │ ├── DumpFileDirBase.cs │ ├── DumpFileEtlBase.cs │ ├── DumpLBR.cs │ ├── DumpMarks.cs │ ├── DumpMemory.cs │ ├── DumpModuleVersions.cs │ ├── DumpObjectRef.cs │ ├── DumpPMC.cs │ ├── DumpPower.cs │ ├── DumpProcesses.cs │ ├── DumpStats.cs │ ├── DumpTcp.cs │ ├── DumpThreadPool.cs │ └── TestRunDumper.cs ├── Extensions │ ├── ObjectCopyExtensions.cs │ ├── TestRunDataExtensions.cs │ └── TestRunExtensions.cs ├── Extract │ ├── CPU │ │ ├── CPUPerProcessMethodList.cs │ │ ├── CPUStats.cs │ │ ├── CPUTimeLine.cs │ │ ├── Extended │ │ │ ├── CPUExtended.cs │ │ │ ├── CPUTopology.cs │ │ │ ├── EnumExtensions.cs │ │ │ ├── FrequencyDuration.cs │ │ │ ├── FrequencySource.cs │ │ │ └── ReadyTimes.cs │ │ ├── ICPUPerProcessMethodList.cs │ │ ├── ICPUStats.cs │ │ ├── ICPUTimeLine.cs │ │ ├── IMethodsByProcess.cs │ │ ├── IProcessStackTags.cs │ │ ├── IProcessTimeLine.cs │ │ ├── IStackTagDuration.cs │ │ ├── MethodCost.cs │ │ ├── MethodsByProcess.cs │ │ ├── ProcessStackTags.cs │ │ ├── ProcessTimeLine.cs │ │ └── StackTagDuration.cs │ ├── Common │ │ ├── StackCollection.cs │ │ └── StackEventBase.cs │ ├── Disk │ │ ├── DiskActivity.cs │ │ ├── DiskIOData.cs │ │ ├── DiskIOEvent.cs │ │ ├── DiskLayout.cs │ │ ├── DiskNrOrDrive.cs │ │ ├── DiskPartition.cs │ │ ├── DiskTypes.cs │ │ ├── FileSystemFormat.cs │ │ ├── IDiskIOData.cs │ │ ├── IDiskLayout.cs │ │ └── IDiskPartition.cs │ ├── Display.cs │ ├── ETWExtract.cs │ ├── ETWMark.cs │ ├── ETWProcess.cs │ ├── Exception │ │ ├── ExceptionEventForQuery.cs │ │ ├── ExceptionMessageAndType.cs │ │ ├── ExceptionStackContainer.cs │ │ ├── ExceptionStats.cs │ │ └── IExceptionStats.cs │ ├── FileIO │ │ ├── FileCloseOperation.cs │ │ ├── FileDeleteOperation.cs │ │ ├── FileIOContainer.cs │ │ ├── FileIOData.cs │ │ ├── FileIOStatistics.cs │ │ ├── FileOffsetOperation.cs │ │ ├── FileOpenOperation.cs │ │ ├── FileRenameOperation.cs │ │ ├── FileSetSecurityOperation.cs │ │ ├── IFileIOData.cs │ │ └── PerProcessFileIOStats.cs │ ├── Handle │ │ ├── HandleCloseEvent.cs │ │ ├── HandleCreateEvent.cs │ │ ├── HandleDuplicateEvent.cs │ │ ├── HandleObjectData.cs │ │ ├── HandleProcess.cs │ │ ├── IHandleObjectData.cs │ │ ├── IObjectRefTrace.cs │ │ ├── ObjectRefTrace.cs │ │ ├── RefCountChangeEvent.cs │ │ └── VAMap.cs │ ├── IETWExtract.cs │ ├── IMemoryStats.cs │ ├── IProcessExtract.cs │ ├── IProcessNameResolver.cs │ ├── IProcessWorkingSet.cs │ ├── Memory │ │ └── VirtualAllocEvent.cs │ ├── MemoryStats.cs │ ├── ModuleVersion.cs │ ├── Modules │ │ ├── IModuleContainer.cs │ │ ├── IPdbIdentifier.cs │ │ ├── ModuleContainer.cs │ │ ├── ModuleDefinition.cs │ │ ├── PdbIdentifier.cs │ │ └── PdbIndex.cs │ ├── Network │ │ ├── DnsClient.cs │ │ ├── DnsEvent.cs │ │ ├── IDnsClient.cs │ │ ├── IDnsEvent.cs │ │ ├── INetwork.cs │ │ ├── Network.cs │ │ └── Tcp │ │ │ ├── Extensions.cs │ │ │ ├── ITcpConnection.cs │ │ │ ├── ITcpConnectionStatistics.cs │ │ │ ├── ITcpRetransmission.cs │ │ │ ├── ITcpStatistics.cs │ │ │ ├── SocketConnection.cs │ │ │ ├── TcpConnection.cs │ │ │ ├── TcpConnectionStatistics.cs │ │ │ ├── TcpRetransmission.cs │ │ │ └── TcpStatistics.cs │ ├── NtStatus.cs │ ├── PInvoke.NET │ │ ├── LICENSE │ │ └── WinErrorCodes.cs │ ├── PMC │ │ ├── ILBRData.cs │ │ ├── IMethodCall.cs │ │ ├── IPMCCounter.cs │ │ ├── IPMCData.cs │ │ ├── LBRData.cs │ │ ├── MethodCall.cs │ │ ├── PMCCounter.cs │ │ └── PMCData.cs │ ├── Power │ │ ├── BasePowerProfile.cs │ │ ├── HeteroThreadSchedulingPolicy.cs │ │ ├── IIdleConfiguration.cs │ │ ├── IPowerConfiguration.cs │ │ ├── IProcessorParkingConfiguration.cs │ │ ├── IdleConfiguration.cs │ │ ├── ParkingPerformanceState.cs │ │ ├── PowerConfiguration.cs │ │ ├── ProcessorParkingConfiguration.cs │ │ ├── ProcessorParkingPolicy.cs │ │ ├── ProcessorPerformanceBoostMode.cs │ │ ├── ProcessorPerformanceChangePolicy.cs │ │ ├── ProcessorThrottlePolicy.cs │ │ └── SystemCoolingPolicy.cs │ ├── ProcessKey.cs │ ├── ProcessRenamer │ │ ├── LICENSE │ │ └── ProcessRenamer.cs │ ├── ProcessWorkingSet.cs │ ├── SimplifiedProfiling │ │ ├── Enums.cs │ │ ├── Info.txt │ │ ├── OutputFileName.cs │ │ ├── ProfilingConstants.cs │ │ └── ProfilingStopArgs.cs │ ├── SingleTest.cs │ ├── TestDataFile.cs │ ├── TestRun.cs │ ├── TestRunData.cs │ ├── ThreadPool │ │ ├── IThreadPoolStats.cs │ │ ├── ThreadPoolStarvationInfo.cs │ │ └── ThreadPoolStats.cs │ └── TraceHeader.cs ├── Extractors │ ├── CPU │ │ ├── CPUExtractor.cs │ │ ├── CPUMethodData.cs │ │ ├── CpuFrequencyExtractor.cs │ │ ├── StackTagExtractor.cs │ │ └── TimelineExtractor.cs │ ├── Disk │ │ └── DiskExtractor.cs │ ├── Dns │ │ ├── DnsClientExtractor.cs │ │ ├── DnsQueryKey.cs │ │ ├── DnsRecordTypes.cs │ │ └── QueryState.cs │ ├── Exception │ │ ├── ExceptionCSVParser.cs │ │ └── ExceptionExtractor │ │ │ ├── ExceptionExtractor.cs │ │ │ └── LICENSE │ ├── ExtractSerializer.cs │ ├── ExtractSingleFile.cs │ ├── ExtractorBase.cs │ ├── FileIO │ │ └── FileExtractor.cs │ ├── Handle │ │ ├── MapFileEventObjects.cs │ │ ├── ObjectRefEventObjects.cs │ │ └── ObjectRefExtractor.cs │ ├── MachineDetailsExtractor.cs │ ├── Memory │ │ ├── MemoryExtractor.cs │ │ └── VirtualAllocExtractor.cs │ ├── Modules │ │ └── ModuleExtractor.cs │ ├── PMC │ │ └── PMCExtractor.cs │ ├── Power │ │ └── PowerExtractor.cs │ ├── SpecialEventsParser.cs │ ├── SymbolPaths.cs │ ├── TCP │ │ ├── IGenericTcpEvent.cs │ │ ├── IpNeighborState.cs │ │ ├── TCPExtractor.cs │ │ ├── TcpAcceptListenerComplete.cs │ │ ├── TcpCloseTcbRequest.cs │ │ ├── TcpConnectTcbFailedRcvdRst.cs │ │ ├── TcpConnectionKeepAlive.cs │ │ ├── TcpDataSend.cs │ │ ├── TcpDataTransferReceive.cs │ │ ├── TcpDisconnectTcbRtoTimeout.cs │ │ ├── TcpRequestConnect.cs │ │ ├── TcpRetransmit.cs │ │ ├── TcpShutdownTcb.cs │ │ ├── TcpTailLossProbe.cs │ │ └── TcpTemplateChanged.cs │ ├── TestRunConfiguration.cs │ └── ThreadPool │ │ └── ThreadPoolExtractor.cs ├── GlobalSuppressions.cs ├── Infrastructure │ ├── ColorConsole │ │ ├── ColorConsole.cs │ │ └── LICENSE │ ├── ColumnDefinition.cs │ ├── ColumnFormatter.cs │ ├── Counter.cs │ ├── CtrlCHandler │ │ ├── CtrlCHandler.cs │ │ └── LICENSE │ ├── Deleter.cs │ ├── EnumerableSorterExtensions.cs │ ├── ExceptionHelper.cs │ ├── Extensions.cs │ ├── Formatter.cs │ ├── JsonCreationBase.cs │ ├── Logger.cs │ ├── Matcher.cs │ ├── MinMaxRange.cs │ ├── MultilineFormatter.cs │ ├── Numeric.cs │ ├── PerfLogger.cs │ ├── ReusableMemoryStream.cs │ ├── SkipTakeRange.cs │ ├── StringFormatExtensions.cs │ ├── TimeRangeCalculatorDateTime.cs │ └── UniqueStringList.cs ├── LoadSymbol │ ├── SymbolLoader.cs │ └── TraceEvent │ │ ├── LICENSE │ │ ├── NativeDlls.cs │ │ └── SymbolModule.cs ├── MakeRelease.cmd ├── ProcessTools │ ├── ETLZipCommand.cs │ ├── ExecResult.cs │ ├── InvalidZipContentsException.cs │ ├── ProcessCommand.cs │ ├── TempDir.cs │ ├── ValueConverter.cs │ └── WpaExportCommand.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── PublishProfiles │ │ ├── Net48.pubxml │ │ └── Net80_SelfContained.pubxml │ └── app.manifest ├── Settings.Designer.cs ├── Settings.settings ├── TraceProcessorHelpers │ ├── ConsoleSymbolProcess.cs │ ├── DnsClientETWConstants.cs │ ├── DotNetETWConstants.cs │ ├── Extensions.cs │ ├── KernelPowerConstants.cs │ ├── MethodFormatter.cs │ ├── NativeHeaders.cs │ ├── StackPrinter.cs │ ├── TcpETWConstants.cs │ ├── TimeRangeCalculator.cs │ └── WindowsConstants.cs └── runtimeconfig.template.json ├── ETWAnalyzer_iTest ├── ETWAnalyzer_iTest.csproj ├── ProgramTestsLong.cs └── Properties │ └── AssemblyInfo.cs ├── ETWAnalyzer_uTest ├── AnalyzeTestCountTests.cs ├── BitmappingTests.cs ├── CPUPerProcessMethodListTests.cs ├── DeleterTests.cs ├── DiskExtractorTests.cs ├── ETLZipCommandTests.cs ├── ETWAnalyzer_uTest.csproj ├── EventDump │ ├── DumpBaseTests.cs │ ├── DumpCPUMethodTests.cs │ ├── DumpDnsTests.cs │ ├── DumpExceptionTests.cs │ ├── DumpFileDirBaseTests.cs │ ├── DumpFileTests.cs │ ├── DumpMemoryTests.cs │ ├── DumpProcessesTests.cs │ └── DumpTcpTests.cs ├── ExceptionAssert.cs ├── ExceptionByDurationAnomalieAnalyzerTests.cs ├── ExceptionDataCleanerTests.cs ├── ExceptionDifferenceAnalyzerPersistentTests.cs ├── ExceptionDifferenceVolatileAnalyzerTests.cs ├── ExceptionFilterTests.cs ├── ExceptionOccurrenceAnalyzerTests.cs ├── Extract │ ├── CPUFrequencyTests.cs │ ├── ConvertCommandTests.cs │ ├── DnsExtractorTests.cs │ ├── ETWExtractTests.cs │ ├── ETWProcessTests.cs │ ├── ExceptionMessageAndTypeTests.cs │ ├── ExtractCommandTests.cs │ ├── FileExtractorTests.cs │ ├── MachineDetailsExtractorTests.cs │ ├── MemoryStatsTests.cs │ ├── ModuleContainerTests.cs │ ├── OutputFileNameTests.cs │ ├── PMCExtractorTests.cs │ ├── PdbIdentifierTests.cs │ ├── SymbolPathsTests.cs │ ├── TcpExtractorTests.cs │ └── TimelineExtractorTests.cs ├── ExtractSingleFileTests.cs ├── Extractors │ └── ExtractSerializerTests.cs ├── GlobalSuppressions.cs ├── Infrastructure │ ├── ArgsParserTests.cs │ ├── CounterTests.cs │ ├── ExtensionsTests.cs │ ├── MatcherTests.cs │ ├── MinMaxRangeTests.cs │ ├── MultilineFormatterTests.cs │ ├── NumericTests.cs │ ├── SorterExtensionTests.cs │ ├── TimeRangeCalculatorDateTimeTests.cs │ ├── TimeRangeCalculatorTests.cs │ └── UniqueStringList.cs ├── LinearRegressionTest.cs ├── MethodCostsTests.cs ├── ProgramTests.cs ├── Properties │ └── AssemblyInfo.cs ├── SingleTestTests.cs ├── TempDirTests.cs ├── TestData.cs ├── TestData │ ├── CPUWeight.wpaProfile │ ├── CallupAdhocWarmReadingCT_3117msDEFOR09T121SRV.20200717-124447.7z │ ├── CallupAdhocWarmReadingCT_3117msDEFOR09T121SRV.20200717-124447.json │ ├── CallupAdhocWarmReadingCT_3117msFO9DE01T0162PC.20200717-124447.7z │ ├── CallupAdhocWarmReadingCT_3117msFO9DE01T0162PC.20200717-124447.json │ ├── DiscIO.wpaProfile │ ├── Disk_Usage_Utilization_by_Disk.csv │ ├── Disk_Usage_Utilization_by_Disk_DE.csv │ ├── Disk_Usage_Utilization_by_Disk_Empty.csv │ ├── EmptyETL.7z │ ├── ExceptionFilters.xml │ ├── MemoryCategory.wpaProfile │ ├── MemoryVirtualAlloc.wpaProfile │ ├── SampleBitmapping │ │ ├── 1 │ │ │ ├── Blue.png │ │ │ └── Red.png │ │ └── 2 │ │ │ └── Yellow.png │ ├── SampleData │ │ └── SampleData.7z │ ├── SampleDataJson │ │ └── Extract │ │ │ └── SampleDataJsonFiles.sample │ ├── SampleDataMoreMachines │ │ └── SampleDataMoreMachines.7z │ ├── SampleDataV2 │ │ └── SampleDataV2.7z │ ├── TestRunConfiguration.xml │ ├── ZipWith7zLogFile.7z │ ├── ZipWithTextFile.7z │ └── ZipWithTwoFiles.zip ├── TestDataFileTests.cs ├── TestInfrastructure │ ├── CultureSwitcher.cs │ ├── DataOutput.cs │ ├── ExceptionalPrinter.cs │ └── TestContext.cs ├── TestRunCreator.cs ├── TestRunDataTests.cs ├── TestRunTests.cs ├── ValueAnomalieDetectorTest.cs └── WpaExporterTests.cs ├── LICENSE ├── ReadMe.md ├── Samples └── EventLeak │ ├── EventLeak.cpp │ └── EventLeak.vcxproj └── Test.runsettings /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # CA1717: Only FlagsAttribute enums should have plural names 4 | dotnet_diagnostic.CA1717.severity = silent 5 | 6 | # CA1303: Do not pass literals as localized parameters 7 | dotnet_diagnostic.CA1303.severity = none 8 | 9 | # CA3075: Insecure DTD processing in XML 10 | dotnet_diagnostic.CA3075.severity = none 11 | 12 | # CA5369: Use XmlReader For Deserialize 13 | dotnet_diagnostic.CA5369.severity = none 14 | 15 | # CA2227: Collection properties should be read only 16 | dotnet_diagnostic.CA2227.severity = none 17 | 18 | # CA1308: Normalize strings to uppercase 19 | dotnet_diagnostic.CA1308.severity = silent 20 | 21 | # CA1822: Member LoadScreenshotOfTest does not access instance data and can be marked as static (Shared in VisualBasic) 22 | dotnet_diagnostic.CA1822.severity = silent 23 | 24 | # CA1034: Nested types should not be visible 25 | dotnet_diagnostic.CA1034.severity = none 26 | 27 | # IDE0059: Unnötige Zuweisung eines Werts. 28 | csharp_style_unused_value_assignment_preference = discard_variable:none 29 | 30 | # IDE0075: Simplify conditional expression 31 | dotnet_diagnostic.IDE0075.severity = none 32 | 33 | # IDE0038: Use pattern matching 34 | dotnet_diagnostic.IDE0038.severity = none 35 | 36 | # CA1707: Identifiers should not contain underscores 37 | dotnet_diagnostic.CA1707.severity = silent 38 | 39 | # CA1028: Enum Storage should be Int32 40 | dotnet_diagnostic.CA1028.severity = silent 41 | 42 | dotnet_diagnostic.CA5369.severity = silent 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | To get most details please let ETWAnalyzer run with the -debug switch to get extended console output. 12 | In many cases the log file is of great help to identify the issue. 13 | 14 | **To Reproduce** 15 | If the error is not dependent on the input ETL file you can share the used command line 16 | to force the error. 17 | If during extraction with specific ETL files goes wrong we would need that file to reproduce the issue and talk potentially to the maintainers of TraceProcessing if that is the expected behavior. 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | **Feature Request** 2 | 3 | Describe what the feature is about. 4 | 5 | **Feature Description** 6 | 7 | Describe how it is implemented. 8 | 9 | **Example** 10 | 11 | Show usage examples. 12 | -------------------------------------------------------------------------------- /BuildScripts/RemoveStrict.ps1: -------------------------------------------------------------------------------- 1 | param([string] $InputFileName) 2 | # Replace in .wprp file Strict="true" to nothing to make recording of wpr data possible 3 | # even when some CPU counter recording is already running 4 | # This looks to be some bug of WPR which bails out even if you do not intend to record any CPU counters 5 | 6 | Write-Host Input: $InputFileName 7 | $var=(Get-Content -path $InputFileName -Raw); 8 | $replaced=$var.Replace('Strict="true"',''); 9 | #Write-Host $replaced 10 | Set-Content -Value $replaced -Path $InputFileName 11 | -------------------------------------------------------------------------------- /ETWAnalyzer/3rdParty/7-Zip/7z.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/3rdParty/7-Zip/7z.dll -------------------------------------------------------------------------------- /ETWAnalyzer/3rdParty/7-Zip/7z.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/3rdParty/7-Zip/7z.exe -------------------------------------------------------------------------------- /ETWAnalyzer/3rdParty/7-Zip/7z1900-src.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/3rdParty/7-Zip/7z1900-src.7z -------------------------------------------------------------------------------- /ETWAnalyzer/3rdParty/Microsoft.Windows.EventTracing.Processing/traceprocessing-eula.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/3rdParty/Microsoft.Windows.EventTracing.Processing/traceprocessing-eula.pdf -------------------------------------------------------------------------------- /ETWAnalyzer/Analyzers/CPU/StackTagAnalyzer.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Commands; 5 | using ETWAnalyzer.Extract; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace ETWAnalyzer.Analyzers.CPU 13 | { 14 | class StackTagAnalyzer : AnalyzerBase 15 | { 16 | public override void AnalyzeTestRun(TestAnalysisResultCollection issues, TestRun run) 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | 21 | public override void AnalyzeTestsByTime(TestAnalysisResultCollection issues, TestDataFile backend, TestDataFile frontend) 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | 26 | public override void Print() 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | 31 | public override void TakePersistentFlagsFrom(AnalyzeCommand analyzeCommand) 32 | { 33 | throw new NotImplementedException(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ETWAnalyzer/Analyzers/Exception/ResultPrinter/ColorConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Analyzers.Exception.ResultPrinter 8 | { 9 | static class ColorConfig 10 | { 11 | public const ConsoleColor ColorOutliers = ConsoleColor.Yellow; 12 | public const ConsoleColor ColorTrends = ConsoleColor.DarkCyan; 13 | public const ConsoleColor ColorHeadings = ConsoleColor.White; 14 | public const ConsoleColor ColorRelevantProcesses = ConsoleColor.Magenta; 15 | public const ConsoleColor ColorExceptionTyp = ConsoleColor.Green; 16 | public const ConsoleColor ColorExceptionMsg = ConsoleColor.Cyan; 17 | public const ConsoleColor ColorExceptionStack = ConsoleColor.White; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ETWAnalyzer/Analyzers/Problem/Classification.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Analyzers 11 | { 12 | 13 | /// 14 | /// Clasifies a potential issue into several sub sub groups 15 | /// 16 | public enum Classification 17 | { 18 | /// 19 | /// Data file of frontend or backend is missing. By default we expect two ETL files 20 | /// 21 | MissingETWData, 22 | 23 | /// 24 | /// Machine setup or other things like Windows Update or NGen is running which can influence the test 25 | /// 26 | EnvironmentProblem, 27 | 28 | /// 29 | /// Functional issues in our software like exceptions in the UI or not working UI at all 30 | /// 31 | Functional, 32 | 33 | /// 34 | /// Performance related issue was identified 35 | /// 36 | Performance 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ETWAnalyzer/Analyzers/Problem/Severities.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Analyzers 11 | { 12 | /// 13 | /// 14 | /// 15 | public enum Severities 16 | { 17 | /// 18 | /// Info only 19 | /// 20 | Info, 21 | 22 | /// 23 | /// Warning 24 | /// 25 | Warning, 26 | 27 | /// 28 | /// Fatal. Needs attention 29 | /// 30 | Fatal 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ETWAnalyzer/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | C:\Symbols 24 | 25 | 26 | SRV*C:\Symbols*https://msdl.microsoft.com/download/symbols 27 | 28 | 29 | SRV*C:\Symbols*https://build-syngo.healthcare.siemens.com/symbols/ 30 | 31 | 32 | SRV*C:\Symbols*https://chromium-browser-symsrv.commondatastorage.googleapis.com 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /ETWAnalyzer/Commands/ICommand.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Commands 11 | { 12 | /// 13 | /// Generic interface for command line parsing and command execution 14 | /// 15 | interface ICommand : ICommandExecutor, ICommandLineParser 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ETWAnalyzer/Commands/ICommandExecutor.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Commands 11 | { 12 | 13 | /// 14 | /// Concrete command which is executed via command line input arguments 15 | /// 16 | interface ICommandExecutor 17 | { 18 | /// 19 | /// Execute command. If an error happens there we will not print the command line help again. 20 | /// 21 | void Run(); 22 | 23 | /// 24 | /// Return code which should be returned by executable when command is finished. 25 | /// 26 | public int? ReturnCode { get; } 27 | 28 | 29 | /// 30 | /// Get Help for current Command 31 | /// 32 | public string Help 33 | { 34 | get; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer/Commands/ICommandLineParser.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Commands 12 | { 13 | /// 14 | /// Parses a previously supplied command line. 15 | /// 16 | interface ICommandLineParser 17 | { 18 | /// 19 | /// Parse supplied command line and throw an exception when not all needed or unkonw arguments were passed. 20 | /// If during parse an error happens the help will be printed before the actual error. 21 | /// 22 | void Parse(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ETWAnalyzer/Commands/MissingInputException.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Runtime.Serialization; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Commands 12 | { 13 | /// 14 | /// Thrown when we have no input file or Directory 15 | /// 16 | class MissingInputException : ApplicationException 17 | { 18 | public MissingInputException() 19 | { 20 | } 21 | 22 | public MissingInputException(string message) : base(message) 23 | { 24 | } 25 | 26 | public MissingInputException(string message, Exception innerException) : base(message, innerException) 27 | { 28 | } 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ETWAnalyzer/Commands/OutDir.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Commands 12 | { 13 | class OutDir 14 | { 15 | public string OutputDirectory 16 | { 17 | get; set; 18 | } 19 | 20 | /// 21 | /// Temporary extraction path 22 | /// 23 | public string TempDirectory 24 | { 25 | get;set; 26 | } 27 | 28 | public bool IsDefault 29 | { 30 | get;set; 31 | } 32 | 33 | public void SetDefault(string outputDirectory) 34 | { 35 | OutputDirectory = TestRun.GetDirectorySave(outputDirectory); // Do not store file query like c:\temp\*.etl 36 | IsDefault = true; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ETWAnalyzer/Configuration/DllToBuildMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "MarkerFiles": [ 3 | { 4 | "DllName": "SomeDll.dll", 5 | "VersionVector": "Some" 6 | }, 7 | 8 | ] 9 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Configuration/GCAndJit.stacktags: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ETWAnalyzer/Configuration/ProcessRenameRules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | svchost.exe 6 | 7 | -s EventLog 8 | 9 | svchost Event Log Service 10 | 11 | 12 | svchost.exe 13 | 14 | -s TermService 15 | 16 | svchost RDP Service 17 | 18 | 19 | svchost.exe 20 | 21 | -s Winmgmt 22 | 23 | svchost WMI Service 24 | 25 | 26 | svchost.exe 27 | 28 | LocalServiceNoNetworkFirewall 29 | 30 | svchost Firewall 31 | 32 | 33 | -------------------------------------------------------------------------------- /ETWAnalyzer/Configuration/RequiredPdbs.txt: -------------------------------------------------------------------------------- 1 | // Flat list of pdb files names which must be loaded to be able to properly use stacktags 2 | // .NET Runtime, some Windows dlls and ivt for volume loading must be present 3 | clr.pdb 4 | ntdll.pdb 5 | kernel32.pdb 6 | gdi32.pdb 7 | 8 | -------------------------------------------------------------------------------- /ETWAnalyzer/Configuration/Special.stacktags: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ETWAnalyzer/Configuration/TestRunConfiguration.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Example 5 | 10 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ETWAnalyzer/Converters/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) .NET Foundation and Contributors 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/ConvertCommand.md: -------------------------------------------------------------------------------- 1 | # -Convert 2 | Convert the CPU sampling data of an ETL File a process to a [speedscope](https://www.speedscope.app/) json file. This was adapted 3 | from [PerfView]( https://github.com/microsoft/perfview/blob/main/src/TraceEvent/Stacks/SpeedScopeStackSourceWriter.cs) which contains the original code. 4 | 5 | Unlike the original code for PerfView it can generate flamegraphs for all threads in a process or even a system wide overview from all processes from all threads. 6 | This can be useful if the input data cannot be viewed with WPA due to time inversion or other recording issues. 7 | 8 | ## Example 9 | 10 | This will convert all processes and all threads into a speedscope file: 11 | ``` 12 | C>ETWAnalyzer -convert -fd 15_18_01.13LongTrace.etl -pid -1 13 | Converting all processes system wide into one file. 14 | Converted File: 15_18_01.13LongTrace_AllProcesses.speedscope 15 | ``` 16 | 17 | Time correlation is lost but it is good to check where most CPU is spent in total. 18 | 19 | ![](Images/SpeedScope.png "SpeedScope") -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/DumpDiskCommand.md: -------------------------------------------------------------------------------- 1 | # -Dump Disk 2 | 3 | Dump Disk IO metrics where the hard disk did actually some work. Unlike FileIO DiskIO normally contains much less data 4 | because if you read the same file again, the second time, the read will be served from the file system cache. If your 5 | disk is some tiered storage like a SAN or a RAID then you still might get to see some cache effects due to e.g. RAID controller 6 | cache effects. 7 | DiskIO is not easy to attribute to a specific process, because many optimizations are in place. If you open a file and then read 8 | a few KB the OS will prefetch data by doing some read ahead caching which can result that an application is not paying of the 9 | IO because it did parse the data so slow that the OS had plenty of time to prefetch data. See [this article of my old blog](https://web.archive.org/web/20141230191825/http://geekswithblogs.net/akraus1/archive/2014/12/14/160652.aspx). 10 | 11 | ![WPA_DiskIO](Images/WPA_DiskIO.png) 12 | 13 | ETWAnalyzer can show aggregates per directory which is configurable via -DirLevel, Read/Write throughput for one, or if *-Merge* is 14 | used a collection of files to check e.g. average throughput over an extended test run. 15 | 16 | ![](Images/DumpDisk.png "Dump Disk") 17 | 18 | You can also get per file metrics by using *-DirLevel 100*. If the output does not suit your needs you can export the data 19 | to a CSV file and analyze it further with Excel or R. 20 | 21 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/DumpExceptionCommand.md: -------------------------------------------------------------------------------- 1 | # -Dump Exception 2 | 3 | Dump all thrown .NET Exceptions. The ETW Provider also logs all rethrows so you might see for a single exception multiple 4 | timepoints. Each rethrow, finally, and using blocks which also use a finally block will rethrow an exception. 5 | 6 | Exceptions are filtered during extraction time with filters defined in the file Configuration/ExceptionFilters.xml. 7 | If you do not want to apply the default filters use during extraction the option *-allExceptions*. 8 | ![](Images/DumpException.png "Dump Exception") 9 | 10 | Exceptions are grouped by File/Process/Type/Message to get readable output. There are multiple options to filter by 11 | - Process ( *-ProcessName* ) 12 | - Process Command Line ( *-CmdLine* ) 13 | - Type ( *-Type* ) 14 | - Message ( *-Message* ) 15 | - Stacktrace ( *-StackFilter* ) 16 | 17 | See [Filters](Filters.md) for more information. 18 | 19 | The exception stacktrace can be displayed after at least one filter was entered with the *-ShowStack* option. 20 | Another useful option is the concept of zerotime to relate exceptions after a specifc method has been seen in the trace. 21 | 22 | The following command will e.g. print exception time relative to the first ocurrence of the method ShowShutdownWindow and store 23 | them in a CSV file. 24 | 25 | >EtwAnalyzer -dump exception -type *timeout* -timefmt s -zerotime first *ShowShutdownWindow* -csv Exceptions.csv -timefmt s 26 | 27 | This allows you to generated e.g. a graph of all TimeoutException 28 | 29 | ![](Images/ZeroTimeTimeoutExceptions.png) 30 | 31 | In this case we know that the default WCF (Windows Communication Foundation) close timeout is 10s. During the shutdown of connected WCF services we see 32 | certain processes hang due to stuck WCF calls which resolve around 10s, 16s, 30s and 36s. As a next step one needs to 33 | identify which processes are killed too early because other processes were still using them hindering a timely shutdown 34 | of the whole system. 35 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/DumpMarkCommand.md: -------------------------------------------------------------------------------- 1 | # -Dump Mark 2 | 3 | WPA has an ETW Marker graph which is useful to navigate to central timepoints of an instrumented test case. 4 | You can write your own marker events via the undocumented API [EtwSetMark](https://web.archive.org/web/20170921050719/http://geekswithblogs.net/akraus1/archive/2015/09/26/167117.aspx) 5 | which needs a ETW Tracing session id (0 is the default kernel session of the NT Kernel Logger which is used by xperf) and the string. 6 | 7 | ![](Images/DumpMark.png "Dump Mark") 8 | 9 | You can use any marker event in other commands to show timing relative to a marker mesasage. That enables method timings relative to the e.g. the Profiling_Start marker message which indicates the start of a profiling action. See [ZeroTime feature](ZeroTime.md) for more information 10 | 11 | To see all marker events relative to the start marker you can use this command 12 | 13 | > EtwAnalyzer -dump mark -timefmt s -ZeroTime marker *Profiling_Start* 14 | 15 | where %f% is an environment variable with *set f=-fd xxxx.json* to the actual Json file to shorten the command line. 16 | 17 | ![](Images/DumpMark_ZeroTime.png "Dump Mark ZeroTime") 18 | 19 | 20 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/DumpThreadPoolCommand.md: -------------------------------------------------------------------------------- 1 | # -Dump ThreadPool 2 | 3 | Dump occurrences of .NET ThreadPool starvation events. These are useful to determine if 4 | an application could have become slower due to increased async/await or TPL usage. The .NET Framework will add a new 5 | TPL thread with a 1s delay when the ThreadPool size has reached the core count. Things have 6 | changed with .NET 6.0 but it is still useful to see. 7 | 8 | ![](Images/DumpThreadPool.png "Dump ThreadPool") 9 | 10 | To get output you need to record with the .NET ETW provider named Microsoft-Windows-DotNETRuntime with the ThreadingKeyword 0x10000. 11 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/DumpVersionCommand.md: -------------------------------------------------------------------------------- 1 | # -Dump Version 2 | 3 | Dump file version of all loaded executables (.exe, .dll and .sys files) of all running processes. 4 | 5 | The concept of loaded Modules is only applicable our internal versioning scheme. 6 | 7 | To dump all device driver versions you can use 8 | 9 | > -dump Version -dll *.sys 10 | 11 | That will give you a large list of all device drivers. Most interesting are non MS drivers which can cause problems. Since all 12 | Windows drivers come with the same OS version build number you can simply exclude all drivers versioned with the Windows version number. 13 | Then you get a list of all external or non standard device drivers: 14 | 15 | ![](Images/DumpVersion.png) 16 | 17 | The *-VersionFilter* string matches everything except the file name which is covered by the *-dll* filter string. 18 | 19 | This way you can quickly identify antivirus drivers of lesser known companies which might cause problems on that specific machine. 20 | 21 | You can also view your own dll file versions loaded by any processes. Select with *-processname* any process from one or a 22 | collection of extracted ETL files to trend your build versions if an issue was introduced with a specific build. 23 | 24 | All commands except -dump TestRun support the *-CSV* option to write the data into a CSV file for further processing. 25 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Filters.md: -------------------------------------------------------------------------------- 1 | # Filters 2 | 3 | ETWAnalyzer supports for all input arguments which work as a filter a common filtering semantic. 4 | A filter string can define multiple in- and exclusion filters. 5 | 6 | 7 | - Filters can be combined with ; as separator e.g. *a;b* 8 | - Exclusion are filters are supported and start with ! e.g. *!a* 9 | - Filters support wildcards 10 | - The character * matches 0 or all characters. E.g. \*chrome\* 11 | - ? matches 0 or one character 12 | 13 | A typical Process query which selects all chrome processes but no chromers would be 14 | 15 | > -ProcessName \*chrome\*;!\*chromers\* 16 | 17 | An exception filter which filters all TimeoutExceptions 18 | 19 | > -Type \*TimeOutException\* 20 | -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/BuildArtifacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/BuildArtifacts.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/BuildProfiling_AVOverhead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/BuildProfiling_AVOverhead.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/BuildProfiling_LoadSymbols.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/BuildProfiling_LoadSymbols.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/BuildProfiling_MethodLevel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/BuildProfiling_MethodLevel.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/BuildProfiling_ProfilingDataView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/BuildProfiling_ProfilingDataView.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/BuildProfiling_Stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/BuildProfiling_Stats.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/CPUTimeFirstLast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/CPUTimeFirstLast.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUAVShowTotal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUAVShowTotal.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUAV_SortByWait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUAV_SortByWait.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUExtended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUExtended.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTop10Stacktags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTop10Stacktags.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTop20Methods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTop20Methods.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTop30Methods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTop30Methods.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTop5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTop5.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTop9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTop9.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTopN2ProcessFmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTopN2ProcessFmt.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPUTopology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPUTopology.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPU_All.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPU_All.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPU_FirstLastDurationCorrelation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPU_FirstLastDurationCorrelation.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPU_Normalized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPU_Normalized.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpCPU_ZeroTime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpCPU_ZeroTime.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpDisk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpDisk.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpDnsCommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpDnsCommand.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpDnsTopN15_ShowAdapter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpDnsTopN15_ShowAdapter.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpException.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpException.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpFile.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpFile_Details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpFile_Details.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpFile_PerFileClippedAndReversed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpFile_PerFileClippedAndReversed.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpLBRExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpLBRExample.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpLBRExample_Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpLBRExample_Overview.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpMark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpMark.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpMark_ZeroTime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpMark_ZeroTime.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpMemory_Top5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpMemory_Top5.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpMemory_Total.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpMemory_Total.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpMemory_TotalMemory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpMemory_TotalMemory.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpObjectRef_Filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpObjectRef_Filter.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpObjectRef_Inherit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpObjectRef_Inherit.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpObjectRef_Leak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpObjectRef_Leak.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpObjectRef_LeakStack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpObjectRef_LeakStack.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpPMC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpPMC.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcessTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcessTree.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_Clip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_Clip.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_Crash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_Crash.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_CtrlC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_CtrlC.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_Merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_Merge.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_RenamedSvcHost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_RenamedSvcHost.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_TimeFmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_TimeFmt.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpProcess_User.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpProcess_User.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpStatsCommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpStatsCommand.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpTCP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpTCP.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpThreadPool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpThreadPool.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/DumpVersion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/DumpVersion.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ETWAnalyzer_ClippedOutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ETWAnalyzer_ClippedOutput.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/EventHorizon20190410-78m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/EventHorizon20190410-78m.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ExtractedDataFiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ExtractedDataFiles.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ExtractionCommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ExtractionCommand.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/IETWExtract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/IETWExtract.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/PowerPlan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/PowerPlan.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ProgramaticAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ProgramaticAccess.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/Raw/CPUTimeFirstLast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/Raw/CPUTimeFirstLast.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ShowFileOnLine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ShowFileOnLine.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/SpeedScope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/SpeedScope.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/StackTags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/StackTags.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_DiskIO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_DiskIO.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_FILEIO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_FILEIO.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_Frequency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_Frequency.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_HandleLeak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_HandleLeak.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_HighCPUAnalysis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_HighCPUAnalysis.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_Memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_Memory.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_PowerSettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_PowerSettings.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_TimeFormat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_TimeFormat.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_TraceStatistics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_TraceStatistics.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WPA_Trace_General.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WPA_Trace_General.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/WindowsDefender_SMI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/WindowsDefender_SMI.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ZeroShutdownMetric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ZeroShutdownMetric.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/Images/ZeroTimeTimeoutExceptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer/Documentation/Images/ZeroTimeTimeoutExceptions.png -------------------------------------------------------------------------------- /ETWAnalyzer/Documentation/LoadSymbolCommand.md: -------------------------------------------------------------------------------- 1 | # -LoadSymbol 2 | If you collect data offline or behind a firewall and you do not want to send around large ETL files you can also extract CPU data 3 | without symbol server support. You will get then from a a multi GB .etl file a small just a few MB sized json7z file which can be shared 4 | even per EMail. 5 | 6 | At the remote site you can still look up method names by rewriting the Json file with a remote symbol server. 7 | 8 | ``` 9 | C>EtwAnalyzer -LoadSymbol -fd 15_12_24.13LongTrace.json7z -symserver ms 10 | Processing file 1/1 15_12_24.13LongTrace.json7z 11 | Resolved 412 pdbs. Still missing: 14 12 | Resolved 2465 methods. 13 | ``` 14 | 15 | ## Limitations 16 | Currently only CPU data is supported. 17 | Late PDB resolution is currently not supported for 18 | 19 | - Exception 20 | - Handle 21 | 22 | data. 23 | 24 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extensions/ObjectCopyExtensions.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.JsonSerializing; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.Serialization.Formatters.Binary; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extensions 11 | { 12 | internal static class ObjectCopyExtensions 13 | { 14 | public static T GetDeepCopy(this T objSource) 15 | { 16 | using (MemoryStream stream = new MemoryStream()) 17 | { 18 | JsonCreationBase json = new JsonCreationBase(); 19 | json.SerializeToJson(objSource, stream); 20 | stream.Position = 0; 21 | T lret = JsonCreationBase.DeserializeJson(stream); 22 | return lret; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/Extended/CPUTopology.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.CPU.Extended 11 | { 12 | /// 13 | /// Contains Nominal CPU Frequency and other CPU data 14 | /// 15 | public interface ICPUTopology 16 | { 17 | /// 18 | /// 100% CPU Frequency with no turbo boost 19 | /// 20 | 21 | int NominalFrequencyMHz { get; } 22 | 23 | /// 24 | /// This number is not based on actual measurements. It could be used as some sort criteria but not to judge CPU performance. 25 | /// 26 | int RelativePerformancePercentage { get; } 27 | 28 | /// 29 | /// EfficiencyClass starts at zero with most efficient but slowest CPUs. The highest number has the most performant (P) Cores. 30 | /// 31 | EfficiencyClass EfficiencyClass { get; } 32 | } 33 | 34 | /// 35 | /// Contains Nominal CPU Frequency and other CPU data 36 | /// 37 | public class CPUTopology : ICPUTopology 38 | { 39 | /// 40 | /// 100% CPU Frquency with no turbo boost 41 | /// 42 | public int NominalFrequencyMHz { get; set; } 43 | 44 | /// 45 | /// This number is not based on actual measurements. It could be used as some sort criteria but not to judge CPU performance. 46 | /// 47 | public int RelativePerformancePercentage { get; set; } 48 | 49 | /// 50 | /// EfficiencyClass starts at zero with most efficient but slowest CPUs. The highest number has the most performant (P) Cores. 51 | /// 52 | public EfficiencyClass EfficiencyClass { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/Extended/EnumExtensions.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.CPU.Extended 5 | { 6 | /// 7 | /// Helper methods to convert a combined ProcessMethodIdx to/from ETWProcessIndex and MethodIndex. 8 | /// 9 | public static class EnumExtensions 10 | { 11 | /// 12 | /// Get MethodIndex from ProcessMethodIdx. 13 | /// 14 | /// 15 | /// 16 | public static MethodIndex MethodIndex(this ProcessMethodIdx processMethodIdx) 17 | { 18 | return (MethodIndex)((long)processMethodIdx & 0xFFFFF); 19 | } 20 | 21 | 22 | /// 23 | /// Get ETWProcessIndex from ProcessMethodIndex. 24 | /// 25 | /// 26 | /// 27 | public static ETWProcessIndex ProcessIndex(this ProcessMethodIdx processMethodIdx) 28 | { 29 | return (ETWProcessIndex) ((long)processMethodIdx >> 20); 30 | } 31 | 32 | /// 33 | /// Create a combined index from ETWProcessIndex and MethodIndex. 34 | /// 35 | /// Process Index can consume up to 44 bits. 36 | /// We support up to 1 million methods (20 bits). 37 | /// 38 | public static ProcessMethodIdx Create(this ETWProcessIndex process, MethodIndex method) 39 | { 40 | return (ProcessMethodIdx)(((long)process << 20) | (long) method); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/Extended/FrequencyDuration.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace ETWAnalyzer.Extract.CPU.Extended 7 | { 8 | 9 | /// 10 | /// Contains sampled frequency for a time range for one core. 11 | /// 12 | public struct FrequencyDuration : IComparer 13 | { 14 | /// 15 | /// Average CPU Frequency in MHz during that time range. 16 | /// 17 | public int FrequencyMHz { get; set; } 18 | 19 | /// 20 | /// Start time 21 | /// 22 | public float StartS { get; set; } 23 | 24 | /// 25 | /// End time 26 | /// 27 | public float EndS { get; set; } 28 | 29 | /// 30 | /// Use for BinarySearch where as input one duration has same Start/End timings. 31 | /// Two durations are equal if the one with same Start/End time is in the range of the other range where Start/End. 32 | /// 33 | /// 34 | /// 35 | /// 36 | public int Compare(FrequencyDuration x, FrequencyDuration y) 37 | { 38 | if (x.StartS == x.EndS) 39 | { 40 | if (x.StartS >= y.StartS && 41 | x.StartS <= y.EndS) 42 | { 43 | return 0; 44 | } 45 | else 46 | return x.StartS.CompareTo(y.StartS); 47 | } 48 | else 49 | { 50 | if (y.StartS >= x.StartS && 51 | y.StartS <= x.EndS) 52 | { 53 | return 0; 54 | } 55 | else 56 | return x.StartS.CompareTo(y.StartS); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/ICPUPerProcessMethodList.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace ETWAnalyzer.Extract 7 | { 8 | /// 9 | /// Read only part of CPU consumption metrics 10 | /// 11 | public interface ICPUPerProcessMethodList 12 | { 13 | /// 14 | /// If true no CPU threshold of 10ms was applied during extraction 15 | /// 16 | bool ContainsAllCPUData { get; } 17 | 18 | /// 19 | /// Input ETL file has recorded Context Switch Data 20 | /// 21 | public bool? HasCSwitchData { get; } 22 | 23 | /// 24 | /// Input ETL file has recorded CPU sampling data 25 | /// 26 | public bool? HasCPUSamplingData { get; } 27 | 28 | /// 29 | /// List of all methods found in ETL file 30 | /// 31 | IReadOnlyList MethodNames { get; } 32 | 33 | /// 34 | /// Store per process per method the CPU in ms 35 | /// Index based structure to support compact serialization 36 | /// 37 | IReadOnlyList MethodStatsPerProcess { get; } 38 | } 39 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/ICPUStats.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract.CPU; 5 | using ETWAnalyzer.Extract.CPU.Extended; 6 | using System.Collections.Generic; 7 | 8 | namespace ETWAnalyzer.Extract 9 | { 10 | /// 11 | /// Part of ETWExtract which contains per process CPU consumption metrics 12 | /// 13 | public interface ICPUStats 14 | { 15 | /// 16 | /// Simple stat which contains the total CPU in ms per process 17 | /// 18 | IReadOnlyDictionary PerProcessCPUConsumptionInMs { get; } 19 | 20 | /// 21 | /// Average process priority taken from CPU sampling data when present 22 | /// 23 | IReadOnlyDictionary PerProcessAvgCPUPriority { get; } 24 | 25 | /// 26 | /// Contains methods which have CPU/Wait > 10ms (default) 27 | /// 28 | ICPUPerProcessMethodList PerProcessMethodCostsInclusive { get; } 29 | 30 | /// 31 | /// When -timeline was used during extraction we generate CPU timeline data which can be used to 32 | /// e.g. graph the data. 33 | /// 34 | ICPUTimeLine TimeLine { get; } 35 | 36 | /// 37 | /// Per core CPU Information 38 | /// 39 | public IReadOnlyDictionary Topology { get; } 40 | 41 | /// 42 | /// Get CPU Frequency related data 43 | /// 44 | public ICPUExtended ExtendedCPUMetrics { get; } 45 | } 46 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/ICPUTimeLine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace ETWAnalyzer.Extract.CPU 5 | { 6 | /// 7 | /// Contains extracted CPU timeline data which can be used to e.g. graph summary data 8 | /// 9 | public interface ICPUTimeLine 10 | { 11 | /// 12 | /// Calculate CPU per process with this interval. The interval is set during exctation with -timeline dd where dd is seconds. 13 | /// 14 | float ExtractionInveralS { get; } 15 | 16 | /// 17 | /// Get raw timeline data for a process. To gt a list of timepoints use the method 18 | /// 19 | /// 20 | /// Raw timeline data which contains a flat array of CPU usage, but no timeoints. 21 | IProcessTimeLine this[ProcessKey key] { get; } 22 | 23 | /// 24 | /// Get from a process a list of timepoints and the CPU consumption. 25 | /// 26 | /// ETW Extract is needed to determine when the timepoints are starting. The timeline tarts with 27 | /// Process key which is used to query other processes. 28 | /// When true the returned list contains % CPU instead of CPU ms per interval. 29 | /// List of timepoints and aggregated CPU consumption in ms since last timepoint. 30 | List> GetProcessTimeLineData(IETWExtract extract, ProcessKey key, bool calculatePercentCPU); 31 | } 32 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/IMethodsByProcess.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace ETWAnalyzer.Extract 7 | { 8 | 9 | /// 10 | /// Contains the read only part of IMethodsByProcess to make querying easier 11 | /// 12 | public interface IMethodsByProcess 13 | { 14 | /// 15 | /// Get costs for each methods. Costs mean here CPU consumption, wait time, first/last call time based on CPU sampling data (this is NOT method call count!) and other stats 16 | /// 17 | IReadOnlyList Costs { get; } 18 | 19 | /// 20 | /// Process 21 | /// 22 | ProcessKey Process { get; } 23 | } 24 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/IProcessStackTags.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace ETWAnalyzer.Extract 7 | { 8 | /// 9 | /// Get summary information per process about CPU consumption of specifically tagged stacks. 10 | /// This contains full CPU information. No CPU cutoff is performed here. 11 | /// 12 | public interface IProcessStackTags 13 | { 14 | /// 15 | /// Get per process stacktag summary 16 | /// 17 | IReadOnlyList>> Stats { get; } 18 | 19 | /// 20 | /// One or more used stacktag files which were used to generate the stacktags 21 | /// 22 | string[] UsedStackTagFiles { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/IProcessTimeLine.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ETWAnalyzer.Extract.CPU 4 | { 5 | /// 6 | /// Contains CPU time of a process split by DeltaTime time slices 7 | /// 8 | public interface IProcessTimeLine 9 | { 10 | /// 11 | /// Contains for given process the CPU time in ms for the duration of DeltaTime. 12 | /// 13 | IReadOnlyList CPUMs { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/ProcessStackTags.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using Newtonsoft.Json; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extract 12 | { 13 | 14 | /// 15 | /// List of processes with stack tag entries which consume either CPU or have wait times 16 | /// 17 | public class ProcessStackTags : IProcessStackTags 18 | { 19 | /// 20 | /// Used input stacktag file. Helps to diagnose issues later 21 | /// 22 | public string[] UsedStackTagFiles { get; set; } 23 | 24 | /// 25 | /// Processes which contain stacktag data 26 | /// 27 | public List>> Stats { get; } = new List>>(); 28 | 29 | IReadOnlyList>> StatsReadOnly; 30 | 31 | IReadOnlyList>> IProcessStackTags.Stats 32 | { 33 | get 34 | { 35 | if( StatsReadOnly == null && Stats != null) 36 | { 37 | StatsReadOnly = Stats.Select(x => new KeyValuePair>(x.Key, new List(x.Value))).ToList(); 38 | } 39 | 40 | return StatsReadOnly; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/CPU/ProcessTimeLine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.CPU 8 | { 9 | /// 10 | /// Contains CPU time of a process split by DeltaTime time slices 11 | /// 12 | public class ProcessTimeLine : IProcessTimeLine 13 | { 14 | /// 15 | /// Contains for given process the CPU time in ms for the duration of DeltaTime. 16 | /// 17 | public List CPUMs 18 | { 19 | get; set; 20 | } = new List(); 21 | 22 | IReadOnlyList IProcessTimeLine.CPUMs => CPUMs; 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Disk/DiskPartition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.Disk 8 | { 9 | /// 10 | /// Contains Partition size and drive letter 11 | /// 12 | public class DiskPartition : IDiskPartition 13 | { 14 | /// 15 | /// File system which is used for the partition 16 | /// 17 | public FileSystemFormat FileSystem { get; set; } 18 | 19 | /// 20 | /// Drive letter as string 21 | /// 22 | public string Drive { get; set; } 23 | 24 | /// 25 | /// Partition size in Gib (= 1024*1024*1024) 26 | /// 27 | public decimal TotalSizeGiB { get; set; } 28 | 29 | /// 30 | /// Free size of partition in GiB (= 1024*1024*1024) 31 | /// 32 | public decimal FreeSizeGiB { get; set; } 33 | 34 | /// 35 | /// 36 | /// 37 | /// 38 | public override string ToString() 39 | { 40 | return $"{Drive} {FileSystem} {TotalSizeGiB:F3} GiB, Free: {FreeSizeGiB:F3} GiB"; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Disk/DiskTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.Disk 8 | { 9 | /// 10 | /// Type of disk 11 | /// 12 | public enum DiskTypes 13 | { 14 | /// 15 | /// Not known 16 | /// 17 | Unknown, 18 | 19 | /// 20 | /// HDD 21 | /// 22 | HDD, 23 | 24 | /// 25 | /// SSD 26 | /// 27 | SSD, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Disk/FileSystemFormat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.Disk 8 | { 9 | /// 10 | /// Defines how partion is formatted 11 | /// 12 | public enum FileSystemFormat 13 | { 14 | /// 15 | /// 16 | /// 17 | Ntfs, 18 | 19 | /// 20 | /// Not formatted 21 | /// 22 | Raw, 23 | 24 | /// 25 | /// 26 | /// 27 | Fat, 28 | 29 | /// 30 | /// 31 | /// 32 | Fat32, 33 | 34 | /// 35 | /// 36 | /// 37 | ExFat, 38 | 39 | /// 40 | /// 41 | /// 42 | Cdfs, 43 | 44 | /// 45 | /// 46 | /// 47 | Udf, 48 | 49 | /// 50 | /// 51 | /// 52 | Csvfs, 53 | 54 | /// 55 | /// 56 | /// 57 | ReFS 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Disk/IDiskIOData.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace ETWAnalyzer.Extract.Disk 7 | { 8 | 9 | /// 10 | /// Disk IO data 11 | /// 12 | public interface IDiskIOData 13 | { 14 | /// 15 | /// List of Disk IO aggregate events per File 16 | /// 17 | DiskIOEvent[] DiskIOEvents { get; } 18 | 19 | /// 20 | /// Total Disk Flush time in microseconds (us = 10^(-6)s) 21 | /// 22 | ulong TotalDiskFlushTimeInus { get;} 23 | 24 | /// 25 | /// Total Disk Read Time in microseconds (us = 10^(-6)s) 26 | /// 27 | ulong TotalDiskReadTimeInus { get; } 28 | 29 | /// 30 | /// Sum of Read/Write/Flush Disk Times in microseconds (us = 10^(-6)s) 31 | /// 32 | ulong TotalDiskServiceTimeInus { get; } 33 | 34 | /// 35 | /// Total Disk Write Time in microseconds (us = 10^(-6)s) 36 | /// 37 | ulong TotalDiskWriteTimeTimeInus { get; } 38 | 39 | /// 40 | /// Contains data about disk layout, partitions and drive letters 41 | /// 42 | public IReadOnlyList DiskInformation { get; } 43 | } 44 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Disk/IDiskLayout.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ETWAnalyzer.Extract.Disk 4 | { 5 | /// 6 | /// Contains disk layout information and partition data 7 | /// 8 | public interface IDiskLayout 9 | { 10 | /// 11 | /// Capacity in GiB = 1024*1024*1024 bytes 12 | /// 13 | decimal CapacityGiB { get; } 14 | 15 | /// 16 | /// Cylinder count 17 | /// 18 | long CylinderCount { get; } 19 | 20 | /// 21 | /// When write cache is enabled writes are faster but it can cause data loss during an unexpected power off event 22 | /// 23 | bool IsWriteCachingEnabled { get; } 24 | 25 | /// 26 | /// Model Name 27 | /// 28 | string Model { get; } 29 | 30 | /// 31 | /// Partitions 32 | /// 33 | IReadOnlyList Partitions { get; } 34 | 35 | /// 36 | /// Size per sector in bytes 37 | /// 38 | 39 | long SectorSizeBytes { get; } 40 | 41 | /// 42 | /// Sectors per Track 43 | /// 44 | int SectorsPerTrack { get; } 45 | 46 | /// 47 | /// Tracks per Cylinder 48 | /// 49 | int TracksPerCylinder { get; } 50 | 51 | /// 52 | /// Disk Type (SSD or HDD) 53 | /// 54 | DiskTypes Type { get; } 55 | } 56 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Disk/IDiskPartition.cs: -------------------------------------------------------------------------------- 1 | namespace ETWAnalyzer.Extract.Disk 2 | { 3 | /// 4 | /// Contains Partition size and drive letter 5 | /// 6 | public interface IDiskPartition 7 | { 8 | /// 9 | /// Drive letter as string 10 | /// 11 | string Drive { get; } 12 | 13 | /// 14 | /// File system which is used for the partition 15 | /// 16 | FileSystemFormat FileSystem { get; } 17 | 18 | /// 19 | /// Free size of partition in GiB (= 1024*1024*1024) 20 | /// 21 | decimal FreeSizeGiB { get; } 22 | 23 | /// 24 | /// Partition size in Gib (= 1024*1024*1024) 25 | /// 26 | decimal TotalSizeGiB { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Display.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using Microsoft.Windows.EventTracing; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extract 12 | { 13 | /// 14 | /// Connected displays 15 | /// 16 | public class Display 17 | { 18 | /// 19 | /// 20 | /// 21 | public int HorizontalResolution { get; set; } 22 | 23 | /// 24 | /// 25 | /// 26 | public int VerticalResolution { get; set; } 27 | 28 | /// 29 | /// 30 | /// 31 | public long RefreshRateHz { get; set; } 32 | 33 | /// 34 | /// 35 | /// 36 | public bool IsPrimaryDevice { get; set; } 37 | 38 | /// 39 | /// The returned value is in units of bits per pixel (bpp). 40 | /// 41 | public int ColorDepth { get; set; } 42 | 43 | /// 44 | /// 45 | /// 46 | public string DisplayName { get; set; } 47 | 48 | /// 49 | /// In Million Bytes (not Mega 1024)) 50 | /// 51 | public long GraphicsCardMemorySizeMiB { get; set; } 52 | 53 | /// 54 | /// 55 | /// 56 | public string GraphicsCardChipName { get; set; } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/ETWMark.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract 11 | { 12 | /// 13 | /// Container for ETWMark events which are extracted when present 14 | /// 15 | public class ETWMark 16 | { 17 | /// 18 | /// 19 | /// 20 | public DateTimeOffset Time { get; } 21 | 22 | /// 23 | /// Message 24 | /// 25 | public string MarkMessage { get; } 26 | 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | public ETWMark(DateTimeOffset time, string markMessage) 33 | { 34 | Time = time; 35 | MarkMessage = markMessage; 36 | } 37 | 38 | /// 39 | /// 40 | /// 41 | /// 42 | public override string ToString() 43 | { 44 | return $"{Time} {MarkMessage}"; 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Exception/ExceptionEventForQuery.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Analyzers; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extract.Exceptions 12 | { 13 | /// 14 | /// This class is used to perform in memory queries on deserialized Json payload for easy querying the contained data. 15 | /// 16 | public class ExceptionEventForQuery 17 | { 18 | /// 19 | /// 20 | /// 21 | public ETWProcess Process { get; } 22 | 23 | /// 24 | /// 25 | /// 26 | public DateTimeOffset Time { get; } 27 | 28 | /// 29 | /// 30 | /// 31 | public string Stack { get; } 32 | 33 | /// 34 | /// 35 | /// 36 | public string Message { get; } 37 | 38 | /// 39 | /// Exception Type 40 | /// 41 | public string Type { get; } 42 | 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | /// 51 | public ExceptionEventForQuery(string message, string type, ETWProcess process, DateTimeOffset time, string stack) 52 | { 53 | Message = message; 54 | Type = type; 55 | Process = process; 56 | Time = time; 57 | Stack = stack; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Exception/ExceptionStackContainer.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extractors; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extract.Exceptions 12 | { 13 | /// 14 | /// 15 | /// 16 | public class ExceptionStackContainer 17 | { 18 | /// 19 | /// 20 | /// 21 | public Dictionary> Stack2Messages 22 | { 23 | get; set; 24 | } = new Dictionary>(); 25 | 26 | internal void Add(IProcessExtract myProcessExtract, ExceptionRowData data) 27 | { 28 | if (!Stack2Messages.TryGetValue(data.Stack, out HashSet messages)) 29 | { 30 | messages = new HashSet(); 31 | Stack2Messages[data.Stack] = messages; 32 | } 33 | 34 | ExceptionMessageAndType tempMsg = new ExceptionMessageAndType 35 | { 36 | Message = data.ExceptionMessage, 37 | Type = data.ExceptionType, 38 | }; 39 | 40 | 41 | if (!messages.TryGetValue(tempMsg, out ExceptionMessageAndType pooled)) 42 | { 43 | messages.Add(tempMsg); 44 | pooled = tempMsg; 45 | } 46 | 47 | if ( ETWExtract.IsValidProcessNameAndId(data.ProcessNameAndPid) ) 48 | { 49 | ETWProcessIndex processIndex = myProcessExtract.GetProcessIndex(data.ProcessNameAndPid); 50 | pooled.AddProcessTimeThread(processIndex, data.ThreadId, data.TimeInSec); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Exception/IExceptionStats.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Exceptions 5 | { 6 | 7 | /// 8 | /// Contains data about all recorded .NET exceptions 9 | /// 10 | public interface IExceptionStats 11 | { 12 | /// 13 | /// Exception count 14 | /// 15 | int Count { get; } 16 | 17 | /// 18 | /// All exceptions with time stamps and stacks as flat list. 19 | /// 20 | ExceptionEventForQuery[] Exceptions { get; } 21 | } 22 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/FileCloseOperation.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// Contains duration, and file close counts 14 | /// 15 | public class FileCloseOperation 16 | { 17 | /// 18 | /// IO Duration summed across all threads in microseconds rounded to nearest value away from 0. 19 | /// This includes als the IO duration from File Cleanup events. The cleanup count is tracked in the counter 20 | /// 21 | public long Durationus { get; set; } 22 | 23 | /// 24 | /// Number of times the file was closed 25 | /// 26 | public long Count { get; set; } 27 | 28 | /// 29 | /// Number of file system Cleanup calls 30 | /// 31 | public long Cleanups { get; set; } 32 | 33 | /// 34 | /// 35 | /// 36 | /// 37 | public override string ToString() 38 | { 39 | return $"Count: {Count} Duration: {Durationus/1000:N0} ms"; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/FileDeleteOperation.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// File Deletion operations 14 | /// 15 | public class FileDeleteOperation 16 | { 17 | /// 18 | /// Number of times the file was deleted 19 | /// 20 | public long Count { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/FileIOContainer.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// Query friendly container to read process data 14 | /// 15 | public class FileIOContainer 16 | { 17 | /// 18 | /// Full Path of accessed file 19 | /// 20 | public string FileName { get; } 21 | 22 | /// 23 | /// Process accessing this file 24 | /// 25 | public ETWProcess Process { get; } 26 | 27 | /// 28 | /// IO Statistics for this file for this process 29 | /// 30 | public FileIOStatistics Stats { get; } 31 | 32 | internal FileIOContainer(string fileName, ETWProcess process, FileIOStatistics stats) 33 | { 34 | FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); 35 | Process = process ?? throw new ArgumentNullException(nameof(process)); 36 | Stats = stats ?? throw new ArgumentNullException(nameof(stats)); 37 | } 38 | 39 | /// 40 | /// Total IO Duration for given file 41 | /// 42 | public long TotalIODurationus 43 | { 44 | get => Stats?.Open?.Durationus ?? 0 + Stats?.Close?.Durationus ?? 0 + Stats?.Read?.Durationus ?? 0 + Stats?.Write?.Durationus ?? 0; 45 | } 46 | 47 | /// 48 | /// 49 | /// 50 | /// 51 | public override string ToString() 52 | { 53 | return $"{FileName} {Process?.ProcessWithID} {Stats?.ToString()}"; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/FileOffsetOperation.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// Contains metrics about how many bytes were read/written and how far the file was read corresponds to 14 | /// the file size if the file was read until the end. 15 | /// 16 | public class FileOffsetOperation 17 | { 18 | /// 19 | /// Maximum Offset+ r/w Size which corresponds to the file size if the file was read/written until the end 20 | /// 21 | public long MaxFilePosition { get; set; } 22 | 23 | /// 24 | /// Read/Written Bytes summed across all threads. The size is the requested buffer size by the Read/WriteFile Api call. 25 | /// This is the reason why AccessedBytes can be much larger than the Maximum file position. 26 | /// 27 | public long AccessedBytes { get; set; } 28 | 29 | /// 30 | /// Number of operations performed 31 | /// 32 | public long Count; 33 | 34 | /// 35 | /// IO Duration summed across all threads in microseconds rounded to nearest value away from 0. 36 | /// This time includes also queuing time if async (overlapped/IO Completion Port) file APIs were used. 37 | /// 38 | public long Durationus { get; set; } 39 | 40 | 41 | /// 42 | /// 43 | /// 44 | /// 45 | public override string ToString() 46 | { 47 | return $"MaxFilePos: {MaxFilePosition:N0} bytes Accessed: {AccessedBytes:N0} bytes Count: {Count} Duration: {Durationus / 1000:N0} ms"; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/FileRenameOperation.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// File Renames 14 | /// 15 | public class FileRenameOperation 16 | { 17 | /// 18 | /// Number of times the file was renamed 19 | /// 20 | public long Count { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/FileSetSecurityOperation.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// Set File Security Events 14 | /// 15 | public class FileSetSecurityOperation 16 | { 17 | /// 18 | /// Time when File Security was set 19 | /// 20 | public List Times { get; set; } = new List(); 21 | 22 | /// 23 | /// Return code what was the result. Only failed unique return codes are saved. When the List is null all calls were successful. 24 | /// 25 | public List NtStatus { get; set; } 26 | 27 | /// 28 | /// Add a Security event this object. To save space in NtStatus array in serialized Json we store only failed NtStatus values ( NtStatus != 0 ). 29 | /// 30 | /// 31 | /// 32 | public void AddSecurityEvent(DateTimeOffset time, int ntStatus) 33 | { 34 | Times.Add(time); 35 | 36 | if( ntStatus != 0) 37 | { 38 | if( NtStatus == null) 39 | { 40 | NtStatus = new List(); 41 | } 42 | 43 | FileOpenOperation.AddUniqueNtStatus(NtStatus, ntStatus); 44 | } 45 | 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/IFileIOData.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace ETWAnalyzer.Extract.FileIO 8 | { 9 | /// 10 | /// Query friendly reading interface which is normally different from the way how the data is stored on disk. 11 | /// 12 | public interface IFileIOData 13 | { 14 | /// 15 | /// Get File IO Data as flat list where for each file the process and its metrics are stored. 16 | /// 17 | /// Usually the IETWExtract instance to map the process indices's to the actual process instance. 18 | IReadOnlyList GetFileNameProcessStats(IProcessExtract processMapper); 19 | } 20 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/FileIO/PerProcessFileIOStats.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.FileIO 11 | { 12 | /// 13 | /// Contains for each process the FileIO data 14 | /// 15 | public class PerProcessFileIOStats 16 | { 17 | /// 18 | /// Mapping a process to the corresponding per process metric 19 | /// 20 | public Dictionary Process 21 | { 22 | get; 23 | set; 24 | } = new(); 25 | 26 | 27 | /// 28 | /// Add for a given process the corresponding file statistics 29 | /// 30 | /// Index to Process list in ETWExtract to save space in serialized output 31 | /// Actual Metric data 32 | public void Add(ETWProcessIndex idx, FileIOStatistics stats) 33 | { 34 | if (!Process.TryGetValue(idx, out FileIOStatistics fileStats)) 35 | { 36 | Process[idx] = stats; 37 | return; 38 | } 39 | 40 | fileStats.Add(stats); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Handle/HandleCloseEvent.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract.Common; 6 | using Microsoft.Windows.EventTracing; 7 | 8 | namespace ETWAnalyzer.Extract.Handle 9 | { 10 | /// 11 | /// Handle close event 12 | /// 13 | public interface IHandleCloseEvent : IStackEventBase 14 | { 15 | /// 16 | /// Handle which was closed 17 | /// 18 | ulong HandleValue { get; } 19 | } 20 | 21 | 22 | /// 23 | /// Handle close event 24 | /// 25 | public class HandleCloseEvent : StackEventBase, IHandleCloseEvent 26 | { 27 | /// 28 | /// Handle which was closed 29 | /// 30 | public ulong HandleValue { get; set; } 31 | 32 | /// 33 | /// Needed for de/serialization 34 | /// 35 | public HandleCloseEvent() : this(default(TraceTimestamp), 0, ETWProcessIndex.Invalid, 0, StackIdx.None) 36 | { } 37 | 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// 45 | /// 46 | public HandleCloseEvent(TraceTimestamp time, ulong handleValue, ETWProcessIndex processIdx, int threadId, StackIdx stackIdx) 47 | : base(time, processIdx, threadId, stackIdx) 48 | { 49 | HandleValue = handleValue; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Handle/HandleCreateEvent.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract.Common; 5 | using Microsoft.Windows.EventTracing; 6 | 7 | namespace ETWAnalyzer.Extract.Handle 8 | { 9 | /// 10 | /// Handle create event 11 | /// 12 | public interface IHandleCreateEvent : IStackEventBase 13 | { 14 | /// 15 | /// Handle value returned by Create... call 16 | /// 17 | ulong HandleValue { get; } 18 | } 19 | 20 | /// 21 | /// Handle create event 22 | /// 23 | public class HandleCreateEvent : StackEventBase, IHandleCreateEvent 24 | { 25 | /// 26 | /// Handle value returned by Create... call 27 | /// 28 | public ulong HandleValue { get; set; } 29 | 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | /// 38 | public HandleCreateEvent(TraceTimestamp time, ulong handleValue, ETWProcessIndex processIdx, int threadId, StackIdx stackIdx) 39 | : base(time, processIdx, threadId, stackIdx) 40 | { 41 | HandleValue = handleValue; 42 | } 43 | 44 | /// 45 | /// 46 | /// 47 | public HandleCreateEvent() : this(default(TraceTimestamp), 0, ETWProcessIndex.Invalid, 0, StackIdx.None) 48 | { } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Handle/HandleProcess.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Handle 5 | { 6 | /// 7 | /// Existing handle which belongs to a process 8 | /// 9 | public interface IHandleProcess 10 | { 11 | /// 12 | /// Handle value 13 | /// 14 | uint Handle { get; } 15 | 16 | /// 17 | /// Process Index 18 | /// 19 | ETWProcessIndex Process { get; } 20 | } 21 | 22 | /// 23 | /// Wrapper around existing handle list 24 | /// 25 | public class HandleProcess : IHandleProcess 26 | { 27 | /// 28 | /// Handle value 29 | /// 30 | public uint Handle { get; set; } 31 | /// 32 | /// Process Index 33 | /// 34 | public ETWProcessIndex Process { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Handle/IHandleObjectData.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using ETWAnalyzer.Extract.Common; 7 | 8 | namespace ETWAnalyzer.Extract.Handle 9 | { 10 | /// 11 | /// This contains no aggregates but all ObjectRef and VAMAP traces. 12 | /// This includes Handle Create/Destroy/Duplicate (Handle Traces) 13 | /// Handle Increase/Decrease RefCount (ObjectRef Traces) 14 | /// File Map/Unmap events (VAMAP traces) 15 | /// 16 | public interface IHandleObjectData 17 | { 18 | /// 19 | /// Object Type id to type name map 20 | /// 21 | public IReadOnlyDictionary ObjectTypeMap { get; } 22 | 23 | /// 24 | /// Contains Object and Handle ETW tracing data 25 | /// 26 | 27 | IReadOnlyList ObjectReferences { get; } 28 | 29 | /// 30 | /// Stacks used by which are referenced by StackIdx values 31 | /// 32 | IStackCollection Stacks { get; } 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/IProcessNameResolver.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract 11 | { 12 | /// 13 | /// 14 | /// 15 | public interface IProcessNameResolver 16 | { 17 | /// 18 | /// Rename a process based on its command line 19 | /// 20 | /// Name of exe 21 | /// Command line arguments to exe 22 | /// Same as exeName or renamed process if one of the RenameRules did match 23 | string GetProcessName(string exeName, string cmdLine); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/IProcessWorkingSet.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract 5 | { 6 | /// 7 | /// When the ETW trace contains sampled workingset data 8 | /// 9 | public interface IProcessWorkingSet 10 | { 11 | /// 12 | /// Committed memory in MiB = bytes/(1024*1024) rounded to next bigger MiB when greater x.5 13 | /// 14 | ulong CommitInMiB { get; } 15 | 16 | /// 17 | /// Process for which the data was gathered. 18 | /// 19 | ProcessKey Process { get; } 20 | 21 | /// 22 | /// This is the size of file mapping data e.g. Page file or other file mapped data 23 | /// in MiB = bytes/(1024*1024) rounded to next bigger MiB when greater x.5 24 | /// 25 | ulong SharedCommitSizeInMiB { get; } 26 | 27 | /// 28 | /// Working Set in MiB = bytes/(1024*1024) rounded to next bigger MiB when greater x.5 29 | /// 30 | ulong WorkingSetInMiB { get; } 31 | 32 | /// 33 | /// Process private working set in MiB = bytes/(1024*1024) rounded to next bigger MiB when greater x.5 34 | /// 35 | ulong WorkingsetPrivateInMiB { get; } 36 | } 37 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Memory/VirtualAllocEvent.cs: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------------------------------- 2 | Copyright (C) Siemens Healthcare GmbH 2023, All rights reserved. Restricted. 3 | ------------------------------------------------------------------------------------------------- */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extract.Memory 12 | { 13 | internal class VirtualAllocEvent 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Modules/IModuleContainer.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Infrastructure; 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace ETWAnalyzer.Extract.Modules 9 | { 10 | /// 11 | /// Contains information about loaded modules from all processes. 12 | /// 13 | public interface IModuleContainer 14 | { 15 | /// 16 | /// List of loaded modules which contain also the processes which have them loaded. 17 | /// 18 | IReadOnlyList Modules { get; } 19 | 20 | /// 21 | /// List of not resolved pdbs during extraction 22 | /// 23 | IReadOnlyList UnresolvedPdbs { get; } 24 | 25 | /// 26 | /// Find Module Definition for a loaded module in a process. 27 | /// 28 | /// Module name 29 | /// Process in which the module is loaded 30 | /// ModuleDefinition when module could be located or null when it could not be found. 31 | ModuleDefinition FindModule(string moduleName, ETWProcess process); 32 | } 33 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Modules/IPdbIdentifier.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | namespace ETWAnalyzer.Extract.Modules 7 | { 8 | /// 9 | /// A pdb on the symbol server is identified by name, id and age. 10 | /// 11 | public interface IPdbIdentifier 12 | { 13 | /// 14 | /// Number of PDB recompilations since PDB was created or completely rebuilt 15 | /// 16 | int Age { get; } 17 | 18 | /// 19 | /// GUID which should be new for every recompile of the target binary 20 | /// 21 | Guid Id { get; } 22 | 23 | /// 24 | /// Pdb name without path 25 | /// 26 | string Name { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Modules/PdbIndex.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Modules 5 | { 6 | /// 7 | /// Index into unresolved pdb array 8 | /// 9 | public enum PdbIndex 10 | { 11 | /// 12 | /// Invalid index 13 | /// 14 | Invalid = -1 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/DnsClient.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace ETWAnalyzer.Extract.Network 8 | { 9 | /// 10 | /// 11 | /// 12 | public class DnsClient : IDnsClient 13 | { 14 | /// 15 | /// DNS Events 16 | /// 17 | 18 | public List Events { get; set; } = new List(); 19 | 20 | 21 | IReadOnlyList IDnsClient.Events => Events; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/IDnsClient.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace ETWAnalyzer.Extract.Network 8 | { 9 | /// 10 | /// Contains DNS Events which originate from the 11 | /// 12 | public interface IDnsClient 13 | { 14 | /// 15 | /// DNS Events 16 | /// 17 | IReadOnlyList Events { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/INetwork.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract.Network.Tcp; 6 | 7 | namespace ETWAnalyzer.Extract.Network 8 | { 9 | /// 10 | /// Contains Network data such as DNS 11 | /// 12 | public interface INetwork 13 | { 14 | /// 15 | /// DNS Events 16 | /// 17 | IDnsClient DnsClient { get; } 18 | 19 | /// 20 | /// 21 | /// 22 | ITcpStatistics TcpData { get; } 23 | } 24 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/Network.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract.Network.Tcp; 5 | 6 | namespace ETWAnalyzer.Extract.Network 7 | { 8 | /// 9 | /// Contains Network data such as DNS 10 | /// 11 | public class Network : INetwork 12 | { 13 | /// 14 | /// DNS Events 15 | /// 16 | public DnsClient DnsClient { get; set; } = new(); 17 | 18 | /// 19 | /// DNS Events 20 | /// 21 | IDnsClient INetwork.DnsClient => DnsClient; 22 | 23 | /// 24 | /// TCP data 25 | /// 26 | public TcpStatistics TcpData { get; set; } = new(); 27 | 28 | ITcpStatistics INetwork.TcpData => TcpData; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/Tcp/Extensions.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extract.Network.Tcp 12 | { 13 | /// 14 | /// Helper methods which cannot be part of classes because Json.NET would try to serialize them by default. 15 | /// 16 | public static class Extensions 17 | { 18 | /// 19 | /// Calculate the time difference between the first packet which was sent with given sequence number and a retransmission event. 20 | /// 21 | /// Retransmission event 22 | /// Time when retransmission did happen after packee was not acked yet. 23 | public static TimeSpan RetransmitDiff(this ITcpRetransmission retrans) 24 | { 25 | return retrans.RetransmitTime - retrans.SendTime; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/Tcp/ITcpRetransmission.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | namespace ETWAnalyzer.Extract.Network.Tcp 7 | { 8 | /// 9 | /// One TCP Retransmission event which is based on the TcpRetransmit and TcpTailLossProbe (id 1385) ETW event of Microsoft-Windows-TCPIP ETW provider. 10 | /// It uses other events like TcpDataSend to correlate the first send try time and how many bytes were tried to send. 11 | /// 12 | public interface ITcpRetransmission 13 | { 14 | /// 15 | /// Bytes which were tried to send. Windows get spurious retransmissions for 0 and 1 byte sized packets which look like ACK and keepalive pings. 16 | /// When is true it is the number of received bytes. 17 | /// 18 | int NumBytes { get; } 19 | 20 | /// 21 | /// Connection Index to retrieve connection later from TcpStatistics.Connections 22 | /// 23 | TcpStatistics.ConnectionIdx ConnectionIdx { get; } 24 | /// 25 | /// Time when Retransmit did occur 26 | /// 27 | DateTimeOffset RetransmitTime { get; } 28 | 29 | /// 30 | /// Time when packet was sent before retransmit was tried. 31 | /// 32 | DateTimeOffset SendTime { get; } 33 | 34 | /// 35 | /// Sequence Number of TCP packet which is missing 36 | /// 37 | uint SequenceNumber { get; } 38 | 39 | /// 40 | /// When true it indicates that retransmission was detected as duplicate client transmision which had a byte count > 1 41 | /// 42 | bool? IsClientRetransmission { get; } 43 | } 44 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/Tcp/ITcpStatistics.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace ETWAnalyzer.Extract.Network.Tcp 8 | { 9 | /// 10 | /// TCP metrics like connections, Retransmissions, ... 11 | /// 12 | public interface ITcpStatistics 13 | { 14 | /// 15 | /// All active TCP connections 16 | /// 17 | IReadOnlyList Connections { get; } 18 | 19 | /// 20 | /// All TCP Retransmission events 21 | /// 22 | IReadOnlyList Retransmissions { get; } 23 | } 24 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Network/Tcp/TcpStatistics.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extract.Network.Tcp 11 | { 12 | /// 13 | /// Contains data about all TCP connections and TCP Retransmissions which are a known source of problems in networks 14 | /// 15 | public class TcpStatistics : ITcpStatistics 16 | { 17 | /// 18 | /// Index to TcpStatistics.Connections array used by other classes to reference a TCP connection 19 | /// 20 | public enum ConnectionIdx 21 | { 22 | /// 23 | /// Invalid index 24 | /// 25 | Invalid = -1, 26 | } 27 | 28 | /// 29 | /// Connections 30 | /// 31 | public List Connections { get; set; } = new(); 32 | 33 | Dictionary myConnectionToIdx = new(); 34 | 35 | internal ConnectionIdx AddConnection(TcpConnection connection) 36 | { 37 | Connections.Add(connection); 38 | ConnectionIdx lret = (ConnectionIdx)(Connections.Count - 1); 39 | myConnectionToIdx[connection] = lret; 40 | return lret; 41 | } 42 | 43 | internal ConnectionIdx GetConnectionIdx(TcpConnection connection) 44 | { 45 | return myConnectionToIdx[connection]; 46 | } 47 | 48 | /// 49 | /// Retransmissions 50 | /// 51 | public List Retransmissions { get; set; } = new(); 52 | 53 | IReadOnlyList ITcpStatistics.Connections => Connections; 54 | IReadOnlyList ITcpStatistics.Retransmissions => Retransmissions; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PInvoke.NET/LICENSE: -------------------------------------------------------------------------------- 1 | This content is governed by Pinvoke terms of service. 2 | http://www.pinvoke.net/termsofuse.htm 3 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/ILBRData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ETWAnalyzer.Extract.PMC 4 | { 5 | /// 6 | /// Last Branch Record Data which contains method call estimates 7 | /// 8 | public interface ILBRData 9 | { 10 | /// 11 | /// Get method call data as flat array for each process and caller/caller count object 12 | /// 13 | /// IETWExtract instance to translate process data 14 | /// Flat list of all call counts of all processes 15 | IReadOnlyList GetMethodCalls(IETWExtract extract); 16 | } 17 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/IMethodCall.cs: -------------------------------------------------------------------------------- 1 | namespace ETWAnalyzer.Extract.PMC 2 | { 3 | /// 4 | /// Method Call data recorded by LBR data 5 | /// 6 | public interface IMethodCall 7 | { 8 | /// 9 | /// Calling method 10 | /// 11 | string Caller { get; } 12 | 13 | /// 14 | /// Method Name 15 | /// 16 | string MethodName { get; } 17 | 18 | /// 19 | /// Sampled Call Count (actual call count is much higher) 20 | /// 21 | long Count { get; } 22 | 23 | /// 24 | /// Process in which these calls did occur 25 | /// 26 | ETWProcess Process { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/IPMCCounter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ETWAnalyzer.Extract.PMC 4 | { 5 | /// 6 | /// PMC Data for a given counter per process 7 | /// 8 | public interface IPMCCounter 9 | { 10 | /// 11 | /// Performance Monitoring Counter Name 12 | /// 13 | string CounterName { get; } 14 | 15 | /// 16 | /// Map of process to Counter value which contains the total counter value for a process for the trace duration 17 | /// 18 | IReadOnlyDictionary ProcessMap { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/IPMCData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ETWAnalyzer.Extract.PMC 4 | { 5 | /// 6 | /// Contains Performance Monitoring Counter data from CPU 7 | /// 8 | public interface IPMCData 9 | { 10 | /// 11 | /// Process Summary data 12 | /// 13 | IReadOnlyList Counters { get; } 14 | 15 | /// 16 | /// Last Branch Record data which contains method call estimates based on the CPU LBR data. 17 | /// 18 | ILBRData LBRData { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/MethodCall.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.PMC 8 | { 9 | /// 10 | /// Method Call data recorded by LBR data 11 | /// 12 | public class MethodCall : IMethodCall 13 | { 14 | /// 15 | /// Calling method 16 | /// 17 | public string Caller { get; private set; } 18 | 19 | /// 20 | /// Method Name 21 | /// 22 | public string MethodName { get; private set; } 23 | 24 | /// 25 | /// Sampled Call Count (actual call count is much higher) 26 | /// 27 | public long Count { get; private set; } 28 | 29 | /// 30 | /// Process in which these calls did occur 31 | /// 32 | public ETWProcess Process { get; private set; } 33 | 34 | /// 35 | /// Construct a Method call object 36 | /// 37 | /// 38 | /// 39 | /// 40 | /// 41 | public MethodCall(string caller, string methodName, long callCount, ETWProcess process) 42 | { 43 | Caller = caller; 44 | MethodName = methodName; 45 | Count = callCount; 46 | Process = process; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/PMCCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.PMC 8 | { 9 | /// 10 | /// PMC Data for a given counter per process 11 | /// 12 | public class PMCCounter : IPMCCounter 13 | { 14 | /// 15 | /// Performance Monitoring Counter Name 16 | /// Set needed by Json.Net 17 | /// 18 | public string CounterName 19 | { 20 | get; 21 | set; 22 | } 23 | 24 | /// 25 | /// Map of process to Counter value which contains the total counter value for a process for the trace duration 26 | /// 27 | public Dictionary ProcessMap { get; set; } = new Dictionary(); 28 | 29 | IReadOnlyDictionary IPMCCounter.ProcessMap { get => ProcessMap; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/PMC/PMCData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.Extract.PMC 8 | { 9 | 10 | /// 11 | /// Contains Performance Monitoring Counter data from CPU 12 | /// 13 | public class PMCData : IPMCData 14 | { 15 | /// 16 | /// Process Summary data 17 | /// 18 | public List Counters 19 | { 20 | get; set; 21 | } = new List(); 22 | 23 | /// 24 | /// Process Summary data 25 | /// 26 | IReadOnlyList IPMCData.Counters => Counters; 27 | 28 | /// 29 | /// Method call estimates based on LBR sampling data 30 | /// 31 | public LBRData LBRData 32 | { 33 | get; set; 34 | } = new LBRData(); 35 | 36 | ILBRData IPMCData.LBRData => LBRData; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/BasePowerProfile.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Power 5 | { 6 | /// 7 | /// Well known base power profile names 8 | /// 9 | public enum BasePowerProfile 10 | { 11 | /// 12 | /// Custom power profile 13 | /// 14 | Custom = 0, 15 | 16 | /// 17 | /// 18 | /// 19 | PowerSaver, 20 | 21 | /// 22 | /// 23 | /// 24 | Balanced, 25 | 26 | /// 27 | /// 28 | /// 29 | HighPerformance, 30 | 31 | /// 32 | /// 33 | /// 34 | UltimatePerformance, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/HeteroThreadSchedulingPolicy.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | namespace ETWAnalyzer.Extract.Power 6 | { 7 | /// 8 | /// Defines how long/short running threads are scheduled on which core type 9 | /// 10 | public enum HeteroThreadSchedulingPolicy 11 | { 12 | /// 13 | /// Schedule to any available processor. 14 | /// 15 | AllProcessors = 0, 16 | 17 | /// 18 | /// Schedule exclusively to more performant processors. 19 | /// 20 | PerformantProcessors = 1, 21 | 22 | /// 23 | /// Schedule to more performant processors when possible. 24 | /// 25 | PreferPerformantProcessors = 2, 26 | 27 | /// 28 | /// Schedule exclusively to more efficient processors. 29 | /// 30 | EfficientProcessors = 3, 31 | 32 | /// 33 | /// Schedule to more efficient processors when possible. 34 | /// 35 | PreferEfficientProcessors = 4, 36 | 37 | /// 38 | /// Let the system choose an appropriate policy. 39 | /// 40 | Automatic = 5, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/ParkingPerformanceState.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | namespace ETWAnalyzer.Extract.Power 6 | { 7 | /// 8 | /// Defines the performance state (target frequency) for parked processor cores. 9 | /// 10 | public enum ParkingPerformanceState 11 | { 12 | /// 13 | /// No specified target frequency. The target frequency will be determined based 14 | /// on other criteria. 15 | /// 16 | NoPreference, 17 | 18 | /// 19 | /// Specify minimum target frequency for parked cores. 20 | /// 21 | Deepest, 22 | 23 | /// 24 | /// Specify maximum target frequency for parked cores. 25 | /// 26 | Lightest 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/ProcessorParkingPolicy.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Power 5 | { 6 | /// 7 | /// Processor Parking Policies 8 | /// 9 | public enum ProcessorParkingPolicy 10 | { 11 | 12 | /// 13 | /// Transition logical processors between the parked and unparked states such that 14 | /// the utilization is kept near the middle of the max and min thresholds. 15 | /// 16 | Ideal, 17 | 18 | 19 | /// 20 | /// Transition only one logical processor at a time between the parked and unparked 21 | /// states. 22 | /// 23 | Single, 24 | 25 | /// 26 | /// Transition all logical processors to the parked state or unparked state at the 27 | /// same time. 28 | /// 29 | Rocket, 30 | 31 | /// 32 | /// Transition more than one logical processor at a time between the parked and unparked 33 | /// states. 34 | /// 35 | Multistep 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/ProcessorPerformanceChangePolicy.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Power 5 | { 6 | /// 7 | /// Defines a policy the system follows when making changes to processor frequency. 8 | /// 9 | public enum ProcessorPerformanceChangePolicy 10 | { 11 | /// 12 | /// Try to achieve the midpoint busy-ness between the increase and the decrease thresholds. 13 | /// 14 | Ideal, 15 | 16 | /// 17 | /// Change by a fixed frequency step. 18 | /// 19 | Single, 20 | 21 | /// 22 | /// Jump directly to the extreme frequency. 23 | /// 24 | Rocket, 25 | 26 | /// 27 | /// Change more aggressively than ideal. 28 | /// 29 | IdealAggressive 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/ProcessorThrottlePolicy.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Power 5 | { 6 | /// 7 | /// Defines the policy the system uses to throttle a processor's frequency. 8 | /// 9 | public enum ProcessorThrottlePolicy 10 | { 11 | /// 12 | /// Processor throttling is disabled. 13 | /// 14 | Disabled, 15 | /// 16 | /// Processor throttling is enabled. 17 | /// 18 | Enabled, 19 | /// 20 | /// Processor throttling is enabled based on other factors. 21 | /// 22 | Automatic 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/Power/SystemCoolingPolicy.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace ETWAnalyzer.Extract.Power 5 | { 6 | /// 7 | /// Defines the policy that determines how system cools down the processor. 8 | /// 9 | public enum SystemCoolingPolicy 10 | { 11 | /// 12 | /// The system increases the fan speed. If the temperature is still too high, it 13 | /// will slow down the processor. 14 | /// 15 | Active, 16 | 17 | /// 18 | /// The system slows down the processor. If the temperature is still too high, it 19 | /// will increase the fan speed. 20 | /// 21 | Passive 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/ProcessRenamer/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Alois-xx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/SimplifiedProfiling/Enums.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace TAU.Toolkit.Diagnostics.Profiling.Simplified 5 | { 6 | 7 | /// 8 | /// enum to determine where the results were generated 9 | /// 10 | public enum GeneratedAt 11 | { 12 | /// 13 | Invalid = 0, 14 | /// 15 | /// generated on the client 16 | /// 17 | CLT =1, 18 | /// 19 | /// generated on the server 20 | /// 21 | SRV = 2, 22 | /// 23 | /// result generated on a single machine containing Server and Client profiling results 24 | /// 25 | SINGLE = 3 26 | } 27 | /// 28 | /// 29 | /// 30 | public enum TestStatus 31 | { 32 | 33 | /// 34 | Unknown = 0, 35 | /// 36 | Passed = 1, 37 | /// 38 | Failed = 2 39 | 40 | } 41 | 42 | internal enum RunningState 43 | { 44 | NoInitialized = 0, 45 | Active = 1, 46 | Stopped = 2, 47 | Finalized =3 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/SimplifiedProfiling/Info.txt: -------------------------------------------------------------------------------- 1 | the clases are copied from 2 | $/TAU/Framework/Main/Toolkit/Source/TAU.Toolkit.Diagnostics/Profiling/Simplified 3 | to reuse the parsing code. We do not want to generate compile dependency between this tool and Tau therefore we copy the relevant classes 4 | Current Version: CS 1038436 5 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/SimplifiedProfiling/ProfilingConstants.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | namespace TAU.Toolkit.Diagnostics.Profiling.Simplified 5 | { 6 | /// 7 | public class ProfilingConstants 8 | { 9 | internal static readonly long MAGIC_DURATION_4_AdjustDurationAndCopyToRemote_CALLED_FROM_DISPOSE = 33666; 10 | internal static readonly string PAYLOAD_FILENAME_CLIENT_TO_SERVER_TIME_DIFF = "AddThisTimeInMSToClientTimeStampToGetTheCorrespondingServerTime.double"; 11 | internal static readonly string PAYLOAD_FILENAME_SERVER_TO_CLIENT_TIME_DIFF = "AddThisTimeInMSToServerTimeStampToGetTheCorrespondingClientTime.double"; 12 | /// 13 | /// Write a marker which starts with this string 14 | /// to automatically set the start point of the default zoom when opening to this region in the WPA, when opening with the ProfilingDataManager or the CompareETL.cmd script 15 | /// you can append any string after this to give your marker more meaning 16 | /// If you use the ProfilingGuard> ensure that you set the parameter 17 | /// writeMarkersForAutoZoom in ProfilingGuard.ProfilingGuard(IUseCaseProfiler, bool) to false 18 | /// 19 | public static readonly string MARKER_NAME_FOR_AUTOZOOM_START = "Start "; 20 | /// 21 | /// Write a marker which starts with this string 22 | /// to automatically set the end point of the default zoom when opening to this region in the WPA, when opening with the ProfilingDataManager or the CompareETL.cmd script 23 | /// you can append any string after this to give your marker more meaning 24 | /// If you use the ProfilingGuard> ensure that you set the parameter 25 | /// writeMarkersForAutoZoom in ProfilingGuard.ProfilingGuard(IUseCaseProfiler, bool) to false 26 | /// 27 | public static readonly string MARKER_NAME_FOR_AUTOZOOM_STOP = "Stop "; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/ThreadPool/IThreadPoolStats.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace ETWAnalyzer.Extract.ThreadPool 8 | { 9 | 10 | /// 11 | /// informations about the thread pool 12 | /// 13 | public interface IThreadPoolStats 14 | { 15 | /// 16 | /// Simple stat which contains the thread pool starvations per process 17 | /// 18 | IReadOnlyDictionary> PerProcessThreadPoolStarvations { get; } 19 | 20 | /// 21 | /// Total number of thread pool events in the trace. 22 | /// 23 | public int? ThreadPoolEventCount { get;} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/ThreadPool/ThreadPoolStarvationInfo.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | namespace ETWAnalyzer.Extract.ThreadPool 7 | { 8 | /// 9 | /// information about a dedicated thread pool starvation 10 | /// 11 | public class ThreadPoolStarvationInfo 12 | { 13 | /// 14 | /// number of new worker threads in the thread pool after the starvation was detected 15 | /// 16 | public uint NewWorkerThreadCount { set; get; } 17 | 18 | /// 19 | /// date time when the starvation was detected from the CLR 20 | /// 21 | public DateTimeOffset DateTime { set; get; } 22 | 23 | /// 24 | /// total seconds from start of this trace when the starvation was detected from the CLR 25 | /// 26 | public decimal TotalSeconds { set; get; } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extract/ThreadPool/ThreadPoolStats.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace ETWAnalyzer.Extract.ThreadPool 8 | { 9 | /// 10 | public class ThreadPoolStats: IThreadPoolStats 11 | 12 | { 13 | /// 14 | public Dictionary> PerProcessThreadPoolStarvations 15 | { 16 | get; 17 | } = new Dictionary>(); 18 | 19 | /// 20 | /// Total number of thread pool events in the trace. 21 | /// 22 | public int? ThreadPoolEventCount { get; set; } 23 | 24 | IReadOnlyDictionary> IThreadPoolStats.PerProcessThreadPoolStarvations => PerProcessThreadPoolStarvations; 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/Disk/DiskExtractor.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract; 5 | using ETWAnalyzer.Extract.Disk; 6 | using ETWAnalyzer.Infrastructure; 7 | using Microsoft.Diagnostics.Tracing.Etlx; 8 | using Microsoft.Windows.EventTracing; 9 | using Microsoft.Windows.EventTracing.Disk; 10 | using Microsoft.Windows.EventTracing.Processes; 11 | using System; 12 | using System.Collections.Generic; 13 | using System.IO; 14 | using System.Linq; 15 | 16 | namespace ETWAnalyzer.Extractors 17 | { 18 | class DiskExtractor : ExtractorBase 19 | { 20 | IPendingResult myDiskIO; 21 | 22 | public DiskExtractor() 23 | { 24 | } 25 | 26 | public override void RegisterParsers(ITraceProcessor processor) 27 | { 28 | myDiskIO = processor.UseDiskIOData(); 29 | } 30 | 31 | public override void Extract(ITraceProcessor processor, ETWExtract results) 32 | { 33 | using var logger = new PerfLogger("Extract Disk"); 34 | if ( !myDiskIO.HasResult ) 35 | { 36 | Console.WriteLine("Warning: No DiskIO activity was recorded"); 37 | return; 38 | } 39 | 40 | DiskIOData data = results.Disk ?? new DiskIOData(); 41 | 42 | foreach (IDiskActivity diskActivity in myDiskIO.Result.Activity) 43 | { 44 | data.Add(diskActivity); 45 | } 46 | 47 | results.Disk = data; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/Dns/DnsQueryKey.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extractors.Dns 12 | { 13 | internal class DnsQueryKey : IEquatable 14 | { 15 | public string DnsQuery { get; } 16 | public ETWProcessIndex Process { get; } 17 | 18 | public DnsQueryKey(string dnsQuery, ETWProcessIndex process) 19 | { 20 | DnsQuery = dnsQuery.ToLowerInvariant(); 21 | Process = process; 22 | } 23 | 24 | public override int GetHashCode() 25 | { 26 | return DnsQuery.GetHashCode(); 27 | } 28 | 29 | /// 30 | /// We group by query, but if in between the DNS Service queries on behalf of other processes we ignore the process to update the currently running query 31 | /// 32 | /// 33 | /// 34 | public bool Equals(DnsQueryKey other) 35 | { 36 | if (other == null) 37 | { 38 | return false; 39 | } 40 | 41 | return DnsQuery == other.DnsQuery && 42 | ( (other.Process != ETWProcessIndex.Invalid && Process != ETWProcessIndex.Invalid && Process == other.Process) || 43 | (other.Process == ETWProcessIndex.Invalid || Process == ETWProcessIndex.Invalid ) 44 | ); 45 | 46 | } 47 | 48 | public override string ToString() 49 | { 50 | return $"{DnsQuery}"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/Dns/QueryState.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract; 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace ETWAnalyzer.Extractors.Dns 9 | { 10 | /// 11 | /// State object to capture DNS query state while collecting key events 12 | /// 13 | class QueryState 14 | { 15 | public ETWProcessIndex ProcessIndex { get; set; } 16 | public DateTimeOffset Start { get; set; } 17 | public TimeSpan Duration { get; set; } 18 | public bool TimedOut { get; set; } 19 | 20 | public List DnsServerList { get; set; } = new List(); 21 | public string TimedOutServer { get; internal set; } 22 | public string AdapterName { get; internal set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/Exception/ExceptionCSVParser.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract; 5 | using ETWAnalyzer.Extract.Exceptions; 6 | using Newtonsoft.Json; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | 11 | namespace ETWAnalyzer.Extractors 12 | { 13 | /// 14 | /// Categories as members from an event 15 | /// 16 | public class ExceptionEvent 17 | { 18 | /// 19 | /// 20 | /// 21 | public string ExceptionType { get; set; } 22 | /// 23 | /// 24 | /// 25 | /// 26 | public string ExceptionMessage { get; set; } 27 | 28 | /// 29 | /// 30 | /// 31 | public int ThreadId { get; set; } 32 | 33 | /// 34 | /// 35 | /// 36 | public DateTimeOffset TimeInSec { get; set; } 37 | 38 | /// 39 | /// 40 | /// 41 | public string Stack { get; set; } 42 | } 43 | 44 | 45 | /// 46 | /// Categories from an event to extract from *.csv file 47 | /// 48 | class ExceptionRowData 49 | { 50 | public string ProcessNameAndPid { get; set; } 51 | public string ExceptionType { get; set; } 52 | public string ExceptionMessage { get; set; } 53 | public int ThreadId { get; set; } 54 | public DateTimeOffset TimeInSec { get; set; } 55 | public string Stack { get; set; } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/Exception/ExceptionExtractor/LICENSE: -------------------------------------------------------------------------------- 1 | This content is governed by Github terms of service. 2 | https://docs.github.com/en/github/site-policy/github-terms-of-service#d-user-generated-content 3 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/IGenericTcpEvent.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using System; 6 | 7 | namespace ETWAnalyzer.Extractors.TCP 8 | { 9 | internal interface IGenericTcpEvent 10 | { 11 | TcpRequestConnect Connection { get; set; } 12 | ulong Tcb { get; set; } 13 | DateTimeOffset Timestamp { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpCloseTcbRequest.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.Extract.Network.Tcp; 2 | using ETWAnalyzer.TraceProcessorHelpers; 3 | using Microsoft.Windows.EventTracing; 4 | using Microsoft.Windows.EventTracing.Events; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.Extractors.TCP 12 | { 13 | /// 14 | /// Represents a request to close a TCP connection. 15 | /// 16 | internal class TcpCloseTcbRequest 17 | { 18 | // Fields: Tcb:Pointer LocalAddress:Binary RemoteAddress:Binary Status:UInt32 ProcessId:UInt32 Compartment:UInt32 19 | public ulong Tcb { get; set; } 20 | public SocketConnection LocalIpAndPort { get; private set; } 21 | public SocketConnection RemoteIpAndPort { get; private set; } 22 | 23 | public UInt32 Compartment { get; private set; } 24 | public UInt32 ProcessId { get; private set; } 25 | 26 | public DateTimeOffset Timestamp { get; set; } 27 | 28 | public TcpCloseTcbRequest(IGenericEvent ev) 29 | { 30 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 31 | LocalIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.LocalAddressField].AsSocketAddress.ToIPEndPoint()); 32 | RemoteIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.RemoteAddressField].AsSocketAddress.ToIPEndPoint()); 33 | ProcessId = ev.Fields[TcpETWConstants.ProcessIdField].AsUInt32; 34 | Compartment = ev.Fields[TcpETWConstants.CompartmentField].AsUInt32; 35 | Timestamp = ev.Timestamp.DateTimeOffset; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpConnectTcbFailedRcvdRst.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.Extract.Network.Tcp; 2 | using ETWAnalyzer.TraceProcessorHelpers; 3 | using Microsoft.Windows.EventTracing.Events; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Extractors.TCP 11 | { 12 | /// 13 | /// When connection attempt fails Kernel logs this events that connection init did fail. 14 | /// 15 | internal class TcpConnectTcbFailedRcvdRst 16 | { 17 | // Fields: Tcb:Pointer, LocalIpAndPort, RemoteIpAndPort, NewState 18 | public ulong Tcb { get; set; } 19 | 20 | public TcpRequestConnect Connection { get; set; } 21 | 22 | public SocketConnection LocalIpAndPort { get; private set; } 23 | public SocketConnection RemoteIpAndPort { get; private set; } 24 | 25 | public UInt32 NewState { get; private set; } 26 | 27 | public DateTimeOffset Timestamp { get; set; } 28 | 29 | public TcpConnectTcbFailedRcvdRst(IGenericEvent ev) 30 | { 31 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 32 | Timestamp = ev.Timestamp.DateTimeOffset; 33 | NewState = ev.Fields[TcpETWConstants.NewStateField].AsUInt32; 34 | LocalIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.LocalAddressField].AsSocketAddress.ToIPEndPoint()); 35 | RemoteIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.RemoteAddressField].AsSocketAddress.ToIPEndPoint()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpConnectionKeepAlive.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.TraceProcessorHelpers; 2 | //// SPDX-FileCopyrightText: © 2025 Siemens Healthcare GmbH 3 | //// SPDX-License-Identifier: MIT 4 | 5 | using Microsoft.Windows.EventTracing.Events; 6 | using System; 7 | 8 | namespace ETWAnalyzer.Extractors.TCP 9 | { 10 | internal class TcpConnectionKeepAlive 11 | { 12 | // Fields: Tcb, SndUna, SndMax 13 | public ulong Tcb { get; set; } 14 | public uint SndUna { get; set; } 15 | 16 | public DateTimeOffset Timestamp { get; set; } 17 | 18 | public TcpConnectionKeepAlive(IGenericEvent ev) 19 | { 20 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 21 | SndUna = ev.Fields[TcpETWConstants.SndUnaField].AsUInt32; 22 | Timestamp = ev.Timestamp.DateTimeOffset; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpDataSend.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract; 5 | using ETWAnalyzer.TraceProcessorHelpers; 6 | using Microsoft.Windows.EventTracing.Events; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace ETWAnalyzer.Extractors.TCP 14 | { 15 | 16 | /// 17 | /// Fired when data is sent over the wire. Used by WPA to calculate send rate. 18 | /// 19 | internal class TcpDataSend : IGenericTcpEvent 20 | { 21 | public ulong Tcb { get; set; } 22 | 23 | public TcpRequestConnect Connection { get; set; } 24 | 25 | public int BytesSent { get; set; } 26 | public uint SequenceNr { get; set; } 27 | 28 | public DateTimeOffset Timestamp { get; set; } 29 | 30 | public TcpDataSend(ulong tcb, int bytesSent, uint sequenceNr, DateTimeOffset timestamp) 31 | { 32 | Tcb = tcb; 33 | BytesSent = bytesSent; 34 | SequenceNr = sequenceNr; 35 | Timestamp = timestamp; 36 | } 37 | 38 | 39 | public TcpDataSend(IGenericEvent ev) 40 | { 41 | 42 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 43 | BytesSent = (int)ev.Fields[TcpETWConstants.BytesSentField].AsUInt32; 44 | SequenceNr = ev.Fields[TcpETWConstants.SeqNoField].AsUInt32; 45 | Timestamp = ev.Timestamp.DateTimeOffset; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpDataTransferReceive.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.TraceProcessorHelpers; 6 | using Microsoft.Windows.EventTracing.Events; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace ETWAnalyzer.Extractors.TCP 14 | { 15 | /// 16 | /// Fired when TCP data is received. That is also used by WPA to calculate Receive rate. 17 | /// 18 | internal class TcpDataTransferReceive : IGenericTcpEvent 19 | { 20 | /// Fields: Tcb, NumBytes:UInt32, SeqNo:UInt32 21 | public ulong Tcb { get; set; } 22 | 23 | public TcpRequestConnect Connection { get; set; } 24 | 25 | public int NumBytes { get; set; } 26 | public uint SequenceNr { get; set; } 27 | 28 | public DateTimeOffset Timestamp { get; set; } 29 | 30 | public TcpDataTransferReceive(IGenericEvent ev) 31 | { 32 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 33 | NumBytes = (int)ev.Fields[TcpETWConstants.NumBytesField].AsUInt32; 34 | SequenceNr = ev.Fields[TcpETWConstants.SeqNoField].AsUInt32; 35 | Timestamp = ev.Timestamp.DateTimeOffset; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpDisconnectTcbRtoTimeout.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract.Network.Tcp; 5 | using ETWAnalyzer.TraceProcessorHelpers; 6 | using Microsoft.Windows.EventTracing.Events; 7 | using System; 8 | 9 | namespace ETWAnalyzer.Extractors.TCP 10 | { 11 | /// 12 | /// Fired when connection is reset after the maximum number of retransmissions Microsoft-Windows-TCPIP/TcpConnectRestransmit in case of 13 | /// connection establishment issues, or TcpDataTransferRetransmitRound after connection has been established have occurred. 14 | /// 15 | internal class TcpDisconnectTcbRtoTimeout 16 | { 17 | // Fields: Tcb:Pointer, LocalIpAndPort, RemoteIpAndPort, Status, Compartment, ... 18 | public ulong Tcb { get; set; } 19 | 20 | public DateTimeOffset Timestamp { get; set; } 21 | 22 | /// 23 | /// not yet parsed. 24 | /// 25 | public int Compartment { get; private set; } 26 | 27 | public SocketConnection LocalIpAndPort { get; private set; } 28 | public SocketConnection RemoteIpAndPort { get; private set; } 29 | 30 | public TcpDisconnectTcbRtoTimeout(IGenericEvent ev) 31 | { 32 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 33 | Timestamp = ev.Timestamp.DateTimeOffset; 34 | LocalIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.LocalAddressField].AsSocketAddress.ToIPEndPoint()); 35 | RemoteIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.RemoteAddressField].AsSocketAddress.ToIPEndPoint()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpRetransmit.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract; 6 | using ETWAnalyzer.TraceProcessorHelpers; 7 | using Microsoft.Windows.EventTracing.Events; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace ETWAnalyzer.Extractors.TCP 15 | { 16 | /// 17 | /// TCP Retransmission event which contain the sequence nr which was sent again. 18 | /// 19 | internal class TcpRetransmit : IGenericTcpEvent 20 | { 21 | public ulong Tcb { get; set; } 22 | public uint SndUna { get; set; } 23 | 24 | public TcpRequestConnect Connection { get; set; } 25 | 26 | public DateTimeOffset Timestamp { get; set; } 27 | 28 | public TcpRetransmit(IGenericEvent ev) 29 | { 30 | Tcb = (ulong) ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 31 | SndUna = ev.Fields[TcpETWConstants.SndUnaField].AsUInt32; 32 | Timestamp = ev.Timestamp.DateTimeOffset; 33 | } 34 | 35 | 36 | public TcpRetransmit(ulong tcb, uint sndUna, DateTimeOffset timestamp) 37 | { 38 | Tcb = tcb; 39 | SndUna = sndUna; 40 | Timestamp = timestamp; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpShutdownTcb.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2025 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract; 6 | using ETWAnalyzer.Extract.Network.Tcp; 7 | using ETWAnalyzer.TraceProcessorHelpers; 8 | using Microsoft.Windows.EventTracing.Events; 9 | using System; 10 | 11 | namespace ETWAnalyzer.Extractors.TCP 12 | { 13 | 14 | /// 15 | /// When a Tcb is released this one will always be called 16 | /// 17 | internal class TcpShutdownTcb 18 | { 19 | // Fields: LocalAddress, RemoteAddress, Status, ProcessId, Compartment, Tcb, ProcessStartKey, 20 | public ulong Tcb { get; set; } 21 | public uint SndUna { get; set; } 22 | 23 | public DateTimeOffset Timestamp { get; set; } 24 | 25 | public SocketConnection LocalIpAndPort { get; private set; } 26 | public SocketConnection RemoteIpAndPort { get; private set; } 27 | 28 | public UInt32 Compartment { get; private set; } 29 | public UInt32 ProcessId { get; private set; } 30 | 31 | public NtStatus Status { get; private set; } 32 | public UInt64 ProcessStartKey { get; private set; } 33 | 34 | public TcpShutdownTcb(IGenericEvent ev) 35 | { 36 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 37 | LocalIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.LocalAddressField].AsSocketAddress.ToIPEndPoint()); 38 | RemoteIpAndPort = new SocketConnection(ev.Fields[TcpETWConstants.RemoteAddressField].AsSocketAddress.ToIPEndPoint()); 39 | ProcessId = ev.Fields[TcpETWConstants.ProcessIdField].AsUInt32; 40 | Compartment = ev.Fields[TcpETWConstants.CompartmentField].AsUInt32; 41 | ProcessStartKey = ev.Fields[TcpETWConstants.ProcessStartKey].AsUInt64; 42 | Status = (NtStatus) ev.Fields[TcpETWConstants.StatusField].AsUInt32; 43 | Timestamp = ev.Timestamp.DateTimeOffset; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpTailLossProbe.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract; 6 | using ETWAnalyzer.TraceProcessorHelpers; 7 | using Microsoft.Windows.EventTracing.Events; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace ETWAnalyzer.Extractors.TCP 15 | { 16 | /// 17 | /// This event seems to resend pending data without causing a retransmit event. That comes usually later. 18 | /// By looking at Wireshark traces we seem to miss the first retransmission which seems to be correlated as Tail Loss probe event. 19 | /// 20 | internal class TcpTailLossProbe 21 | { 22 | // Fields: Tcb:Pointer, SndUna:UInt32, SndMax:UInt32, SendAvailable:UInt32, TailProbeSeq:UInt32, TailProbeLast:UInt32, ControlsToSend:UInt32, ThFlags:UInt8 23 | public ulong Tcb { get; set; } 24 | public uint SndUna { get; set; } 25 | 26 | public TcpRequestConnect Connection { get; set; } 27 | 28 | public DateTimeOffset Timestamp { get; set; } 29 | 30 | public TcpTailLossProbe(IGenericEvent ev) 31 | { 32 | Tcb = (ulong) ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 33 | SndUna = ev.Fields["SndUna"].AsUInt32; 34 | Timestamp = ev.Timestamp.DateTimeOffset; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer/Extractors/TCP/TcpTemplateChanged.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2023 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract; 6 | using ETWAnalyzer.TraceProcessorHelpers; 7 | using Microsoft.Windows.EventTracing.Events; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | using static ETWAnalyzer.TraceProcessorHelpers.TcpETWConstants; 14 | 15 | namespace ETWAnalyzer.Extractors.TCP 16 | { 17 | /// 18 | /// When a TCP connection is established it applies a TCP template which defines RTO and other things. Predefined are DataCenter and Internet Template 19 | /// 20 | internal class TcpTemplateChanged 21 | { 22 | /// Fields: Tcb, TemplateType:UInt32 of TCPIP_TEMPLATE_TYPE_ValueMap, Context:String 23 | public ulong Tcb { get; set; } 24 | 25 | public TCPIP_TEMPLATE_TYPES TemplateType { get; set; } 26 | 27 | public DateTimeOffset Timestamp { get; set; } 28 | public TcpRequestConnect Connection { get; internal set; } 29 | 30 | public TcpTemplateChanged(IGenericEvent ev) 31 | { 32 | Tcb = (ulong)ev.Fields[TcpETWConstants.TcbField].AsAddress.Value; 33 | Timestamp = ev.Timestamp.DateTimeOffset; 34 | TemplateType = (TCPIP_TEMPLATE_TYPES) ev.Fields[TemplateTypeField].AsUInt32; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/ColorConsole/LICENSE: -------------------------------------------------------------------------------- 1 | This content is governed by Github terms of service. 2 | https://docs.github.com/en/github/site-policy/github-terms-of-service#d-user-generated-content 3 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/ColumnDefinition.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Infrastructure 11 | { 12 | 13 | /// 14 | /// Defines an output column which can contain multiline data. 15 | /// 16 | internal class ColumnDefinition 17 | { 18 | /// 19 | /// Column title which is printed to console 20 | /// 21 | public string Title { get; set; } 22 | 23 | /// 24 | /// Symbolic name which is referenced by -Column property to enabled/disable specific columns 25 | /// 26 | public string Name { get; set; } 27 | 28 | /// 29 | /// String which is printed at each row 30 | /// 31 | public string Prefix { get; set; } = ""; 32 | 33 | /// 34 | /// Color in which the text is printed 35 | /// 36 | public ConsoleColor? Color { get; set; } 37 | 38 | /// 39 | /// When false column will not be printed. 40 | /// 41 | public bool Enabled { get; set; } = true; 42 | 43 | 44 | int myDataWidth; 45 | /// 46 | /// Column width excluding extra space to separate columns in output. 47 | /// When zero then the column data is simply appended which in effect turns wrapping off. 48 | /// Minimum non zero data width is 3 49 | /// 50 | public int DataWidth 51 | { 52 | get => myDataWidth; 53 | set => myDataWidth = value > 0 ? Math.Max(3, value) : Math.Max(0,value); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/ColumnFormatter.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Infrastructure 11 | { 12 | class ColumnFormatter 13 | { 14 | public Func Formatter; 15 | string myHeader; 16 | public string Header 17 | { 18 | get => myHeader; 19 | set => myHeader = value; 20 | } 21 | 22 | public ConsoleColor? Color; 23 | 24 | public ColumnFormatter() 25 | { 26 | Header = ""; 27 | Formatter = x => ""; 28 | Color = null; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/CtrlCHandler/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alois-xx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/ExceptionHelper.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace ETWAnalyzer 8 | { 9 | /// 10 | /// Helper methods to find e.g. if you are in an exception unwind scenario. 11 | /// 12 | public static class ExceptionHelper 13 | { 14 | /// 15 | /// Check if we are in a exception unwind scenario or not. 16 | /// 17 | public static bool InException 18 | { 19 | get 20 | { 21 | return Marshal.GetExceptionPointers() == IntPtr.Zero && 22 | Marshal.GetExceptionCode() == 0 ? false : true; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/PerfLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace ETWAnalyzer.Infrastructure 9 | { 10 | internal class PerfLogger : IDisposable 11 | { 12 | Stopwatch myStopWatch; 13 | string myOperationName; 14 | 15 | public PerfLogger(string operationName) 16 | { 17 | myStopWatch = Stopwatch.StartNew(); 18 | myOperationName = operationName; 19 | Logger.Info($"Start {operationName}"); 20 | } 21 | 22 | public void Dispose() 23 | { 24 | Logger.Info($"End {myOperationName} in {myStopWatch.Elapsed.TotalSeconds:F1} s"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/ReusableMemoryStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace ETWAnalyzer.Infrastructure 9 | { 10 | /// 11 | /// Do not close memory stream on dispose, so we can reuse it 12 | /// 13 | internal class ReusableMemoryStream : MemoryStream 14 | { 15 | protected override void Dispose(bool disposing) 16 | { 17 | 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/SkipTakeRange.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Infrastructure 11 | { 12 | /// 13 | /// Define a skip and take range with sane default iif nothing is specified. 14 | /// 15 | internal class SkipTakeRange 16 | { 17 | /// 18 | /// When none is specified 0 19 | /// 20 | public int SkipN { get; } 21 | 22 | /// 23 | /// When none is specified int.MaxValue is used 24 | /// 25 | public int TakeN { get; } 26 | 27 | /// 28 | /// Create a default range which skips nothing and takes everything. 29 | /// 30 | public SkipTakeRange() : this(null, null) 31 | { } 32 | 33 | 34 | /// 35 | /// Create a range 36 | /// 37 | /// 38 | /// 39 | public SkipTakeRange(int? takeN, int? skipN) 40 | { 41 | SkipN = skipN ?? 0; 42 | TakeN = takeN ?? int.MaxValue; 43 | } 44 | 45 | public bool IsEmpty 46 | { 47 | get => SkipN == 0 && TakeN == int.MaxValue; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ETWAnalyzer/Infrastructure/StringFormatExtensions.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.Infrastructure 11 | { 12 | internal static class StringFormatExtensions 13 | { 14 | /// 15 | /// New Line characters used for triming. 16 | /// 17 | internal static char[] NewLineChars = Environment.NewLine.ToCharArray(); 18 | 19 | /// 20 | /// Format a string with the format expression and then adds spaces before, after the string until the desired width for tabular output is reached. 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | public static string WidthFormat(this string fmt, object arg, int width) 27 | { 28 | string str = string.Format("{0:"+fmt+"}", arg); 29 | return str.WithWidth(width); 30 | } 31 | 32 | /// 33 | /// Add spaces before, after the string until the desired width for tabular output is reached. 34 | /// 35 | /// String to potentially widen 36 | /// width. If positive spaces before the string are added, otherwise afterwards. 37 | /// String with at least the input width 38 | public static string WithWidth(this string str, int width) 39 | { 40 | if (width == 0) 41 | { 42 | return str; 43 | } 44 | else 45 | { 46 | string widthFmt = "{0," + width + "}"; 47 | return String.Format(widthFmt, str); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ETWAnalyzer/LoadSymbol/TraceEvent/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) .NET Foundation and Contributors 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. -------------------------------------------------------------------------------- /ETWAnalyzer/MakeRelease.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Build Targets 3 | 4 | setlocal enabledelayedexpansion 5 | set ScriptLocation=%~d0%~p0 6 | set BinFolderNet48=!ScriptLocation!..\bin\Release\publishNet48 7 | set BinFolderNet8=!ScriptLocation!..\bin\Release\publishNet8 8 | set BinSamplesFolder=!ScriptLocation!..\Samples\bin\x64\Release 9 | 10 | set ObjFolder=!ScriptLocation!\obj 11 | 12 | set ReleaseZipNet6=!BinFolderNet8!\..\ETWAnalyzer_Net8.zip 13 | set ReleaseZipNet48=!BinFolderNet48!\..\ETWAnalyzer_Net48.zip 14 | set ReleaseSamples=!ScriptLocation!..\Samples_Binaries.zip 15 | 16 | del !ReleaseZipNet6! 2> NUL 17 | del !ReleaseZipNet48! 2> NUL 18 | del !ReleaseSamples! 2> NUL 19 | 20 | rd /q /s !BinFolderNet48! 21 | rd /q /s !BinFolderNet8! 22 | rd /q /s !BinSamplesFolder! 23 | rd /q /s !ObjFolder! 24 | 25 | dotnet publish !ScriptLocation!\ETWAnalyzer.csproj /p:PublishProfile=!ScriptLocation!\ETWAnalyzer\Properties\PublishProfiles\Net80_SelfContained.pubxml /p:Configuration=Release /p:TargetFramework=net8.0-windows /p:PublishDir=!BinFolderNet8! 26 | dotnet publish !ScriptLocation!\ETWAnalyzer.csproj /p:PublishProfile=!ScriptLocation!\ETWAnalyzer\Properties\PublishProfiles\Net48.pubxml /p:Configuration=Release /p:TargetFramework=net48 /p:PublishDir=!BinFolderNet48! 27 | dotnet pack !ScriptLocation!\ETWAnalyzer.csproj /p:Configuration=Release 28 | 29 | msbuild /p:Configuration=Release /p:Platform=x64 /p:OutDir=!BinSamplesFolder! !ScriptLocation!\..\Samples\EventLeak\EventLeak.vcxproj 30 | 31 | call :DelFile "!BinFolderNet48!" 32 | call :DelFile "!BinFolderNet8!" 33 | 34 | 7z a !ReleaseZipNet6! -r "!BinFolderNet8!\*.*" 35 | 7z a !ReleaseZipNet48! -r "!BinFolderNet48!\*.*" 36 | 7z a !ReleaseSamples! -r "!BinSamplesFolder!\*.*" 37 | 38 | goto :EOF 39 | 40 | :DelFile 41 | echo Binfolder is %1 42 | cd %1 43 | echo Delete superflous files 44 | del ETWAnalyzer_Trace.log 2> NUL 45 | rd /q /s x86 46 | rd /q /s arm64 47 | exit /B 1 48 | -------------------------------------------------------------------------------- /ETWAnalyzer/ProcessTools/InvalidZipContentsException.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.ProcessTools 11 | { 12 | /// 13 | /// Thrown when the Zip file did not contain right informaton 14 | /// 15 | [Serializable] 16 | #pragma warning disable CA1032 // Implement standard exception constructors 17 | public class InvalidZipContentsException : Exception 18 | #pragma warning restore CA1032 // Implement standard exception constructors 19 | { 20 | /// 21 | /// 22 | /// 23 | public string ZipFile 24 | { 25 | get; 26 | } 27 | 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | public InvalidZipContentsException(string message, string zipFile) : base(message) 34 | { 35 | ZipFile = zipFile ?? throw new ArgumentNullException(nameof(zipFile)); 36 | } 37 | 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// 43 | public InvalidZipContentsException(string message, Exception innerException) : base(message, innerException) 44 | { 45 | } 46 | 47 | /// 48 | /// 49 | /// 50 | /// 51 | /// 52 | protected InvalidZipContentsException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) 53 | { 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ETWAnalyzer/ProcessTools/ValueConverter.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.ProcessTools 12 | { 13 | class ValueConverter 14 | { 15 | public static bool GetBool(string str) 16 | { 17 | if( int.TryParse(str, out int value) ) 18 | { 19 | if( value == 0 || value == 1) 20 | { 21 | return value == 1; 22 | } 23 | throw new InvalidDataException($"Expected a bool value but got: {str}"); 24 | } 25 | 26 | if( bool.TryParse(str, out bool bValue)) 27 | { 28 | return bValue; 29 | } 30 | 31 | throw new InvalidDataException($"Expected a bool value but got: {str}"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ETWAnalyzer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Reflection; 5 | using System.Resources; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("ETWAnalyzer")] 13 | [assembly: AssemblyDescription("")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("ETWAnalyzer")] 17 | [assembly: AssemblyCopyright("Copyright © 2022-2024")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | [assembly: NeutralResourcesLanguage("en")] 21 | 22 | // Setting ComVisible to false makes the types in this assembly not visible 23 | // to COM components. If you need to access a type in this assembly from 24 | // COM, set the ComVisible attribute to true on that type. 25 | [assembly: ComVisible(false)] 26 | 27 | // The following GUID is for the ID of the typelib if this project is exposed to COM 28 | [assembly: Guid("b163151c-42dc-44da-a153-fc833ee4c9e2")] 29 | [assembly: InternalsVisibleTo("ETWAnalyzer_uTest")] 30 | [assembly: InternalsVisibleTo("ETWAnalyzer_iTest")] 31 | [assembly: InternalsVisibleTo("LogTester")] 32 | [assembly: InternalsVisibleTo("ProfilingDataManager")] 33 | 34 | // Version information for an assembly consists of the following four values: 35 | // 36 | // Major Version 37 | // Minor Version 38 | // Build Number 39 | // Revision 40 | // 41 | // You can specify all the values or you can default the Build and Revision Numbers 42 | // by using the '*' as shown below: 43 | // [assembly: AssemblyVersion("1.0.*")] 44 | [assembly: AssemblyVersion("1.0.0.0")] 45 | [assembly: AssemblyFileVersion("3.0.0.12")] 46 | -------------------------------------------------------------------------------- /ETWAnalyzer/Properties/PublishProfiles/Net48.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release48 8 | x64 9 | ..\bin\Release\publish48\ 10 | FileSystem 11 | net48 12 | 13 | -------------------------------------------------------------------------------- /ETWAnalyzer/Properties/PublishProfiles/Net80_SelfContained.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | x64 9 | ..\bin\Release\publish\ 10 | FileSystem 11 | net8.0-windows 12 | win-x64 13 | true 14 | true 15 | True 16 | True 17 | 18 | -------------------------------------------------------------------------------- /ETWAnalyzer/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | C:\Symbols 7 | 8 | 9 | SRV*C:\Symbols*https://msdl.microsoft.com/download/symbols 10 | 11 | 12 | SRV*C:\Symbols*https://build-syngo.healthcare.siemens.com/symbols/ 13 | 14 | 15 | SRV*C:\Symbols*https://chromium-browser-symsrv.commondatastorage.googleapis.com 16 | 17 | 18 | -------------------------------------------------------------------------------- /ETWAnalyzer/TraceProcessorHelpers/ConsoleSymbolProcess.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using Microsoft.Windows.EventTracing.Symbols; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer.TraceProcessorHelpers 12 | { 13 | internal class ConsoleSymbolLoadingProgress : IProgress 14 | { 15 | public static ConsoleSymbolLoadingProgress Instance 16 | { 17 | get; 18 | } = new ConsoleSymbolLoadingProgress(); 19 | 20 | 21 | private ConsoleSymbolLoadingProgress() 22 | { 23 | } 24 | 25 | public void Report(SymbolLoadingProgress progress) 26 | { 27 | Console.WriteLine("{0:N1}% ({1} of {3}; {2} loaded)", (decimal)progress.ImagesProcessed / (decimal)progress.ImagesTotal * 100m, progress.ImagesProcessed, progress.ImagesLoaded, progress.ImagesTotal); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ETWAnalyzer/TraceProcessorHelpers/DotNetETWConstants.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ETWAnalyzer.TraceProcessorHelpers 11 | { 12 | /// 13 | /// Common .NET Runtime ETW Constants 14 | /// 15 | public static class DotNetETWConstants 16 | { 17 | /// 18 | /// Registered ETW Provider name for .NET Runtime 19 | /// 20 | public const string DotNetRuntimeProviderName = "Microsoft-Windows-DotNETRuntime"; 21 | 22 | /// 23 | /// Guid of .NET Runtime ETW provider 24 | /// 25 | public static readonly Guid DotNetRuntimeGuid = new("e13c0d23-ccbc-4e12-931b-d9cc2eee27e4"); 26 | 27 | /// 28 | /// .NET Threadpool, especially thread starvation events 29 | /// 30 | public const int ThreadingKeyword = 0x10000; 31 | 32 | /// 33 | /// Event id for Exception event 34 | /// 35 | public const int ExceptionEventId = 80; 36 | 37 | /// 38 | /// Event Id for Clr Stack walk event 39 | /// 40 | public const int ClrStackWalkEventId = 82; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ETWAnalyzer/TraceProcessorHelpers/KernelPowerConstants.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2024 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | 5 | using ETWAnalyzer.Extract.Power; 6 | using System; 7 | using System.Collections.Generic; 8 | 9 | namespace ETWAnalyzer.TraceProcessorHelpers 10 | { 11 | internal class KernelPowerConstants 12 | { 13 | public static readonly Guid Guid = new Guid("331c3b3a-2005-44c2-ac5e-77220c37d6b4"); 14 | public const int PowerSettingsRundownEventId = 111; 15 | 16 | public static readonly Dictionary BasePowerProfiles = new Dictionary() 17 | { 18 | { new Guid("381b4222-f694-41f0-9685-ff5bb260df2e"), BasePowerProfile.Balanced }, 19 | { new Guid("8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"), BasePowerProfile.HighPerformance }, 20 | { new Guid("a1841308-3541-4fab-bc81-f71556f20b4a"), BasePowerProfile.PowerSaver }, 21 | { new Guid("e9a42b02-d5df-448d-aa00-03f14749eb61"), BasePowerProfile.UltimatePerformance }, 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ETWAnalyzer/TraceProcessorHelpers/WindowsConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer.TraceProcessorHelpers 8 | { 9 | internal class WindowsConstants 10 | { 11 | /// 12 | /// Pid of Idle process. In this process live the device drivers belonging to the System process. 13 | /// 14 | public const int IdleProcessId = 0; 15 | 16 | public const int SystemProcessId = 4; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ETWAnalyzer/runtimeconfig.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "configProperties": { 3 | "System.GC.Server": true, 4 | "System.GC.NoAffinitize": true 5 | } 6 | } -------------------------------------------------------------------------------- /ETWAnalyzer_iTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Reflection; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | [assembly: AssemblyTitle("ETWAnalyzer_iTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ETWAnalyzer_iTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | [assembly: ComVisible(false)] 18 | 19 | [assembly: Guid("b7a9f2ab-bed5-4485-9c10-734a87a97080")] 20 | 21 | // [assembly: AssemblyVersion("1.0.*")] 22 | [assembly: AssemblyVersion("1.0.0.0")] 23 | [assembly: AssemblyFileVersion("1.0.0.0")] 24 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Extract/CPUFrequencyTests.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.Extract; 2 | using ETWAnalyzer.Extract.CPU; 3 | using ETWAnalyzer.Extract.CPU.Extended; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Xunit; 10 | 11 | namespace ETWAnalyzer_uTest.Extract 12 | { 13 | public class CPUFrequencyTests 14 | { 15 | [Fact] 16 | public void Can_Add_And_GetFrequencies() 17 | { 18 | var frequencies = new CPUExtended(); 19 | 20 | float startTime = 1.0f; 21 | 22 | frequencies.AddFrequencyDuration(0, startTime, startTime + 1, 5000); 23 | frequencies.AddFrequencyDuration(0, startTime + 3, startTime + 15, 2000); 24 | frequencies.AddFrequencyDuration(0, startTime + 2, startTime + 3, 3000); 25 | frequencies.AddFrequencyDuration(0, startTime + 1, startTime + 2, 4000); 26 | 27 | Assert.Equal(5000, frequencies.GetFrequency(0, startTime)); 28 | Assert.Equal(4000, frequencies.GetFrequency(0, startTime + 1.500f)); 29 | Assert.Equal(3000, frequencies.GetFrequency(0, startTime + 3.000f)); 30 | Assert.Equal(2000, frequencies.GetFrequency(0, startTime + 5.000f)); 31 | Assert.Equal(-1, frequencies.GetFrequency(0, startTime + 50.000f)); 32 | } 33 | 34 | [Fact] 35 | public void Process_MethodIndex_Works() 36 | { 37 | ETWProcessIndex idx = (ETWProcessIndex) 1000; 38 | MethodIndex method = (MethodIndex) 15000; 39 | 40 | ProcessMethodIdx merged = idx.Create(method); 41 | Assert.Equal(15000, (int) merged.MethodIndex()); 42 | Assert.Equal(1000, (int) merged.ProcessIndex()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Extract/ExceptionMessageAndTypeTests.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Extract.Exceptions; 5 | using Xunit; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace ETWAnalyzer_uTest 12 | { 13 | 14 | public class ExceptionMessageAndTypeTests 15 | { 16 | [Fact] 17 | public void Can_Use_In_HashSet() 18 | { 19 | HashSet set = new HashSet(); 20 | 21 | for(int i=0;i<10;i++) 22 | { 23 | const int Same = 1; 24 | ExceptionMessageAndType cont = new ExceptionMessageAndType 25 | { 26 | Message = Same.ToString() 27 | }; 28 | 29 | bool bAdded = set.Add(cont); 30 | if( i > 0 ) 31 | { 32 | Assert.False(bAdded, "Object has same content. If it is added more than once then the GetHashCode or EqualityComparer does not work"); 33 | } 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Extract/ExtractCommandTests.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.Commands; 2 | using ETWAnalyzer.Helper; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Xunit; 10 | 11 | namespace ETWAnalyzer_uTest.Extract 12 | { 13 | public class ExtractCommandTests 14 | { 15 | [Fact] 16 | public void Can_Generate_ChildCmdLine() 17 | { 18 | using (var tmp = TempDir.Create()) 19 | { 20 | string spaceDir = Path.Combine(tmp.Name, "Space Dir"); 21 | Directory.CreateDirectory(spaceDir); 22 | 23 | ExtractCommand cmd = new ExtractCommand(new string[] { "-extract", "all", "-filedir", spaceDir, ArgParser.UnzipOperationArg, "c:\\perftools\\ETLRewrite -injectOnly " + ExtractCommand.ETLFileDirVariable, "-outdir", spaceDir } ); 24 | cmd.Parse(); 25 | string cmdLine = cmd.GetCommandLineForSingleExtractFile("None.etl"); 26 | string expected = $"-extract all -filedir \"None.etl\" -unzipoperation \"c:\\perftools\\ETLRewrite -injectOnly #EtlFileDir#\" -outdir \"{spaceDir}\" -child"; 27 | Assert.Equal(expected, cmdLine); 28 | } 29 | 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Extract/OutputFileNameTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TAU.Toolkit.Diagnostics.Profiling.Simplified; 7 | using Xunit; 8 | 9 | namespace ETWAnalyzer_uTest.Extract 10 | { 11 | public class OutputFileNameTests 12 | { 13 | [Fact] 14 | public void Can_Parse_Valid_Name() 15 | { 16 | var name = OutputFileName.ParseFromFileName("Load_2382ms_RN1884F4EB-386C_SRV_TestStatus-Passed_20220425-215857.7z"); 17 | Assert.NotNull(name); 18 | 19 | Assert.Equal(2382, name.TestDurationinMS); 20 | Assert.Equal("Load", name.TestCaseName); 21 | Assert.Equal("RN1884F4EB-386C", name.MachineWhereResultsAreGeneratedOn); 22 | Assert.Equal(TestStatus.Passed, name.TestStatus); 23 | Assert.Equal(new DateTime(2022, 04, 25, 21, 58, 57), name.ProfilingStoppedTime); 24 | } 25 | 26 | [Fact] 27 | public void Invalid_FileName_Returns_Null() 28 | { 29 | var name = OutputFileName.ParseFromFileName("Load_2382asdfdasRN1884F4EB-386C_SRV_TestStatus-Passed_20220425-215857.7z"); 30 | Assert.Null(name); 31 | } 32 | 33 | [Fact] 34 | public void HostName_Can_Contain_Underscores() 35 | { 36 | var name = OutputFileName.ParseFromFileName("Load_2624ms_PERF_100K20H2-V_CLT_TestStatus-Passed_20220425-213643.7z"); 37 | Assert.NotNull(name); 38 | 39 | Assert.Equal(2624, name.TestDurationinMS); 40 | Assert.Equal("Load", name.TestCaseName); 41 | Assert.Equal("PERF_100K20H2-V", name.MachineWhereResultsAreGeneratedOn); 42 | Assert.Equal(TestStatus.Passed, name.TestStatus); 43 | Assert.Equal(new DateTime(2022, 04, 25, 21, 36, 43), name.ProfilingStoppedTime); 44 | 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Extract/PdbIdentifierTests.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | /// 4 | using ETWAnalyzer.Extract.Modules; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Xunit; 11 | 12 | namespace ETWAnalyzer_uTest.Extract 13 | { 14 | public class PdbIdentifierTests 15 | { 16 | [Fact] 17 | public void Can_Deserialize_PdbName_WithSpaces() 18 | { 19 | const string pdbName = "Name With Spaces.pdb"; 20 | Guid pdbGuid = new Guid("39e2c995-82fe-4437-9c23-50af818eae5e"); 21 | 22 | PdbIdentifier pdb = new PdbIdentifier(pdbName, pdbGuid, 15); 23 | Assert.Equal(15, pdb.Age); 24 | Assert.Equal(pdbGuid, pdb.Id); 25 | Assert.Equal(pdbName, pdb.Name); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Usage", "xUnit1013:Public method should be marked as test", Justification = "", Scope = "member", Target = "~M:ETWAnalyzer_uTest.ExceptionOccurrenceAnalyzerTests.Can_Update_ArisenExceptionHistoryFile_For_TestRuns_Of_Two_TestTypes")] 9 | [assembly: SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen", Justification = "", Scope = "member", Target = "~M:ETWAnalyzer_uTest.TestInfrastructure.TestContext.IsAdministrator~System.Boolean")] 10 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Infrastructure/CounterTests.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Infrastructure; 5 | using Xunit; 6 | 7 | namespace ETWAnalyzer_uTest.Infrastructure 8 | { 9 | public class CounterTests 10 | { 11 | [Fact] 12 | public void Empty_Count_Has_ZeroLength_Counts() 13 | { 14 | var counter = new Counter(); 15 | Assert.Empty(counter.Counts); 16 | } 17 | 18 | [Fact] 19 | public void Count_IsPreserved_After_One_Increment() 20 | { 21 | Counter counter = new Counter(); 22 | counter.Increment("Test"); 23 | Assert.Equal(1, counter["Test"]); 24 | Assert.Single(counter.Counts); 25 | } 26 | 27 | [Fact] 28 | public void Count_IsPreserved_After_Two_Increment() 29 | { 30 | Counter counter = new Counter(); 31 | counter.Increment("Test"); 32 | counter.Increment("Test"); 33 | Assert.Equal(2, counter["Test"]); 34 | Assert.Single(counter.Counts); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Infrastructure/NumericTests.cs: -------------------------------------------------------------------------------- 1 | using ETWAnalyzer.Infrastructure; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Xunit; 8 | 9 | namespace ETWAnalyzer_uTest.Infrastructure 10 | { 11 | public class NumericTests 12 | { 13 | [Fact] 14 | public void PercentileEmptyList() 15 | { 16 | List values = []; 17 | Assert.Equal(0, values.Percentile(0.5f)); 18 | } 19 | 20 | [Fact] 21 | public void PercentileTwoItems_Zero() 22 | { 23 | List floats = [1, 2]; 24 | Assert.Equal(1, floats.Percentile(0)); 25 | Assert.Equal(2, floats.Percentile(1)); 26 | } 27 | 28 | [Fact] 29 | public void Percentile_Interpolate() 30 | { 31 | List floats = [1, 2]; 32 | Assert.Equal(1.5f, floats.Percentile(0.5f)); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Infrastructure/UniqueStringList.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer.Infrastructure; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Xunit; 11 | 12 | namespace ETWAnalyzer_uTest.Infrastructure 13 | { 14 | public class UniqueStringListTests 15 | 16 | { 17 | [Fact] 18 | public void Can_Add_Null() 19 | { 20 | UniqueStringList list = new UniqueStringList(); 21 | Assert.Equal(-2, list.GetIndexForString(null)); 22 | 23 | Assert.Null(list.GetStringByIndex(-2)); 24 | } 25 | 26 | [Fact] 27 | public void Adding_Same_String_ReturnsSameIndex() 28 | { 29 | UniqueStringList list = new UniqueStringList(); 30 | int idx1 = list.GetIndexForString("A"); 31 | int idx2 = list.GetIndexForString("A"); 32 | 33 | Assert.Equal(idx1, idx2); 34 | Assert.Single(list.Strings); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System.Reflection; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | using Xunit; 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("ETWAnalyzer_uTest")] 13 | [assembly: AssemblyDescription("")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("ETWAnalyzer_uTest")] 17 | [assembly: AssemblyCopyright("Copyright © 2017")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // Setting ComVisible to false makes the types in this assembly not visible 22 | // to COM components. If you need to access a type in this assembly from 23 | // COM, set the ComVisible attribute to true on that type. 24 | [assembly: ComVisible(false)] 25 | 26 | // The following GUID is for the ID of the typelib if this project is exposed to COM 27 | [assembly: Guid("025ac7f6-c444-403c-ac95-5b535ce1fbc5")] 28 | 29 | // Version information for an assembly consists of the following four values: 30 | // 31 | // Major Version 32 | // Minor Version 33 | // Build Number 34 | // Revision 35 | // 36 | // You can specify all the values or you can default the Build and Revision Numbers 37 | // by using the '*' as shown below: 38 | // [assembly: AssemblyVersion("1.0.*")] 39 | [assembly: AssemblyVersion("1.0.0.0")] 40 | [assembly: AssemblyFileVersion("1.0.0.0")] 41 | [assembly: CollectionBehavior(DisableTestParallelization = true)] 42 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/CallupAdhocWarmReadingCT_3117msDEFOR09T121SRV.20200717-124447.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/CallupAdhocWarmReadingCT_3117msDEFOR09T121SRV.20200717-124447.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/CallupAdhocWarmReadingCT_3117msFO9DE01T0162PC.20200717-124447.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/CallupAdhocWarmReadingCT_3117msFO9DE01T0162PC.20200717-124447.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/Disk_Usage_Utilization_by_Disk_DE.csv: -------------------------------------------------------------------------------- 1 | Disk,Process,Thread ID,Path Name,IO Type,Priority,Disk Service Time (µs),IO Time (µs),Size (B),Complete Time (s),QD/I - Queue Depth at Init Time,QD/C - Queue Depth at Complete Time 2 | 0,syngo.Common.Communication.DynamicServices.Host.exe (8876),9468,,Flush,Normal,5.909,5.909,0,"1,176567818",0,0 3 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/Disk_Usage_Utilization_by_Disk_Empty.csv: -------------------------------------------------------------------------------- 1 | Disk,Process,Thread ID,Path Name,IO Type,Priority,Disk Service Time (µs),IO Time (µs),Size (B),Complete Time (s),QD/I - Queue Depth at Init Time,QD/C - Queue Depth at Complete Time 2 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/EmptyETL.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/EmptyETL.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleBitmapping/1/Blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleBitmapping/1/Blue.png -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleBitmapping/1/Red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleBitmapping/1/Red.png -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleBitmapping/2/Yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleBitmapping/2/Yellow.png -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleData/SampleData.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleData/SampleData.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleDataJson/Extract/SampleDataJsonFiles.sample: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleDataJson/Extract/SampleDataJsonFiles.sample -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleDataMoreMachines/SampleDataMoreMachines.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleDataMoreMachines/SampleDataMoreMachines.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/SampleDataV2/SampleDataV2.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/SampleDataV2/SampleDataV2.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/ZipWith7zLogFile.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/ZipWith7zLogFile.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/ZipWithTextFile.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/ZipWithTextFile.7z -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestData/ZipWithTwoFiles.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siemens-Healthineers/ETWAnalyzer/64f1a258a3a3ff7ee798beaa2d26d78ba441fd9e/ETWAnalyzer_uTest/TestData/ZipWithTwoFiles.zip -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestInfrastructure/CultureSwitcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace ETWAnalyzer_uTest.TestInfrastructure 10 | { 11 | /// 12 | /// Set thread language to English and revert on dispose to allow stable unit tests with a specific culture dependant formatting. 13 | /// 14 | internal class CultureSwitcher : IDisposable 15 | { 16 | CultureInfo myUICulture; 17 | CultureInfo myThreadCulture; 18 | 19 | /// 20 | /// Set Thread language to English. This sets CurrentUICulture and CurrentCulture. 21 | /// 22 | public CultureSwitcher() 23 | { 24 | myUICulture = Thread.CurrentThread.CurrentUICulture; 25 | myThreadCulture = Thread.CurrentThread.CurrentCulture; 26 | Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us"); 27 | Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us"); 28 | } 29 | 30 | /// 31 | /// Reset culture to previous values 32 | /// 33 | public void Dispose() 34 | { 35 | Thread.CurrentThread.CurrentUICulture = myUICulture; 36 | Thread.CurrentThread.CurrentCulture = myThreadCulture; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestInfrastructure/DataOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETWAnalyzer_uTest.TestInfrastructure 8 | { 9 | /// 10 | /// Enscapsualates data with some cached output which is meant to be written to console or log 11 | /// 12 | /// 13 | public class DataOutput 14 | { 15 | /// 16 | /// Wraped output 17 | /// 18 | public T Data { get; } 19 | 20 | /// 21 | /// Cached ouptut data 22 | /// 23 | public string Output { get; } 24 | 25 | /// 26 | /// 27 | /// 28 | /// 29 | /// 30 | public DataOutput(T data, string output) 31 | { 32 | Data = data; 33 | Output = output; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/TestInfrastructure/TestContext.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Security.Principal; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ETWAnalyzer_uTest.TestInfrastructure 12 | { 13 | public class TestContext 14 | { 15 | public static bool IsInGithubPipeline() 16 | { 17 | return Environment.GetEnvironmentVariable("GITHUB_ACTION") != null; 18 | } 19 | 20 | public static bool IsAdministrator() 21 | { 22 | using (WindowsIdentity identity = WindowsIdentity.GetCurrent()) 23 | { 24 | WindowsPrincipal principal = new WindowsPrincipal(identity); 25 | return principal.IsInRole(WindowsBuiltInRole.Administrator); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ETWAnalyzer_uTest/WpaExporterTests.cs: -------------------------------------------------------------------------------- 1 | //// SPDX-FileCopyrightText: © 2022 Siemens Healthcare GmbH 2 | //// SPDX-License-Identifier: MIT 3 | 4 | using ETWAnalyzer; 5 | using System; 6 | using Xunit; 7 | 8 | namespace ETWAnalyzer_uTest 9 | { 10 | 11 | public class WpaExporterTests 12 | { 13 | [Fact] 14 | public void ThrowArgumentException_When_InputFile_Is_Null_Or_Empty() 15 | { 16 | ExceptionAssert.Throws( 17 | () => new WpaExportCommand("", TestData.CPUWPAProfile, TestData.ExecutableDirectory, null, null), 18 | "etlFile"); 19 | } 20 | 21 | [Fact] 22 | public void ThrowArgumentException_When_WpaProfileFile_Is_Null_Or_Empty() 23 | { 24 | ExceptionAssert.Throws( 25 | () => new WpaExportCommand(TestData.ServerEtlFile, "", TestData.ExecutableDirectory, null, null), 26 | "wpaProfile"); 27 | } 28 | 29 | [Fact] 30 | public void ThrowArgumentException_When_OutputDirectory_Is_Null_Or_Empty() 31 | { 32 | ExceptionAssert.Throws( 33 | () => new WpaExportCommand(TestData.ServerEtlFile, TestData.CPUWPAProfile, "", null, null), 34 | "outputFolder"); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | © 2022 Siemens Healthcare GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Test.runsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | cobertura 8 | [ETWAnalyzer_uTest]*,[ETWAnalyzer_iTest]* 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | --------------------------------------------------------------------------------