public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var connections = quicState.Connections;

            if (connections.Count == 0)
            {
                return;
            }

            var connData =
                connections.SelectMany(
                    x => x.GetFlowBlockedEvents()
                    .Where(x => x.Flags != QuicFlowBlockedFlags.None)
                    .Select(y => new Data(x, y)));
            var streamData =
                connections.SelectMany(
                    x => x.Streams.SelectMany(
                        y => y.GetFlowBlockedEvents()
                        .Where(z => z.Flags != QuicFlowBlockedFlags.None)
                        .Select(z => new Data(x, z, y))));
            var data = connData.Concat(streamData).ToArray();

            var table          = tableBuilder.SetRowCount(data.Length);
            var dataProjection = Projection.Index(data);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(streamColumnConfig, dataProjection.Compose(ProjectStreamId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(reasonColumnConfig, dataProjection.Compose(ProjectReason));
            table.AddColumn(countColumnConfig, Projection.Constant <uint>(1));
            table.AddColumn(weightColumnConfig, dataProjection.Compose(ProjectWeight));
            table.AddColumn(percentWeightColumnConfig, dataProjection.Compose(ProjectPercentWeight));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig1.InitialSelectionQuery = "[Series Name]:=\"Connection\" OR [Series Name]:=\"Reason\"";
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableConfig2.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig2.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig2.InitialSelectionQuery = "[Series Name]:=\"Reason\"";
            tableBuilder.AddTableConfiguration(tableConfig2);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
Beispiel #2
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            var data = quicState.Connections.SelectMany(
                x => x.GetRawTputEvents().Select(y => new ValueTuple <QuicConnection, QuicRawTputData>(x, y))).ToArray();

            var table          = tableBuilder.SetRowCount(data.Length);
            var dataProjection = Projection.Index(data);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(typeColumnConfig, dataProjection.Compose(ProjectType));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));
            table.AddColumn(bitsColumnConfig, dataProjection.Compose(ProjectBits));
            table.AddColumn(bytesColumnConfig, dataProjection.Compose(ProjectBytes));
            table.AddColumn(rttColumnConfig, dataProjection.Compose(ProjectRtt));
            table.AddColumn(txDelayColumnConfig, dataProjection.Compose(ProjectTxDelay));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.InitialSelectionQuery = "[Type]:=\"Tx\" OR [Type]:=\"Rx\"";
            tableConfig1.InitialFilterQuery    = "[Type]:<>\"Tx\" AND [Type]:<>\"PktCreate\" AND [Type]:<>\"TxAck\" AND [Type]:<>\"Rx\"";
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableConfig2.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig2.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig2.InitialSelectionQuery = "[Type]:=\"InFlight\"";
            tableConfig2.InitialFilterQuery    =
                "[Type]:=\"Tx\" OR [Type]:=\"TxAck\" OR [Type]:=\"PktCreate\" OR [Type]:=\"Rx\" OR [Type]:=\"Rtt\" OR [Type]:=\"TxDelay\"";
            tableBuilder.AddTableConfiguration(tableConfig2);

            tableConfig3.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig3.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig3.InitialFilterQuery = "[Type]:<>\"Rtt\"";
            tableBuilder.AddTableConfiguration(tableConfig3);

            tableConfig4.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig4.InitialSelectionQuery = "[Type]:=\"Tx\" OR [Type]:=\"Rx\"";
            tableConfig4.InitialFilterQuery    =
                "[Type]:<>\"Tx\" AND [Type]:<>\"TxAck\" AND [Type]:<>\"PktCreate\" AND [Type]:<>\"Rx\"";
            tableBuilder.AddTableConfiguration(tableConfig4);

            tableConfig5.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig5.InitialFilterQuery = "[Type]:<>\"TxDelay\"";
            tableBuilder.AddTableConfiguration(tableConfig5);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
Beispiel #3
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var connections = quicState.Connections;

            if (connections.Count == 0)
            {
                return;
            }

            var data = connections.SelectMany(
                x => x.GetExecutionEvents().Select(
                    y => new ValueTuple <QuicConnection, QuicExecutionData>(x, y))).ToArray();

            var table          = tableBuilder.SetRowCount(data.Length);
            var dataProjection = Projection.Index(data);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(threadIdColumnConfig, dataProjection.Compose(ProjectThreadId));
            table.AddColumn(cpuColumnConfig, dataProjection.Compose(ProjectCpu));
            table.AddColumn(nameColumnConfig, dataProjection.Compose(ProjectName));
            table.AddColumn(countColumnConfig, Projection.Constant <uint>(1));
            table.AddColumn(weightColumnConfig, dataProjection.Compose(ProjectWeight));
            table.AddColumn(percentWeightColumnConfig, dataProjection.Compose(ProjectPercentWeight));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            //tableConfig1.InitialExpansionQuery = "[Series Name]:=\"Process (ID)\"";
            //tableConfig1.InitialSelectionQuery = "[Series Name]:=\"Connection\" OR [Series Name]:=\"State\"";
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableConfig2.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig2.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig2.AddColumnRole(ColumnRole.ResourceId, cpuColumnConfig);
            //tableConfig2.InitialExpansionQuery = "[Series Name]:=\"Process (ID)\"";
            //tableConfig2.InitialSelectionQuery = "[Series Name]:=\"State\"";
            tableBuilder.AddTableConfiguration(tableConfig2);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
