├── .github └── workflows │ ├── ci.yml │ └── codeql-analysis.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CtfPlayback ├── App.config ├── CtfPlayback.cs ├── CtfPlayback.csproj ├── CtfPlaybackException.cs ├── CtfPlaybackOptions.cs ├── CtfStreamPlayback.cs ├── CtfStreamReadAhead.cs ├── EventStreams │ ├── CtfEvent.cs │ ├── CtfEventStream.cs │ ├── CtfPacket.cs │ └── Interfaces │ │ ├── ICtfEvent.cs │ │ ├── ICtfEventStream.cs │ │ └── ICtfPacket.cs ├── FieldValues │ ├── CtfArrayValue.cs │ ├── CtfDoubleValue.cs │ ├── CtfEnumValue.cs │ ├── CtfFieldValue.cs │ ├── CtfFloatValue.cs │ ├── CtfIntegerValue.cs │ ├── CtfStringValue.cs │ ├── CtfStructValue.cs │ ├── CtfTimestamp.cs │ ├── CtfVariantValue.cs │ └── GetValueAsStringOptions.cs ├── Helpers │ ├── ComparableExtensions.cs │ ├── Guard.cs │ └── StreamExts.cs ├── ICtfPlaybackCustomization.cs ├── IPacketReader.cs ├── IPacketReaderContext.cs ├── Inputs │ ├── ICtfInput.cs │ ├── ICtfInputStream.cs │ └── ICtfTraceInput.cs ├── Metadata │ ├── AntlrParser │ │ ├── Contexts │ │ │ └── CtfParser.cs │ │ ├── CtfAntlrMetadataParser.cs │ │ ├── CtfListener.cs │ │ ├── DebugErrorListener.cs │ │ ├── EnumeratorMapping.cs │ │ ├── Generated │ │ │ ├── CtfBaseListener.cs │ │ │ ├── CtfLexer.cs │ │ │ ├── CtfParser.cs │ │ │ └── ICtfListener.cs │ │ ├── Grammar │ │ │ ├── Ctf.g4 │ │ │ └── Lexer.g4 │ │ ├── PostfixExpressionValue.cs │ │ ├── Scopes │ │ │ ├── CtfCompoundTypeScope.cs │ │ │ ├── CtfGlobalScope.cs │ │ │ └── CtfScope.cs │ │ └── TypeDeclaration.cs │ ├── CtfMetadataException.cs │ ├── CtfTypes.cs │ ├── EncodingTypes.cs │ ├── Helpers │ │ └── IntegerLiteral.cs │ ├── ICtfMetadataCustomization.cs │ ├── Interfaces │ │ ├── ICtfClockDescriptor.cs │ │ ├── ICtfEnvironmentDescriptor.cs │ │ ├── ICtfEventDescriptor.cs │ │ ├── ICtfFieldDescriptor.cs │ │ ├── ICtfIntegerRange.cs │ │ ├── ICtfMetadata.cs │ │ ├── ICtfMetadataBuilder.cs │ │ ├── ICtfMetadataParser.cs │ │ ├── ICtfNamedRange.cs │ │ ├── ICtfStreamDescriptor.cs │ │ └── ICtfTraceDescriptor.cs │ ├── InternalHelpers │ │ ├── CtfIntegerRange.cs │ │ ├── CtfNamedRange.cs │ │ ├── CtfPropertyBag.cs │ │ └── IntegerLiteralString.cs │ ├── NamedScopes │ │ ├── CtfClockDescriptor.cs │ │ ├── CtfEnvironmentDescriptor.cs │ │ ├── CtfFieldDescriptor.cs │ │ ├── CtfStreamDescriptor.cs │ │ └── CtfTraceDescriptor.cs │ ├── TypeInterfaces │ │ ├── ICtfArrayDescriptor.cs │ │ ├── ICtfEnumDescriptor.cs │ │ ├── ICtfFloatingPointDescriptor.cs │ │ ├── ICtfIntegerDescriptor.cs │ │ ├── ICtfStringDescriptor.cs │ │ ├── ICtfStructDescriptor.cs │ │ ├── ICtfTypeDescriptor.cs │ │ └── ICtfVariantDescriptor.cs │ └── Types │ │ ├── CtfArrayDescriptor.cs │ │ ├── CtfEnumDescriptor.cs │ │ ├── CtfFloatingPointDescriptor.cs │ │ ├── CtfIntegerDescriptor.cs │ │ ├── CtfMetadataTypes.cs │ │ ├── CtfStringDescriptor.cs │ │ ├── CtfStructDescriptor.cs │ │ └── CtfVariantDescriptor.cs ├── PacketReader.cs ├── Properties │ └── AssemblyInfo.cs ├── TestingAssemblyInfo.cs └── packages.config ├── CtfUnitTest ├── CtfBaseTest.cs ├── CtfUnitTest.csproj ├── EnumTests.cs ├── EnumeratorTestValue.cs ├── FloatingPointTest.cs ├── IntegerLiteralStringTests.cs ├── IntegerLiteralTests.cs ├── ScopeGenerationTests.cs ├── StructDeclarationTests.cs ├── SyntaxErrorTests.cs ├── TestCtfEventDescriptor.cs ├── TestCtfMetadataCustomization.cs └── TestErrorListener.cs ├── DeveloperInfo.md ├── Images ├── ADK_WPT.jpg ├── PerfettoCookerPipeline.png ├── PerfettoPluginArchitecture.png └── WpaLinux.JPG ├── LICENSE.txt ├── LTTngCds ├── CookerData │ ├── ICursor.cs │ ├── LTTngConstants.cs │ ├── LTTngContext.cs │ └── LTTngEvent.cs ├── CtfExtensions │ ├── DescriptorInterfaces │ │ └── IEventDescriptor.cs │ ├── Descriptors │ │ └── EventDescriptor.cs │ ├── FolderInput │ │ ├── LTTngFileInputStream.cs │ │ ├── LTTngFolderInput.cs │ │ └── LTTngFolderTraceInput.cs │ ├── LTTngMetadata.cs │ ├── LTTngMetadataCustomization.cs │ ├── LTTngMetadataException.cs │ ├── LTTngPlaybackCustomization.cs │ ├── LTTngPlaybackException.cs │ ├── TraceContext.cs │ └── ZipArchiveInput │ │ ├── LTTngZipArchiveInput.cs │ │ ├── LTTngZipArchiveInputStream.cs │ │ └── LTTngZipArchiveTraceInput.cs ├── LTTngCds.csproj ├── LTTngDataProcessor.cs ├── LTTngDataSource.cs ├── LTTngSourceParser.cs ├── MetadataTables │ ├── TraceStatsPrebuiltConfiguration.json │ └── TraceStatsTable.cs ├── TestingAssemblyInfo.cs └── TraceStatsData.cs ├── LTTngCdsUnitTest ├── LTTngBaseSourceCooker.cs ├── LTTngCdsUnitTest.cs ├── LTTngCdsUnitTest.csproj ├── LTTngEventDataCooker.cs └── LTTngEventWithContext.cs ├── LTTngDataExtUnitTest ├── LTTngDataExtUnitTest.csproj └── LTTngUnitTest.cs ├── LTTngDataExtensions ├── DataOutputTypes │ ├── DataSize.cs │ ├── IContextSwitch.cs │ ├── IDiskActivity.cs │ ├── IExecutionEvent.cs │ ├── IFileEvent.cs │ ├── IMessage.cs │ ├── IModule.cs │ ├── IProcess.cs │ ├── ISyscall.cs │ ├── ISyscallEvent.cs │ ├── IThread.cs │ └── LTTngGenericEvent.cs ├── LTTngDataExtensions.csproj ├── Properties │ └── launchSettings.json ├── Resources │ ├── CpuTablePrebuiltConfigurations.json │ ├── DiskActivityPrebuiltConfiguration.json │ ├── FileEventsTablePrebuiltConfigurations.json │ ├── GenericEventTablePrebuiltConfigurations.json │ ├── ProcessTablePrebuiltConfigurations.json │ └── SyscallTablePrebuiltConfigurations.json ├── SourceDataCookers │ ├── Cpu │ │ ├── ContextSwitch.cs │ │ ├── IContextSwitchIn.cs │ │ ├── IContextSwitchOut.cs │ │ └── LTTngCpuDataCooker.cs │ ├── Diagnostic Messages │ │ ├── DmesgDataCooker.cs │ │ └── Message.cs │ ├── Disk │ │ ├── DiskActivity.cs │ │ ├── DiskActivityBuilder.cs │ │ ├── FileEvent.cs │ │ └── LTTngDiskDataCooker.cs │ ├── LTTngBaseSourceCooker.cs │ ├── LTTngGenericEventDataCooker.cs │ ├── Module │ │ ├── LTTngModuleDataCooker.cs │ │ └── Module.cs │ ├── Process │ │ ├── IBuilder.cs │ │ ├── LTTngProcessDataCooker.cs │ │ ├── Process.cs │ │ └── ProcessBuilder.cs │ ├── Syscall │ │ ├── LTTngSyscallDataCooker.cs │ │ ├── Syscall.cs │ │ └── SyscallEvent.cs │ └── Thread │ │ ├── ContextSwitch.cs │ │ ├── DiscardedEventsTracker.cs │ │ ├── ExecutingThreadTracker.cs │ │ ├── ExecutionEvent.cs │ │ ├── LTTngThreadDataCooker.cs │ │ ├── PidTracker.cs │ │ └── Thread.cs ├── Tables │ ├── CpuTable.cs │ ├── DiagnosticMessageTable.cs │ ├── DiskTable.cs │ ├── ExecutionEventTable.cs │ ├── FileEventsTable.cs │ ├── GenericEventTable.cs │ ├── ModuleEventsTable.cs │ ├── ProcessTable.cs │ ├── SyscallTable.cs │ └── ThreadTable.cs └── pluginManifest.json ├── LTTngDriver ├── LTTngDriver.csproj ├── Program.Main.cs ├── Program.cs ├── Properties │ └── launchSettings.json └── run_driver.cmd ├── Launcher └── Windows │ ├── LaunchWpaPerfToolsLinuxAndroid.bat │ ├── LaunchWpaPerfToolsLinuxAndroid.ps1 │ └── MicrosoftPerfToolsLinuxAndroid.url ├── LinuxLogParsers ├── LinuxLogParser │ ├── AndroidLogcat │ │ ├── AndroidLogcatLogParsedEntry.cs │ │ └── AndroidLogcatLogParser.cs │ ├── CloudInitLog │ │ ├── CloudInitLogParsedEntry.cs │ │ └── CloudInitLogParser.cs │ ├── DmesgIsoLog │ │ ├── DmesgIsoLogParsedEntry.cs │ │ └── DmesgIsoLogParser.cs │ ├── LinuxLogParser.csproj │ ├── SourceParserIds.cs │ └── WaLinuxAgentLog │ │ ├── WaLinuxAgentLogParsedEntry.cs │ │ └── WaLinuxAgentLogParser.cs ├── LinuxLogParserCore │ ├── FileMetadata.cs │ ├── FileTimestampSort.cs │ ├── LinuxLogParserCore.csproj │ ├── LogContext.cs │ └── LogParserBase.cs ├── LinuxLogParsersUnitTest │ ├── LinuxLogParsersUnitTest.cs │ └── LinuxLogParsersUnitTest.csproj └── LinuxPlugins-MicrosoftPerformanceToolkSDK │ ├── AndroidLogCat │ ├── AndroidLogcat.csproj │ ├── AndroidLogcatCustomDataProcessor.cs │ ├── AndroidLogcatDataCooker.cs │ ├── AndroidLogcatDataSource.cs │ ├── AndroidLogcatParsedResult.cs │ ├── Tables │ │ ├── DurationTable.cs │ │ ├── LogTable.cs │ │ └── Metadata │ │ │ └── FileStatsMetadataTable.cs │ └── pluginManifest.json │ ├── Cloud-init │ ├── Cloud-Init.csproj │ ├── CloudInitCustomDataProcessor.cs │ ├── CloudInitDataCooker.cs │ ├── CloudInitLogParsedResult.cs │ ├── CloudInitProcessingSource.cs │ ├── Tables │ │ ├── CloudInitTable.cs │ │ └── Metadata │ │ │ └── FileStatsMetadataTable.cs │ └── pluginManifest.json │ ├── DmesgIsoLog │ ├── Dmesg.csproj │ ├── DmesgIsoCustomDataProcessor.cs │ ├── DmesgIsoDataCooker.cs │ ├── DmesgIsoDataSource.cs │ ├── DmesgIsoLogParsedResult.cs │ ├── Tables │ │ ├── LogTable.cs │ │ ├── Metadata │ │ │ └── FileStatsMetadataTable.cs │ │ └── RawTable.cs │ └── pluginManifest.json │ └── WaLinuxAgent │ ├── Tables │ ├── Metadata │ │ └── FileStatsMetadataTable.cs │ └── WaLinuxAgentTable.cs │ ├── WaLinuxAgent.csproj │ ├── WaLinuxAgentCustomDataProcessor.cs │ ├── WaLinuxAgentDataCooker.cs │ ├── WaLinuxAgentLogParsedResult.cs │ ├── WaLinuxAgentProcessingSource.cs │ └── pluginManifest.json ├── LinuxTraceLogCapture.md ├── Microsoft-Perf-Tools-Linux-Android.sln ├── NOTICE.md ├── PerfDataExtension ├── PerfDataEvent.cs ├── PerfDataExtension.csproj ├── PerfDataFileInfo.cs ├── PerfDataFilesTable.cs ├── PerfDataFormatter.cs ├── PerfDataGenericEventsTable.cs ├── PerfDataGenericSourceCooker.cs ├── PerfDataProcessingSource.cs ├── PerfDataSourceParser.cs ├── README.md ├── Utility.cs └── pluginManifest.json ├── PerfDataTxtExtension ├── DataOutputTypes │ └── DataSize.cs ├── PerfDataTxtExtension.csproj ├── Properties │ └── launchSettings.json ├── SourceDataCookers │ ├── PerfDataCustomDataProcessor.cs │ └── PerfDataProcessingSource.cs ├── Tables │ ├── Generators │ │ ├── IMapListToStream.cs │ │ └── SequentialGenerator.cs │ ├── LinuxPerfScriptTableBase.cs │ ├── PerfTxtCpuSamplingTable.cs │ └── TimeHelper.cs └── pluginManifest.json ├── PerfDataUnitTest ├── PerfDataUnitTest.cs ├── PerfDataUnitTest.csproj └── TestData │ └── perf.data ├── PerfUnitTest ├── PerfUnitTest.cs └── PerfUnitTest.csproj ├── PerfettoCds ├── Architecture.md ├── PerfettoCds.csproj ├── Pipeline │ ├── Args.cs │ ├── CompositeDataCookers │ │ ├── PerfettoCpuCountersEventCooker.cs │ │ ├── PerfettoCpuFrequencyEventCooker.cs │ │ ├── PerfettoCpuSamplingEventCooker.cs │ │ ├── PerfettoCpuSchedEventCooker.cs │ │ ├── PerfettoFrameEventCooker.cs │ │ ├── PerfettoFtraceEventCooker.cs │ │ ├── PerfettoGenericEventCooker.cs │ │ ├── PerfettoGpuCountersEventCooker.cs │ │ ├── PerfettoLogcatEventCooker.cs │ │ ├── PerfettoProcessEventCooker.cs │ │ ├── PerfettoProcessMemoryEventCooker.cs │ │ └── PerfettoSystemMemoryEventCooker.cs │ ├── DataOutput │ │ ├── PerfettoCpuCountersEvent.cs │ │ ├── PerfettoCpuFrequencyEvent.cs │ │ ├── PerfettoCpuSamplingEvent.cs │ │ ├── PerfettoCpuSchedEvent.cs │ │ ├── PerfettoCpuWakeEvent.cs │ │ ├── PerfettoFrameEvent.cs │ │ ├── PerfettoFtraceEvent.cs.cs │ │ ├── PerfettoGenericEvent.cs │ │ ├── PerfettoGpuCountersEvent.cs │ │ ├── PerfettoLogcatEvent.cs │ │ ├── PerfettoProcessEvent.cs │ │ ├── PerfettoProcessMemoryEvent.cs │ │ └── PerfettoSystemMemoryEvent.cs │ ├── Events │ │ └── PerfettoSqlEventKeyed.cs │ ├── PerfettoDataProcessor.cs │ ├── PerfettoDataSource.cs │ ├── PerfettoPluginConstants.cs │ ├── PerfettoSourceParser.cs │ ├── SourceDataCookers │ │ ├── PerfettoActualFrameCooker.cs │ │ ├── PerfettoAndroidLogCooker.cs │ │ ├── PerfettoArgCooker.cs │ │ ├── PerfettoCounterCooker.cs │ │ ├── PerfettoCounterTrackCooker.cs │ │ ├── PerfettoCpuCounterTrack.cs │ │ ├── PerfettoExpectedFrameCooker.cs │ │ ├── PerfettoGpuCounterTrack.cs │ │ ├── PerfettoPackageListCooker.cs │ │ ├── PerfettoPerfSampleCooker.cs │ │ ├── PerfettoProcessCounterTrackCooker.cs │ │ ├── PerfettoProcessRawCooker.cs │ │ ├── PerfettoProcessTrackCooker.cs │ │ ├── PerfettoRawCooker.cs │ │ ├── PerfettoSchedSliceCooker.cs │ │ ├── PerfettoSliceCooker.cs │ │ ├── PerfettoStackProfileCallSiteCooker.cs │ │ ├── PerfettoStackProfileFrameCooker.cs │ │ ├── PerfettoStackProfileMappingCooker.cs │ │ ├── PerfettoStackProfileSymbolCooker.cs │ │ ├── PerfettoThreadCooker.cs │ │ └── PerfettoThreadTrackerCooker.cs │ └── Tables │ │ ├── PerfettoCpuCountersTable.cs │ │ ├── PerfettoCpuFrequencyTable.cs │ │ ├── PerfettoCpuSamplingTable.cs │ │ ├── PerfettoCpuSchedTable.cs │ │ ├── PerfettoFrameTable.cs │ │ ├── PerfettoFtraceEventTable.cs │ │ ├── PerfettoGenericEventTable.cs │ │ ├── PerfettoGpuCountersTable.cs │ │ ├── PerfettoLogcatEventTable.cs │ │ ├── PerfettoPackageTable.cs │ │ ├── PerfettoProcessMemoryTable.cs │ │ ├── PerfettoProcessTable.cs │ │ └── PerfettoSystemMemoryTable.cs ├── ReadMe.md └── pluginManifest.json ├── PerfettoProcessor ├── Events │ ├── PerfettoActualFrameEvent.cs │ ├── PerfettoAndroidLogEvent.cs │ ├── PerfettoArgEvent.cs │ ├── PerfettoClockSnapshotEvent.cs │ ├── PerfettoCounterEvent.cs │ ├── PerfettoCounterTrackEvent.cs │ ├── PerfettoCpuCounterTrackEvent.cs │ ├── PerfettoExpectedFrameEvent.cs │ ├── PerfettoGpuCounterTrackEvent.cs │ ├── PerfettoMetadataEvent.cs │ ├── PerfettoPackageListEvent.cs │ ├── PerfettoPerfSampleEvent.cs │ ├── PerfettoProcessCounterTrackEvent.cs │ ├── PerfettoProcessRawEvent.cs │ ├── PerfettoProcessTrackEvent.cs │ ├── PerfettoRawEvent.cs │ ├── PerfettoSchedSliceEvent.cs │ ├── PerfettoSliceEvent.cs │ ├── PerfettoSqlEvent.cs │ ├── PerfettoStackProfileCallSiteEvent.cs │ ├── PerfettoStackProfileFrameEvent.cs │ ├── PerfettoStackProfileMappingEvent.cs │ ├── PerfettoStackProfileSymbolEvent.cs │ ├── PerfettoThreadEvent.cs │ ├── PerfettoThreadTrackEvent.cs │ ├── PerfettoTraceBoundsEvent.cs │ └── PerfettoTrackEvent.cs ├── PerfettoProcessor.csproj ├── PerfettoTraceProcessor.cs ├── Protobuf │ ├── Descriptor.cs │ ├── Readme.txt │ ├── TraceProcessor.cs │ ├── descriptor.proto │ └── trace_processor.proto └── StackWalk.cs ├── PerfettoUnitTest ├── ConsoleLogger.cs ├── PerfettoUnitTest.cs └── PerfettoUnitTest.csproj ├── README.md ├── ReleaseFiles └── README.txt ├── SECURITY.md ├── SUPPORT.md ├── TestData ├── AndroidLogs │ └── Logcat │ │ └── AndroidLogcatWSA.log ├── LTTng │ └── lttng-kernel-trace.ctf ├── LinuxLogs │ ├── Cloud-Init │ │ └── cloud-init.log │ ├── Dmesg │ │ └── dmesg.iso.log │ └── WaLinuxAgent │ │ └── waagent.log ├── Perf │ ├── perf.data.txt │ └── timestamp.txt └── Perfetto │ ├── androidBasicMemory.pftrace │ ├── androidGpu.pftrace │ ├── chrome.pftrace │ ├── jankFrame.pftrace │ ├── perfetto_trace_cpu_sampling_not_scoped.pftrace │ └── test_trace.perfetto-trace ├── UnitTestCommon ├── ITableResultExts.cs ├── Progress.cs ├── TableBuilder.cs ├── TableBuilderTests.cs ├── TableBuilderWithRowCount.cs ├── UnitTest.cs └── UnitTestCommon.csproj ├── Utilities ├── AccessProviders │ └── ArrayAccessProvider`1.cs ├── Common.cs ├── EventProjection.cs ├── ProcessingSourceInfoGenerator.cs ├── Utilities.projitems └── Utilities.shproj └── grammar ├── Ctf.g4 ├── Lexer.g4 ├── antlr-4.11.1-complete.jar └── ctf.cmd /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /CtfPlayback/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CtfPlayback/CtfPlayback.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.1 5 | 1.2.3 6 | true 7 | Microsoft 8 | Microsoft Corp. 9 | Performance ToolKit 10 | Contains the LTTng CTF playback library. 11 | Microsoft.Performance.Toolkit.Plugins.LTTngCtfPlayback 12 | © Microsoft Corporation. All rights reserved. 13 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | LICENSE.txt 16 | 17 | 18 | 19 | true 20 | 21 | 22 | 23 | true 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | True 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /CtfPlayback/CtfPlaybackException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Runtime.Serialization; 6 | 7 | namespace CtfPlayback 8 | { 9 | /// 10 | /// This exception is thrown when the unexpected happens while playing back the CTF event streams. 11 | /// 12 | public class CtfPlaybackException 13 | : Exception 14 | { 15 | public CtfPlaybackException() 16 | { 17 | } 18 | 19 | public CtfPlaybackException(string message) : base(message) 20 | { 21 | } 22 | 23 | public CtfPlaybackException(string message, Exception innerException) : base(message, innerException) 24 | { 25 | } 26 | 27 | protected CtfPlaybackException(SerializationInfo info, StreamingContext context) : base(info, context) 28 | { 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /CtfPlayback/CtfPlaybackOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback 5 | { 6 | /// 7 | /// Options for controlling event playback. 8 | /// 9 | public struct CtfPlaybackOptions 10 | { 11 | /// 12 | /// When this is set, each stream will attempt to pre-read events so they are immediately ready 13 | /// for processing. There is some overhead with this approach, and will not always be the optimal 14 | /// approach. 15 | /// 16 | public bool ReadAhead { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /CtfPlayback/EventStreams/CtfEventStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using CtfPlayback.EventStreams.Interfaces; 6 | using CtfPlayback.Inputs; 7 | using CtfPlayback.Metadata.Interfaces; 8 | 9 | namespace CtfPlayback.EventStreams 10 | { 11 | internal sealed class CtfEventStream 12 | : ICtfEventStream 13 | { 14 | public CtfEventStream( 15 | ICtfInputStream inputStream, 16 | ICtfMetadata metadata, 17 | ICtfPlaybackCustomization playbackCustomization) 18 | { 19 | this.InputStream = inputStream; 20 | this.Metadata = metadata; 21 | this.PlaybackCustomization = playbackCustomization; 22 | } 23 | 24 | public ICtfInputStream InputStream { get; } 25 | 26 | public string StreamSource => InputStream.StreamSource; 27 | 28 | public Stream Stream => InputStream.Stream; 29 | 30 | public ICtfMetadata Metadata { get; } 31 | 32 | public ICtfPlaybackCustomization PlaybackCustomization { get; } 33 | 34 | public ulong ByteCount => this.InputStream.ByteCount; 35 | 36 | public void Dispose() 37 | { 38 | // this is just a wrapper around an object that owns the input stream 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /CtfPlayback/EventStreams/Interfaces/ICtfEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.FieldValues; 5 | using CtfPlayback.Metadata.Interfaces; 6 | 7 | namespace CtfPlayback.EventStreams.Interfaces 8 | { 9 | /// 10 | /// Represents an event from a CTF event stream. 11 | /// 12 | public interface ICtfEvent 13 | { 14 | /// 15 | /// For debugging purposes. 16 | /// 17 | ulong ByteOffsetWithinPacket { get; } 18 | 19 | /// 20 | /// Timestamp associated with the event 21 | /// 22 | CtfTimestamp Timestamp { get; } 23 | 24 | /// 25 | /// If stream.event.header is defined, this is that value read from the event. 26 | /// 27 | CtfFieldValue StreamDefinedEventHeader { get; } 28 | 29 | /// 30 | /// If stream.event.context is defined, this is that value read from the event. 31 | /// 32 | CtfFieldValue StreamDefinedEventContext { get; } 33 | 34 | /// 35 | /// If an event context is defined, this is that value read from the event. 36 | /// 37 | CtfFieldValue Context { get; } 38 | 39 | /// 40 | /// The event payload value read from the event. 41 | /// 42 | CtfFieldValue Payload { get; } 43 | 44 | /// 45 | /// The number of bits consumed from the stream for Payload. 46 | /// 47 | uint PayloadBitCount { get; } 48 | 49 | /// 50 | /// Number of discarded events so far. 51 | /// 52 | uint DiscardedEvents { get; } 53 | 54 | /// 55 | /// The metadata descriptor associated with this event. 56 | /// 57 | ICtfEventDescriptor EventDescriptor { get; } 58 | 59 | /// 60 | /// Read StreamDefinedEventHeader and StreamDefinedEventContext. 61 | /// 62 | void ReadEventMetadata(); 63 | 64 | /// 65 | /// Read Context and Payload. 66 | /// 67 | void Read(); 68 | } 69 | } -------------------------------------------------------------------------------- /CtfPlayback/EventStreams/Interfaces/ICtfEventStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Inputs; 5 | using CtfPlayback.Metadata.Interfaces; 6 | 7 | namespace CtfPlayback.EventStreams.Interfaces 8 | { 9 | /// 10 | /// Data necessary to read and process a CTF event stream. 11 | /// 12 | public interface ICtfEventStream 13 | : ICtfInputStream 14 | { 15 | /// 16 | /// Metadata associated with the event stream. 17 | /// 18 | ICtfMetadata Metadata { get; } 19 | 20 | /// 21 | /// Extensibility points for processing the event stream. 22 | /// 23 | ICtfPlaybackCustomization PlaybackCustomization { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /CtfPlayback/FieldValues/CtfDoubleValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Globalization; 5 | using CtfPlayback.Metadata; 6 | using CtfPlayback.Metadata.TypeInterfaces; 7 | 8 | namespace CtfPlayback.FieldValues 9 | { 10 | /// 11 | /// Represents a floating point field from a CTF event 12 | /// 13 | public class CtfDoubleValue 14 | : CtfFieldValue 15 | { 16 | /// 17 | /// Constructor 18 | /// 19 | /// Floating point value 20 | public CtfDoubleValue(double value, ICtfFloatingPointDescriptor descriptor) 21 | : base(CtfTypes.FloatingPoint) 22 | { 23 | this.Value = value; 24 | this.Descriptor = descriptor; 25 | } 26 | 27 | /// 28 | /// Field value 29 | /// 30 | public double Value { get; } 31 | 32 | /// 33 | /// CTF floating point descriptor associated with the field 34 | /// 35 | public ICtfFloatingPointDescriptor Descriptor { get; } 36 | 37 | /// 38 | /// Returns a string representation of the field value. 39 | /// Useful when text dumping the contents of an event stream. 40 | /// 41 | /// The field value as a string 42 | public override string GetValueAsString(GetValueAsStringOptions options = GetValueAsStringOptions.NoOptions) 43 | { 44 | return string.Intern(Value.ToString(CultureInfo.InvariantCulture)); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /CtfPlayback/FieldValues/CtfEnumValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata; 5 | using CtfPlayback.Metadata.Helpers; 6 | 7 | namespace CtfPlayback.FieldValues 8 | { 9 | /// 10 | /// Represents an enum field from a CTF event. 11 | /// 12 | public class CtfEnumValue 13 | : CtfFieldValue 14 | { 15 | /// 16 | /// Constructor 17 | /// 18 | /// string value of the enum 19 | /// the enum base integer type 20 | public CtfEnumValue(string value, IntegerLiteral integerValue) 21 | : base(CtfTypes.Enum) 22 | { 23 | this.Value = string.Intern(value); 24 | this.IntegerValue = integerValue; 25 | } 26 | 27 | /// 28 | /// This is the value the base integer mapped to for the enum. 29 | /// 30 | public string Value { get; } 31 | 32 | /// 33 | /// This was the integer value that mapped to the enum value. 34 | /// 35 | public IntegerLiteral IntegerValue { get; } 36 | 37 | /// 38 | /// Returns a string representation of the field value. 39 | /// Useful when text dumping the contents of an event stream. 40 | /// 41 | /// The field value as a string 42 | public override string GetValueAsString(GetValueAsStringOptions options = GetValueAsStringOptions.NoOptions) 43 | { 44 | return Value; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /CtfPlayback/FieldValues/CtfFloatValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Globalization; 5 | using CtfPlayback.Metadata; 6 | using CtfPlayback.Metadata.TypeInterfaces; 7 | 8 | namespace CtfPlayback.FieldValues 9 | { 10 | /// 11 | /// Represents a floating point field from a CTF event 12 | /// 13 | public class CtfFloatValue 14 | : CtfFieldValue 15 | { 16 | /// 17 | /// Constructor 18 | /// 19 | /// Floating point value 20 | public CtfFloatValue(float value, ICtfFloatingPointDescriptor descriptor) 21 | : base(CtfTypes.FloatingPoint) 22 | { 23 | this.Value = value; 24 | this.Descriptor = descriptor; 25 | } 26 | 27 | /// 28 | /// Field value 29 | /// 30 | public float Value { get; } 31 | 32 | /// 33 | /// CTF floating point descriptor associated with the field 34 | /// 35 | public ICtfFloatingPointDescriptor Descriptor { get; } 36 | 37 | /// 38 | /// Returns a string representation of the field value. 39 | /// Useful when text dumping the contents of an event stream. 40 | /// 41 | /// The field value as a string 42 | public override string GetValueAsString(GetValueAsStringOptions options = GetValueAsStringOptions.NoOptions) 43 | { 44 | return string.Intern(Value.ToString(CultureInfo.InvariantCulture)); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /CtfPlayback/FieldValues/CtfStringValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata; 5 | 6 | namespace CtfPlayback.FieldValues 7 | { 8 | /// 9 | /// Represents a string field from a CTF event 10 | /// 11 | public class CtfStringValue 12 | : CtfFieldValue 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// Field value 18 | public CtfStringValue(string value) 19 | : base(CtfTypes.String) 20 | { 21 | this.Value = value; 22 | } 23 | 24 | /// 25 | /// Field value 26 | /// 27 | public string Value { get; } 28 | 29 | /// 30 | /// Returns a string representation of the field value. 31 | /// Useful when text dumping the contents of an event stream. 32 | /// 33 | /// The field value as a string 34 | public override string GetValueAsString(GetValueAsStringOptions options = GetValueAsStringOptions.NoOptions) 35 | { 36 | if (options.HasFlag(GetValueAsStringOptions.QuotesAroundStrings)) 37 | { 38 | return '"' + Value + '"'; 39 | } 40 | 41 | return Value; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /CtfPlayback/FieldValues/CtfVariantValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata; 5 | 6 | namespace CtfPlayback.FieldValues 7 | { 8 | /// 9 | /// Represents a CTF variant, which is basically a union whose value is established by an enum. 10 | /// 11 | public class CtfVariantValue 12 | : CtfFieldValue 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// The selected field from the variant 18 | /// The variant tag which identifies an enum 19 | /// The enum value which selected the field 20 | public CtfVariantValue(CtfFieldValue value, string identifier, CtfEnumValue tagEnum) 21 | : base(CtfTypes.Variant) 22 | { 23 | this.Value = value; 24 | this.Identifier = identifier; 25 | this.TagEnum = tagEnum; 26 | } 27 | 28 | /// 29 | /// This is the field chosen based on the enum tag for the variant. 30 | /// 31 | public CtfFieldValue Value { get; } 32 | 33 | /// 34 | /// This is the value in the variant tag used to determine which field to 35 | /// use as the value of the variant. 36 | /// 37 | public string Identifier { get; } 38 | 39 | /// 40 | /// This is the enum that was used for the tag value. 41 | /// 42 | public CtfEnumValue TagEnum { get; } 43 | 44 | /// 45 | public override string GetValueAsString(GetValueAsStringOptions options = GetValueAsStringOptions.NoOptions) 46 | { 47 | return string.Intern($"<{Identifier}> {Value.GetValueAsString()}"); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /CtfPlayback/FieldValues/GetValueAsStringOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace CtfPlayback.FieldValues 7 | { 8 | /// 9 | /// Provides options for string formatting. 10 | /// 11 | [Flags] 12 | public enum GetValueAsStringOptions 13 | { 14 | /// 15 | /// Default value, no options specified 16 | /// 17 | NoOptions = 0, 18 | 19 | /// 20 | /// Strings should include quotes around the value. 21 | /// 22 | QuotesAroundStrings, 23 | 24 | /// 25 | /// If there is an underscore at the beginning of the string, remove the first underscore. 26 | /// 27 | TrimBeginningUnderscore, 28 | } 29 | } -------------------------------------------------------------------------------- /CtfPlayback/IPacketReader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback 5 | { 6 | /// 7 | /// Used to read through a packet in a CTF event stream. 8 | /// 9 | public interface IPacketReader 10 | { 11 | /// 12 | /// Identifies whether the end of the stream has been reached. 13 | /// 14 | bool EndOfStream { get; } 15 | 16 | /// 17 | /// The number of cached bits remaining for consumption. 18 | /// 19 | uint RemainingBufferedBitCount { get; } 20 | 21 | /// 22 | /// Read data from the packet. 23 | /// 24 | /// The number of bits to read. 25 | /// dThe data read 26 | byte[] ReadBits(uint bitCount); 27 | 28 | /// 29 | /// Reads a null-terminated string from the packet. 30 | /// 31 | /// The string as a byte array 32 | byte[] ReadString(); 33 | 34 | /// 35 | /// Align the packet reader to the given bit count. 36 | /// 37 | /// 38 | void Align(uint bitCount); 39 | } 40 | } -------------------------------------------------------------------------------- /CtfPlayback/IPacketReaderContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback 5 | { 6 | internal interface IPacketReaderContext 7 | { 8 | ulong BitsInPacket { get; } 9 | 10 | ulong BitsReadFromPacket { get; } 11 | 12 | void SetPacketSize(ulong bitCount); 13 | 14 | void ReadToEndOfPacket(); 15 | } 16 | } -------------------------------------------------------------------------------- /CtfPlayback/Inputs/ICtfInput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace CtfPlayback.Inputs 8 | { 9 | /// 10 | /// A set of traces be processed. 11 | /// 12 | public interface ICtfInput 13 | : IDisposable 14 | { 15 | /// 16 | /// A set of traces be processed. 17 | /// 18 | IReadOnlyList Traces { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /CtfPlayback/Inputs/ICtfInputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | 7 | namespace CtfPlayback.Inputs 8 | { 9 | /// 10 | /// Data necessary to process an event stream. 11 | /// 12 | public interface ICtfInputStream 13 | : IDisposable 14 | { 15 | /// 16 | /// Identify the stream source. 17 | /// 18 | string StreamSource { get; } 19 | 20 | /// 21 | /// Stream from which to read. 22 | /// 23 | Stream Stream { get; } 24 | 25 | /// 26 | /// Size of the stream. 27 | /// This is necessary as not all streams support seeking, which is necessary for the Length property. 28 | /// 29 | ulong ByteCount { get; } 30 | } 31 | } -------------------------------------------------------------------------------- /CtfPlayback/Inputs/ICtfTraceInput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace CtfPlayback.Inputs 8 | { 9 | /// 10 | /// Data about a trace necessary to process the trace. 11 | /// 12 | public interface ICtfTraceInput 13 | : IDisposable 14 | { 15 | /// 16 | /// Trace metadata stream. 17 | /// 18 | ICtfInputStream MetadataStream { get; } 19 | 20 | /// 21 | /// Trace event streams. 22 | /// 23 | IList EventStreams { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/AntlrParser/DebugErrorListener.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using Antlr4.Runtime; 9 | using Antlr4.Runtime.Atn; 10 | using Antlr4.Runtime.Dfa; 11 | using Antlr4.Runtime.Sharpen; 12 | 13 | namespace CtfPlayback.Metadata.AntlrParser 14 | { 15 | /// 16 | /// This class may be assigned to the parser when debugging parsing issues to print out more information to the console. 17 | /// 18 | internal class DebugErrorListener 19 | : BaseErrorListener 20 | { 21 | public override void SyntaxError( 22 | TextWriter output, 23 | IRecognizer recognizer, 24 | IToken offendingSymbol, 25 | int line, 26 | int charPositionInLine, 27 | string msg, 28 | RecognitionException e) 29 | { 30 | IList reverseStack = ((Parser) recognizer).GetRuleInvocationStack(); 31 | var stack = reverseStack.Reverse().ToList(); 32 | Console.WriteLine($"rule stack: {stack}"); 33 | Console.WriteLine($"line {line}:{charPositionInLine} at {offendingSymbol}:{msg}"); 34 | } 35 | 36 | public override void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, 37 | ATNConfigSet configs) 38 | { 39 | base.ReportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs); 40 | } 41 | 42 | public override void ReportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, 43 | SimulatorState conflictState) 44 | { 45 | base.ReportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, conflictState); 46 | } 47 | 48 | public override void ReportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, 49 | SimulatorState acceptState) 50 | { 51 | base.ReportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, acceptState); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/AntlrParser/EnumeratorMapping.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.Helpers; 5 | 6 | namespace CtfPlayback.Metadata.AntlrParser 7 | { 8 | internal class EnumeratorMapping 9 | { 10 | internal string EnumIdentifier { get; set; } 11 | 12 | internal IntegerLiteral StartingValue { get; set; } 13 | 14 | internal IntegerLiteral EndingValue { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | if (this.EndingValue != null && this.EndingValue != this.StartingValue) 19 | { 20 | return $"EnumIdentifier = {this.StartingValue} ... {this.EndingValue}"; 21 | } 22 | 23 | return $"EnumIdentifier = {this.StartingValue}"; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/AntlrParser/Scopes/CtfCompoundTypeScope.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.Metadata.Interfaces; 6 | 7 | namespace CtfPlayback.Metadata.AntlrParser.Scopes 8 | { 9 | /// 10 | /// This is a scope used for constructs that have multiple child elements, such as structs and variants. 11 | /// 12 | internal class CtfCompoundTypeScope 13 | : CtfScope 14 | { 15 | internal CtfCompoundTypeScope(string name, CtfScope parent) 16 | :base(name, parent) 17 | { 18 | } 19 | 20 | internal List Fields { get; } = new List(); 21 | } 22 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/AntlrParser/TypeDeclaration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using CtfPlayback.Metadata.Types; 7 | 8 | namespace CtfPlayback.Metadata.AntlrParser 9 | { 10 | internal enum DeclarationMethod 11 | { 12 | Unspecified, 13 | TypeAlias, 14 | TypeDef, 15 | TypeAssignment, 16 | EnumDeclaration, 17 | StructDeclaration, 18 | VariantDeclaration 19 | } 20 | 21 | internal class TypeDeclaration 22 | { 23 | public CtfMetadataTypeDescriptor Type { get; set; } 24 | 25 | // This is not a simple string, because this type of syntax is valid 26 | // typealias integer { size=64; signed=false; } := unsigned long; 27 | // And now "unsigned long" are tied together. "long" has no meaning outside of "unsigned long". 28 | // 29 | public IEnumerable TypeName { get; set; } 30 | 31 | public override string ToString() 32 | { 33 | if (this.TypeName == null || !this.TypeName.Any()) 34 | { 35 | return "n/a"; 36 | } 37 | 38 | return string.Join(" ", this.TypeName); 39 | } 40 | 41 | // This is for analysis/debuggin only. 42 | internal DeclarationMethod DeclarationMethod { get; set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /CtfPlayback/Metadata/CtfMetadataException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Runtime.Serialization; 6 | 7 | namespace CtfPlayback.Metadata 8 | { 9 | /// 10 | /// Exception thrown because of problems with the CTF metadata. 11 | /// 12 | public class CtfMetadataException 13 | : Exception 14 | { 15 | public CtfMetadataException() 16 | { 17 | } 18 | 19 | public CtfMetadataException(string message) : base(message) 20 | { 21 | } 22 | 23 | public CtfMetadataException(string message, Exception innerException) : base(message, innerException) 24 | { 25 | } 26 | 27 | protected CtfMetadataException(SerializationInfo info, StreamingContext context) : base(info, context) 28 | { 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/CtfTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback.Metadata 5 | { 6 | /// 7 | /// Types defined in the CTF specification. 8 | /// 9 | public enum CtfTypes 10 | { 11 | /// 12 | /// An unknown CTF descriptor type 13 | /// 14 | Unknown, 15 | 16 | /// 17 | /// A string CTF descriptor type 18 | /// 19 | String, 20 | 21 | /// 22 | /// An integer CTF descriptor type 23 | /// 24 | Integer, 25 | 26 | /// 27 | /// A struct CTF descriptor type 28 | /// 29 | Struct, 30 | 31 | /// 32 | /// An array CTF descriptor type 33 | /// 34 | Array, 35 | 36 | /// 37 | /// An enum CTF descriptor type 38 | /// 39 | Enum, 40 | 41 | /// 42 | /// A variant CTF descriptor type 43 | /// 44 | Variant, 45 | 46 | /// 47 | /// A float CTF descriptor type 48 | /// 49 | FloatingPoint 50 | } 51 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/EncodingTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback.Metadata 5 | { 6 | /// 7 | /// Text encoding methods 8 | /// 9 | public enum EncodingTypes 10 | { 11 | /// 12 | /// The encoding type is not specified 13 | /// 14 | None, 15 | 16 | /// 17 | /// Uses UTF-8 encoding 18 | /// 19 | Utf8, 20 | 21 | /// 22 | /// Uses ASCII encoding 23 | /// 24 | Ascii, 25 | 26 | /// 27 | /// The encoding type was specified and is not valid 28 | /// 29 | Invalid 30 | } 31 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/ICtfMetadataCustomization.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.FieldValues; 5 | using CtfPlayback.Metadata.Interfaces; 6 | 7 | namespace CtfPlayback.Metadata 8 | { 9 | /// 10 | /// Extensibility points for dealing with trace metadata. 11 | /// 12 | public interface ICtfMetadataCustomization 13 | { 14 | /// 15 | /// The trace metadata. 16 | /// 17 | ICtfMetadata Metadata { get; } 18 | 19 | /// 20 | /// Retrieve a clock name from an integer type. 21 | /// It's not clear to me that the CTF specification mandates this clock reference format. 22 | /// There is an example in the specification: clock..value in the "map" field. 23 | /// where is the name of the clock 24 | /// e.g. "clock.monotonic.value" 25 | /// 26 | /// The integer class that should have a clock name 27 | /// The clock name 28 | string GetTimestampClockName(CtfIntegerValue timestampField); 29 | } 30 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfClockDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace CtfPlayback.Metadata.Interfaces 7 | { 8 | /// 9 | /// Describes a clock from the CTF metadata. 10 | /// 11 | public interface ICtfClockDescriptor 12 | { 13 | /// 14 | /// Mandatory clock identifier. 15 | /// 16 | string Name { get; } 17 | 18 | /// 19 | /// Description 20 | /// 21 | string Description { get; } 22 | 23 | /// 24 | /// Initial frequency of the clock in Hz. 25 | /// Default value is 1000000000 (1ns). 26 | /// 27 | ulong Frequency { get; } 28 | 29 | /// 30 | /// Describes uncertainty in the clock measurements. 31 | /// Unit is (1/freq) - nanoseconds in the default case. 32 | /// 33 | ulong Precision { get; } 34 | 35 | /// 36 | /// Offset from the POSIX.1 Epoch, 1970-01-01 00:00:00 +0000 (UTC). 37 | /// Unit: (1/freq) - nanoseconds in the default case. 38 | /// Defaults to zero. 39 | /// 40 | ulong Offset { get; } 41 | 42 | /// 43 | /// This is used to correlate different traces that use the same clock. 44 | /// 45 | Guid Uuid { get; } 46 | 47 | /// 48 | /// When true, the clock may be synchronized with any other clocks. 49 | /// When false, the clock may only be synchronized to clocks with the same UUID. 50 | /// 51 | bool Absolute { get; } 52 | } 53 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfEnvironmentDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace CtfPlayback.Metadata.Interfaces 7 | { 8 | /// 9 | /// Describes the environment from CTF metadata. 10 | /// 11 | public interface ICtfEnvironmentDescriptor 12 | { 13 | // The name/value pairs specified in the descriptor. 14 | IReadOnlyDictionary Properties { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfEventDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.TypeInterfaces; 5 | 6 | namespace CtfPlayback.Metadata.Interfaces 7 | { 8 | /// 9 | /// Represents a CTF event 10 | /// 11 | public interface ICtfEventDescriptor 12 | { 13 | /// 14 | /// The id of the event 15 | /// 16 | public uint Id { get; } 17 | 18 | /// 19 | /// Event context type 20 | /// 21 | ICtfTypeDescriptor Context { get; } 22 | 23 | /// 24 | /// Event payload type 25 | /// 26 | ICtfTypeDescriptor Payload { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfFieldDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.FieldValues; 5 | using CtfPlayback.Metadata.TypeInterfaces; 6 | 7 | namespace CtfPlayback.Metadata.Interfaces 8 | { 9 | /// 10 | /// Represents a field from CTF metadata 11 | /// 12 | public interface ICtfFieldDescriptor 13 | { 14 | /// 15 | /// The type of the field 16 | /// 17 | ICtfTypeDescriptor TypeDescriptor { get; } 18 | 19 | /// 20 | /// The name of the field 21 | /// 22 | string Name { get; } 23 | 24 | /// 25 | /// Reads the field from a packet of an event stream 26 | /// 27 | /// Packet reader 28 | /// Container of this field 29 | /// The field value 30 | CtfFieldValue Read(IPacketReader reader, CtfFieldValue parent = null); 31 | } 32 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfIntegerRange.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.Helpers; 5 | using CtfPlayback.Metadata.TypeInterfaces; 6 | 7 | namespace CtfPlayback.Metadata.Interfaces 8 | { 9 | /// 10 | /// Describes an integer range. 11 | /// 12 | public interface ICtfIntegerRange 13 | { 14 | /// 15 | /// The integer properties for the values in the range. 16 | /// 17 | ICtfIntegerDescriptor Base { get; } 18 | 19 | /// 20 | /// The starting value. 21 | /// 22 | IntegerLiteral Begin { get; } 23 | 24 | /// 25 | /// The ending value. 26 | /// 27 | IntegerLiteral End { get; } 28 | 29 | /// 30 | /// Determines if the range contains the given value. 31 | /// 32 | /// Value to check 33 | /// true if the range contains the value. 34 | bool ContainsValue(long value); 35 | 36 | /// 37 | /// Determines if the range contains the given value. 38 | /// 39 | /// Value to check 40 | /// true if the range contains the value. 41 | bool ContainsValue(ulong value); 42 | } 43 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfMetadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace CtfPlayback.Metadata.Interfaces 7 | { 8 | /// 9 | /// Represents the metadata from a CTF trace 10 | /// 11 | public interface ICtfMetadata 12 | { 13 | /// 14 | /// The trace descriptor 15 | /// 16 | ICtfTraceDescriptor TraceDescriptor { get; } 17 | 18 | /// 19 | /// The environment descriptor 20 | /// 21 | ICtfEnvironmentDescriptor EnvironmentDescriptor { get; } 22 | 23 | /// 24 | /// All of the clock descriptors 25 | /// 26 | IReadOnlyList Clocks { get; } 27 | 28 | /// 29 | /// Clock descriptors accessible by name 30 | /// 31 | IReadOnlyDictionary ClocksByName { get; } 32 | 33 | /// 34 | /// All of the stream descriptors 35 | /// 36 | IReadOnlyList Streams { get; } 37 | 38 | /// 39 | /// All of the event descriptors 40 | /// 41 | IReadOnlyList Events { get; } 42 | } 43 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfMetadataBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.Metadata.TypeInterfaces; 6 | 7 | namespace CtfPlayback.Metadata.Interfaces 8 | { 9 | public interface ICtfMetadataBuilder 10 | : ICtfMetadata 11 | { 12 | /// 13 | /// Sets the 'trace' scope ing the metadata file. 14 | /// 15 | /// The 'trace' descriptor 16 | /// true on success 17 | void SetTraceDescriptor(ICtfTraceDescriptor traceDescriptor); 18 | 19 | /// 20 | /// Sets the 'env' scope in the metadata file. 21 | /// 22 | /// The 'env' descriptor 23 | /// true on success 24 | void SetEnvironmentDescriptor(ICtfEnvironmentDescriptor environmentDescriptor); 25 | 26 | /// 27 | /// Add an event descriptor found in the metadata file. 28 | /// 29 | /// Type assignments 30 | /// Type declarations 31 | void AddEvent( 32 | IReadOnlyDictionary assignments, 33 | IReadOnlyDictionary typeDeclarations); 34 | 35 | /// 36 | /// Add a clock descriptor found in the metadata file. 37 | /// 38 | /// Clock descriptor 39 | void AddClock(ICtfClockDescriptor clockDescriptor); 40 | 41 | /// 42 | /// Add a stream descriptor found in the metadata file. 43 | /// 44 | /// Stream descriptor 45 | void AddStream(ICtfStreamDescriptor streamDescriptor); 46 | } 47 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfMetadataParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | 6 | namespace CtfPlayback.Metadata.Interfaces 7 | { 8 | /// 9 | /// Metadata parser interface 10 | /// 11 | public interface ICtfMetadataParser 12 | { 13 | /// 14 | /// Parses a CTF metadata file. 15 | /// 16 | /// Metadata stream 17 | /// The parsed metadata 18 | ICtfMetadata Parse(Stream metadataStream); 19 | } 20 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfNamedRange.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.Metadata.TypeInterfaces; 6 | 7 | namespace CtfPlayback.Metadata.Interfaces 8 | { 9 | /// 10 | /// A named range used in CTF enumerators. 11 | /// 12 | public interface ICtfNamedRange 13 | { 14 | /// 15 | /// Range name 16 | /// 17 | string Name { get; } 18 | 19 | /// 20 | /// The ranges associated with the name 21 | /// 22 | IReadOnlyList Ranges { get; } 23 | 24 | /// 25 | /// Determines if the named range contains the given value 26 | /// 27 | /// Value to search for 28 | /// true if the value is found 29 | bool ContainsValue(long value); 30 | 31 | /// 32 | /// Determines if the named range contains the given value 33 | /// 34 | /// Value to search for 35 | /// true if the value is found 36 | bool ContainsValue(ulong value); 37 | } 38 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfStreamDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.TypeInterfaces; 5 | 6 | namespace CtfPlayback.Metadata.Interfaces 7 | { 8 | /// 9 | /// A CTF stream descriptor 10 | /// 11 | public interface ICtfStreamDescriptor 12 | { 13 | /// 14 | /// Stream id is optional if there is only one stream in the trace. 15 | /// 16 | uint Id { get; } 17 | 18 | /// 19 | /// stream.packet.context 20 | /// The structure defined by this descriptor exists in the packet, before any event. 21 | /// 22 | ICtfStructDescriptor PacketContext { get; } 23 | 24 | /// 25 | /// stream.event.header 26 | /// The structure defined by this descriptor exists in an event within a packet. 27 | /// 28 | ICtfStructDescriptor EventHeader { get; } 29 | 30 | /// 31 | /// stream.event.context 32 | /// The structure defined by this descriptor exists in an event within a packet, after the EventHeader. 33 | /// 34 | ICtfStructDescriptor EventContext { get; } 35 | } 36 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Interfaces/ICtfTraceDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using CtfPlayback.Metadata.TypeInterfaces; 6 | 7 | namespace CtfPlayback.Metadata.Interfaces 8 | { 9 | /// 10 | /// CTF trace descriptor 11 | /// 12 | public interface ICtfTraceDescriptor 13 | { 14 | /// 15 | /// CTF major version 16 | /// 17 | short Major { get; } 18 | 19 | /// 20 | /// CTF minor version 21 | /// 22 | short Minor { get; } 23 | 24 | /// 25 | /// Trace Id 26 | /// 27 | Guid Uuid { get; } 28 | 29 | /// 30 | /// Default byte order 31 | /// 32 | string ByteOrder { get; } 33 | 34 | /// 35 | /// Packet header 36 | /// 37 | ICtfStructDescriptor PacketHeader { get; } 38 | } 39 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/NamedScopes/CtfEnvironmentDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.Interfaces; 5 | using CtfPlayback.Metadata.InternalHelpers; 6 | using System.Collections.Generic; 7 | 8 | namespace CtfPlayback.Metadata.NamedScopes 9 | { 10 | /// 11 | /// The environment the trace was taken in. 12 | /// The CTF specification doesn't specify values for this scope. It is up to the implementation. 13 | /// 14 | internal class CtfEnvironmentDescriptor 15 | : ICtfEnvironmentDescriptor 16 | { 17 | internal CtfEnvironmentDescriptor(CtfPropertyBag bag) 18 | { 19 | this.Properties = bag.Assignments; 20 | } 21 | 22 | /// 23 | public IReadOnlyDictionary Properties { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/NamedScopes/CtfFieldDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.FieldValues; 5 | using CtfPlayback.Helpers; 6 | using CtfPlayback.Metadata.Interfaces; 7 | using CtfPlayback.Metadata.TypeInterfaces; 8 | using CtfPlayback.Metadata.Types; 9 | using System.Diagnostics; 10 | 11 | namespace CtfPlayback.Metadata.NamedScopes 12 | { 13 | internal class CtfFieldDescriptor 14 | : ICtfFieldDescriptor 15 | { 16 | internal CtfFieldDescriptor(CtfMetadataTypeDescriptor type, string name) 17 | { 18 | Debug.Assert(type != null); 19 | Debug.Assert(!string.IsNullOrWhiteSpace(name)); 20 | 21 | this.TypeDescriptor = type; 22 | this.Name = name; 23 | } 24 | 25 | /// 26 | public ICtfTypeDescriptor TypeDescriptor { get; } 27 | 28 | /// 29 | public string Name { get; } 30 | 31 | /// 32 | public override string ToString() 33 | { 34 | return this.TypeDescriptor.ToString() + " " + this.Name; 35 | } 36 | 37 | /// 38 | public CtfFieldValue Read(IPacketReader reader, CtfFieldValue parent = null) 39 | { 40 | Guard.NotNull(reader, nameof(reader)); 41 | 42 | var fieldValue = this.TypeDescriptor.Read(reader, parent); 43 | fieldValue.FieldName = this.Name; 44 | return fieldValue; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfArrayDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback.Metadata.TypeInterfaces 5 | { 6 | /// 7 | /// Describes a CTF array 8 | /// 9 | public interface ICtfArrayDescriptor 10 | : ICtfTypeDescriptor 11 | { 12 | /// 13 | /// The array element type 14 | /// 15 | ICtfTypeDescriptor Type { get; } 16 | 17 | /// 18 | /// The string value of the index 19 | /// 20 | string Index { get; } 21 | } 22 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfEnumDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.Interfaces; 5 | using System.Collections.Generic; 6 | 7 | namespace CtfPlayback.Metadata.TypeInterfaces 8 | { 9 | /// 10 | /// Describe a CTF enum. A CTF enum consists of a set of values mapped to an integer value or range (or ranges). 11 | /// The exact integer properties are not defined by CTF, but are specified in the metadata. 12 | /// 13 | public interface ICtfEnumDescriptor 14 | : ICtfTypeDescriptor 15 | { 16 | /// 17 | /// The integer type of the mapped value or range. 18 | /// 19 | ICtfIntegerDescriptor BaseType { get; } 20 | 21 | /// 22 | /// The mapped values/ranges in the enum. 23 | /// 24 | IEnumerable EnumeratorValues { get; } 25 | 26 | /// 27 | /// Returns an enum value that is mapped to the given integer value. 28 | /// 29 | /// A mapped value 30 | /// The enum value represented by the given integer value 31 | string GetName(ulong value); 32 | 33 | /// 34 | /// Returns an enum value that is mapped to the given integer value. 35 | /// 36 | /// A mapped value 37 | /// The enum value represented by the given integer value 38 | string GetName(long value); 39 | 40 | /// 41 | /// Retrieve the named range for the given enum value. 42 | /// 43 | /// Enum value 44 | /// Named range 45 | ICtfNamedRange GetValue(string name); 46 | } 47 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfFloatingPointDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback.Metadata.TypeInterfaces 5 | { 6 | /// 7 | /// Describes the properties of a floating point type. 8 | /// 9 | public interface ICtfFloatingPointDescriptor 10 | : ICtfTypeDescriptor 11 | { 12 | /// 13 | /// Byte order layout 14 | /// 15 | string ByteOrder { get; } 16 | 17 | /// 18 | /// Exponent 19 | /// 20 | int Exponent { get; } 21 | 22 | /// 23 | /// Mantissa 24 | /// 25 | int Mantissa { get; } 26 | } 27 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfIntegerDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback.Metadata.TypeInterfaces 5 | { 6 | /// 7 | /// Describes the properties of an integer type. 8 | /// 9 | public interface ICtfIntegerDescriptor 10 | : ICtfTypeDescriptor 11 | { 12 | /// 13 | /// The number of bits in the integer. 14 | /// 15 | int Size { get; } 16 | 17 | /// 18 | /// Whether the integer if signed. 19 | /// 20 | bool Signed { get; } 21 | 22 | /// 23 | /// When represented as a string, this is how it is encoded: UTF8 or ASCII 24 | /// 25 | string Encoding { get; } 26 | 27 | /// 28 | /// The radix. Useful when printing the value. 29 | /// 30 | short Base { get; } 31 | 32 | /// 33 | /// For integers that represent a timestamp, this identifies the clock with which the timestamp is associated. 34 | /// 35 | string Map { get; } 36 | } 37 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfStringDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace CtfPlayback.Metadata.TypeInterfaces 5 | { 6 | /// 7 | /// Describes a string type 8 | /// 9 | public interface ICtfStringDescriptor 10 | { 11 | /// 12 | /// The encoding method used for the string. 13 | /// 14 | EncodingTypes Encoding { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfStructDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.Metadata.Interfaces; 6 | 7 | namespace CtfPlayback.Metadata.TypeInterfaces 8 | { 9 | /// 10 | /// Describes a CTF struct type 11 | /// 12 | public interface ICtfStructDescriptor 13 | : ICtfTypeDescriptor 14 | { 15 | /// 16 | /// Describes the fields in the struct. 17 | /// 18 | IReadOnlyList Fields { get; } 19 | 20 | /// 21 | /// Returns a field type descriptor given the field name. 22 | /// 23 | /// Field name 24 | /// Field type descriptor 25 | ICtfFieldDescriptor GetField(string name); 26 | } 27 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfTypeDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.FieldValues; 5 | 6 | namespace CtfPlayback.Metadata.TypeInterfaces 7 | { 8 | /// 9 | /// Describes a type in a CTF metadata file 10 | /// 11 | public interface ICtfTypeDescriptor 12 | { 13 | /// 14 | /// Type of the type 15 | /// 16 | CtfTypes CtfType { get; } 17 | 18 | /// 19 | /// Bit alignment for the type 20 | /// 21 | int Align { get; } 22 | 23 | /// 24 | /// Read an instance of the type from an event stream 25 | /// 26 | /// Source to read from 27 | /// Container of the instance of this type 28 | /// An instance of this type read from the source 29 | CtfFieldValue Read(IPacketReader reader, CtfFieldValue parent = null); 30 | } 31 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/TypeInterfaces/ICtfVariantDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.Metadata.Interfaces; 6 | 7 | namespace CtfPlayback.Metadata.TypeInterfaces 8 | { 9 | /// 10 | /// Describes a CTF variant type 11 | /// 12 | internal interface ICtfVariantDescriptor 13 | : ICtfTypeDescriptor 14 | { 15 | /// 16 | /// The name of the enum field used as a switch for this variant. 17 | /// 18 | string Switch { get; } 19 | 20 | /// 21 | /// Descriptions of the possible types in this variant. 22 | /// 23 | IReadOnlyList Union { get; } 24 | 25 | 26 | /// 27 | /// Returns a type descriptor given the name of the variant type. 28 | /// 29 | /// Variant name 30 | /// Field type descriptor 31 | ICtfFieldDescriptor GetVariant(string name); 32 | } 33 | } -------------------------------------------------------------------------------- /CtfPlayback/Metadata/Types/CtfMetadataTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.FieldValues; 5 | using CtfPlayback.Metadata.TypeInterfaces; 6 | 7 | namespace CtfPlayback.Metadata.Types 8 | { 9 | internal abstract class CtfMetadataTypeDescriptor 10 | : ICtfTypeDescriptor 11 | { 12 | protected CtfMetadataTypeDescriptor(CtfTypes type) 13 | { 14 | this.CtfType = type; 15 | } 16 | 17 | /// 18 | public abstract int Align { get; } 19 | 20 | /// 21 | public CtfTypes CtfType { get; protected set; } 22 | 23 | /// 24 | public abstract CtfFieldValue Read(IPacketReader reader, CtfFieldValue parent = null); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CtfPlayback/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Reflection; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("CtfPlayground")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("CtfPlayground")] 16 | [assembly: AssemblyCopyright("Copyright © 2019")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("17d2a31d-c6a6-43c5-af2a-9e4ffdaba4db")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | // You can specify all the values or you can default the Build and Revision Numbers 36 | // by using the '*' as shown below: 37 | // [assembly: AssemblyVersion("1.0.*")] 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] 40 | -------------------------------------------------------------------------------- /CtfPlayback/TestingAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("CtfUnitTest")] 7 | -------------------------------------------------------------------------------- /CtfPlayback/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /CtfUnitTest/CtfBaseTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using Antlr4.Runtime; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace CtfUnitTest 9 | { 10 | public class CtfBaseTest 11 | { 12 | protected TestErrorListener TestErrorListener { get; set; } 13 | 14 | protected static Stream StreamFromString(string value) 15 | { 16 | var memoryStream = new MemoryStream(); 17 | 18 | var writer = new StreamWriter(memoryStream); 19 | writer.Write(value); 20 | writer.Flush(); 21 | 22 | memoryStream.Position = 0; 23 | 24 | return memoryStream; 25 | } 26 | 27 | protected CtfParser GetParser(Stream inputStream) 28 | { 29 | var input = new AntlrInputStream(inputStream); 30 | var lexer = new CtfLexer(input); 31 | var tokens = new CommonTokenStream(lexer); 32 | var parser = new CtfParser(tokens); 33 | 34 | TestErrorListener = new TestErrorListener(); 35 | parser.RemoveErrorListeners(); 36 | parser.AddErrorListener(TestErrorListener); 37 | 38 | return parser; 39 | } 40 | 41 | protected CtfParser GetParser(string value) 42 | { 43 | using (var inputStream = StreamFromString(value)) 44 | { 45 | return GetParser(inputStream); 46 | } 47 | } 48 | 49 | protected void ValidateEmptyErrorListener() 50 | { 51 | Assert.AreEqual(TestErrorListener.AmbiguityErrors.Count, 0); 52 | Assert.AreEqual(TestErrorListener.SyntaxErrors.Count, 0); 53 | Assert.AreEqual(TestErrorListener.AttemptingFullContextMessages.Count, 0); 54 | Assert.AreEqual(TestErrorListener.ContextSensitivityMessages.Count, 0); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /CtfUnitTest/CtfUnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /CtfUnitTest/EnumeratorTestValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | 7 | namespace CtfUnitTest 8 | { 9 | public class EnumeratorTestValue 10 | { 11 | public string Name { get; set; } 12 | 13 | public long StartValue { get; set; } 14 | 15 | public bool StartValueIsSigned { get; set; } = true; 16 | 17 | public long EndValue { get; set; } 18 | 19 | public bool EndValueIsSigned { get; set; } = true; 20 | 21 | public bool Range { get; set; } 22 | 23 | public bool ValueSpecified { get; set; } = true; 24 | 25 | public bool AddComma { get; set; } 26 | 27 | public override string ToString() 28 | { 29 | Assert.IsFalse(Range && !ValueSpecified); 30 | 31 | var sb = new StringBuilder($"{this.Name}"); 32 | 33 | if (ValueSpecified) 34 | { 35 | sb.Append($"= {this.StartValue}{(StartValueIsSigned ? "" : "u")}"); 36 | } 37 | 38 | if (this.Range) 39 | { 40 | sb.Append($"...{this.EndValue}{(EndValueIsSigned ? "" : "u")}"); 41 | } 42 | 43 | if (this.AddComma) 44 | { 45 | sb.Append(", "); 46 | } 47 | 48 | return sb.ToString(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /CtfUnitTest/StructDeclarationTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace CtfUnitTest 7 | { 8 | [TestClass] 9 | public class StructDeclarationTests 10 | : CtfBaseTest 11 | { 12 | // todo: add tests for structure declarations 13 | 14 | //[TestMethod] 15 | //[TestCategory("UnitTest")] 16 | //public void StructTestOne() 17 | //{ 18 | // var metadataText = 19 | // "struct event_header_compact {" + 20 | // "enum : uint5_t { compact = 0... 30, extended = 31 } id;" ; 21 | //} 22 | } 23 | } -------------------------------------------------------------------------------- /CtfUnitTest/SyntaxErrorTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace CtfUnitTest 7 | { 8 | /// 9 | /// These tests parse metadata text with syntax errors, and are expected to report errors accordingly. 10 | /// 11 | [TestClass] 12 | public class SyntaxErrorTests 13 | : CtfBaseTest 14 | { 15 | [TestMethod] 16 | [TestCategory("UnitTest")] 17 | public void UnnamedTypeOutsideCompoundType() 18 | { 19 | var metadataText = 20 | "env {\n" + 21 | " integer { size=32; } someField;\n" + 22 | "};"; 23 | 24 | var parser = GetParser(metadataText); 25 | 26 | var metadataContext = parser.file(); 27 | 28 | Assert.IsTrue(this.TestErrorListener.SyntaxErrors.Count > 1); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /CtfUnitTest/TestCtfEventDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using CtfPlayback.Metadata.Helpers; 7 | using CtfPlayback.Metadata.Interfaces; 8 | using CtfPlayback.Metadata.TypeInterfaces; 9 | 10 | namespace CtfUnitTest 11 | { 12 | public class TestCtfEventDescriptor 13 | : ICtfEventDescriptor 14 | { 15 | public ICtfTypeDescriptor Context { get; set; } 16 | 17 | public ICtfTypeDescriptor Payload { get; set; } 18 | 19 | public IReadOnlyDictionary Assignments { get; set; } 20 | 21 | public IReadOnlyDictionary TypeDeclarations { get; set; } 22 | 23 | public uint? id; 24 | public uint Id 25 | { 26 | get 27 | { 28 | if (this.id.HasValue) 29 | { 30 | return this.id.Value; 31 | } 32 | 33 | if (!this.Assignments.TryGetValue("id", out var idString)) 34 | { 35 | throw new Exception("Id was not present in the event descriptor."); 36 | } 37 | 38 | var idIntegerLiteral = IntegerLiteral.CreateIntegerLiteral(idString); 39 | if (!idIntegerLiteral.TryGetUInt32(out var idValue)) 40 | { 41 | throw new Exception("Id was not a uint."); 42 | } 43 | 44 | this.id = idValue; 45 | 46 | return idValue; 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /DeveloperInfo.md: -------------------------------------------------------------------------------- 1 | # Microsoft Performance Tools Linux / Android - Developer Information 2 | 3 | # Prerequisites 4 | 5 | See [Readme Dev PreReqs](Readme.md#Dev%20prereqs) 6 | 7 | # Code Editing 8 | 9 | ## Entire Project 10 | If working on the entire project, or editing .sln or .csproj files 11 | [Visual Studio](https://visualstudio.microsoft.com/) is recommended 12 | 13 | Open [Microsoft-Perf-Tools-Linux-Android.sln](Microsoft-Perf-Tools-Linux-Android.sln) in VS 14 | 15 | ## Single Files 16 | Use your favorite editor 17 | 18 | ## Build & Test 19 | 20 | ### Cross Platform Cmd-Line 21 | - ```dotnet build``` 22 | - ```dotnet test``` 23 | 24 | ### IDE 25 | - VS Build Solution or Build Project 26 | 27 | # Debugging & Testing 28 | 29 | ## Dev inner loop 30 | It's often fastest to debug the Unit Test examples since they wrap the plugins. This method keeps runtime overhead to a minimum. See the various *UnitTest projects 31 | 32 | - VS Test Explorer is a great way to visualize / run / debug tests. Test -> Test Explorer 33 | 34 | ## Plugin visualization and trace testing 35 | - After getting some stabilization in a plugin, it's often fastest to test or investigate multiple traces using a GUI. 36 | 37 | - The plugins are not tied to any specific GUI. However the GUI does need to support the [Microsoft Performance Toolkit SDK](https://github.com/microsoft/microsoft-performance-toolkit-sdk) 38 | 39 | ### WPA GUI 40 | - Debugging using WPA 41 | - We have not figured out to debug attach using Store versions of WPA. Therefore, as a developer, you will need to use a non-Store version 42 | - For external devs outside Microsoft, use latest [Windows Insider Preview ADK](https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewADK) and install just WPA 43 | - For internal devs inside Microsoft, use the latest internal WPA 44 | - Using VS2022 Launch Profiles 45 | - To Start WPA with your plugin (doesn't auto-open file) 46 | - Executable 47 | - "C:\PATH\TO\wpa.exe" 48 | - Command line arguments - 49 | - -addsearchdir "C:\src\Microsoft-Performance-Tools-Linux-Android\ThePlugin\bin\Debug" 50 | - To Start WPA with your plugin AND auto-open file 51 | - Executable 52 | - "C:\PATH\TO\wpa.exe" 53 | - Command line arguments - 54 | - -addsearchdir "C:\src\Microsoft-Performance-Tools-Linux-Android\ThePlugin\bin\Debug" -i "C:\PATH\TO\tracefile.ext" -------------------------------------------------------------------------------- /Images/ADK_WPT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/Images/ADK_WPT.jpg -------------------------------------------------------------------------------- /Images/PerfettoCookerPipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/Images/PerfettoCookerPipeline.png -------------------------------------------------------------------------------- /Images/PerfettoPluginArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/Images/PerfettoPluginArchitecture.png -------------------------------------------------------------------------------- /Images/WpaLinux.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/Images/WpaLinux.JPG -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 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 | -------------------------------------------------------------------------------- /LTTngCds/CookerData/ICursor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngCds.CookerData 5 | { 6 | //todo:do we need/want this interface? LTTngContext might be enough 7 | public interface ICursor 8 | { 9 | /// 10 | /// Offset from the first earliest event in all traces 11 | /// 12 | long Timestamp { get; } 13 | 14 | /// 15 | /// CPU associated with the event 16 | /// 17 | uint CurrentCpu { get; } 18 | 19 | /// 20 | /// The event number, across all streams and traces 21 | /// 22 | ulong CurrentEventNumber { get; } 23 | 24 | /// 25 | /// The event number, within the current trace 26 | /// 27 | ulong CurrentEventNumberWithinTrace { get; } 28 | 29 | /// 30 | /// The stream in which this event exists 31 | /// 32 | string StreamSource { get; } 33 | } 34 | } -------------------------------------------------------------------------------- /LTTngCds/CookerData/LTTngConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | namespace LTTngCds.CookerData 4 | { 5 | public class LTTngConstants 6 | { 7 | /// 8 | /// Id of the LTTng source parser for use in data extensions. 9 | /// 10 | public const string SourceId = "LTTng"; 11 | } 12 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/DescriptorInterfaces/IEventDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CtfPlayback.Metadata.Interfaces; 5 | 6 | namespace LTTngCds.CtfExtensions.DescriptorInterfaces 7 | { 8 | /// 9 | /// LTTng specific event information combined with CTF event information 10 | /// 11 | public interface IEventDescriptor 12 | : ICtfEventDescriptor 13 | { 14 | /// 15 | /// Event Id 16 | /// 17 | uint Id { get; } 18 | 19 | /// 20 | /// Event name 21 | /// 22 | string Name { get; } 23 | 24 | /// 25 | /// Stream id associated with the event 26 | /// 27 | int Stream { get; } 28 | } 29 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/FolderInput/LTTngFileInputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using CtfPlayback.Inputs; 7 | 8 | namespace LTTngCds.CtfExtensions.FolderInput 9 | { 10 | internal sealed class LTTngFileInputStream 11 | : ICtfInputStream 12 | { 13 | public LTTngFileInputStream(string fileName) 14 | { 15 | if (!File.Exists(fileName)) 16 | { 17 | throw new ArgumentException($"File does not exist: {fileName}", nameof(fileName)); 18 | } 19 | 20 | this.StreamSource = fileName; 21 | 22 | this.Stream = File.OpenRead(fileName); 23 | 24 | this.ByteCount = (ulong)Stream.Length; 25 | } 26 | 27 | public string StreamSource { get; } 28 | 29 | public Stream Stream { get; } 30 | 31 | public ulong ByteCount { get; } 32 | 33 | public void Dispose() 34 | { 35 | this.Stream?.Dispose(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/FolderInput/LTTngFolderInput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.IO; 8 | using System.Linq; 9 | using CtfPlayback.Inputs; 10 | 11 | namespace LTTngCds.CtfExtensions.FolderInput 12 | { 13 | internal sealed class LTTngFolderInput 14 | : ICtfInput 15 | { 16 | private readonly List traces = new List(); 17 | 18 | public LTTngFolderInput(string folderPath) 19 | { 20 | if (!Directory.Exists(folderPath)) 21 | { 22 | throw new ArgumentException("Folder does not exist.", nameof(folderPath)); 23 | } 24 | 25 | var metadataFiles = Directory.GetFiles(folderPath, "metadata", SearchOption.AllDirectories); 26 | foreach (var metadataFile in metadataFiles) 27 | { 28 | // each CTF trace is associated with one metadata stream and one or more event streams. 29 | var traceInput = new LTTngFolderTraceInput 30 | { 31 | MetadataStream = new LTTngFileInputStream(metadataFile) 32 | }; 33 | 34 | string traceDirectoryPath = Path.GetDirectoryName(metadataFile); 35 | Debug.Assert(traceDirectoryPath != null, nameof(traceDirectoryPath) + " != null"); 36 | 37 | var associatedEntries = Directory.GetFiles(traceDirectoryPath).Where(entry => 38 | Path.GetFileName(entry).StartsWith("chan")); 39 | 40 | traceInput.EventStreams = associatedEntries.Select( 41 | fileName => new LTTngFileInputStream(fileName)).Cast().ToList(); 42 | 43 | this.traces.Add(traceInput); 44 | } 45 | } 46 | 47 | public IReadOnlyList Traces => this.traces; 48 | 49 | public void Dispose() 50 | { 51 | foreach (var traceInput in this.traces) 52 | { 53 | traceInput.Dispose(); 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/FolderInput/LTTngFolderTraceInput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.Inputs; 6 | 7 | namespace LTTngCds.CtfExtensions.FolderInput 8 | { 9 | internal sealed class LTTngFolderTraceInput 10 | : ICtfTraceInput 11 | { 12 | public ICtfInputStream MetadataStream { get; set; } 13 | 14 | public IList EventStreams { get; set; } 15 | 16 | public void Dispose() 17 | { 18 | this.MetadataStream?.Dispose(); 19 | 20 | if (EventStreams is null) 21 | { 22 | return; 23 | } 24 | 25 | foreach (var eventStream in this.EventStreams) 26 | { 27 | eventStream.Dispose(); 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/LTTngMetadataException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Runtime.Serialization; 6 | using CtfPlayback.Metadata; 7 | 8 | namespace LTTngCds.CtfExtensions 9 | { 10 | /// 11 | /// An LTTng exception related to trace metadata 12 | /// 13 | public class LTTngMetadataException 14 | : CtfMetadataException 15 | { 16 | public LTTngMetadataException() 17 | { 18 | } 19 | 20 | public LTTngMetadataException(string message) 21 | : base("LTTng: " + message) 22 | { 23 | } 24 | 25 | public LTTngMetadataException(string message, Exception innerException) 26 | : base("LTTng: " + message, innerException) 27 | { 28 | } 29 | 30 | protected LTTngMetadataException(SerializationInfo info, StreamingContext context) 31 | : base(info, context) 32 | { 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/LTTngPlaybackException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Runtime.Serialization; 6 | using CtfPlayback; 7 | 8 | namespace LTTngCds.CtfExtensions 9 | { 10 | /// 11 | /// An LTTng exception related to trace playback 12 | /// 13 | public class LTTngPlaybackException 14 | : CtfPlaybackException 15 | { 16 | public LTTngPlaybackException() 17 | { 18 | } 19 | 20 | public LTTngPlaybackException(string message) 21 | : base("LTTng: " + message) 22 | { 23 | } 24 | 25 | public LTTngPlaybackException(string message, Exception innerException) 26 | : base("LTTng: " + message, innerException) 27 | { 28 | } 29 | 30 | protected LTTngPlaybackException(SerializationInfo info, StreamingContext context) 31 | : base(info, context) 32 | { 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/ZipArchiveInput/LTTngZipArchiveInputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.IO.Compression; 6 | using CtfPlayback.Inputs; 7 | 8 | namespace LTTngCds.CtfExtensions.ZipArchiveInput 9 | { 10 | internal sealed class LTTngZipArchiveInputStream 11 | : ICtfInputStream 12 | { 13 | public LTTngZipArchiveInputStream(ZipArchiveEntry archiveEntry) 14 | { 15 | this.StreamSource = archiveEntry.FullName; 16 | 17 | this.Stream = archiveEntry.Open(); 18 | 19 | this.ByteCount = (ulong) archiveEntry.Length; 20 | } 21 | 22 | public string StreamSource { get; } 23 | 24 | public Stream Stream { get; } 25 | 26 | public ulong ByteCount { get; } 27 | 28 | public void Dispose() 29 | { 30 | this.Stream?.Dispose(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /LTTngCds/CtfExtensions/ZipArchiveInput/LTTngZipArchiveTraceInput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using CtfPlayback.Inputs; 7 | 8 | namespace LTTngCds.CtfExtensions.ZipArchiveInput 9 | { 10 | internal sealed class LTTngZipArchiveTraceInput 11 | : ICtfTraceInput 12 | { 13 | public ICtfInputStream MetadataStream { get; set; } 14 | 15 | public IList EventStreams { get; set; } 16 | 17 | public int NumberOfProc { get; private set; } 18 | 19 | internal void EstablishNumberOfProcessors() 20 | { 21 | this.NumberOfProc = (from stream in this.EventStreams 22 | let filename = stream.StreamSource.ToString() 23 | let i = filename.LastIndexOf('_') 24 | let processor = filename.Substring(i + 1) 25 | select int.Parse(processor) 26 | ).Max() + 1; 27 | } 28 | 29 | public void Dispose() 30 | { 31 | this.MetadataStream?.Dispose(); 32 | 33 | if (this.EventStreams is null) 34 | { 35 | return; 36 | } 37 | 38 | foreach (var eventStream in this.EventStreams) 39 | { 40 | eventStream.Dispose(); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /LTTngCds/LTTngCds.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.3.1 6 | true 7 | Microsoft 8 | Microsoft Corp. 9 | Performance ToolKit 10 | Contains the LTTng CTF datasource plugin. 11 | Microsoft.Performance.Toolkit.Plugins.LTTngPlugin 12 | © Microsoft Corporation. All rights reserved. 13 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | LICENSE.txt 16 | 17 | 18 | 19 | 20 | 21 | True 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LTTngCds/LTTngDataProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using LTTngCds.CookerData; 6 | using LTTngCds.MetadataTables; 7 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 8 | using Microsoft.Performance.SDK.Processing; 9 | 10 | namespace LTTngCds 11 | { 12 | internal sealed class LTTngDataProcessor 13 | : CustomDataProcessorWithSourceParser, 14 | IDisposable 15 | { 16 | public LTTngDataProcessor( 17 | ISourceParser sourceParser, 18 | ProcessorOptions options, 19 | IApplicationEnvironment applicationEnvironment, 20 | IProcessorEnvironment processorEnvironment) 21 | : base(sourceParser, options, applicationEnvironment, processorEnvironment) 22 | { 23 | } 24 | 25 | protected override void BuildTableCore( 26 | TableDescriptor tableDescriptor, 27 | ITableBuilder tableBuilder) 28 | { 29 | if (tableDescriptor.IsMetadataTable) 30 | { 31 | BuildMetadataTable(tableDescriptor, tableBuilder); 32 | } 33 | } 34 | 35 | private void BuildMetadataTable( 36 | TableDescriptor tableDescriptor, 37 | ITableBuilder tableBuilder) 38 | { 39 | if (tableDescriptor.Guid == TraceStatsTable.TableDescriptor.Guid) 40 | { 41 | TraceStatsTable.BuildMetadataTable( 42 | tableBuilder, 43 | this.SourceParser as LTTngSourceParser, 44 | this.ApplicationEnvironment.Serializer); 45 | } 46 | } 47 | 48 | public void Dispose() 49 | { 50 | var sourceParser = this.SourceParser as LTTngSourceParser; 51 | sourceParser?.Dispose(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /LTTngCds/TestingAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("CtfPrinter")] 7 | -------------------------------------------------------------------------------- /LTTngCds/TraceStatsData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngCds 5 | { 6 | /// 7 | /// This is a class, not a struct, because its values are updated throughout CTF playback. 8 | /// 9 | internal class TraceStatsData 10 | { 11 | /// 12 | /// The number of events of a given type in a given trace. 13 | /// 14 | public ulong EventCount; 15 | 16 | /// 17 | /// The total payload size, in bits, of the given event in the given trace. 18 | /// 19 | public ulong PayloadBitCount; 20 | } 21 | } -------------------------------------------------------------------------------- /LTTngCdsUnitTest/LTTngCdsUnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LTTngCdsUnitTest/LTTngEventWithContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using LTTngCds.CookerData; 5 | 6 | namespace LTTngCdsUnitTest 7 | { 8 | public class LTTngEventWithContext 9 | { 10 | public LTTngEventWithContext(LTTngEvent lTTngEvent, LTTngContext lTTngContext) 11 | { 12 | LTTngEvent = lTTngEvent; 13 | LTTngContext = lTTngContext; 14 | } 15 | 16 | public LTTngEvent LTTngEvent { get; private set; } 17 | public LTTngContext LTTngContext { get; private set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LTTngDataExtUnitTest/LTTngDataExtUnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IContextSwitch.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LTTngDataExtensions.SourceDataCookers.Cpu; 5 | using Microsoft.Performance.SDK; 6 | 7 | namespace LTTngDataExtensions.DataOutputTypes 8 | { 9 | public interface IContextSwitch 10 | { 11 | IContextSwitchOut SwitchOut { get; } 12 | 13 | IContextSwitchIn SwitchIn { get; } 14 | 15 | Timestamp Timestamp { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IDiskActivity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.DataOutputTypes 7 | { 8 | public interface IDiskActivity 9 | { 10 | Timestamp? InsertTime { get; } 11 | 12 | Timestamp? IssueTime { get; } 13 | 14 | Timestamp? CompleteTime { get; } 15 | 16 | uint DeviceId { get; } 17 | 18 | string DeviceName { get; } 19 | 20 | ulong SectorNumber { get; } 21 | 22 | DataSize? Size { get; } 23 | 24 | string Filepath { get; } 25 | 26 | int ThreadId { get; } 27 | 28 | string ProcessId { get; } 29 | 30 | string ProcessCommand { get; } 31 | 32 | int Error { get; } 33 | } 34 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IExecutionEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.SourceDataCookers.Thread 7 | { 8 | public interface IExecutionEvent 9 | { 10 | uint Cpu { get; } 11 | string NextPid { get; } 12 | int NextTid { get; } 13 | string PreviousPid { get; } 14 | int PreviousTid { get; } 15 | int Priority { get; } 16 | string ReadyingPid { get; } 17 | string ReadyingTid { get; } 18 | string PreviousState { get; } 19 | string NextImage { get; } 20 | string PreviousImage { get; } 21 | TimestampDelta ReadyTime { get; } 22 | TimestampDelta WaitTime { get; } 23 | Timestamp SwitchInTime { get; } 24 | Timestamp SwitchOutTime { get; } 25 | Timestamp NextThreadPreviousSwitchOutTime { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IFileEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.DataOutputTypes 7 | { 8 | public interface IFileEvent 9 | { 10 | string Name { get; } 11 | string ProcessId { get; } 12 | string ProcessCommand { get; } 13 | int ThreadId { get; } 14 | DataSize Size { get; } 15 | string Filepath { get; } 16 | Timestamp StartTime { get; } 17 | Timestamp EndTime { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IMessage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.SourceDataCookers.Diagnostic_Messages 7 | { 8 | public interface IDiagnosticMessage 9 | { 10 | string Message { get; } 11 | Timestamp Timestamp { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IModule.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.SourceDataCookers.Module 7 | { 8 | public interface IModuleEvent 9 | { 10 | string EventType { get; } 11 | string InstructionPointer { get; } 12 | string ThreadId { get; } 13 | string ProcessId { get; } 14 | string ProcessCommand { get; } 15 | int RefCount { get; } 16 | string ModuleName { get; } 17 | Timestamp Time { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IProcess.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace LTTngDataExtensions.SourceDataCookers.Process 5 | { 6 | public interface IProcess 7 | { 8 | ulong ForkTime { get; } 9 | ulong ExecTime { get; } 10 | ulong ExitTime { get; } 11 | ulong WaitTime { get; } 12 | ulong FreeTime { get; } 13 | int ProcessId { get; } 14 | int ParentProcessId { get; } 15 | string Name { get; } 16 | string Path { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/ISyscall.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.SourceDataCookers.Syscall 7 | { 8 | public interface ISyscall 9 | { 10 | string Name { get; } 11 | string ReturnValue { get; } 12 | string ThreadId { get; } 13 | string ProcessId { get; } 14 | string ProcessCommand { get; } 15 | string Arguments { get; } 16 | Timestamp StartTime { get; } 17 | Timestamp EndTime { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/ISyscallEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using CtfPlayback.FieldValues; 6 | using Microsoft.Performance.SDK; 7 | 8 | namespace LTTngDataExtensions.DataOutputTypes 9 | { 10 | public interface ISyscallEvent 11 | { 12 | string Name { get; } 13 | int Tid { get; } 14 | Timestamp Timestamp { get; } 15 | bool IsEntry { get; } 16 | IReadOnlyDictionary Fields { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /LTTngDataExtensions/DataOutputTypes/IThread.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace LTTngDataExtensions.SourceDataCookers.Thread 7 | { 8 | public interface IThread 9 | { 10 | int ThreadId { get; } 11 | string ProcessId { get; } 12 | string Command { get; } 13 | Timestamp StartTime { get; } 14 | Timestamp ExitTime { get; } 15 | TimestampDelta ExecTime { get; } 16 | TimestampDelta ReadyTime { get; } 17 | TimestampDelta SleepTime { get; } 18 | TimestampDelta DiskSleepTime { get; } 19 | TimestampDelta StoppedTime { get; } 20 | TimestampDelta ParkedTime { get; } 21 | TimestampDelta IdleTime { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LTTngDataExtensions/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "LTTngDataExtensions": { 4 | "commandName": "Executable", 5 | "executablePath": "C:\\Tools\\WPT\\latest\\wpa.exe", 6 | "commandLineArgs": "-addsearchdir C:\\src\\Microsoft-Performance-Tools-Linux\\LTTngDataExtensions\\bin\\Debug\\netstandard2.1" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Cpu/ContextSwitch.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LTTngDataExtensions.DataOutputTypes; 5 | using Microsoft.Performance.SDK; 6 | 7 | namespace LTTngDataExtensions.SourceDataCookers.Cpu 8 | { 9 | public struct ContextSwitch 10 | : IContextSwitch, 11 | IContextSwitchIn, 12 | IContextSwitchOut 13 | { 14 | readonly Timestamp timestamp; 15 | readonly string switchInImageName; 16 | readonly int switchInThreadId; 17 | readonly int switchInThreadPriority; 18 | readonly string switchOutImageName; 19 | readonly int switchOutThreadId; 20 | readonly int switchOutThreadPriority; 21 | 22 | public ContextSwitch(Timestamp timestamp, string switchInImageName, int switchInThreadId, 23 | int switchInThreadPriority, string switchOutImageName, int switchOutThreadId, 24 | int switchOutThreadPriority) 25 | { 26 | this.timestamp = timestamp; 27 | this.switchInImageName = switchInImageName; 28 | this.switchInThreadId = switchInThreadId; 29 | this.switchInThreadPriority = switchInThreadPriority; 30 | this.switchOutImageName = switchOutImageName; 31 | this.switchOutThreadId = switchOutThreadId; 32 | this.switchOutThreadPriority = switchOutThreadPriority; 33 | } 34 | 35 | public Timestamp Timestamp => timestamp; 36 | 37 | public IContextSwitchIn SwitchIn => this; 38 | 39 | public IContextSwitchOut SwitchOut => this; 40 | 41 | string IContextSwitchIn.ImageName => switchInImageName; 42 | 43 | int IContextSwitchIn.ThreadId => switchInThreadId; 44 | 45 | int IContextSwitchIn.Priority => switchInThreadPriority; 46 | 47 | string IContextSwitchOut.ImageName => switchOutImageName; 48 | 49 | int IContextSwitchOut.ThreadId => switchOutThreadId; 50 | 51 | int IContextSwitchOut.Priority => switchOutThreadPriority; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Cpu/IContextSwitchIn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngDataExtensions.SourceDataCookers.Cpu 5 | { 6 | public interface IContextSwitchIn 7 | { 8 | string ImageName { get; } 9 | 10 | int ThreadId { get; } 11 | 12 | int Priority { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Cpu/IContextSwitchOut.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngDataExtensions.SourceDataCookers.Cpu 5 | { 6 | public interface IContextSwitchOut 7 | { 8 | string ImageName { get; } 9 | 10 | int ThreadId { get; } 11 | 12 | int Priority { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Diagnostic Messages/Message.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using LTTngDataExtensions.DataOutputTypes; 5 | using Microsoft.Performance.SDK; 6 | 7 | namespace LTTngDataExtensions.SourceDataCookers.Diagnostic_Messages 8 | { 9 | public class DiagnosticMessage 10 | : IDiagnosticMessage 11 | { 12 | readonly string message; 13 | readonly Timestamp timestamp; 14 | 15 | public DiagnosticMessage(string message, Timestamp timestamp) 16 | { 17 | this.message = message; 18 | this.timestamp = timestamp; 19 | } 20 | 21 | public string Message => this.message; 22 | public Timestamp Timestamp => this.timestamp; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Disk/DiskActivity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using LTTngDataExtensions.DataOutputTypes; 5 | using Microsoft.Performance.SDK; 6 | using System; 7 | 8 | namespace LTTngDataExtensions.SourceDataCookers.Disk 9 | { 10 | public class DiskActivity 11 | : IDiskActivity 12 | { 13 | 14 | private Timestamp? insertTime; 15 | private Timestamp? issueTime; 16 | private Timestamp? completeTime; 17 | private string deviceName; 18 | private uint deviceId; 19 | private ulong sectorNumber; 20 | private DataSize? size; 21 | private string filepath; 22 | private int error; 23 | private int threadId; 24 | private string processId; 25 | private string processCommand; 26 | 27 | 28 | public DiskActivity(DiskActivityBuilder builder) 29 | { 30 | this.insertTime = builder.InsertTime; 31 | this.issueTime = builder.IssueTime; 32 | this.completeTime = builder.CompleteTime; 33 | this.deviceId = builder.DeviceId; 34 | this.deviceName = builder.DeviceName; 35 | this.sectorNumber = builder.SectorNumber; 36 | this.size = builder.Size; 37 | this.filepath = builder.Filepath; 38 | this.threadId = builder.ThreadId; 39 | this.processId = builder.ProcessId; 40 | this.processCommand = builder.ProcessCommand; 41 | this.error = builder.Error; 42 | } 43 | 44 | public Timestamp? InsertTime => this.insertTime; 45 | 46 | public Timestamp? IssueTime => this.issueTime; 47 | 48 | public Timestamp? CompleteTime => this.completeTime; 49 | 50 | public string DeviceName=> this.deviceName; 51 | 52 | public uint DeviceId => this.deviceId; 53 | 54 | public ulong SectorNumber => this.sectorNumber; 55 | 56 | public DataSize? Size => this.size; 57 | 58 | public string Filepath => this.filepath; 59 | 60 | public int ThreadId => this.threadId; 61 | 62 | public string ProcessId => this.processId; 63 | 64 | public string ProcessCommand => this.processCommand; 65 | 66 | public int Error => this.error; 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Disk/DiskActivityBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using LTTngDataExtensions.DataOutputTypes; 5 | using LTTngDataExtensions.SourceDataCookers.Thread; 6 | using Microsoft.Performance.SDK; 7 | using System; 8 | 9 | namespace LTTngDataExtensions.SourceDataCookers.Disk 10 | { 11 | public class DiskActivityBuilder 12 | { 13 | public DiskActivityBuilder(uint deviceId, ulong sectorNumber, string filepath, int tid) 14 | { 15 | this.DeviceId = deviceId; 16 | this.SectorNumber = sectorNumber; 17 | this.Filepath = filepath; 18 | this.ThreadId = tid; 19 | this.Error = 0; 20 | this.DeviceName = String.Empty; 21 | } 22 | 23 | public Timestamp? InsertTime { get; set; } 24 | 25 | public Timestamp? IssueTime { get; set; } 26 | 27 | public Timestamp? CompleteTime { get; set; } 28 | 29 | public uint DeviceId { get; set; } 30 | 31 | public string DeviceName { get; set; } 32 | 33 | public ulong SectorNumber { get; set; } 34 | 35 | public DataSize? Size { get; set; } 36 | 37 | public string Filepath { get; set; } 38 | 39 | public int ThreadId { get; set; } 40 | 41 | public String ProcessId { get; set; } 42 | 43 | public String ProcessCommand { get; set; } 44 | 45 | public int Error { get; set; } 46 | 47 | public DiskActivity Build() 48 | { 49 | return new DiskActivity(this); 50 | } 51 | public void SetThreadInfo(ThreadBasicInfo info) 52 | { 53 | this.ProcessId = info.Pid; 54 | this.ProcessCommand = info.Command; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Disk/FileEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using LTTngDataExtensions.DataOutputTypes; 5 | using LTTngDataExtensions.SourceDataCookers.Thread; 6 | using Microsoft.Performance.SDK; 7 | 8 | namespace LTTngDataExtensions.SourceDataCookers.Disk 9 | { 10 | public class FileEvent 11 | : IFileEvent 12 | { 13 | readonly string name; 14 | readonly string filepath; 15 | readonly Timestamp startTime; 16 | readonly Timestamp endTime; 17 | private string processId; 18 | private string processCommand; 19 | readonly int threadId; 20 | readonly DataSize size; 21 | 22 | public FileEvent(string name, int threadId, string filepath, long sizeInBytes, Timestamp startTime, Timestamp endTime) 23 | { 24 | this.name = name; 25 | this.threadId = threadId; 26 | this.filepath = filepath; 27 | this.size = new DataSize(sizeInBytes); 28 | this.startTime = startTime; 29 | this.endTime = endTime; 30 | } 31 | 32 | public void SetThreadInfo(ThreadBasicInfo info) 33 | { 34 | this.processId = info.Pid; 35 | this.processCommand = info.Command; 36 | } 37 | 38 | public string Name => this.name; 39 | public string ProcessId => this.processId; 40 | public string ProcessCommand => this.processCommand; 41 | public int ThreadId => this.threadId; 42 | public DataSize Size => this.size; 43 | public string Filepath => this.filepath; 44 | public Timestamp StartTime => this.startTime; 45 | public Timestamp EndTime => this.endTime; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Process/IBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngDataExtensions.SourceDataCookers.Process 5 | { 6 | public interface IBuilder 7 | { 8 | T Build(); 9 | } 10 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Process/Process.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngDataExtensions.SourceDataCookers.Process 5 | { 6 | public class Process 7 | : IProcess 8 | { 9 | readonly ulong forkTime; 10 | readonly ulong execTime; 11 | readonly ulong exitTime; 12 | readonly ulong waitTime; 13 | readonly ulong freeTime; 14 | readonly int processId; 15 | readonly int parentProcessId; 16 | readonly string name; 17 | readonly string path; 18 | 19 | public Process(ulong forkTime, ulong execTime, ulong exitTime, ulong waitTime, ulong freeTime, int processId, 20 | int parentProcessId, string name, string path) 21 | { 22 | this.forkTime = forkTime; 23 | this.execTime = execTime; 24 | this.exitTime = exitTime; 25 | this.waitTime = waitTime; 26 | this.freeTime = freeTime; 27 | this.processId = processId; 28 | this.parentProcessId = parentProcessId; 29 | this.name = name; 30 | this.path = path; 31 | } 32 | 33 | public ulong ForkTime => this.forkTime; 34 | 35 | public ulong ExecTime => this.execTime; 36 | 37 | public ulong ExitTime => this.exitTime; 38 | 39 | public ulong WaitTime => this.waitTime; 40 | 41 | public ulong FreeTime => this.freeTime; 42 | 43 | public int ProcessId => this.processId; 44 | 45 | public int ParentProcessId => this.parentProcessId; 46 | 47 | public string Name => this.name; 48 | 49 | public string Path => this.path; 50 | } 51 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Process/ProcessBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LTTngDataExtensions.SourceDataCookers.Process 5 | { 6 | internal class ProcessBuilder : IBuilder 7 | { 8 | public ulong ForkTime { get; set; } 9 | 10 | public ulong ExecTime { get; set; } 11 | 12 | public ulong ExitTime { get; set; } 13 | 14 | public ulong WaitTime { get; set; } 15 | 16 | public ulong FreeTime { get; set; } 17 | 18 | public int ProcessId { get; set; } 19 | 20 | public int ParentProcessId { get; set; } 21 | 22 | public string Name { get; set; } 23 | 24 | public string Path { get; set; } 25 | 26 | public IProcess Build() 27 | { 28 | return new Process(this.ForkTime, this.ExecTime, this.ExitTime, this.WaitTime, this.FreeTime, this.ProcessId, this.ParentProcessId, this.Name, 29 | this.Path); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Thread/DiscardedEventsTracker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using LTTngCds.CookerData; 6 | 7 | namespace LTTngDataExtensions.SourceDataCookers.Thread 8 | { 9 | class DiscardedEventsTracker 10 | { 11 | private List discardedEventsPerCpu = new List(); 12 | 13 | public uint EventsDiscardedBetweenLastTwoEvents(LTTngEvent data, LTTngContext context) 14 | { 15 | while (this.discardedEventsPerCpu.Count <= context.CurrentCpu) 16 | { 17 | this.discardedEventsPerCpu.Add(0); 18 | } 19 | uint previousDiscardedEvents = this.discardedEventsPerCpu[(int)context.CurrentCpu]; 20 | if (previousDiscardedEvents < data.DiscardedEvents) 21 | { 22 | discardedEventsPerCpu[(int)context.CurrentCpu] = data.DiscardedEvents; 23 | return data.DiscardedEvents - previousDiscardedEvents; 24 | } 25 | return 0; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LTTngDataExtensions/SourceDataCookers/Thread/ExecutingThreadTracker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using LTTngCds.CookerData; 6 | 7 | namespace LTTngDataExtensions.SourceDataCookers.Thread 8 | { 9 | public class ExecutingThreadTracker 10 | { 11 | static readonly string ContextSwitchEventName = "sched_switch"; 12 | private List executingThreadPerCpu = new List(); 13 | public static readonly HashSet UsedDataKeys = new HashSet() { ContextSwitchEventName }; 14 | 15 | public void ProcessEvent(LTTngEvent data, LTTngContext context) 16 | { 17 | if (ContextSwitchEventName.Equals(data.Name)) 18 | { 19 | while (this.executingThreadPerCpu.Count <= context.CurrentCpu) 20 | { 21 | this.executingThreadPerCpu.Add(-1); 22 | } 23 | this.executingThreadPerCpu[(int)context.CurrentCpu] = data.Payload.ReadFieldAsInt32("_next_tid"); 24 | } 25 | } 26 | public void ReportEventsDiscarded(uint cpu) 27 | { 28 | if (executingThreadPerCpu.Count > cpu) 29 | { 30 | executingThreadPerCpu[(int)cpu] = -1; 31 | } 32 | } 33 | 34 | public string CurrentTidAsString(uint cpu) 35 | { 36 | int executingTid = this.CurrentTidAsInt(cpu); 37 | if (executingTid >= 0) 38 | { 39 | return executingTid.ToString(); 40 | } 41 | return ""; 42 | } 43 | 44 | public int CurrentTidAsInt(uint cpu) 45 | { 46 | if (this.executingThreadPerCpu.Count > cpu) 47 | { 48 | return this.executingThreadPerCpu[(int)cpu]; 49 | } 50 | return -1; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LTTngDataExtensions/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.LTTngDataExtensions", 5 | "version": "1.3.1" 6 | }, 7 | "displayName": "Linux - LTTng", 8 | "description": "Enables processing LTTng performance trace files that contain key Linux performance indicators, such as kernel CPU scheduling, system calls, file events, and userspace applications", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /LTTngDriver/LTTngDriver.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | false 7 | 1.2.1 8 | true 9 | Microsoft 10 | Microsoft Corp. 11 | Performance ToolKit 12 | Contains the LTTNG Driver tool. 13 | Microsoft.Performance.Toolkit.Plugins.LTTngDriver 14 | © Microsoft Corporation. All rights reserved. 15 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 16 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 17 | LICENSE.txt 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | True 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /LTTngDriver/Program.Main.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace LTTngDriver 7 | { 8 | public sealed partial class Program 9 | { 10 | public static int Main(string[] args) 11 | { 12 | try 13 | { 14 | var p = new Program(args); 15 | return p.Run() 16 | ? 0 17 | : -1; 18 | } 19 | catch (Exception e) 20 | { 21 | Console.Error.WriteLine(e); 22 | return e.HResult; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LTTngDriver/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "LTTngDriver": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-e C:\\src\\Microsoft-Performance-Tools-Linux\\LTTngDataExtensions\\bin\\Debug\\netstandard2.1 C:\\src\\Microsoft-Performance-Tools-Linux\\TestData\\LTTng\\lttng-kernel-trace.ctf" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /LTTngDriver/run_driver.cmd: -------------------------------------------------------------------------------- 1 | :: Copyright (c) Microsoft Corporation. 2 | :: Licensed under the MIT License. 3 | 4 | @ECHO OFF 5 | SETLOCAL ENABLEDELAYEDEXPANSION 6 | 7 | IF "%~1" == "-?" ( 8 | CALL :_SHOW_HELP 9 | EXIT /B 0 10 | ) 11 | 12 | IF "%~1" == "-h" ( 13 | CALL :_SHOW_HELP 14 | EXIT /B 0 15 | ) 16 | 17 | IF "%~1" == "-help" ( 18 | CALL :_SHOW_HELP 19 | EXIT /B 0 20 | ) 21 | 22 | SET CONFIG=%~1 23 | 24 | REM Grab the second argument to the last argument to pass along to the driver 25 | SET PARAMETERS=%* 26 | CALL SET PARAMETERS=%%PARAMETERS:*%1=%% 27 | 28 | IF NOT EXIST bin\%CONFIG%\netcoreapp2.2 ( 29 | MKDIR bin\%CONFIG%\netcoreapp2.2 30 | ) 31 | 32 | PUSHD bin\%CONFIG%\netcoreapp2.2 33 | 34 | @ECHO ON 35 | 36 | dotnet run ^ 37 | --project ..\..\.. ^ 38 | -c %CONFIG% ^ 39 | -- ^ 40 | %PARAMETERS% 41 | 42 | @ECHO OFF 43 | 44 | POPD 45 | EXIT /B 0 46 | 47 | :_SHOW_HELP 48 | ECHO usage: run_driver ^ ^ 49 | ECHO use 'run_driver ^ -?' for driver help 50 | ECHO. 51 | GOTO :EOF 52 | -------------------------------------------------------------------------------- /Launcher/Windows/LaunchWpaPerfToolsLinuxAndroid.bat: -------------------------------------------------------------------------------- 1 | :: Copyright (c) Microsoft Corporation. 2 | :: Licensed under the MIT License. 3 | 4 | @ECHO OFF 5 | 6 | IF "%~1" == "" ( 7 | %windir%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0\LaunchWpaPerfToolsLinuxAndroid.ps1" 8 | ) ELSE ( 9 | IF "%~2" == "" ( 10 | %windir%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0\LaunchWpaPerfToolsLinuxAndroid.ps1" -InputFile "%~1" 11 | ) ELSE ( 12 | %windir%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0\LaunchWpaPerfToolsLinuxAndroid.ps1" -InputFile "%~1" -WpaProfile "%~2" 13 | ) 14 | ) -------------------------------------------------------------------------------- /Launcher/Windows/MicrosoftPerfToolsLinuxAndroid.url: -------------------------------------------------------------------------------- 1 | [{000214A0-0000-0000-C000-000000000046}] 2 | Prop3=19,11 3 | [InternetShortcut] 4 | IDList= 5 | URL=https://aka.ms/linuxperftools 6 | HotKey=0 7 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParser/CloudInitLog/CloudInitLogParsedEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK; 5 | using Microsoft.Performance.SDK.Extensibility; 6 | 7 | namespace LinuxLogParser.CloudInitLog 8 | { 9 | public enum LogParsedDataKey 10 | { 11 | GeneralLog 12 | } 13 | 14 | public class CloudInitLogParsedEntry : IKeyedDataType 15 | { 16 | private readonly LogParsedDataKey key; 17 | 18 | public CloudInitLogParsedEntry(LogParsedDataKey key) 19 | { 20 | this.key = key; 21 | } 22 | 23 | public int CompareTo(LogParsedDataKey other) 24 | { 25 | return key.CompareTo(other); 26 | } 27 | 28 | public LogParsedDataKey GetKey() 29 | { 30 | return key; 31 | } 32 | } 33 | 34 | public class LogEntry: CloudInitLogParsedEntry 35 | { 36 | public string FilePath { get; private set; } 37 | public ulong LineNumber { get; private set; } 38 | public Timestamp EventTimestamp { get; private set; } 39 | 40 | public string PythonFile { get; private set; } 41 | 42 | public string LogLevel { get; private set; } 43 | public string Log { get; private set; } 44 | 45 | public LogEntry(string filePath, ulong lineNumber, Timestamp eventTimestamp, string pythonFile, 46 | string logLevel, string log): 47 | base(LogParsedDataKey.GeneralLog) 48 | { 49 | FilePath = filePath; 50 | LineNumber = lineNumber; 51 | EventTimestamp = eventTimestamp; 52 | PythonFile = pythonFile; 53 | LogLevel = logLevel; 54 | Log = log; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParser/DmesgIsoLog/DmesgIsoLogParsedEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK; 5 | using Microsoft.Performance.SDK.Extensibility; 6 | 7 | namespace LinuxLogParser.DmesgIsoLog 8 | { 9 | public enum LogParsedDataKey 10 | { 11 | GeneralLog 12 | } 13 | 14 | public class DmesgIsoLogParsedEntry : IKeyedDataType 15 | { 16 | private readonly LogParsedDataKey key; 17 | 18 | public DmesgIsoLogParsedEntry(LogParsedDataKey key) 19 | { 20 | this.key = key; 21 | } 22 | 23 | public int CompareTo(LogParsedDataKey other) 24 | { 25 | return key.CompareTo(other); 26 | } 27 | 28 | public LogParsedDataKey GetKey() 29 | { 30 | return key; 31 | } 32 | } 33 | 34 | public class LogEntry: DmesgIsoLogParsedEntry 35 | { 36 | public Timestamp timestamp; 37 | public string filePath; 38 | public ulong lineNumber; 39 | public string entity; 40 | public string topic; 41 | public string message; 42 | public string metadata; 43 | public string rawLog; 44 | 45 | public LogEntry(): base(LogParsedDataKey.GeneralLog) 46 | { 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParser/LinuxLogParser.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.2.1 6 | true 7 | Microsoft 8 | Microsoft Corp. 9 | Performance ToolKit 10 | Contains the Linux log parsing library. 11 | Microsoft.Performance.Toolkit.Plugins.LinuxLogParser 12 | © Microsoft Corporation. All rights reserved. 13 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | LICENSE.txt 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | True 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParser/SourceParserIds.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LinuxLogParser 5 | { 6 | public static class SourceParserIds 7 | { 8 | public const string CloudInitLog = "CloudInitLog"; 9 | public const string WaLinuxAgentLog = "WaLinuxAgentLog"; 10 | public const string DmesgIsoLog = "DmesgIsoLog"; 11 | public const string AndroidLogcatLog = "AndroidLogcatLog"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParser/WaLinuxAgentLog/WaLinuxAgentLogParsedEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK; 5 | using Microsoft.Performance.SDK.Extensibility; 6 | 7 | namespace LinuxLogParser.WaLinuxAgentLog 8 | { 9 | public enum LogParsedDataKey 10 | { 11 | GeneralLog 12 | } 13 | 14 | public class WaLinuxAgentLogParsedEntry : IKeyedDataType 15 | { 16 | private readonly LogParsedDataKey key; 17 | 18 | public WaLinuxAgentLogParsedEntry(LogParsedDataKey key) 19 | { 20 | this.key = key; 21 | } 22 | 23 | public int CompareTo(LogParsedDataKey other) 24 | { 25 | return key.CompareTo(other); 26 | } 27 | 28 | public LogParsedDataKey GetKey() 29 | { 30 | return key; 31 | } 32 | } 33 | 34 | public class LogEntry: WaLinuxAgentLogParsedEntry 35 | { 36 | public string FilePath { get; private set; } 37 | public ulong LineNumber { get; private set; } 38 | public Timestamp EventTimestamp { get; private set; } 39 | 40 | public string LogLevel { get; private set; } 41 | public string Log { get; set; } 42 | 43 | public LogEntry(string filePath, ulong lineNumber, Timestamp eventTimestamp, string logLevel, string log): 44 | base(LogParsedDataKey.GeneralLog) 45 | { 46 | FilePath = filePath; 47 | LineNumber = lineNumber; 48 | EventTimestamp = eventTimestamp; 49 | LogLevel = logLevel; 50 | Log = log; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParserCore/FileMetadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace LinuxLogParserCore 5 | { 6 | public class FileMetadata 7 | { 8 | public ulong LineCount { get; private set; } 9 | 10 | public FileMetadata(ulong lineCount) 11 | { 12 | LineCount = lineCount; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParserCore/LinuxLogParserCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.2.1 6 | true 7 | Microsoft 8 | Microsoft Corp. 9 | Performance ToolKit 10 | Contains the Linux log parsing core library. 11 | Microsoft.Performance.Toolkit.Plugins.LinuxLogParserCore 12 | © Microsoft Corporation. All rights reserved. 13 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | LICENSE.txt 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | True 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParserCore/LogContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace LinuxLogParserCore 7 | { 8 | public class LogContext 9 | { 10 | public Dictionary FileToMetadata { get; } = new Dictionary(); 11 | 12 | public void UpdateFileMetadata(string filePath, FileMetadata metadata) 13 | { 14 | FileToMetadata[filePath] = metadata; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParserCore/LogParserBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK.Extensibility; 5 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 6 | 7 | namespace LinuxLogParserCore 8 | { 9 | public abstract class LogParserBase : SourceParser 10 | where TLogEntry : IKeyedDataType 11 | { 12 | public LogParserBase(string[] filePaths) 13 | { 14 | FilePaths = filePaths; 15 | } 16 | 17 | protected LogContext Context { get; private set; } = new LogContext(); 18 | 19 | protected string[] FilePaths { get; private set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxLogParsersUnitTest/LinuxLogParsersUnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/AndroidLogCat/AndroidLogcat.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.3.4 6 | true 7 | Android Logcat 8 | Microsoft 9 | Microsoft Corp. 10 | Performance ToolKit 11 | Contains the datasource plugin to parse Android Logcat log files. 12 | Microsoft.Performance.Toolkit.Plugins.AndroidLogcatPlugin 13 | © Microsoft Corporation. All rights reserved. 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 16 | LICENSE.txt 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | True 30 | 31 | 32 | 33 | 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/AndroidLogCat/AndroidLogcatCustomDataProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.AndroidLogcat; 5 | using LinuxLogParserCore; 6 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 7 | using Microsoft.Performance.SDK.Processing; 8 | 9 | namespace AndroidLogcatMPTAddin 10 | { 11 | public sealed class AndroidLogcatCustomDataProcessor 12 | : CustomDataProcessorWithSourceParser 13 | { 14 | public AndroidLogcatCustomDataProcessor( 15 | ISourceParser sourceParser, 16 | ProcessorOptions options, 17 | IApplicationEnvironment applicationEnvironment, 18 | IProcessorEnvironment processorEnvironment) 19 | : base(sourceParser, options, applicationEnvironment, processorEnvironment) 20 | { 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/AndroidLogCat/AndroidLogcatDataSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using LinuxLogParser.AndroidLogcat; 8 | using Microsoft.Performance.SDK.Processing; 9 | 10 | namespace AndroidLogcatMPTAddin 11 | { 12 | [ProcessingSource( 13 | "{DC6FAB5D-D839-4745-8F6C-5BF6941E0DB4}", 14 | "Android Logcat (Txt)", 15 | "A data source to parse logcat events in a text file")] 16 | [FileDataSource( 17 | "log", 18 | "Log files")] 19 | public class AndroidLogcatDataSource : ProcessingSource 20 | { 21 | private IApplicationEnvironment applicationEnvironment; 22 | 23 | protected override ICustomDataProcessor CreateProcessorCore(IEnumerable dataSources, IProcessorEnvironment processorEnvironment, ProcessorOptions options) 24 | { 25 | string[] filePaths = dataSources.Select(x => x.Uri.LocalPath).ToArray(); 26 | var sourceParser = new AndroidLogcatLogParser(filePaths); 27 | 28 | return new AndroidLogcatCustomDataProcessor( 29 | sourceParser, 30 | options, 31 | this.applicationEnvironment, 32 | processorEnvironment); 33 | } 34 | 35 | protected override bool IsDataSourceSupportedCore(IDataSource dataSource) 36 | { 37 | return dataSource.IsFile() && 38 | (Path.GetExtension(dataSource.Uri.LocalPath) == ".log"); 39 | } 40 | 41 | protected override void SetApplicationEnvironmentCore(IApplicationEnvironment applicationEnvironment) 42 | { 43 | this.applicationEnvironment = applicationEnvironment; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/AndroidLogCat/AndroidLogcatParsedResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.AndroidLogcat; 5 | using LinuxLogParserCore; 6 | using System.Collections.Generic; 7 | 8 | namespace AndroidLogcatMPTAddin 9 | { 10 | public class AndroidLogcatParsedResult 11 | { 12 | public List LogEntries { get; } 13 | public List DurationLogEntries; 14 | public IReadOnlyDictionary FileToMetadata { get; } 15 | 16 | public AndroidLogcatParsedResult(List logEntries, List durationLogEntries, Dictionary fileToMetadata) 17 | { 18 | LogEntries = logEntries; 19 | DurationLogEntries = durationLogEntries; 20 | FileToMetadata = fileToMetadata; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/AndroidLogCat/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.AndroidLogcatPlugin", 5 | "version": "1.3.4" 6 | }, 7 | "displayName": "Android Logcat", 8 | "description": "Enables viewing Android system and application logs recorded with Android Logcat", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/Cloud-init/Cloud-Init.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.2.1 6 | Cloud-InitMPTPlugin 7 | Cloud-InitMPTPlugin 8 | PackageReference 9 | Always 10 | true 11 | Microsoft 12 | Microsoft Corp. 13 | Performance ToolKit 14 | Contains the Linux Cloud-Init log parser datasource plugin. 15 | Microsoft.Performance.Toolkit.Plugins.Cloud-Init 16 | © Microsoft Corporation. All rights reserved. 17 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 18 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 19 | LICENSE.txt 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | True 33 | 34 | 35 | 36 | 37 | 38 | 39 | PreserveNewest 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/Cloud-init/CloudInitCustomDataProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.CloudInitLog; 5 | using LinuxLogParserCore; 6 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 7 | using Microsoft.Performance.SDK.Processing; 8 | 9 | namespace CloudInitMPTAddin 10 | { 11 | public sealed class CloudInitCustomDataProcessor 12 | : CustomDataProcessorWithSourceParser 13 | { 14 | public CloudInitCustomDataProcessor( 15 | ISourceParser sourceParser, 16 | ProcessorOptions options, 17 | IApplicationEnvironment applicationEnvironment, 18 | IProcessorEnvironment processorEnvironment) 19 | : base(sourceParser, options, applicationEnvironment, processorEnvironment) 20 | { 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/Cloud-init/CloudInitLogParsedResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser; 5 | using LinuxLogParser.CloudInitLog; 6 | using LinuxLogParserCore; 7 | using System.Collections.Generic; 8 | 9 | namespace CloudInitMPTAddin 10 | { 11 | public class CloudInitLogParsedResult 12 | { 13 | public List LogEntries { get; } 14 | public IReadOnlyDictionary FileToMetadata { get; } 15 | 16 | public CloudInitLogParsedResult(List logEntries, Dictionary fileToMetadata) 17 | { 18 | LogEntries = logEntries; 19 | FileToMetadata = fileToMetadata; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/Cloud-init/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.Cloud-Init", 5 | "version": "1.2.1" 6 | }, 7 | "displayName": "Linux - Cloud-Init", 8 | "description": "Processes log files from Cloud-init. Linux/UNIX Cloud-init is the industry standard multi-distribution method for cross-platform cloud instance initialization", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/DmesgIsoLog/Dmesg.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.2.1 6 | true 7 | DMesg 8 | Microsoft 9 | Microsoft Corp. 10 | Performance ToolKit 11 | Contains the datasource plugin to parse dmesg.iso.log files. 12 | Microsoft.Performance.Toolkit.Plugins.DmesgPlugin 13 | © Microsoft Corporation. All rights reserved. 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 16 | LICENSE.txt 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | True 30 | 31 | 32 | 33 | 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/DmesgIsoLog/DmesgIsoCustomDataProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.DmesgIsoLog; 5 | using LinuxLogParserCore; 6 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 7 | using Microsoft.Performance.SDK.Processing; 8 | 9 | namespace DmesgIsoMPTAddin 10 | { 11 | public sealed class DmesgIsoCustomDataProcessor 12 | : CustomDataProcessorWithSourceParser 13 | { 14 | public DmesgIsoCustomDataProcessor( 15 | ISourceParser sourceParser, 16 | ProcessorOptions options, 17 | IApplicationEnvironment applicationEnvironment, 18 | IProcessorEnvironment processorEnvironment) 19 | : base(sourceParser, options, applicationEnvironment, processorEnvironment) 20 | { 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/DmesgIsoLog/DmesgIsoDataSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using LinuxLogParser.DmesgIsoLog; 7 | using Microsoft.Performance.SDK.Processing; 8 | 9 | namespace DmesgIsoMPTAddin 10 | { 11 | [ProcessingSource( 12 | "{D1440EE2-DD94-4141-953A-82131BA3C91D}", 13 | "DmesgIsoLog", 14 | "A data source to parse dmesg.iso.log file")] 15 | [FileDataSource( 16 | "log", 17 | "Log files")] 18 | public class DmesgIsoDataSource : ProcessingSource 19 | { 20 | private IApplicationEnvironment applicationEnvironment; 21 | 22 | protected override ICustomDataProcessor CreateProcessorCore(IEnumerable dataSources, IProcessorEnvironment processorEnvironment, ProcessorOptions options) 23 | { 24 | string[] filePaths = dataSources.Select(x => x.Uri.LocalPath).ToArray(); 25 | var sourceParser = new DmesgIsoLogParser(filePaths); 26 | 27 | return new DmesgIsoCustomDataProcessor( 28 | sourceParser, 29 | options, 30 | this.applicationEnvironment, 31 | processorEnvironment); 32 | } 33 | 34 | protected override bool IsDataSourceSupportedCore(IDataSource dataSource) 35 | { 36 | return dataSource.IsFile() && dataSource.Uri.LocalPath.ToLower().EndsWith("dmesg.iso.log"); 37 | } 38 | 39 | protected override void SetApplicationEnvironmentCore(IApplicationEnvironment applicationEnvironment) 40 | { 41 | this.applicationEnvironment = applicationEnvironment; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/DmesgIsoLog/DmesgIsoLogParsedResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.DmesgIsoLog; 5 | using LinuxLogParserCore; 6 | using System.Collections.Generic; 7 | 8 | namespace DmesgIsoMPTAddin 9 | { 10 | public class DmesgIsoLogParsedResult 11 | { 12 | public List LogEntries { get; } 13 | public IReadOnlyDictionary FileToMetadata { get; } 14 | 15 | public DmesgIsoLogParsedResult(List logEntries, Dictionary fileToMetadata) 16 | { 17 | LogEntries = logEntries; 18 | FileToMetadata = fileToMetadata; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/DmesgIsoLog/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.DmesgPlugin", 5 | "version": "1.2.1" 6 | }, 7 | "displayName": "Linux - Dmesg", 8 | "description": "Processes Dmesg Linux/UNIX kernel ring buffer logs", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/WaLinuxAgent/WaLinuxAgent.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.2.1 6 | WaLinuxAgent 7 | WaLinuxAgent 8 | Always 9 | true 10 | Microsoft 11 | Microsoft Corp. 12 | Performance ToolKit 13 | Contains the WaLinux Agent log parser datasource plugin. 14 | Microsoft.Performance.Toolkit.Plugins.WaLinuxAgent 15 | © Microsoft Corporation. All rights reserved. 16 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 17 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 18 | LICENSE.txt 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | True 32 | 33 | 34 | 35 | 36 | 37 | 38 | PreserveNewest 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/WaLinuxAgent/WaLinuxAgentCustomDataProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.WaLinuxAgentLog; 5 | using LinuxLogParserCore; 6 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 7 | using Microsoft.Performance.SDK.Processing; 8 | 9 | namespace WaLinuxAgentMPTAddin 10 | { 11 | public sealed class WaLinuxAgentCustomDataProcessor 12 | : CustomDataProcessorWithSourceParser 13 | { 14 | public WaLinuxAgentCustomDataProcessor( 15 | ISourceParser sourceParser, 16 | ProcessorOptions options, 17 | IApplicationEnvironment applicationEnvironment, 18 | IProcessorEnvironment processorEnvironment) 19 | : base(sourceParser, options, applicationEnvironment, processorEnvironment) 20 | { 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/WaLinuxAgent/WaLinuxAgentLogParsedResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using LinuxLogParser.WaLinuxAgentLog; 5 | using LinuxLogParserCore; 6 | using System.Collections.Generic; 7 | 8 | namespace WaLinuxAgentMPTAddin 9 | { 10 | public class WaLinuxAgentLogParsedResult 11 | { 12 | public List LogEntries { get; } 13 | public IReadOnlyDictionary FileToMetadata { get; } 14 | 15 | public WaLinuxAgentLogParsedResult(List logEntries, Dictionary fileToMetadata) 16 | { 17 | LogEntries = logEntries; 18 | FileToMetadata = fileToMetadata; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/WaLinuxAgent/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.WaLinuxAgent", 5 | "version": "1.2.1" 6 | }, 7 | "displayName": "Linux - Microsoft Azure Linux Guest Agent", 8 | "description": "Processes log files produced by Microsoft Azure Linux Guest Agent (WALinuxAgent)", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /PerfDataExtension/README.md: -------------------------------------------------------------------------------- 1 | # Perf.data plugin 2 | 3 | Enables use of Linux perf.data files with 4 | [Microsoft Performance Toolkit](https://github.com/microsoft/microsoft-performance-toolkit-sdk) 5 | components such as 6 | [Windows Performance Analyzer](https://learn.microsoft.com/windows-hardware/test/wpt/windows-performance-analyzer). 7 | 8 | Uses the LinuxTracepoints Decode library from 9 | [LinuxTracepoints-Net](https://github.com/microsoft/LinuxTracepoints-Net). 10 | 11 | ## Changelog 12 | 13 | ### 0.1.2 (TBD) 14 | 15 | - Initial release. 16 | -------------------------------------------------------------------------------- /PerfDataExtension/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.PerfDataExtension", 5 | "version": "0.2.0" 6 | }, 7 | "displayName": "Linux - Perf", 8 | "description": "Enables loading Linux events from perf.data files (e.g. generated by the perf tool)", 9 | "owners": [ 10 | { 11 | "name": "LinuxTracepoints", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "linuxtracepoints@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } 20 | -------------------------------------------------------------------------------- /PerfDataTxtExtension/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "PerfDataExtensions": { 4 | "commandName": "Executable", 5 | "executablePath": "C:\\Tools\\WPT\\latest\\wpa.exe", 6 | "commandLineArgs": "-addsearchdir E:\\src\\Microsoft-Performance-Tools-Linux-Android\\PerfDataTxtExtension\\bin\\Debug\\netstandard2.1" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /PerfDataTxtExtension/Tables/Generators/IMapListToStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace PerfDataExtensions.Tables.Generators 5 | { 6 | public interface IMapListToStream 7 | { 8 | uint[] MapListToStartIndex 9 | { 10 | get; 11 | } 12 | 13 | uint[] MapIndexToList 14 | { 15 | get; 16 | } 17 | } 18 | 19 | public interface IMapListToStream 20 | : IMapListToStream 21 | { 22 | int ListSize(uint list); 23 | 24 | T IndexIntoList(uint list, int index); 25 | } 26 | } -------------------------------------------------------------------------------- /PerfDataTxtExtension/Tables/LinuxPerfScriptTableBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Diagnostics.Tracing.StackSources; 6 | using Microsoft.Performance.SDK.Processing; 7 | 8 | namespace PerfDataExtensions.Tables 9 | { 10 | // 11 | // This is a sample base class for all regular and metadata tables in your project which helps simplify management of them. 12 | // 13 | // A table is a logical collection of similar data points. 14 | // Things like CPU Usage, Thread Lifetimes, File I/O, etc. are all tables 15 | // 16 | // There is no explicit table interface so as to give you flexibility in how you implement your tables. 17 | // All that matters is that you have some way of getting the data out of the data files and into the ITableBuilder in CreateTable 18 | // in order for analyzer to understand your data. 19 | // 20 | 21 | public abstract class LinuxPerfScriptTableBase 22 | { 23 | protected LinuxPerfScriptTableBase(IReadOnlyDictionary perfDataTxtLogParsed) 24 | { 25 | this.PerfDataTxtLogParsed = perfDataTxtLogParsed; 26 | } 27 | 28 | // 29 | // In this sample we are going to assume the files will fit in memory, 30 | // and so we will make sure all tables have access to the collection of lines in the file. 31 | // 32 | 33 | public IReadOnlyDictionary PerfDataTxtLogParsed { get; } 34 | 35 | // 36 | // All tables will need some way to build themselves via the ITableBuilder interface. 37 | // 38 | 39 | public abstract void Build(ITableBuilder tableBuilder); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /PerfDataTxtExtension/Tables/TimeHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK; 5 | 6 | namespace PerfDataExtensions.Tables 7 | { 8 | public static class TimeHelper 9 | { 10 | public struct ReduceTimeSinceLastDiff 11 | : IFunc 12 | { 13 | public TimestampDelta Invoke(int value, Timestamp timeSinceLast1, Timestamp timeSinceLast2) 14 | { 15 | return timeSinceLast1 - timeSinceLast2; 16 | } 17 | } 18 | 19 | private struct ReduceTimeMinusDelta 20 | : IFunc 21 | { 22 | public Timestamp Invoke(int value, Timestamp timestamp, TimestampDelta delta) 23 | { 24 | return timestamp - delta; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PerfDataTxtExtension/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.PerfDataTxtExtension", 5 | "version": "1.2.6" 6 | }, 7 | "displayName": "Linux - Perf", 8 | "description": "Enables viewing Linux CPU Sampling events recorded with the kernel perf profiling utility", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /PerfDataUnitTest/PerfDataUnitTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.Toolkit.Engine; 5 | using Microsoft.Performance.Toolkit.Plugins.PerfDataExtension; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using System.IO; 8 | using Assembly = System.Reflection.Assembly; 9 | 10 | namespace PerfDataUnitTest 11 | { 12 | [TestClass] 13 | public class PerfDataUnitTest 14 | { 15 | [TestMethod] 16 | public void ProcessPerfGenericEvents() 17 | { 18 | // Input data 19 | var inputPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 20 | var perfDataPath = Path.Combine(inputPath, "TestData\\perf.data"); 21 | Assert.IsTrue(File.Exists(perfDataPath)); 22 | 23 | var pluginPath = Path.GetDirectoryName(typeof(PerfDataProcessingSource).Assembly.Location); 24 | using var plugins = PluginSet.Load(pluginPath); 25 | 26 | using var dataSources = DataSourceSet.Create(plugins); 27 | dataSources.AddFile(perfDataPath); 28 | 29 | var createInfo = new EngineCreateInfo(dataSources.AsReadOnly()); 30 | using var engine = Engine.Create(createInfo); 31 | engine.EnableCooker(PerfDataGenericSourceCooker.DataCookerPath); 32 | engine.EnableTable(PerfDataGenericEventsTable.TableDescriptor); 33 | var results = engine.Process(); 34 | 35 | var table = results.BuildTable(PerfDataGenericEventsTable.TableDescriptor); 36 | Assert.AreEqual(1003, table.RowCount); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PerfDataUnitTest/PerfDataUnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | false 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /PerfDataUnitTest/TestData/perf.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/PerfDataUnitTest/TestData/perf.data -------------------------------------------------------------------------------- /PerfUnitTest/PerfUnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | true 26 | true 27 | compile 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/Args.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using Microsoft.Performance.SDK.Processing; 8 | using PerfettoProcessor; 9 | using Utilities; 10 | 11 | namespace PerfettoCds 12 | { 13 | public class Args 14 | { 15 | public static Dictionary ParseArgs(IEnumerable perfettoArgEvents) 16 | { 17 | var args = new Dictionary(); 18 | 19 | // Each event has multiple of these "debug annotations". They get stored in lists 20 | foreach (var arg in perfettoArgEvents) 21 | { 22 | switch (arg.ValueType) 23 | { 24 | case "json": 25 | case "string": 26 | args.Add(arg.ArgKey, Common.StringIntern(arg.StringValue)); 27 | break; 28 | case "bool": 29 | case "int": 30 | args.Add(arg.ArgKey, arg.IntValue); 31 | break; 32 | case "uint": 33 | case "pointer": 34 | args.Add(arg.ArgKey, (uint)arg.IntValue); 35 | break; 36 | case "real": 37 | args.Add(arg.ArgKey, arg.RealValue); 38 | break; 39 | case "null": 40 | args.Add(arg.ArgKey, null); 41 | break; 42 | default: 43 | throw new Exception("Unexpected Perfetto value type"); 44 | } 45 | } 46 | 47 | return args; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoCpuFrequencyEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using System.Collections.Generic; 5 | 6 | namespace PerfettoCds.Pipeline.DataOutput 7 | { 8 | /// 9 | /// A event that represents the frequency and state of a CPU at a point in time 10 | /// 11 | public readonly struct PerfettoCpuFrequencyEvent 12 | { 13 | // The current frequency of this CPU 14 | public double CpuFrequency { get; } 15 | // The specific CPU core 16 | public int CpuNum { get; } 17 | public Timestamp StartTimestamp { get; } 18 | // Type of CPU frequency event. Whether it's an idle change or frequency change event 19 | public string Name { get; } 20 | public TimestampDelta Duration { get; } 21 | public bool IsIdle { get; } 22 | 23 | public PerfettoCpuFrequencyEvent(double cpuFrequency, int cpuNum, Timestamp startTimestamp, TimestampDelta duration, string name, bool isIdle) 24 | { 25 | this.CpuFrequency = cpuFrequency; 26 | this.CpuNum = cpuNum; 27 | this.StartTimestamp = startTimestamp; 28 | this.Duration = duration; 29 | this.Name = name; 30 | this.IsIdle = isIdle; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoCpuSamplingEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using Utilities; 5 | 6 | namespace PerfettoCds.Pipeline.DataOutput 7 | { 8 | /// 9 | /// A CPU sampling event that samples at some interval 10 | /// Shows process and threads, and stacks that were running on which CPUs at specific times. 11 | /// 12 | public readonly struct PerfettoCpuSamplingEvent 13 | { 14 | public string ProcessName { get; } 15 | public string ThreadName { get; } 16 | public Timestamp Timestamp { get; } 17 | public uint Cpu { get; } 18 | public string CpuMode { get; } 19 | public string UnwindError { get; } 20 | public string[] CallStack { get; } 21 | /// 22 | /// filename of the binary / library for the instruction pointer 23 | /// 24 | public string Module { get; } 25 | /// 26 | /// Functionname of the instruction pointer 27 | /// 28 | public string Function { get; } 29 | 30 | public PerfettoCpuSamplingEvent( 31 | string processName, 32 | string threadName, 33 | Timestamp timestamp, 34 | uint cpu, 35 | string cpuMode, 36 | string unwindError, 37 | string[] callStack, 38 | string module, 39 | string function 40 | ) 41 | { 42 | ProcessName = Common.StringIntern(processName); 43 | ThreadName = Common.StringIntern(threadName); 44 | Timestamp = timestamp; 45 | Cpu = cpu; 46 | CpuMode = cpuMode; 47 | UnwindError = unwindError; 48 | CallStack = callStack; 49 | Module = module; 50 | Function = function; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoCpuWakeEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using Utilities; 5 | 6 | namespace PerfettoCds.Pipeline.DataOutput 7 | { 8 | /// 9 | /// A CPU wake event that displays which process and threads were woken on which CPUs at specific times. 10 | /// 11 | public class PerfettoCpuWakeEvent 12 | { 13 | public string WokenProcessName { get; } 14 | public long? WokenPid { get; } 15 | public string WokenThreadName { get; } 16 | public long WokenTid { get; } 17 | 18 | public string WakerProcessName { get; } 19 | public long? WakerPid { get; } 20 | public string WakerThreadName { get; } 21 | public long WakerTid { get; } 22 | 23 | public Timestamp Timestamp { get; } 24 | public int Success { get; } 25 | public uint Cpu { get; } 26 | public int TargetCpu { get; } 27 | public int Priority { get; } 28 | 29 | public PerfettoCpuWakeEvent(string wokenProcessName, 30 | long? wokenPid, 31 | string wokenThreadName, 32 | long wokenTid, 33 | string wakerProcessName, 34 | long? wakerPid, 35 | string wakerThreadName, 36 | long wakerTid, 37 | Timestamp timestamp, 38 | int success, 39 | uint cpu, 40 | int targetCpu, 41 | int priority) 42 | { 43 | this.WokenProcessName = Common.StringIntern(wokenProcessName); 44 | this.WokenPid = wokenPid; 45 | this.WokenThreadName = Common.StringIntern(wokenThreadName); 46 | this.WokenTid = wokenTid; 47 | 48 | this.WakerProcessName = Common.StringIntern(wakerProcessName); 49 | this.WakerPid = wakerPid; 50 | this.WakerThreadName = Common.StringIntern(wakerThreadName); 51 | this.WakerTid = wakerTid; 52 | 53 | this.Timestamp = timestamp; 54 | this.Success = success; 55 | this.Cpu = cpu; 56 | this.TargetCpu = targetCpu; 57 | this.Priority = priority; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoFtraceEvent.cs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using System.Collections.Generic; 5 | using Utilities; 6 | 7 | namespace PerfettoCds.Pipeline.DataOutput 8 | { 9 | /// 10 | /// An Ftrace event with extra args 11 | /// 12 | public readonly struct PerfettoFtraceEvent 13 | { 14 | public Timestamp StartTimestamp { get; } 15 | public string ProcessFormattedName { get; } 16 | public string ThreadFormattedName { get; } 17 | public string ThreadName { get; } 18 | public uint Tid { get; } 19 | public uint Cpu { get; } 20 | // Name of the ftrace event 21 | public string Name { get; } 22 | 23 | // From Args table. Variable number per event 24 | public Dictionary Args { get; } 25 | 26 | public PerfettoFtraceEvent(Timestamp startTimestamp, 27 | string processFormattedName, 28 | string threadFormattedName, 29 | string threadName, 30 | uint tid, 31 | uint cpu, 32 | string name, 33 | Dictionary args) 34 | { 35 | this.StartTimestamp = startTimestamp; 36 | this.ProcessFormattedName = Common.StringIntern(processFormattedName); 37 | this.ThreadFormattedName = Common.StringIntern(threadFormattedName); 38 | this.ThreadName = Common.StringIntern(threadName); 39 | this.Tid = tid; 40 | this.Cpu = cpu; 41 | this.Name = Common.StringIntern(name); 42 | this.Args = args; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoGpuCountersEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using System.Collections.Generic; 5 | using Utilities; 6 | 7 | namespace PerfettoCds.Pipeline.DataOutput 8 | { 9 | public readonly struct PerfettoGpuCountersEvent 10 | { 11 | /// 12 | /// Name (type) of GPU counter 13 | /// 14 | public string Name { get; } 15 | 16 | /// 17 | /// Actual value of this counter at this point in time 18 | /// 19 | public double Value { get; } 20 | 21 | public Timestamp StartTimestamp { get; } 22 | public TimestampDelta Duration { get; } 23 | 24 | /// 25 | /// For populating the current counter values 26 | /// 27 | public PerfettoGpuCountersEvent(string name, double value, Timestamp startTimestamp, TimestampDelta duration) 28 | { 29 | this.Name = Common.StringIntern(name); 30 | this.Value = value; 31 | this.StartTimestamp = startTimestamp; 32 | this.Duration = duration; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoLogcatEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using System.Collections.Generic; 5 | using Utilities; 6 | 7 | namespace PerfettoCds.Pipeline.DataOutput 8 | { 9 | /// 10 | /// A logcat message 11 | /// 12 | public readonly struct PerfettoLogcatEvent 13 | { 14 | public Timestamp StartTimestamp { get; } 15 | public string ProcessName { get; } 16 | public string ThreadName { get; } 17 | public string Priority { get; } 18 | public string Tag { get; } 19 | public string Message { get; } 20 | 21 | public PerfettoLogcatEvent(Timestamp startTimestamp, 22 | string processName, 23 | string threadName, 24 | string priority, 25 | string tag, 26 | string message) 27 | { 28 | this.StartTimestamp = startTimestamp; 29 | this.ProcessName = Common.StringIntern(processName); 30 | this.ThreadName = Common.StringIntern(threadName); 31 | this.Priority = Common.StringIntern(priority); 32 | this.Tag = Common.StringIntern(tag); 33 | this.Message = Common.StringIntern(message); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoProcessMemoryEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using System.Collections.Generic; 5 | 6 | namespace PerfettoCds.Pipeline.DataOutput 7 | { 8 | /// 9 | /// A event that represents several memory values for a process at a point in time 10 | /// 11 | public readonly struct PerfettoProcessMemoryEvent 12 | { 13 | public string ProcessName { get; } 14 | public Timestamp StartTimestamp { get; } 15 | public TimestampDelta Duration { get; } 16 | 17 | /// Resident set size - anonymous memory 18 | public double RssAnon { get; } 19 | /// Resident set size - shared memory 20 | public double RssShMem { get; } 21 | /// Resident set size - file mappings 22 | public double RssFile { get; } 23 | /// Resident set size - Peak (high water mark) 24 | public double RssHwm { get; } 25 | /// Resident set size - Sum of anon, file, ShMem 26 | public double Rss { get; } 27 | /// Locked memory size 28 | public double Locked { get; } 29 | /// Swapped out VM size by anonymous private pages 30 | public double Swap { get; } 31 | /// Peak virtual memory size 32 | public double Virt { get; } 33 | 34 | public PerfettoProcessMemoryEvent(string processName, Timestamp startTimestamp, TimestampDelta duration, 35 | double rssAnon, 36 | double rssShMem, 37 | double rssFile, 38 | double rssHwm, 39 | double rss, 40 | double locked, 41 | double swap, 42 | double virt) 43 | { 44 | this.ProcessName = processName; 45 | this.StartTimestamp = startTimestamp; 46 | this.Duration = duration; 47 | 48 | this.RssAnon = rssAnon; 49 | this.Locked = locked; 50 | this.RssShMem = rssShMem; 51 | this.RssFile = rssFile; 52 | this.RssHwm = rssHwm; 53 | this.Rss = rss; 54 | this.Swap = swap; 55 | this.Virt = virt; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/DataOutput/PerfettoSystemMemoryEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK; 4 | using System.Collections.Generic; 5 | 6 | namespace PerfettoCds.Pipeline.DataOutput 7 | { 8 | /// 9 | /// A event that represents a single system memory value at a point in time 10 | /// 11 | public readonly struct PerfettoSystemMemoryEvent 12 | { 13 | public double Value { get; } 14 | public string MemoryType { get; } 15 | public Timestamp StartTimestamp { get; } 16 | public TimestampDelta Duration { get; } 17 | 18 | public PerfettoSystemMemoryEvent(double value, string memoryType, Timestamp startTimestamp, TimestampDelta duration) 19 | { 20 | this.Value = value; 21 | this.MemoryType = memoryType; 22 | this.StartTimestamp = startTimestamp; 23 | this.Duration = duration; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/Events/PerfettoSqlEventKeyed.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Performance.SDK.Extensibility; 2 | using PerfettoProcessor; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace PerfettoCds.Pipeline.Events 8 | { 9 | /// 10 | /// This class serves as a holder for PerfettoSqlEvents as they pass through cookers. It stores 11 | /// the PerfettoSqlEvent and the key that identifies its type and which cookers process it 12 | /// 13 | public class PerfettoSqlEventKeyed : IKeyedDataType 14 | { 15 | public readonly string Key; 16 | 17 | // The SQL event being passed on 18 | public PerfettoSqlEvent SqlEvent; 19 | 20 | public PerfettoSqlEventKeyed(string key, PerfettoSqlEvent sqlEvent) 21 | { 22 | this.Key = key; 23 | this.SqlEvent = sqlEvent; 24 | } 25 | 26 | public string GetKey() 27 | { 28 | return Key; 29 | } 30 | 31 | public int CompareTo(string other) 32 | { 33 | return this.Key.CompareTo(other); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/PerfettoDataProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.Performance.SDK.Extensibility.SourceParsing; 4 | using Microsoft.Performance.SDK.Processing; 5 | using PerfettoCds.Pipeline.Events; 6 | 7 | namespace PerfettoCds 8 | { 9 | /// 10 | /// This class only delegates work off to the source parser, so there's no logic inside of it. 11 | /// 12 | /// Since our table has required data cookers, the SDK takes care of making sure it 13 | /// gets built. 14 | /// 15 | public class PerfettoDataProcessor : CustomDataProcessorWithSourceParser 16 | { 17 | internal PerfettoDataProcessor( 18 | ISourceParser sourceParser, 19 | ProcessorOptions options, 20 | IApplicationEnvironment applicationEnvironment, 21 | IProcessorEnvironment processorEnvironment) 22 | : base(sourceParser, options, applicationEnvironment, processorEnvironment) 23 | { 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/SourceDataCookers/PerfettoArgCooker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System.Collections.Generic; 4 | using System.Threading; 5 | using Microsoft.Performance.SDK; 6 | using Microsoft.Performance.SDK.Extensibility; 7 | using Microsoft.Performance.SDK.Extensibility.DataCooking; 8 | using Microsoft.Performance.SDK.Extensibility.DataCooking.SourceDataCooking; 9 | using Microsoft.Performance.SDK.Processing; 10 | using PerfettoCds.Pipeline.Events; 11 | using PerfettoProcessor; 12 | 13 | namespace PerfettoCds.Pipeline.SourceDataCookers 14 | { 15 | /// 16 | /// Cooks the data from the Args table in Perfetto traces 17 | /// 18 | public sealed class PerfettoArgCooker : SourceDataCooker 19 | { 20 | public override string Description => "Processes events from the args Perfetto SQL table"; 21 | 22 | // 23 | // The data this cooker outputs. Tables or other cookers can query for this data 24 | // via the SDK runtime 25 | // 26 | [DataOutput] 27 | public ProcessedEventData ArgEvents { get; } 28 | 29 | // Instructs runtime to only send events with the given keys this data cooker 30 | public override ReadOnlyHashSet DataKeys => 31 | new ReadOnlyHashSet(new HashSet { PerfettoPluginConstants.ArgEvent }); 32 | 33 | public PerfettoArgCooker() : base(PerfettoPluginConstants.ArgCookerPath) 34 | { 35 | this.ArgEvents = new ProcessedEventData(); 36 | } 37 | 38 | public override DataProcessingResult CookDataElement(PerfettoSqlEventKeyed perfettoEvent, PerfettoSourceParser context, CancellationToken cancellationToken) 39 | { 40 | this.ArgEvents.AddEvent((PerfettoArgEvent)perfettoEvent.SqlEvent); 41 | 42 | return DataProcessingResult.Processed; 43 | } 44 | 45 | public override void EndDataCooking(CancellationToken cancellationToken) 46 | { 47 | base.EndDataCooking(cancellationToken); 48 | this.ArgEvents.FinalizeData(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/SourceDataCookers/PerfettoRawCooker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System.Collections.Generic; 4 | using System.Threading; 5 | using Microsoft.Performance.SDK; 6 | using Microsoft.Performance.SDK.Extensibility; 7 | using Microsoft.Performance.SDK.Extensibility.DataCooking; 8 | using Microsoft.Performance.SDK.Extensibility.DataCooking.SourceDataCooking; 9 | using Microsoft.Performance.SDK.Processing; 10 | using PerfettoCds.Pipeline.Events; 11 | using PerfettoProcessor; 12 | 13 | namespace PerfettoCds.Pipeline.SourceDataCookers 14 | { 15 | /// 16 | /// Cooks the data from the Raw table in Perfetto traces 17 | /// 18 | public sealed class PerfettoRawCooker : SourceDataCooker 19 | { 20 | public override string Description => "Processes events from the Raw Perfetto SQL table"; 21 | 22 | // 23 | // The data this cooker outputs. Tables or other cookers can query for this data 24 | // via the SDK runtime 25 | // 26 | [DataOutput] 27 | public ProcessedEventData RawEvents { get; } 28 | 29 | // Instructs runtime to only send events with the given keys this data cooker 30 | public override ReadOnlyHashSet DataKeys => 31 | new ReadOnlyHashSet(new HashSet { PerfettoPluginConstants.RawEvent }); 32 | 33 | 34 | public PerfettoRawCooker() : base(PerfettoPluginConstants.RawCookerPath) 35 | { 36 | this.RawEvents = new ProcessedEventData(); 37 | } 38 | 39 | public override DataProcessingResult CookDataElement(PerfettoSqlEventKeyed perfettoEvent, PerfettoSourceParser context, CancellationToken cancellationToken) 40 | { 41 | var newEvent = (PerfettoRawEvent)perfettoEvent.SqlEvent; 42 | newEvent.RelativeTimestamp = newEvent.Timestamp - context.FirstEventTimestamp.ToNanoseconds; 43 | this.RawEvents.AddEvent(newEvent); 44 | 45 | return DataProcessingResult.Processed; 46 | } 47 | 48 | public override void EndDataCooking(CancellationToken cancellationToken) 49 | { 50 | base.EndDataCooking(cancellationToken); 51 | this.RawEvents.FinalizeData(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /PerfettoCds/Pipeline/SourceDataCookers/PerfettoThreadTrackerCooker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System.Collections.Generic; 4 | using System.Threading; 5 | using Microsoft.Performance.SDK; 6 | using Microsoft.Performance.SDK.Extensibility; 7 | using Microsoft.Performance.SDK.Extensibility.DataCooking; 8 | using Microsoft.Performance.SDK.Extensibility.DataCooking.SourceDataCooking; 9 | using Microsoft.Performance.SDK.Processing; 10 | using PerfettoCds.Pipeline.Events; 11 | using PerfettoProcessor; 12 | 13 | namespace PerfettoCds.Pipeline.SourceDataCookers 14 | { 15 | /// 16 | /// Cooks the data from the ThreadTrack table in Perfetto traces 17 | /// 18 | public sealed class PerfettoThreadTrackCooker : SourceDataCooker 19 | { 20 | public override string Description => "Processes events from the thread_tracks Perfetto SQL table"; 21 | 22 | // 23 | // The data this cooker outputs. Tables or other cookers can query for this data 24 | // via the SDK runtime 25 | // 26 | [DataOutput] 27 | public ProcessedEventData ThreadTrackEvents { get; } 28 | 29 | // Instructs runtime to only send events with the given keys this data cooker 30 | public override ReadOnlyHashSet DataKeys => 31 | new ReadOnlyHashSet(new HashSet { PerfettoPluginConstants.ThreadTrackEvent }); 32 | 33 | 34 | public PerfettoThreadTrackCooker() : base(PerfettoPluginConstants.ThreadTrackCookerPath) 35 | { 36 | this.ThreadTrackEvents = 37 | new ProcessedEventData(); 38 | } 39 | 40 | public override DataProcessingResult CookDataElement(PerfettoSqlEventKeyed perfettoEvent, PerfettoSourceParser context, CancellationToken cancellationToken) 41 | { 42 | this.ThreadTrackEvents.AddEvent((PerfettoThreadTrackEvent)perfettoEvent.SqlEvent); 43 | 44 | return DataProcessingResult.Processed; 45 | } 46 | 47 | public override void EndDataCooking(CancellationToken cancellationToken) 48 | { 49 | base.EndDataCooking(cancellationToken); 50 | this.ThreadTrackEvents.FinalizeData(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PerfettoCds/pluginManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/microsoft-performance-toolkit-sdk/main/src/PluginsSystem/Tools/Microsoft.Performance.Toolkit.Plugins.Cli/Manifest/PluginManifestSchema.json", 3 | "identity": { 4 | "id": "Microsoft.Performance.Toolkit.Plugins.PerfettoPlugin", 5 | "version": "1.6.2" 6 | }, 7 | "displayName": "Perfetto for Android and Chromium", 8 | "description": "Processes Android system and user traces, as well as Chromium based browser performance trace files", 9 | "owners": [ 10 | { 11 | "name": "Ivan Berg", 12 | "address": "1 Microsoft Way, Redmond, WA 98052", 13 | "emailAddresses": [ "ivberg@microsoft.com" ], 14 | "phoneNumbers": [] 15 | } 16 | ], 17 | "projectUrl": "https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android", 18 | "manifestVersion": 1.0 19 | } -------------------------------------------------------------------------------- /PerfettoProcessor/PerfettoProcessor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | 1.6.2 6 | true 7 | Microsoft 8 | Microsoft Corp. 9 | Performance ToolKit 10 | Contains library for processing Perfetto traces. 11 | Microsoft.Performance.Toolkit.Plugins.PerfettoProcessor 12 | © Microsoft Corporation. All rights reserved. 13 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 14 | https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android 15 | LICENSE.txt 16 | 17 | 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | True 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PerfettoProcessor/Protobuf/Readme.txt: -------------------------------------------------------------------------------- 1 | TraceProcessor.cs and Descriptor.cs are C# equivalent versions of traceprocessor.proto and descriptor.proto. 2 | The .proto files are from the Perfetto repo (https://github.com/google/perfetto). To convert .proto to a C# class, 3 | the protoc.exe executable can be used, which can be retrieved from the Google.Protobuf.Tools Nuget package. 4 | 5 | The command lines to generate the C# files are something like this: 6 | 7 | protoc.exe -I d:\perfetto_root --csharp_out=output_dir D:\perfetto_root\protos\perfetto\trace_processor\trace_processor.proto 8 | protoc.exe -I d:\perfetto_root --csharp_out=output_dir D:\perfetto_root\protos\perfetto\common\descriptor.proto -------------------------------------------------------------------------------- /PerfettoUnitTest/PerfettoUnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ReleaseFiles/README.txt: -------------------------------------------------------------------------------- 1 | This README covers the basics of what's included in this release and how to use/run. 2 | 3 | For more detailed help and pre-requisites see https://aka.ms/linuxperftools 4 | 5 | └── Microsoft-Performance-Tools-Linux 6 | ├── LTTngDriver - Standalone LTTngDriver.exe cross-platform .NET Core program to dump processed LTTng events to stdout or a file 7 | ├── Launcher - Launches WPA UI configured to point at these additional Linux plugins 8 | └── MicrosoftPerfToolkitAddins - The actual various plugins each self-contained per sub-folder -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | 2 | ## How to file issues and get help 3 | 4 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 5 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 6 | feature request as a new Issue. 7 | 8 | For help and questions about using this project, please use https://stackoverflow.com/ with the tag [microsoft-perf-tools-linux] 9 | 10 | ## Microsoft Support Policy 11 | 12 | Support for this project is limited to the resources listed above. 13 | -------------------------------------------------------------------------------- /TestData/LTTng/lttng-kernel-trace.ctf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/LTTng/lttng-kernel-trace.ctf -------------------------------------------------------------------------------- /TestData/Perf/timestamp.txt: -------------------------------------------------------------------------------- 1 | Thu Aug 15 23:36:56 2019 -------------------------------------------------------------------------------- /TestData/Perfetto/androidBasicMemory.pftrace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/Perfetto/androidBasicMemory.pftrace -------------------------------------------------------------------------------- /TestData/Perfetto/androidGpu.pftrace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/Perfetto/androidGpu.pftrace -------------------------------------------------------------------------------- /TestData/Perfetto/chrome.pftrace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/Perfetto/chrome.pftrace -------------------------------------------------------------------------------- /TestData/Perfetto/jankFrame.pftrace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/Perfetto/jankFrame.pftrace -------------------------------------------------------------------------------- /TestData/Perfetto/perfetto_trace_cpu_sampling_not_scoped.pftrace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/Perfetto/perfetto_trace_cpu_sampling_not_scoped.pftrace -------------------------------------------------------------------------------- /TestData/Perfetto/test_trace.perfetto-trace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/TestData/Perfetto/test_trace.perfetto-trace -------------------------------------------------------------------------------- /UnitTestCommon/ITableResultExts.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.Toolkit.Engine; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace UnitTestCommon 9 | { 10 | public static class ITableResultExts 11 | { 12 | public static object[][] GetDataForAllRows(this ITableResult tableResult) 13 | { 14 | var allColumns = tableResult.Columns.Select(f => f.Configuration.Metadata.Guid).ToArray(); 15 | return GetDataForAllRows(tableResult, allColumns); 16 | } 17 | 18 | public static object[][] GetDataForAllRows(this ITableResult tableResult, Guid[] columns) 19 | { 20 | var allRowData = new object[tableResult.RowCount][]; 21 | for (int rowNum = 0; rowNum < tableResult.RowCount; rowNum++) 22 | { 23 | allRowData[rowNum] = GetRowData(tableResult, columns, rowNum); 24 | } 25 | return allRowData; 26 | } 27 | 28 | public static object[] GetRowData(this ITableResult tableResult, Guid[] columns, int row) 29 | { 30 | var rowData = new object[columns.Length]; 31 | for(int colIdx = 0; colIdx < columns.Length; colIdx++) 32 | { 33 | var col = tableResult.Columns.Single(f => f.Configuration.Metadata.Guid == columns[colIdx]); 34 | 35 | if (col.ProjectorInterface.Name != "PercentGenerator`2") // % col.Projector.DependsOnVisibleDomain = true (not easily accessible) and we haven't set this 36 | { 37 | rowData[colIdx] = col.Project(row); 38 | } 39 | } 40 | 41 | return rowData; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /UnitTestCommon/Progress.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace UnitTestCommon 7 | { 8 | public class Progress : IProgress 9 | { 10 | public void Report(int progress) 11 | { 12 | Console.WriteLine($"Progress: {progress}"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /UnitTestCommon/TableBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK.Processing; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace UnitTestCommon 10 | { 11 | public class TableBuilder : ITableBuilder 12 | { 13 | public IEnumerable BuiltInTableConfigurations { get; } 14 | public TableConfiguration DefaultConfiguration { get; private set; } 15 | 16 | private List tableConfigurations; 17 | private List> tables; 18 | 19 | public TableBuilderWithRowCount TableBuilderWithRowCount; 20 | 21 | public TableBuilder() 22 | { 23 | TableBuilderWithRowCount = new TableBuilderWithRowCount(); 24 | tableConfigurations = new List(); 25 | tables = new List>(); 26 | } 27 | 28 | public ITableBuilder AddTableCommand(string commandName, TableCommandCallback callback) 29 | { 30 | tables.Add(new Tuple(commandName, callback)); 31 | return this; 32 | } 33 | 34 | public ITableBuilder AddTableConfiguration(TableConfiguration configuration) 35 | { 36 | if (tableConfigurations.Any(f => f.Name == configuration.Name)) 37 | { 38 | throw new Exception("TableConfiguration: Already existing name"); 39 | } 40 | 41 | tableConfigurations.Add(configuration); 42 | 43 | return this; 44 | } 45 | 46 | public ITableBuilder SetDefaultTableConfiguration(TableConfiguration configuration) 47 | { 48 | DefaultConfiguration = configuration; 49 | return this; 50 | } 51 | 52 | public ITableBuilderWithRowCount SetRowCount(int numberOfRows) 53 | { 54 | TableBuilderWithRowCount.RowCount = numberOfRows; 55 | return TableBuilderWithRowCount; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /UnitTestCommon/TableBuilderTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK.Processing; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace UnitTestCommon 12 | { 13 | public static class TableBuilderTests 14 | { 15 | public static bool TestRowTypesMatchColTypes(ITableBuilderWithRowCount tbr, int rowNumber) 16 | { 17 | for (var i = 0; i < tbr.Columns.Count; i++) 18 | { 19 | var col = tbr.Columns.ElementAt(i); 20 | try 21 | { 22 | var projResult = col.Project(rowNumber); 23 | 24 | if (projResult != null) 25 | { 26 | var projResultType = projResult.GetType(); 27 | throw new InvalidDataException($"Column DataType {col.DataType} does not match projected type {projResultType}"); 28 | } 29 | } 30 | catch (Exception) 31 | { 32 | 33 | } 34 | } 35 | 36 | return true; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /UnitTestCommon/TableBuilderWithRowCount.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK.Processing; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace UnitTestCommon 10 | { 11 | public class TableBuilderWithRowCount : ITableBuilderWithRowCount 12 | { 13 | public int RowCount { get; set; } 14 | 15 | public IReadOnlyCollection Columns 16 | { 17 | get { return _columns; } 18 | } 19 | 20 | private List _columns { get; set; } 21 | 22 | public TableBuilderWithRowCount() 23 | { 24 | _columns = new List(); 25 | } 26 | 27 | public ITableBuilderWithRowCount AddColumn(IDataColumn column) 28 | { 29 | if (_columns.Any(f => f.Configuration.Metadata.Name == column.Configuration.Metadata.Name)) 30 | { 31 | throw new Exception("AddColumn: Already existing name"); 32 | } 33 | if (_columns.Any(f => f.Configuration.Metadata.Guid == column.Configuration.Metadata.Guid)) 34 | { 35 | throw new Exception("AddColumn: Already existing Guid"); 36 | } 37 | _columns.Add(column); 38 | 39 | return this; 40 | } 41 | 42 | public ITableBuilderWithRowCount ReplaceColumn(IDataColumn oldColumn, IDataColumn newColumn) 43 | { 44 | _columns[_columns.IndexOf(oldColumn)] = newColumn; 45 | return this; 46 | } 47 | 48 | public ITableBuilderWithRowCount SetTableRowDetailsGenerator(Func> generator) 49 | { 50 | return this; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /UnitTestCommon/UnitTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK.Processing; 5 | using Microsoft.Performance.Toolkit.Engine; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Text; 10 | 11 | namespace UnitTestCommon 12 | { 13 | public static class UnitTest 14 | { 15 | public static void TestTableBuild(RuntimeExecutionResults runtimeExecutionResults, TableDescriptor tableDescriptor, int expectedCount, bool skipDataAvailableCheck = false) 16 | { 17 | var isTableDataAvailable = runtimeExecutionResults.IsTableDataAvailable(tableDescriptor) == true; 18 | 19 | if (skipDataAvailableCheck || isTableDataAvailable) 20 | { 21 | var tableResult = runtimeExecutionResults.BuildTable(tableDescriptor); 22 | Assert.IsTrue(tableResult.RowCount == expectedCount); 23 | var tableData = tableResult.GetDataForAllRows(); 24 | Assert.IsTrue(tableData.Length == expectedCount); 25 | } 26 | else if (!isTableDataAvailable && expectedCount > 0) 27 | { 28 | throw new Exception($"No data available for {tableDescriptor.Name} but we expected {expectedCount} rows"); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /UnitTestCommon/UnitTestCommon.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Utilities/AccessProviders/ArrayAccessProvider`1.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Performance.SDK.Processing; 5 | 6 | namespace Utilities.AccessProviders 7 | { 8 | // This is copied from elsewhere + bugfix and probably needs to be in the SDK 9 | public struct ArrayAccessProvider 10 | : ICollectionAccessProvider 11 | { 12 | #region ICollectionAccessProvider Members 13 | 14 | public T GetValue(T[] collection, int index) 15 | { 16 | if (collection == null) 17 | { 18 | return default(T); 19 | } 20 | 21 | if (index < collection.Length) 22 | { 23 | T value = collection[index]; 24 | return value; 25 | } 26 | return PastEndValue; 27 | } 28 | 29 | public T PastEndValue 30 | { 31 | get 32 | { 33 | return default(T); 34 | } 35 | } 36 | 37 | #endregion 38 | 39 | #region ICollectionInfoProvider Members 40 | 41 | public bool HasUniqueStart 42 | { 43 | get { return false; } 44 | } 45 | 46 | public int GetCount(T[] collection) 47 | { 48 | return collection.Length; 49 | } 50 | 51 | #endregion 52 | 53 | #region INullableInfoProvider Members 54 | 55 | public bool IsNull(T[] value) 56 | { 57 | return (value == null); 58 | } 59 | 60 | #endregion 61 | 62 | public T[] GetParent(T[] collection) 63 | { 64 | throw new System.NotImplementedException(); 65 | } 66 | 67 | public bool Equals(T[] x, T[] y) 68 | { 69 | throw new System.NotImplementedException(); 70 | } 71 | 72 | public int GetHashCode(T[] x) 73 | { 74 | throw new System.NotImplementedException(); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Utilities/EventProjection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System; 4 | using Microsoft.Performance.SDK.Processing; 5 | 6 | namespace Utilities 7 | { 8 | public struct EventProjection : IProjection 9 | { 10 | private readonly ProcessedEventData events; 11 | 12 | public EventProjection(ProcessedEventData events) 13 | { 14 | this.events = events; 15 | } 16 | 17 | public Type SourceType => typeof(int); 18 | 19 | public Type ResultType => typeof(T); 20 | 21 | public T this[int value] => this.events[(uint)value]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Utilities/ProcessingSourceInfoGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Microsoft.Performance.SDK.Processing; 6 | 7 | namespace Utilities 8 | { 9 | public static class ProcessingSourceInfoGenerator 10 | { 11 | public static ProcessingSourceInfo GetEmpty() 12 | { 13 | return new ProcessingSourceInfo() 14 | { 15 | Owners = Array.Empty(), 16 | ProjectInfo = null, 17 | LicenseInfo = null, 18 | CopyrightNotice = null, 19 | AdditionalInformation = Array.Empty(), 20 | }; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Utilities/Utilities.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | b0f4d7f4-b11c-41b8-96f5-2414174c3e7d 7 | 8 | 9 | Utilities 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Utilities/Utilities.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | b0f4d7f4-b11c-41b8-96f5-2414174c3e7d 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /grammar/antlr-4.11.1-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Microsoft-Performance-Tools-Linux-Android/774054bd35b616d8fb0913e2c089ccd828fd7c41/grammar/antlr-4.11.1-complete.jar -------------------------------------------------------------------------------- /grammar/ctf.cmd: -------------------------------------------------------------------------------- 1 | @echo on 2 | java.exe -jar antlr-4.11.1-complete.jar -Dlanguage=CSharp Ctf.g4 3 | move CtfListener.cs ICtfListener.cs 4 | 5 | --------------------------------------------------------------------------------