Beispiel #4
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoPackageListEvent> >(
                new DataOutputPath(PerfettoPluginConstants.PackageListCookerPath, nameof(PerfettoPackageListCooker.PackageListEvents)));

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            tableGenerator.AddColumn(PackageNameColumn, baseProjection.Compose(x => x.PackageName));
            tableGenerator.AddColumn(UidColumn, baseProjection.Compose(x => x.Uid));
            tableGenerator.AddColumn(DebuggableColumn, baseProjection.Compose(x => x.Debuggable));
            tableGenerator.AddColumn(ProfileableFromShellColumn, baseProjection.Compose(x => x.ProfileableFromShell));
            tableGenerator.AddColumn(VersionCodeColumn, baseProjection.Compose(x => x.VersionCode));

            // Default
            List <ColumnConfiguration> defaultColumns = new List <ColumnConfiguration>()
            {
                PackageNameColumn,
                TableConfiguration.PivotColumn,     // Columns before this get pivotted on
                UidColumn,
                VersionCodeColumn,
                ProfileableFromShellColumn,
                TableConfiguration.GraphColumn,
            };

            var packageListDefaultConfig = new TableConfiguration("Default")
            {
                Columns   = defaultColumns,
                ChartType = ChartType.Line
            };

            tableBuilder.AddTableConfiguration(packageListDefaultConfig)
            .SetDefaultTableConfiguration(packageListDefaultConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var events = quicState.Events
                         .Where(x => x.EventId == QuicEventId.DatapathSend || x.EventId == QuicEventId.DatapathRecv).ToArray();

            if (events.Length == 0)
            {
                return;
            }

            var table          = tableBuilder.SetRowCount(events.Length);
            var dataProjection = Projection.Index(events);

            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(cpuColumnConfig, dataProjection.Compose(ProjectCPU));
            table.AddColumn(typeColumnConfig, dataProjection.Compose(ProjectType));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(bytesColumnConfig, dataProjection.Compose(ProjectBytes));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
Beispiel #6
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoGpuCountersEvent> >(
                new DataOutputPath(PerfettoPluginConstants.GpuCountersEventCookerPath, nameof(PerfettoGpuCountersEventCooker.GpuCountersEvents)));

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            tableGenerator.AddColumn(NameColumn, baseProjection.Compose(x => x.Name));
            tableGenerator.AddColumn(ValueColumn, baseProjection.Compose(x => x.Value));
            tableGenerator.AddColumn(StartTimestampColumn, baseProjection.Compose(x => x.StartTimestamp));
            tableGenerator.AddColumn(DurationColumn, baseProjection.Compose(x => x.Duration));

            var tableConfig = new TableConfiguration("GPU Counters")
            {
                Columns = new[]
                {
                    NameColumn,
                    TableConfiguration.PivotColumn, // Columns before this get pivotted on
                    StartTimestampColumn,
                    DurationColumn,
                    TableConfiguration.GraphColumn, // Columns after this get graphed
                    ValueColumn
                },
                ChartType = ChartType.Line
            };

            tableConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn.Metadata.Guid);
            tableConfig.AddColumnRole(ColumnRole.Duration, DurationColumn);

            tableBuilder
            .AddTableConfiguration(tableConfig)
            .SetDefaultTableConfiguration(tableConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var events = quicState.Events
                         .Where(x => x.ID == QuicEventId.StreamCreated || x.ID == QuicEventId.StreamDestroyed).ToArray();

            if (events.Length == 0)
            {
                return;
            }

            var table          = tableBuilder.SetRowCount(events.Length);
            var dataProjection = Projection.Index(events);

            table.AddColumn(typeColumnConfig, dataProjection.Compose(ProjectType));
            table.AddColumn(countColumnConfig, Projection.Constant <uint>(1));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var messages = tableData.QueryOutput <IReadOnlyList <IDiagnosticMessage> >(
                DataOutputPath.ForSource(LTTngConstants.SourceId, LTTngDmesgDataCooker.Identifier, nameof(LTTngDmesgDataCooker.DiagnosticMessages)));

            if (messages.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("MessagesByTimestamp")
            {
                Columns = new[]
                {
                    messageColumn,
                    TableConfiguration.PivotColumn,
                    TableConfiguration.GraphColumn,
                    timestampColumn
                },
            };

            config.AddColumnRole(ColumnRole.StartTime, timestampColumn);
            config.AddColumnRole(ColumnRole.EndTime, timestampColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(messages.Count);

            table.AddColumn(messageColumn, Projection.CreateUsingFuncAdaptor((i) => messages[i].Message));
            table.AddColumn(timestampColumn, Projection.CreateUsingFuncAdaptor((i) => messages[i].Timestamp));
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoFrameEvent> >(
                new DataOutputPath(PerfettoPluginConstants.FrameEventCookerPath, nameof(PerfettoFrameEventCooker.FrameEvents)));

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            var startProjection = baseProjection.Compose(x => x.StartTimestamp);
            var endProjection   = baseProjection.Compose(x => x.EndTimestamp);

            tableGenerator.AddColumn(ProcessNameColumn, baseProjection.Compose(x => x.ProcessName));
            tableGenerator.AddColumn(ProcessIdColumn, baseProjection.Compose(x => x.Upid));
            tableGenerator.AddColumn(FrameTypeColumn, baseProjection.Compose(x => x.FrameType));
            tableGenerator.AddColumn(JankTypeColumn, baseProjection.Compose(x => x.JankType));
            tableGenerator.AddColumn(OnTimeFinishColumn, baseProjection.Compose(x => x.OnTimeFinish));
            tableGenerator.AddColumn(DurationColumn, baseProjection.Compose(x => x.Duration));
            tableGenerator.AddColumn(DisplayTokenColumn, baseProjection.Compose(x => x.DisplayFrameToken));
            tableGenerator.AddColumn(SurfaceTokenColumn, baseProjection.Compose(x => x.SurfaceFrameToken));
            tableGenerator.AddColumn(PresentTypeColumn, baseProjection.Compose(x => x.PresentType));
            tableGenerator.AddColumn(PredictionTypeColumn, baseProjection.Compose(x => x.PredictionType));
            tableGenerator.AddColumn(GpuCompositionColumn, baseProjection.Compose(x => x.GpuComposition));
            tableGenerator.AddColumn(JankTagColumn, baseProjection.Compose(x => x.JankTag));
            tableGenerator.AddColumn(StartTimestampColumn, startProjection);
            tableGenerator.AddColumn(EndTimestampColumn, endProjection);


            var jankFramesConfig = new TableConfiguration("Expected/Actual Frames by Process")
            {
                Columns = new[]
                {
                    ProcessNameColumn,
                    DisplayTokenColumn,
                    SurfaceTokenColumn,
                    FrameTypeColumn,
                    TableConfiguration.PivotColumn, // Columns before this get pivotted on
                    PresentTypeColumn,
                    OnTimeFinishColumn,
                    PredictionTypeColumn,
                    JankTypeColumn,
                    JankTagColumn,
                    GpuCompositionColumn,
                    ProcessIdColumn,
                    DurationColumn,
                    TableConfiguration.GraphColumn, // Columns after this get graphed
                    StartTimestampColumn,
                    EndTimestampColumn
                },
            };

            jankFramesConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn.Metadata.Guid);
            jankFramesConfig.AddColumnRole(ColumnRole.EndTime, EndTimestampColumn.Metadata.Guid);
            jankFramesConfig.AddColumnRole(ColumnRole.Duration, DurationColumn.Metadata.Guid);

            tableBuilder
            .AddTableConfiguration(jankFramesConfig)
            .SetDefaultTableConfiguration(jankFramesConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            WaLinuxAgentLogParsedResult parsedResult = tableData.QueryOutput <WaLinuxAgentLogParsedResult>(
                DataOutputPath.Create(SourceParserIds.WaLinuxAgentLog, WaLinuxAgentDataCooker.CookerId, "ParsedResult"));
            var logEntries = parsedResult.LogEntries;

            var baseProjection = Projection.Index(logEntries);

            var fileNameProjection   = baseProjection.Compose(x => x.FilePath);
            var lineNumberProjection = baseProjection.Compose(x => x.LineNumber);
            var eventTimeProjection  = baseProjection.Compose(x => x.EventTimestamp);
            var logLevelProjection   = baseProjection.Compose(x => x.LogLevel);
            var logProjection        = baseProjection.Compose(x => x.Log);

            //
            // Table Configurations describe how your table should be presented to the user:
            // the columns to show, what order to show them, which columns to aggregate, and which columns to graph.
            // You may provide a number of columns in your table, but only want to show a subset of them by default so as not to overwhelm the user.
            // The user can still open the table properties in UI to turn on or off columns.
            // The table configuration class also exposes four (4) columns that UI explicitly recognizes: Pivot Column, Graph Column, Left Freeze Column, Right Freeze Column
            // For more information about what these columns do, go to "Advanced Topics" -> "Table Configuration" in our Wiki. Link can be found in README.md
            //

            var config = new TableConfiguration("Default")
            {
                Columns = new[]
                {
                    LogLevelColumn,
                    TableConfiguration.PivotColumn,
                    LineNumberColumn,
                    LogColumn,
                    EventTimestampDateTimeColumn,
                    TableConfiguration.GraphColumn,
                    EventTimestampColumn,
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, EventTimestampColumn);

            //
            //
            //  Use the table builder to build the table.
            //  Add and set table configuration if applicable.
            //  Then set the row count (we have one row per file) and then add the columns using AddColumn.
            //
            tableBuilder
            .AddTableConfiguration(config)
            .SetDefaultTableConfiguration(config)
            .SetRowCount(logEntries.Count)
            .AddColumn(FileNameColumn, fileNameProjection)
            .AddColumn(LineNumberColumn, lineNumberProjection)
            .AddColumn(EventTimestampColumn, eventTimeProjection)
            .AddColumn(LogLevelColumn, logLevelProjection)
            .AddColumn(LogColumn, logProjection);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var threads = tableData.QueryOutput <IReadOnlyList <IThread> >(
                DataOutputPath.Create(LTTngThreadDataCooker.CookerPath + "/Threads"));

            if (threads.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("ThreadsByProcessId")
            {
                Columns = new[]
                {
                    processIdColumn,
                    threadIdColumn,
                    commandColumn,
                    TableConfiguration.PivotColumn,
                    threadExecTimeColumn,
                    threadReadyTimeColumn,
                    threadRunningTimeColumn,
                    threadSleepTimeColumn,
                    threadDiskSleepTimeColumn,
                    threadWaitingTimeColumn,
                    threadIdleTimeColumn,
                    TableConfiguration.GraphColumn,
                    threadStartTimeColumn,
                    threadExitTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, threadStartTimeColumn);
            config.AddColumnRole(ColumnRole.EndTime, threadExitTimeColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(threads.Count);

            table.AddColumn(threadIdColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ThreadId));
            table.AddColumn(processIdColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ProcessId));
            table.AddColumn(commandColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].Command));
            table.AddColumn(threadExecTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExecTime));
            table.AddColumn(threadReadyTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyTime));
            table.AddColumn(threadRunningTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExecTime + threads[i].ReadyTime));
            table.AddColumn(threadSleepTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].SleepTime));
            table.AddColumn(threadDiskSleepTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].DiskSleepTime));
            table.AddColumn(threadWaitingTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].SleepTime + threads[i].DiskSleepTime));
            table.AddColumn(threadStoppedTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].StoppedTime));
            table.AddColumn(threadParkedTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ParkedTime));
            table.AddColumn(threadIdleTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].IdleTime));
            table.AddColumn(threadStartTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].StartTime));
            table.AddColumn(threadExitTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExitTime));
            table.AddColumn(threadLifespanColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExitTime - threads[i].StartTime));
        }
Beispiel #12
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var data = quicState.GetApiCalls();

            if (data.Count == 0)
            {
                return;
            }

            var table          = tableBuilder.SetRowCount(data.Count);
            var dataProjection = Projection.Index(data);

            table.AddColumn(typeColumnConfig, dataProjection.Compose(ProjectType));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(threadIdColumnConfig, dataProjection.Compose(ProjectThreadId));
            table.AddColumn(cpuColumnConfig, dataProjection.Compose(ProjectCpu));
            table.AddColumn(pointerColumnConfig, dataProjection.Compose(ProjectPointer));
            table.AddColumn(resultColumnConfig, dataProjection.Compose(ProjectResult));
            table.AddColumn(countColumnConfig, Projection.Constant <uint>(1));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableConfig2.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig2.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableBuilder.AddTableConfiguration(tableConfig2);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            CloudInitLogParsedResult parsedResult = tableData.QueryOutput <CloudInitLogParsedResult>(
                DataOutputPath.Create(SourceParserIds.CloudInitLog, CloudInitDataCooker.CookerId, "ParsedResult"));
            var logEntries = parsedResult.LogEntries;

            var baseProjection = Projection.Index(logEntries);

            var fileNameProjection   = baseProjection.Compose(x => x.FilePath);
            var lineNumberProjection = baseProjection.Compose(x => x.LineNumber);
            var eventTimeProjection  = baseProjection.Compose(x => x.EventTimestamp);
            var pythonFileProjection = baseProjection.Compose(x => x.PythonFile);
            var logLevelProjection   = baseProjection.Compose(x => x.LogLevel);
            var logProjection        = baseProjection.Compose(x => x.Log);

            var config = new TableConfiguration("Default")
            {
                Columns = new[]
                {
                    FileNameColumn,
                    LogLevelColumn,
                    TableConfiguration.PivotColumn,
                    PythonFileColumn,
                    LineNumberColumn,
                    LogColumn,
                    EventTimestampDateTimeColumn,
                    TableConfiguration.GraphColumn,
                    EventTimestampColumn,
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, EventTimestampColumn);

            //
            //
            //  Use the table builder to build the table.
            //  Add and set table configuration if applicable.
            //  Then set the row count (we have one row per file) and then add the columns using AddColumn.
            //
            tableBuilder
            .AddTableConfiguration(config)
            .SetDefaultTableConfiguration(config)
            .SetRowCount(logEntries.Count)
            .AddColumn(FileNameColumn, fileNameProjection)
            .AddColumn(LineNumberColumn, lineNumberProjection)
            .AddColumn(EventTimestampColumn, eventTimeProjection)
            .AddColumn(PythonFileColumn, pythonFileProjection)
            .AddColumn(LogLevelColumn, logLevelProjection)
            .AddColumn(LogColumn, logProjection)
            ;
        }
Beispiel #14
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var parsedResult = tableData.QueryOutput <AndroidLogcatParsedResult>(
                DataOutputPath.ForSource(SourceParserIds.AndroidLogcatLog, AndroidLogcatDataCooker.CookerId, nameof(AndroidLogcatDataCooker.ParsedResult)));
            var logEntries = parsedResult.LogEntries;

            var baseProjection = Projection.Index(logEntries);

            var timestampProjection  = baseProjection.Compose(x => x.Timestamp);
            var fileNameProjection   = baseProjection.Compose(x => x.FilePath);
            var lineNumberProjection = baseProjection.Compose(x => x.LineNumber);
            var pidProjection        = baseProjection.Compose(x => x.PID);
            var tidProjection        = baseProjection.Compose(x => x.TID);
            var priorityProjection   = baseProjection.Compose(x => x.Priority);
            var tagProjection        = baseProjection.Compose(x => x.Tag);
            var messageProjection    = baseProjection.Compose(x => x.Message);

            var config = new TableConfiguration("Default")
            {
                Columns = new[]
                {
                    FileNameColumn,
                    TableConfiguration.PivotColumn,
                    LineNumberColumn,
                    TimestampAbsColumn,
                    PIDColumn,
                    TIDColumn,
                    PriorityColumn,
                    TagColumn,
                    MessageColumn,
                    TableConfiguration.RightFreezeColumn,
                    TableConfiguration.GraphColumn,
                    TimestampColumn
                },
            };

            config.AddColumnRole(ColumnRole.StartTime, TimestampColumn);

            tableBuilder.AddTableConfiguration(config)
            .SetDefaultTableConfiguration(config)
            .SetRowCount(logEntries.Count)
            .AddColumn(FileNameColumn, fileNameProjection)
            .AddColumn(LineNumberColumn, lineNumberProjection)
            .AddColumn(PIDColumn, pidProjection)
            .AddColumn(TIDColumn, pidProjection)
            .AddColumn(PriorityColumn, priorityProjection)
            .AddColumn(MessageColumn, messageProjection)
            .AddColumn(TimestampColumn, timestampProjection)
            .AddColumn(TagColumn, tagProjection);
        }
Beispiel #15
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var connections = quicState.Connections;

            if (connections.Count == 0)
            {
                return;
            }

            var data = new List <Data>();

            foreach (var conn in connections)
            {
                foreach (var evt in conn.GetThroughputEvents())
                {
                    data.Add(new Data(conn, "InFlight", evt.TimeStamp, evt.Duration, evt.BytesInFlight));
                    data.Add(new Data(conn, "Buffered", evt.TimeStamp, evt.Duration, evt.BytesBufferedForSend));
                    data.Add(new Data(conn, "CongestionWindow", evt.TimeStamp, evt.Duration, evt.CongestionWindow));
                    data.Add(new Data(conn, "ConnectionFlowControl", evt.TimeStamp, evt.Duration, evt.FlowControlAvailable));
                    data.Add(new Data(conn, "StreamFlowControl", evt.TimeStamp, evt.Duration, evt.StreamFlowControlAvailable));
                }
            }

            var table          = tableBuilder.SetRowCount(data.Count);
            var dataProjection = Projection.Index(data);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(typeColumnConfig, dataProjection.Compose(ProjectType));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));
            table.AddColumn(bytesColumnConfig, dataProjection.Compose(ProjectBytes));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig1.InitialSelectionQuery = "[Type]:=\"InFlight\"";
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var syscalls = tableData.QueryOutput <IReadOnlyList <ISyscall> >(
                DataOutputPath.Create(LTTngSyscallDataCooker.CookerPath + '/' + nameof(LTTngSyscallDataCooker.Syscalls)));

            if (syscalls.Count == 0)
            {
                return;
            }

            var defaultConfig = new TableConfiguration("Individual Syscalls")
            {
                Columns = new[]
                {
                    syscallNumberColumn,
                    TableConfiguration.PivotColumn,
                    syscallNameColumn,
                    syscallDurationColumn,
                    syscallArgumentsColumn,
                    syscallReturnValueColumn,
                    syscallThreadIdColumn,
                    syscallCommandColumn,
                    syscallProcessIdColumn,
                    TableConfiguration.GraphColumn,
                    syscallStartTimeColumn,
                    syscallEndTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            defaultConfig.AddColumnRole(ColumnRole.StartTime, syscallStartTimeColumn);
            defaultConfig.AddColumnRole(ColumnRole.EndTime, syscallEndTimeColumn);

            var table = tableBuilder.AddTableConfiguration(defaultConfig)
                        .SetDefaultTableConfiguration(defaultConfig)
                        .SetRowCount(syscalls.Count);

            table.AddColumn(syscallNameColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].Name));
            table.AddColumn(syscallThreadIdColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ThreadId));
            table.AddColumn(syscallProcessIdColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ProcessId));
            table.AddColumn(syscallCommandColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ProcessCommand));
            table.AddColumn(syscallNumberColumn, Projection.CreateUsingFuncAdaptor((i) => i + 1));
            table.AddColumn(syscallStartTimeColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].StartTime));
            table.AddColumn(syscallEndTimeColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].EndTime));
            table.AddColumn(syscallDurationColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].EndTime - syscalls[i].StartTime));
            table.AddColumn(syscallReturnValueColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ReturnValue));
            table.AddColumn(syscallArgumentsColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].Arguments));
        }
Beispiel #17
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            DmesgIsoLogParsedResult parsedResult = tableData.QueryOutput <DmesgIsoLogParsedResult>(
                DataOutputPath.Create(SourceParserIds.DmesgIsoLog, DmesgIsoDataCooker.CookerId, "ParsedResult"));
            var logEntries = parsedResult.LogEntries;

            var baseProjection = Projection.Index(logEntries);

            var fileNameProjection   = baseProjection.Compose(x => x.filePath);
            var lineNumberProjection = baseProjection.Compose(x => x.lineNumber);
            var entityProjection     = baseProjection.Compose(x => x.entity);
            var topicProjection      = baseProjection.Compose(x => x.topic);
            var timestampProjection  = baseProjection.Compose(x => x.timestamp);
            var metadataProjection   = baseProjection.Compose(x => x.metadata);
            var messageProjection    = baseProjection.Compose(x => x.message);

            var config = new TableConfiguration("Default")
            {
                Columns = new[]
                {
                    FileNameColumn,
                    EntityColumn,
                    TableConfiguration.PivotColumn,
                    MessageNumberColumn,
                    TopicColumn,
                    MessageColumn,
                    MetadataColumn,
                    TableConfiguration.GraphColumn,
                    TimestampColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, TimestampColumn);
            config.AddColumnRole(ColumnRole.EndTime, TimestampColumn);

            tableBuilder.AddTableConfiguration(config)
            .SetDefaultTableConfiguration(config)
            .SetRowCount(logEntries.Count)
            .AddColumn(FileNameColumn, fileNameProjection)
            .AddColumn(MessageNumberColumn, lineNumberProjection)
            .AddColumn(EntityColumn, entityProjection)
            .AddColumn(TopicColumn, topicProjection)
            .AddColumn(MessageColumn, messageProjection)
            .AddColumn(TimestampColumn, timestampProjection)
            .AddColumn(MetadataColumn, metadataProjection);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var fileEvents = tableData.QueryOutput <IReadOnlyList <IFileEvent> >(
                DataOutputPath.Create(LTTngDiskDataCooker.CookerPath + '/' + nameof(LTTngDiskDataCooker.FileEvents)));

            if (fileEvents.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("EventsBySyscallType")
            {
                Columns = new[]
                {
                    fileEventNameColumn,
                    TableConfiguration.PivotColumn,
                    fileEventThreadIdColumn,
                    fileEventProcessIdColumn,
                    fileEventCommandColumn,
                    fileEventFilePathColumn,
                    fileEventSizeColumn,
                    fileEventDurationColumn,
                    TableConfiguration.GraphColumn,
                    fileEventStartTimeColumn,
                    fileEventEndTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, fileEventStartTimeColumn);
            config.AddColumnRole(ColumnRole.EndTime, fileEventEndTimeColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(fileEvents.Count);

            table.AddColumn(fileEventNameColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].Name));
            table.AddColumn(fileEventThreadIdColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].ThreadId));
            table.AddColumn(fileEventProcessIdColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].ProcessId));
            table.AddColumn(fileEventCommandColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].ProcessCommand));
            table.AddColumn(fileEventFilePathColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].Filepath));
            table.AddColumn(fileEventStartTimeColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].StartTime));
            table.AddColumn(fileEventEndTimeColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].EndTime));
            table.AddColumn(fileEventDurationColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].EndTime - fileEvents[i].StartTime));
            table.AddColumn(fileEventSizeColumn, new FileActivitySizeProjection(Projection.CreateUsingFuncAdaptor((i) => fileEvents[i])));
        }
Beispiel #19
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var connections = quicState.Connections;

            if (connections.Count == 0)
            {
                return;
            }

            var data = new List <Data>();

            foreach (var conn in connections)
            {
                foreach (var evt in conn.GetThroughputEvents())
                {
                    data.Add(new Data(conn, true, evt.TimeStamp, evt.Duration, evt.TxRate));
                    data.Add(new Data(conn, false, evt.TimeStamp, evt.Duration, evt.RxRate));
                }
            }

            var table          = tableBuilder.SetRowCount(data.Count);
            var dataProjection = Projection.Index(data);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(typeColumnConfig, dataProjection.Compose(ProjectType));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));
            table.AddColumn(rateColumnConfig, dataProjection.Compose(ProjectRate));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig1.InitialSelectionQuery = "[Series Name]:=\"Type\"";
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var moduleEvents = tableData.QueryOutput <IReadOnlyList <IModuleEvent> >(
                DataOutputPath.Create(LTTngModuleDataCooker.CookerPath + '/' + nameof(LTTngModuleDataCooker.ModuleEvents)));

            if (moduleEvents.Count == 0)
            {
                return;
            }

            var defaultConfig = new TableConfiguration("Module Events")
            {
                Columns = new[]
                {
                    moduleNameColumn,
                    eventTypeColumn,
                    TableConfiguration.PivotColumn,
                    instructionPointerColumn,
                    refCountColumn,
                    threadIdColumn,
                    processIdColumn,
                    commandColumn,
                    TableConfiguration.GraphColumn,
                    timestampColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            defaultConfig.AddColumnRole(ColumnRole.StartTime, timestampColumn);
            defaultConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);

            var table = tableBuilder.AddTableConfiguration(defaultConfig)
                        .SetDefaultTableConfiguration(defaultConfig)
                        .SetRowCount(moduleEvents.Count);

            table.AddColumn(eventTypeColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].EventType));
            table.AddColumn(moduleNameColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ModuleName));
            table.AddColumn(instructionPointerColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].InstructionPointer));
            table.AddColumn(refCountColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].RefCount));
            table.AddColumn(threadIdColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ThreadId));
            table.AddColumn(processIdColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ProcessId));
            table.AddColumn(commandColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ProcessCommand));
            table.AddColumn(timestampColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].Time));
        }
Beispiel #21
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoCpuFrequencyEvent> >(
                new DataOutputPath(PerfettoPluginConstants.CpuFrequencyEventCookerPath, nameof(PerfettoCpuFrequencyEventCooker.CpuFrequencyEvents)));

            // Start construction of the column order. Pivot on process and thread
            List <ColumnConfiguration> allColumns = new List <ColumnConfiguration>()
            {
                CpuNumColumn,
                TableConfiguration.PivotColumn, // Columns before this get pivotted on
                StartTimestampColumn,
                CpuStateColumn,
                DurationColumn,
                IsIdleColumn,
                TableConfiguration.GraphColumn, // Columns after this get graphed
                CpuFrequencyColumn
            };

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            tableGenerator.AddColumn(CpuNumColumn, baseProjection.Compose(x => x.CpuNum));
            tableGenerator.AddColumn(CpuFrequencyColumn, baseProjection.Compose(x => x.CpuFrequency));
            tableGenerator.AddColumn(StartTimestampColumn, baseProjection.Compose(x => x.StartTimestamp));
            tableGenerator.AddColumn(CpuStateColumn, baseProjection.Compose(x => x.Name));
            tableGenerator.AddColumn(DurationColumn, baseProjection.Compose(x => x.Duration));
            tableGenerator.AddColumn(IsIdleColumn, baseProjection.Compose(x => x.IsIdle));

            // We are graphing CPU frequency + duration with MAX accumulation, which gives a steady line graph of the current CPU frequency
            var tableConfig = new TableConfiguration("CPU Frequency")
            {
                Columns   = allColumns,
                ChartType = ChartType.Line
            };

            tableConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn.Metadata.Guid);
            tableConfig.AddColumnRole(ColumnRole.ResourceId, CpuNumColumn);
            tableConfig.AddColumnRole(ColumnRole.Duration, DurationColumn);

            tableBuilder.AddTableConfiguration(tableConfig).SetDefaultTableConfiguration(tableConfig);
        }
        internal static void BuildMetadataTable(ITableBuilder tableBuilder, LTTngSourceParser sourceParser, ITableConfigurationsSerializer serializer)
        {
            ITableBuilderWithRowCount table = tableBuilder.SetRowCount(sourceParser.TraceStats.Count);

            IReadOnlyList <string> eventNames = sourceParser.TraceStats.Keys.ToList();

            var eventNameProjection       = Projection.CreateUsingFuncAdaptor(x => eventNames[x]);
            var traceStatsProjection      = eventNameProjection.Compose(eventName => sourceParser.TraceStats[eventName]);
            var eventCountProjection      = traceStatsProjection.Compose(traceStats => traceStats.EventCount);
            var payloadBitCountProjection = traceStatsProjection.Compose(traceStats => (double)traceStats.PayloadBitCount / 8);

            table.AddColumn(
                new DataColumn <string>(
                    EventNameConfiguration,
                    eventNameProjection));

            table.AddColumn(
                new DataColumn <ulong>(
                    CountConfiguration,
                    eventCountProjection));

            table.AddColumn(
                new DataColumn <double>(
                    TotalPayloadSizeConfiguration,
                    payloadBitCountProjection));

            var configurations = TableConfigurations.GetPrebuiltTableConfigurations(
                typeof(TraceStatsTable),
                TableDescriptor.Guid,
                serializer);

            foreach (var configuration in configurations)
            {
                tableBuilder.AddTableConfiguration(configuration);
                if (StringComparer.Ordinal.Equals(configuration.Name, configurations.DefaultConfigurationName))
                {
                    tableBuilder.SetDefaultTableConfiguration(configuration);
                }
            }
        }
Beispiel #23
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var connections = quicState.Connections;

            if (connections.Count == 0)
            {
                return;
            }

            var table          = tableBuilder.SetRowCount(connections.Count);
            var dataProjection = Projection.Index(connections);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(pointerColumnConfig, dataProjection.Compose(ProjectPointer));
            table.AddColumn(correlationIdColumnConfig, dataProjection.Compose(ProjectCorrelationId));
            table.AddColumn(isServerColumnConfig, dataProjection.Compose(ProjectIsServer));
            table.AddColumn(stateColumnConfig, dataProjection.Compose(ProjectState));
            table.AddColumn(bytesSentColumnConfig, dataProjection.Compose(ProjectBytesSent));
            table.AddColumn(bytesReceivedColumnConfig, dataProjection.Compose(ProjectBytesReceived));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableConfig1.InitialExpansionQuery = "[Series Name]:=\"Process (ID)\"";
            tableConfig1.InitialSelectionQuery = "[Series Name]:=\"Connection\"";
            tableBuilder.AddTableConfiguration(tableConfig1);
            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
Beispiel #24
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoLogcatEvent> >(
                new DataOutputPath(PerfettoPluginConstants.LogcatEventCookerPath, nameof(PerfettoLogcatEventCooker.LogcatEvents)));

            // Start construction of the column order. Pivot on process and thread
            List <ColumnConfiguration> allColumns = new List <ColumnConfiguration>()
            {
                ProcessNameColumn,
                ThreadNameColumn,
                TagColumn,
                MessageColumn,
                PriorityColumn,
                TableConfiguration.GraphColumn, // Columns after this get graphed
                StartTimestampColumn
            };

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            tableGenerator.AddColumn(StartTimestampColumn, baseProjection.Compose(x => x.StartTimestamp));
            tableGenerator.AddColumn(ProcessNameColumn, baseProjection.Compose(x => x.ProcessName));
            tableGenerator.AddColumn(ThreadNameColumn, baseProjection.Compose(x => x.ThreadName));
            tableGenerator.AddColumn(PriorityColumn, baseProjection.Compose(x => x.Priority));
            tableGenerator.AddColumn(TagColumn, baseProjection.Compose(x => x.Tag));
            tableGenerator.AddColumn(MessageColumn, baseProjection.Compose(x => x.Message));

            var tableConfig = new TableConfiguration("Logcat Events")
            {
                Columns = allColumns,
            };

            tableConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn.Metadata.Guid);

            tableBuilder.AddTableConfiguration(tableConfig).SetDefaultTableConfiguration(tableConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            DmesgIsoLogParsedResult parsedResult = tableData.QueryOutput <DmesgIsoLogParsedResult>(
                DataOutputPath.ForSource(SourceParserIds.DmesgIsoLog, DmesgIsoDataCooker.CookerId, nameof(DmesgIsoDataCooker.ParsedResult)));
            var logEntries = parsedResult.LogEntries;

            var baseProjection = Projection.Index(logEntries);

            var fileNameProjection  = baseProjection.Compose(x => x.filePath);
            var logNumberProjection = baseProjection.Compose(x => x.lineNumber);
            var timestampProjection = baseProjection.Compose(x => x.timestamp);
            var rawLogProjection    = baseProjection.Compose(x => x.rawLog);

            var columnsConfig = new TableConfiguration("Default")
            {
                Columns = new[]
                {
                    FileNameColumn,
                    TableConfiguration.PivotColumn,
                    LogNumberColumn,
                    LogColumn,
                    TableConfiguration.GraphColumn,
                    LogTimestampColumn
                },
            };

            columnsConfig.AddColumnRole(ColumnRole.StartTime, LogTimestampColumn);
            columnsConfig.AddColumnRole(ColumnRole.EndTime, LogTimestampColumn);

            tableBuilder.AddTableConfiguration(columnsConfig)
            .SetDefaultTableConfiguration(columnsConfig)
            .SetRowCount(logEntries.Count)
            .AddColumn(FileNameColumn, fileNameProjection)
            .AddColumn(LogNumberColumn, logNumberProjection)
            .AddColumn(LogColumn, rawLogProjection)
            .AddColumn(LogTimestampColumn, timestampProjection);
        }
Beispiel #26
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            Debug.Assert(!(tableBuilder is null) && !(tableData is null));

            var quicState = tableData.QueryOutput <QuicState>(new DataOutputPath(QuicEventCooker.CookerPath, "State"));

            if (quicState == null)
            {
                return;
            }

            var connections = quicState.Connections;

            if (connections.Count == 0)
            {
                return;
            }

            var data = connections.SelectMany(
                x => x.GetThroughputEvents().Select(
                    y => new ValueTuple <QuicConnection, QuicThroughputData>(x, y))).ToArray();

            var table          = tableBuilder.SetRowCount(data.Length);
            var dataProjection = Projection.Index(data);

            table.AddColumn(connectionColumnConfig, dataProjection.Compose(ProjectId));
            table.AddColumn(processIdColumnConfig, dataProjection.Compose(ProjectProcessId));
            table.AddColumn(timeColumnConfig, dataProjection.Compose(ProjectTime));
            table.AddColumn(durationColumnConfig, dataProjection.Compose(ProjectDuration));
            table.AddColumn(rttColumnConfig, dataProjection.Compose(ProjectRate));

            tableConfig1.AddColumnRole(ColumnRole.StartTime, timeColumnConfig);
            tableConfig1.AddColumnRole(ColumnRole.Duration, durationColumnConfig);
            tableBuilder.AddTableConfiguration(tableConfig1);

            tableBuilder.SetDefaultTableConfiguration(tableConfig1);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // We dynamically adjust the column headers
            // This is the max number of fields we can expect for this table
            int maxFieldCount = Math.Min(AbsoluteMaxFields, tableData.QueryOutput <int>(
                                             new DataOutputPath(PerfettoPluginConstants.FtraceEventCookerPath, nameof(PerfettoFtraceEventCooker.MaximumEventFieldCount))));

            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoFtraceEvent> >(
                new DataOutputPath(PerfettoPluginConstants.FtraceEventCookerPath, nameof(PerfettoFtraceEventCooker.FtraceEvents)));

            var tableGenerator  = tableBuilder.SetRowCount((int)events.Count);
            var eventProjection = new EventProjection <PerfettoFtraceEvent>(events);

            var processNameColumn = new DataColumn <string>(
                ProcessNameColumn,
                eventProjection.Compose((ftraceEvent) => ftraceEvent.ProcessFormattedName));

            tableGenerator.AddColumn(processNameColumn);

            var threadNameColumn = new DataColumn <string>(
                ThreadNameColumn,
                eventProjection.Compose((ftraceEvent) => ftraceEvent.ThreadFormattedName));

            tableGenerator.AddColumn(threadNameColumn);

            var startTimestampColumn = new DataColumn <Timestamp>(
                StartTimestampColumn,
                eventProjection.Compose((ftraceEvent) => ftraceEvent.StartTimestamp));

            tableGenerator.AddColumn(startTimestampColumn);

            var cpuColumn = new DataColumn <uint>(
                CpuColumn,
                eventProjection.Compose((ftraceEvent) => ftraceEvent.Cpu));

            tableGenerator.AddColumn(cpuColumn);

            var nameColumn = new DataColumn <string>(
                NameColumn,
                eventProjection.Compose((ftraceEvent) => ftraceEvent.Name));

            tableGenerator.AddColumn(nameColumn);

            List <ColumnConfiguration> fieldColumns = new List <ColumnConfiguration>();

            // Add the field columns, with column names depending on the given event
            for (int index = 0; index < maxFieldCount; index++)
            {
                var    colIndex  = index; // This seems unncessary but causes odd runtime behavior if not done this way. Compiler is confused perhaps because w/o this func will index=event.FieldNames.Count every time. index is passed as ref but colIndex as value into func
                string fieldName = "Field " + (colIndex + 1);

                var eventFieldNameProjection = eventProjection.Compose((ftraceEvent) => colIndex < ftraceEvent.Args?.Count ? ftraceEvent.Args.ElementAt(colIndex).Key : string.Empty);

                // generate a column configuration
                var fieldColumnConfiguration = new ColumnConfiguration(
                    new ColumnMetadata(Common.GenerateGuidFromName(fieldName), fieldName, eventFieldNameProjection, fieldName),
                    new UIHints
                {
                    IsVisible     = true,
                    Width         = 150,
                    TextAlignment = TextAlignment.Left,
                });

                // Add this column to the column order
                fieldColumns.Add(fieldColumnConfiguration);

                var eventFieldAsStringProjection = eventProjection.Compose((ftraceEvent) => colIndex < ftraceEvent.Args?.Count ? ftraceEvent.Args.ElementAt(colIndex).Value : string.Empty);

                tableGenerator.AddColumn(fieldColumnConfiguration, eventFieldAsStringProjection);
            }

            // Start construction of the column order. Pivot on CPU
            List <ColumnConfiguration> cpuColumns = new List <ColumnConfiguration>()
            {
                CpuColumn,
                TableConfiguration.PivotColumn, // Columns before this get pivotted
                ProcessNameColumn,
                ThreadNameColumn,
                NameColumn,
            };

            cpuColumns.AddRange(fieldColumns);
            cpuColumns.Add(TableConfiguration.GraphColumn); // Columns after this get graphed
            cpuColumns.Add(StartTimestampColumn);

            var cpuConfig = new TableConfiguration("CPU")
            {
                Columns = cpuColumns,
            };

            cpuConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn.Metadata.Guid);

            // Start construction of the column order. Pivot on process and thread
            List <ColumnConfiguration> processThreadColumns = new List <ColumnConfiguration>()
            {
                ProcessNameColumn,
                ThreadNameColumn,
                NameColumn,
                TableConfiguration.PivotColumn, // Columns before this get pivotted
                CpuColumn,
            };

            processThreadColumns.AddRange(fieldColumns);
            processThreadColumns.Add(TableConfiguration.GraphColumn); // Columns after this get graphed
            processThreadColumns.Add(StartTimestampColumn);

            var processThreadConfig = new TableConfiguration("Process-Thread")
            {
                Columns = processThreadColumns,
            };

            processThreadConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn.Metadata.Guid);

            tableBuilder
            .AddTableConfiguration(cpuConfig)
            .AddTableConfiguration(processThreadConfig)
            .SetDefaultTableConfiguration(processThreadConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var threads = tableData.QueryOutput <IReadOnlyList <IExecutionEvent> >(
                DataOutputPath.ForSource(LTTngConstants.SourceId, LTTngThreadDataCooker.Identifier, nameof(LTTngThreadDataCooker.ExecutionEvents)));

            if (threads.Count == 0)
            {
                return;
            }

            const string filterIdleSamplesQuery   = "[New Thread Id]:=\"0\"";
            var          timelineByCPUTableConfig = new TableConfiguration("Timeline by CPU")
            {
                Columns = new[]
                {
                    cpuColumn,
                    nextPidColumn,
                    nextTidColumn,
                    TableConfiguration.PivotColumn,
                    nextCommandColumn,
                    previousStateColumn,
                    nextThreadPreviousSwitchOutTimeColumn,
                    previousTidColumn,
                    readyingPidColumn,
                    readyingTidColumn,
                    readyTimeColumn,
                    waitTimeColumn,
                    switchedInTimeColumn,
                    priorityColumn,
                    TableConfiguration.GraphColumn,
                    switchInTimeColumn,
                    switchOutTimeColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            timelineByCPUTableConfig.AddColumnRole(ColumnRole.StartTime, switchInTimeColumn);
            timelineByCPUTableConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);
            timelineByCPUTableConfig.AddColumnRole(ColumnRole.Duration, switchedInTimeColumn);

            var utilByProcessCmdTable = new TableConfiguration("Utilization by Process Id, Thread Id, Cmd")
            {
                Columns = new[]
                {
                    nextPidColumn,
                    nextTidColumn,
                    nextCommandColumn,
                    TableConfiguration.PivotColumn,
                    cpuColumn,
                    previousStateColumn,
                    nextThreadPreviousSwitchOutTimeColumn,
                    previousTidColumn,
                    readyingPidColumn,
                    readyingTidColumn,
                    switchInTimeColumn,
                    readyTimeColumn,
                    waitTimeColumn,
                    switchedInTimeColumn,
                    priorityColumn,
                    TableConfiguration.GraphColumn,
                    percentCpuUsagePreset,
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByProcessCmdTable.AddColumnRole(ColumnRole.StartTime, switchInTimeColumn);
            utilByProcessCmdTable.AddColumnRole(ColumnRole.ResourceId, cpuColumn);
            utilByProcessCmdTable.AddColumnRole(ColumnRole.Duration, switchedInTimeColumn);

            var utilByCpuTable = new TableConfiguration("Utilization by CPU")
            {
                Columns = new[]
                {
                    cpuColumn,
                    TableConfiguration.PivotColumn,
                    nextPidColumn,
                    nextTidColumn,
                    nextCommandColumn,
                    previousStateColumn,
                    nextThreadPreviousSwitchOutTimeColumn,
                    previousTidColumn,
                    readyingPidColumn,
                    readyingTidColumn,
                    switchInTimeColumn,
                    readyTimeColumn,
                    waitTimeColumn,
                    switchedInTimeColumn,
                    priorityColumn,
                    TableConfiguration.GraphColumn,
                    percentCpuUsagePreset,
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByCpuTable.AddColumnRole(ColumnRole.StartTime, switchInTimeColumn);
            utilByCpuTable.AddColumnRole(ColumnRole.ResourceId, cpuColumn);
            utilByCpuTable.AddColumnRole(ColumnRole.Duration, switchedInTimeColumn);

            var table = tableBuilder.AddTableConfiguration(timelineByCPUTableConfig)
                        .AddTableConfiguration(utilByProcessCmdTable)
                        .AddTableConfiguration(utilByCpuTable)
                        .SetDefaultTableConfiguration(utilByProcessCmdTable)
                        .SetRowCount(threads.Count);

            var switchInTime  = Projection.CreateUsingFuncAdaptor((i) => threads[i].SwitchInTime);
            var switchOutTime = Projection.CreateUsingFuncAdaptor((i) => threads[i].SwitchOutTime);

            table.AddColumn(cpuColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].Cpu));
            table.AddColumn(nextPidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextPid));
            table.AddColumn(nextTidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextTid));
            table.AddColumn(previousStateColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousState));
            table.AddColumn(nextThreadPreviousSwitchOutTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextThreadPreviousSwitchOutTime));
            table.AddColumn(previousTidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousTid));
            table.AddColumn(readyingPidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyingPid));
            table.AddColumn(readyingTidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyingTid));
            table.AddColumn(readyTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyTime));
            table.AddColumn(waitTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].WaitTime));
            table.AddColumn(switchedInTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].SwitchOutTime - threads[i].SwitchInTime));
            table.AddColumn(priorityColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].Priority));
            table.AddColumn(switchInTimeColumn, switchInTime);
            table.AddColumn(switchOutTimeColumn, switchOutTime);
            table.AddColumn(previousPidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousPid));
            table.AddColumn(nextCommandColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextImage));
            table.AddColumn(previousCommandColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousImage));


            // Time the thread switching in switches out
            var viewportClippedSwitchOutTimeForNextOnCpuColumn = Projection.ClipTimeToVisibleDomain.Create(switchOutTime);

            // Switch in time is the thread switching in, which is the switch out time of the thread switching out on the CPU
            var viewportClippedSwitchOutTimeForPreviousOnCpuColumn = Projection.ClipTimeToVisibleDomain.Create(switchInTime);

            IProjection <int, TimestampDelta> cpuUsageInViewportColumn = Projection.Select(
                viewportClippedSwitchOutTimeForNextOnCpuColumn,
                viewportClippedSwitchOutTimeForPreviousOnCpuColumn,
                new ReduceTimeSinceLastDiff());

            var percentCpuUsageColumn = Projection.VisibleDomainRelativePercent.Create(cpuUsageInViewportColumn);

            var cpuUsageColumn = Projection.Select(switchOutTime, switchInTime, new ReduceTimeSinceLastDiff());

            table.AddColumn(cpuUsageInViewportPreset, cpuUsageInViewportColumn);
            table.AddColumn(cpuUsagePreset, cpuUsageColumn);
            table.AddColumn(percentCpuUsagePreset, percentCpuUsageColumn);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoProcessEvent> >(
                new DataOutputPath(PerfettoPluginConstants.ProcessEventCookerPath, nameof(PerfettoProcessEventCooker.ProcessEvents)));

            int maxArgsFieldCount = Math.Min(AbsoluteMaxFields, tableData.QueryOutput <int>(
                                                 new DataOutputPath(PerfettoPluginConstants.ProcessEventCookerPath, nameof(PerfettoProcessEventCooker.MaximumArgsEventFieldCount))));

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            tableGenerator.AddColumn(ProcessNameColumn, baseProjection.Compose(x => x.Name));
            tableGenerator.AddColumn(ProcessLabelColumn, baseProjection.Compose(x => x.Label));
            tableGenerator.AddColumn(StartTimestampColumn, baseProjection.Compose(x => x.StartTimestamp));
            tableGenerator.AddColumn(EndTimestampColumn, baseProjection.Compose(x => x.EndTimestamp));
            tableGenerator.AddColumn(UpidColumn, baseProjection.Compose(x => x.Upid));
            tableGenerator.AddColumn(PidColumn, baseProjection.Compose(x => x.Pid));
            tableGenerator.AddColumn(ParentUpidColumn, baseProjection.Compose(x => x.ParentUpid));
            tableGenerator.AddColumn(ParentProcessNameColumn, baseProjection.Compose(x => x.ParentProcess != null ? x.ParentProcess.Name : String.Empty));

            tableGenerator.AddColumn(UidColumn, baseProjection.Compose(x => x.Uid));
            tableGenerator.AddColumn(AndroidAppIdColumn, baseProjection.Compose(x => x.AndroidAppId));
            tableGenerator.AddColumn(CmdLineColumn, baseProjection.Compose(x => x.CmdLine));

            if (events.Any(f => !String.IsNullOrWhiteSpace(f.Label)))
            {
                ProcessLabelColumn.DisplayHints.IsVisible = true;
            }

            List <ColumnConfiguration> extraProcessArgColumns = new List <ColumnConfiguration>();

            // Add the field columns, with column names depending on the given event
            for (int index = 0; index < maxArgsFieldCount; index++)
            {
                var    colIndex  = index; // This seems unncessary but causes odd runtime behavior if not done this way. Compiler is confused perhaps because w/o this func will index=genericEvent.FieldNames.Count every time. index is passed as ref but colIndex as value into func
                string fieldName = "Field " + (colIndex + 1);

                var processArgKeysFieldNameProjection = baseProjection.Compose((pe) => colIndex < pe.Args?.Count ? pe.Args.Keys.ElementAt(colIndex) : string.Empty);

                // generate a column configuration
                var fieldColumnConfiguration = new ColumnConfiguration(
                    new ColumnMetadata(Common.GenerateGuidFromName(fieldName), fieldName, processArgKeysFieldNameProjection, fieldName)
                {
                    IsDynamic = true
                },
                    new UIHints
                {
                    IsVisible     = true,
                    Width         = 150,
                    TextAlignment = TextAlignment.Left,
                });

                // Add this column to the column order
                extraProcessArgColumns.Add(fieldColumnConfiguration);

                var argsAsStringProjection = baseProjection.Compose((pe) => colIndex < pe.Args?.Count ? pe.Args.Values.ElementAt(colIndex).ToString() : string.Empty);

                tableGenerator.AddColumn(fieldColumnConfiguration, argsAsStringProjection);
            }

            // Default
            List <ColumnConfiguration> defaultColumns = new List <ColumnConfiguration>()
            {
                ProcessNameColumn,
                ProcessLabelColumn,
                TableConfiguration.PivotColumn,     // Columns before this get pivotted on
                CmdLineColumn,
                PidColumn,
                UpidColumn,
                ParentUpidColumn,
                ParentProcessNameColumn,
                UidColumn,
                AndroidAppIdColumn,
            };

            defaultColumns.AddRange(extraProcessArgColumns);
            defaultColumns.Add(TableConfiguration.GraphColumn); // Columns after this get graphed
            defaultColumns.Add(StartTimestampColumn);
            defaultColumns.Add(EndTimestampColumn);

            var processDefaultConfig = new TableConfiguration("Default")
            {
                Columns   = defaultColumns,
                ChartType = ChartType.Line
            };

            processDefaultConfig.AddColumnRole(ColumnRole.StartTime, StartTimestampColumn);
            processDefaultConfig.AddColumnRole(ColumnRole.EndTime, EndTimestampColumn);;

            tableBuilder.AddTableConfiguration(processDefaultConfig)
            .SetDefaultTableConfiguration(processDefaultConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoCpuSamplingEvent> >(
                new DataOutputPath(PerfettoPluginConstants.CpuSamplingEventCookerPath, nameof(PerfettoCpuSamplingEventCooker.CpuSamplingEvents)));

            var tableGenerator = tableBuilder.SetRowCount((int)events.Count);
            var baseProjection = Projection.Index(events);

            var startProjection = baseProjection.Compose(x => x.Timestamp);

            tableGenerator.AddColumn(CpuColumn, baseProjection.Compose(x => x.Cpu));
            tableGenerator.AddColumn(ProcessNameColumn, baseProjection.Compose(x => x.ProcessName));
            tableGenerator.AddColumn(ThreadNameColumn, baseProjection.Compose(x => x.ThreadName));
            tableGenerator.AddColumn(UnwindErrorColumn, baseProjection.Compose(x => x.UnwindError));
            tableGenerator.AddColumn(ModuleColumn, baseProjection.Compose(x => x.Module));
            tableGenerator.AddColumn(FunctionColumn, baseProjection.Compose(x => x.Function));
            tableGenerator.AddHierarchicalColumn(CallStackColumn, baseProjection.Compose(x => x.CallStack), new ArrayAccessProvider <string>());
            tableGenerator.AddColumn(TimestampColumn, startProjection);

            var processStackConfig = new TableConfiguration("By Process, Stack")
            {
                Columns = new[]
                {
                    ProcessNameColumn,
                    CallStackColumn,
                    TableConfiguration.PivotColumn, // Columns before this get pivotted on
                    ThreadNameColumn,
                    ModuleColumn,
                    FunctionColumn,
                    CpuColumn,
                    UnwindErrorColumn,
                    TableConfiguration.GraphColumn, // Columns after this get graphed
                    TimestampColumn,
                },
            };

            processStackConfig.AddColumnRole(ColumnRole.StartTime, TimestampColumn.Metadata.Guid);

            var processThreadStackConfig = new TableConfiguration("By Process, Thread, Stack")
            {
                Columns = new[]
                {
                    ProcessNameColumn,
                    ThreadNameColumn,
                    CallStackColumn,
                    TableConfiguration.PivotColumn, // Columns before this get pivotted on
                    ModuleColumn,
                    FunctionColumn,
                    CpuColumn,
                    UnwindErrorColumn,
                    TableConfiguration.GraphColumn, // Columns after this get graphed
                    TimestampColumn,
                },
            };

            processThreadStackConfig.AddColumnRole(ColumnRole.StartTime, TimestampColumn.Metadata.Guid);

            tableBuilder
            .AddTableConfiguration(processStackConfig)
            .AddTableConfiguration(processThreadStackConfig)
            .SetDefaultTableConfiguration(processStackConfig);
        }