Exemple #1
0
        public void Project_3_ThrowsForNull()
        {
            Assert.ThrowsException <ArgumentNullException>(
                () => Projection.Project <int, DateTime, Guid, TimeSpan, string>(
                    null,
                    Projection.Constant(Guid.NewGuid()),
                    Projection.Constant(TimeSpan.Zero),
                    Project_3_Projector));

            Assert.ThrowsException <ArgumentNullException>(
                () => Projection.Project <int, DateTime, Guid, TimeSpan, string>(
                    Projection.Constant(DateTime.UtcNow),
                    null,
                    Projection.Constant(TimeSpan.Zero),
                    Project_3_Projector));

            Assert.ThrowsException <ArgumentNullException>(
                () => Projection.Project <int, DateTime, Guid, TimeSpan, string>(
                    Projection.Constant(DateTime.UtcNow),
                    Projection.Constant(Guid.NewGuid()),
                    null,
                    Project_3_Projector));

            Assert.ThrowsException <ArgumentNullException>(
                () => Projection.Project <int, DateTime, Guid, TimeSpan, string>(
                    Projection.Constant(DateTime.UtcNow),
                    Projection.Constant(Guid.NewGuid()),
                    Projection.Constant(TimeSpan.Zero),
                    null));
        }
Exemple #2
0
 public void Project_1_ThrowsIfNonStaticFuncGiven()
 {
     Assert.ThrowsException <InvalidOperationException>(
         () => Projection.Project <int, DateTime, string>(
             Projection.Constant(DateTime.UtcNow),
             x => x.ToString()));
 }
Exemple #3
0
        public void IsConstant_ReturnsTrueForConstantProject()
        {
            var projection = Projection.Constant(1);

            Assert.IsTrue(Projection.IsConstant(projection));
            Assert.IsTrue(projection.IsConstant());
        }
        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 void ConstantTitleProjection_NameIsConstantReturnsTrue()
        {
            var projection = Projection.Constant("name");
            var metadata   = new ColumnMetadata(this.ColumnGuid, "default", projection, "test column");

            Assert.IsTrue(metadata.IsNameConstant);
        }
Exemple #6
0
 public void Project_2_ThrowsIfNonStaticFuncGiven()
 {
     Assert.ThrowsException <InvalidOperationException>(
         () => Projection.Project <int, DateTime, Guid, string>(
             Projection.Constant(DateTime.UtcNow),
             Projection.Constant(Guid.NewGuid()),
             (x, y) => (x.ToString() + y.ToString())));
 }
        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);
        }
Exemple #8
0
 public void Project_4_ThrowsIfNonStaticFuncGiven()
 {
     Assert.ThrowsException <InvalidOperationException>(
         () => Projection.Project <int, DateTime, Guid, TimeSpan, DateTimeOffset, string>(
             Projection.Constant(DateTime.UtcNow),
             Projection.Constant(Guid.NewGuid()),
             Projection.Constant(TimeSpan.Zero),
             Projection.Constant(DateTimeOffset.MaxValue),
             (x, y, z, a) => (x.ToString() + y.ToString() + z.ToString() + a.ToString())));
 }
        public void ConstantTitleProjection_NameStillRespectsDefault()
        {
            var projection = Projection.Constant("name");
            var metadata   = new ColumnMetadata(this.ColumnGuid, "default", projection, "test column");

            for (var i = 0; i < 1000; ++i)
            {
                Assert.AreEqual("default", metadata.Name);
            }
        }
Exemple #10
0
        public void ConstantProjectionAlwaysReturnsTheSameValue()
        {
            var value = Guid.NewGuid();

            var projection = Projection.Constant(value);

            for (var i = 0; i < 100; ++i)
            {
                Assert.AreEqual(value, projection[i]);
            }
        }
Exemple #11
0
        public void Project_1_ThrowsForNull()
        {
            Assert.ThrowsException <ArgumentNullException>(
                () => Projection.Project <int, DateTime, string>(
                    null,
                    Project_1_Projector));

            Assert.ThrowsException <ArgumentNullException>(
                () => Projection.Project <int, DateTime, string>(
                    Projection.Constant(DateTime.UtcNow),
                    null));
        }
Exemple #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 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);
        }
Exemple #13
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);
        }
Exemple #14
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="ColumnMetadata"/>
 ///     class.
 /// </summary>
 /// <param name="guid">
 ///     The unique identifier for this column. This MAY NOT be
 ///     the default (empty) <see cref="Guid"/>.
 /// </param>
 /// <param name="name">
 ///     The name of this column.
 /// </param>
 /// <param name="description">
 ///     A user friendly description of this column.
 /// </param>
 /// <exception cref="System.ArgumentException">
 ///     <paramref name="guid"/> is equal to <c>default(Guid)</c>.
 ///     - or -
 ///     <paramref name="name"/> is whitespace.
 ///     - or -
 ///     <paramref name="description"/> is whitespace.
 /// </exception>
 /// <exception cref="System.ArgumentNullException">
 ///     <paramref name="name"/> is <c>null</c>.
 ///     - or -
 ///     <paramref name="description"/> is <c>null</c>.
 /// </exception>
 public ColumnMetadata(Guid guid, string name, string description)
     : this(guid, name, Projection.Constant(name), description)
 {
 }
        public override void Build(ITableBuilder tableBuilder)
        {
            if (PerfDataTxtLogParsed == null || PerfDataTxtLogParsed.Count == 0)
            {
                return;
            }

            var firstPerfDataTxtLogParsed = PerfDataTxtLogParsed.First().Value;  // First Log

            // Init
            IpStackFrames        = new ConcurrentDictionary <long, StackFrame>();
            SampleThreadDict     = new ConcurrentDictionary <long, int>();
            SampleProcessDict    = new ConcurrentDictionary <long, string>();
            SampleStackWalkEvent = new ConcurrentDictionary <long, ManualResetEvent>();

            var baseProjection = Projection.CreateUsingFuncAdaptor(new Func <int, LinuxPerfScriptStackSourceSample>(i => firstPerfDataTxtLogParsed.GetLinuxPerfScriptSampleByIndex((StackSourceSampleIndex)i)));

            // Calculate sample weights
            var sampleWeights = CalculateSampleWeights(firstPerfDataTxtLogParsed);

            var oneNs      = new TimestampDelta(1);
            var weightProj = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? TimestampDelta.Zero : new TimestampDelta(Convert.ToInt64(sampleWeights[(int)s.SampleIndex] * 1000000)));

            // Constant columns
            var sampleIndex            = baseProjection.Compose(s => (long)s.SampleIndex);
            var timeStampProjection    = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? Timestamp.Zero : new Timestamp(Convert.ToInt64(s.TimeRelativeMSec * 1000000)));
            var cpuProjection          = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? -1 : s.CpuNumber);
            var countProjection        = baseProjection.Compose(s => 1);
            var ipStackFrameProjection = baseProjection.Compose(s => GetIpStackFrame(s, firstPerfDataTxtLogParsed)?.Frame);
            var ipModuleProjection     = baseProjection.Compose(s => GetIpStackFrame(s, firstPerfDataTxtLogParsed)?.Module);
            var threadIdProjection     = baseProjection.Compose(s => GetThreadId(s, firstPerfDataTxtLogParsed));
            var processProjection      = baseProjection.Compose(s => GetProcess(s, firstPerfDataTxtLogParsed));


            // For calculating cpu %
            var timeStampStartProjection = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? Timestamp.Zero : new Timestamp(Convert.ToInt64(s.TimeRelativeMSec * 1000000)) - new TimestampDelta(Convert.ToInt64(sampleWeights[(int)s.SampleIndex] * 1000000)));
            IProjection <int, Timestamp> viewportClippedStartTimeProj = Projection.ClipTimeToVisibleDomain.Create(timeStampStartProjection);
            IProjection <int, Timestamp> viewportClippedEndTimeProj   = Projection.ClipTimeToVisibleDomain.Create(timeStampProjection);

            IProjection <int, TimestampDelta> clippedWeightProj = Projection.Select(
                viewportClippedEndTimeProj,
                viewportClippedStartTimeProj,
                new ReduceTimeSinceLastDiff());

            IProjection <int, double> weightPercentProj = Projection.VisibleDomainRelativePercent.Create(clippedWeightProj);

            IProjection <int, int> countProj = SequentialGenerator.Create(
                firstPerfDataTxtLogParsed.SampleIndexLimit,
                Projection.Constant(1),
                Projection.Constant(0));

            //
            // 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 to turn on or off columns.
            // The table configuration class also exposes four (4) columns 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
            //

            const string filterIdleSamplesQuery = "[IP]:=\"native_safe_halt\"";

            var utilByCpuStackConfig = new TableConfiguration("Utilization by CPU, Stack")
            {
                Columns = new[]
                {
                    cpuColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    processColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    countColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByCpuStackConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByCpuStackConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByCpuStackConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var utilByCpuConfig = new TableConfiguration("Utilization by CPU")
            {
                Columns = new[]
                {
                    cpuColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    callStackColumn,
                    processColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByCpuConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByCpuConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByCpuConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var utilByProcessConfig = new TableConfiguration("Utilization by Process")
            {
                Columns = new[]
                {
                    processColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    callStackColumn,
                    cpuColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByProcessConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByProcessConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByProcessConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var utilByProcessStackConfig = new TableConfiguration("Utilization by Process, Stack")
            {
                Columns = new[]
                {
                    processColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    cpuColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByProcessStackConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByProcessStackConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByProcessStackConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var flameByProcessStackConfig = new TableConfiguration("Flame by Process, Stack")
            {
                Columns = new[]
                {
                    processColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    cpuColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                ChartType = ChartType.Flame,
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            flameByProcessStackConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            flameByProcessStackConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            flameByProcessStackConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            //
            //
            //  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.
            //
            var table = tableBuilder
                        .AddTableConfiguration(utilByCpuStackConfig)
                        .SetDefaultTableConfiguration(utilByCpuStackConfig)
                        .AddTableConfiguration(utilByCpuConfig)
                        .AddTableConfiguration(utilByProcessConfig)
                        .AddTableConfiguration(utilByProcessStackConfig)
                        .AddTableConfiguration(flameByProcessStackConfig)
                        .SetRowCount(firstPerfDataTxtLogParsed.SampleIndexLimit)
                        .AddColumn(sampleNumberColumn, sampleIndex)
                        .AddColumn(timestampColumn, timeStampProjection)
                        .AddColumn(instructionPointerColumn, ipStackFrameProjection)
                        .AddColumn(instructionPointerModuleColumn, ipModuleProjection)
                        .AddColumn(countColumn, countProjection)
                        .AddColumn(weightColumn, weightProj)
                        .AddColumn(threadIdColumn, threadIdProjection)
                        .AddColumn(processColumn, processProjection)
                        .AddColumn(weightPctColumn, weightPercentProj)
                        .AddColumn(startTimeCol, timeStampStartProjection)
                        .AddColumn(viewportClippedStartTimeCol, viewportClippedStartTimeProj)
                        .AddColumn(viewportClippedEndTimeCol, viewportClippedEndTimeProj)
                        .AddColumn(clippedWeightCol, clippedWeightProj)
                        .AddColumn(cpuColumn, cpuProjection)
            ;

            table.AddHierarchicalColumn(callStackColumn, baseProjection.Compose((i) => GetCallStack(i, firstPerfDataTxtLogParsed)), new ArrayAccessProvider <string>());
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var pathIdentifier = DataOutputPath.ForSource(PerfConstants.SourceId, PerfCpuClockDataCooker.Identifier, nameof(PerfCpuClockDataCooker.CpuClockEvents));

            var cpuClocks = tableData.QueryOutput <IReadOnlyList <ICpuClockEvent> >(pathIdentifier);

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

            var config = new TableConfiguration("CPU Utilization")
            {
                Columns = new[]
                {
                    cpuColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    pidColumn,
                    threadIdColumn,
                    ipColumn,
                    symbolTypeColumn,
                    ipSymbolColumn,
                    idColumn,
                    weightColumn,
                    countColumn,
                    timeStampColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
            };

            config.AddColumnRole(ColumnRole.EndTime, timeStampColumn);
            config.AddColumnRole(ColumnRole.Duration, weightColumn);
            config.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

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

            var timeStampProjection = Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Timestamp);

            table.AddColumn(cpuColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Cpu));
            table.AddColumn(ipColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Ip));
            table.AddColumn(symbolTypeColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Ip_Symbol?.SymbolType?.SymbolTypeDescription.SymbolTypeShortName));
            table.AddColumn(ipSymbolColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Ip_Symbol?.Name));
            table.AddColumn(threadIdColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Tid));
            table.AddColumn(pidColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Pid));
            table.AddColumn(idColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Id));
            table.AddColumn(perfPeriodColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Perf_Period));
            table.AddColumn(perfCallchainSizeColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Perf_Callchain_Size));
            table.AddHierarchicalColumn(callStackColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].CallStack), new ArrayAccessProvider <string>());
            table.AddColumn(timeStampColumn, timeStampProjection);

            var oneMsSample = new TimestampDelta(1000000); // 1ms for now until we can figure out weight better
            var oneNs       = new TimestampDelta(1);
            var weightProj  = Projection.Constant(oneMsSample);

            var timeStampStartProjection = Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Timestamp - oneNs); // We will say sample lasted 1ns
            IProjection <int, Timestamp> viewportClippedStartTimeProj = Projection.ClipTimeToVisibleDomain.Create(timeStampStartProjection);
            IProjection <int, Timestamp> viewportClippedEndTimeProj   = Projection.ClipTimeToVisibleDomain.Create(timeStampProjection);

            IProjection <int, TimestampDelta> clippedWeightProj = Projection.Select(
                viewportClippedEndTimeProj,
                viewportClippedStartTimeProj,
                new ReduceTimeSinceLastDiff());

            IProjection <int, double> weightPercentProj = Projection.VisibleDomainRelativePercent.Create(clippedWeightProj);

            IProjection <int, int> countProj = SequentialGenerator.Create(
                cpuClocks.Count,
                Projection.Constant(1),
                Projection.Constant(0));

            table.AddColumn(weightColumn, weightProj);
            table.AddColumn(countColumn, countProj);
            table.AddColumn(weightPctColumn, weightPercentProj);
            table.AddColumn(startTimeCol, timeStampStartProjection);
            table.AddColumn(viewportClippedStartTimeCol, viewportClippedStartTimeProj);
            table.AddColumn(viewportClippedEndTimeCol, viewportClippedEndTimeProj);
            table.AddColumn(clippedWeightCol, clippedWeightProj);
        }
        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.GenericEventCookerPath, nameof(PerfettoGenericEventCooker.MaximumEventFieldCount))));

            bool hasProviders = tableData.QueryOutput <bool>(
                new DataOutputPath(PerfettoPluginConstants.GenericEventCookerPath, nameof(PerfettoGenericEventCooker.HasProviders)));

            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoGenericEvent> >(
                new DataOutputPath(PerfettoPluginConstants.GenericEventCookerPath, nameof(PerfettoGenericEventCooker.GenericEvents)));

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

            // Add all the data projections
            var sliceIdColumn = new DataColumn <int>(
                SliceIdColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.SliceId));

            tableGenerator.AddColumn(sliceIdColumn);

            var processNameColumn = new DataColumn <string>(
                ProcessNameColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Process));

            tableGenerator.AddColumn(processNameColumn);

            var processLabelColumn = new DataColumn <string>(
                ProcessLabelColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.ProcessLabel));

            tableGenerator.AddColumn(processLabelColumn);
            if (events.Any(f => !String.IsNullOrWhiteSpace(f.ProcessLabel)))
            {
                ProcessLabelColConfig.DisplayHints.IsVisible = true;
            }

            var threadNameColumn = new DataColumn <string>(
                ThreadNameColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Thread));

            tableGenerator.AddColumn(threadNameColumn);

            var eventNameColumn = new DataColumn <string>(
                EventNameColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.EventName));

            tableGenerator.AddColumn(eventNameColumn);

            var startTimestampColumn = new DataColumn <Timestamp>(
                StartTimestampColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.StartTimestamp));

            tableGenerator.AddColumn(startTimestampColumn);

            var endTimestampColumn = new DataColumn <Timestamp>(
                EndTimestampColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.EndTimestamp));

            tableGenerator.AddColumn(endTimestampColumn);

            var durationColumn = new DataColumn <TimestampDelta>(
                DurationNotSortedColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Duration));

            tableGenerator.AddColumn(durationColumn);

            var durationExColumn = new DataColumn <TimestampDelta>(
                DurationExSortedColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.DurationExclusive));

            tableGenerator.AddColumn(durationExColumn);

            var categoryColumn = new DataColumn <string>(
                CategoryColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Category));

            tableGenerator.AddColumn(categoryColumn);

            var typeColumn = new DataColumn <string>(
                TypeColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Type));

            tableGenerator.AddColumn(typeColumn);

            var providerColumn = new DataColumn <string>(
                ProviderColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Provider));

            tableGenerator.AddColumn(providerColumn);

            var trackNameIdColumn = new DataColumn <string>(
                TrackNameIdColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.ThreadTrack != null ?
                                               (!String.IsNullOrWhiteSpace(genericEvent.ThreadTrack.Name) ? $"{genericEvent.ThreadTrack.Name} ({genericEvent.ThreadTrack.Id})" : genericEvent.ThreadTrack.Id.ToString())
                                                                    : String.Empty));

            tableGenerator.AddColumn(trackNameIdColumn);

            var parentIdColumn = new DataColumn <int>(
                ParentIdColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.ParentId.HasValue ? genericEvent.ParentId.Value : -1));

            tableGenerator.AddColumn(parentIdColumn);

            var parentDepthLevelColumn = new DataColumn <int>(
                ParentDepthLevelColConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.ParentTreeDepthLevel));

            tableGenerator.AddColumn(parentDepthLevelColumn);

            tableGenerator.AddHierarchicalColumn(ParentEventNameTreeBranchColConfig, genericEventProjection.Compose((genericEvent) => genericEvent.ParentEventNameTree), new ArrayAccessProvider <string>());

            tableGenerator.AddColumn(CountColConfig, Projection.Constant <int>(1));

            // The provider column is optionally populated depending on whether or not the user specified a ProviderGUID mapping file
            ProviderColConfig.DisplayHints.IsVisible = hasProviders;

            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=genericEvent.FieldNames.Count every time. index is passed as ref but colIndex as value into func
                string fieldName = "Field " + (colIndex + 1);

                var genericEventFieldNameProjection = genericEventProjection.Compose((genericEvent) => colIndex < genericEvent.Args?.Count ? genericEvent.Args.ElementAt(colIndex).Key : string.Empty);

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

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

                var genericEventFieldAsStringProjection = genericEventProjection.Compose((genericEvent) => colIndex < genericEvent.Args?.Count ? genericEvent.Args.ElementAt(colIndex).Value : string.Empty);

                tableGenerator.AddColumn(fieldColumnConfiguration, genericEventFieldAsStringProjection);
            }

            List <ColumnConfiguration> defaultColumns = new List <ColumnConfiguration>()
            {
                ProviderColConfig,
                ProcessNameColConfig,
                ProcessLabelColConfig,
                ThreadNameColConfig,
                TableConfiguration.PivotColumn, // Columns before this get pivotted on
                EventNameColConfig,
                CategoryColConfig,
                TypeColConfig,
                DurationNotSortedColConfig,
                DurationExSortedColConfig,
            };

            defaultColumns.AddRange(fieldColumns);
            defaultColumns.Add(TableConfiguration.GraphColumn); // Columns after this get graphed
            defaultColumns.Add(StartTimestampColConfig);
            defaultColumns.Add(EndTimestampColConfig);

            // Proces-Thread config
            var processThreadConfig = new TableConfiguration("Process-Thread")
            {
                Columns = defaultColumns,
            };

            SetGraphTableConfig(processThreadConfig);
            tableBuilder.AddTableConfiguration(processThreadConfig);

            // Process-Thread by StartTime config
            var processThreadByStartTimeColumns = new List <ColumnConfiguration>(defaultColumns);

            processThreadByStartTimeColumns.Remove(EndTimestampColConfig);
            processThreadByStartTimeColumns.Insert(processThreadByStartTimeColumns.Count - 2, EndTimestampColConfig);

            var processThreadByStartTimeConfig = new TableConfiguration("Process-Thread by Start Time")
            {
                Columns = processThreadByStartTimeColumns,
            };

            SetGraphTableConfig(processThreadByStartTimeConfig);
            tableBuilder.AddTableConfiguration(processThreadByStartTimeConfig);

            // Process-Thread Activity config
            var processThreadActivityColumns = new List <ColumnConfiguration>(defaultColumns);

            processThreadActivityColumns.Remove(StartTimestampColConfig);
            processThreadActivityColumns.Insert(10, StartTimestampColConfig);
            processThreadActivityColumns.Remove(EndTimestampColConfig);
            processThreadActivityColumns.Insert(11, EndTimestampColConfig);
            processThreadActivityColumns.Add(CountSortedColConfig);

            // Different sorting than default
            processThreadActivityColumns.Remove(DurationExSortedColConfig);
            processThreadActivityColumns.Insert(9, DurationExNotSortedMaxColConfig);
            DurationExNotSortedMaxColConfig.DisplayHints.SortPriority = 1;
            DurationExNotSortedMaxColConfig.DisplayHints.SortOrder    = SortOrder.Descending;

            var processThreadActivityConfig = new TableConfiguration("Process-Thread Activity")
            {
                Columns = processThreadActivityColumns,
            };

            SetGraphTableConfig(processThreadActivityConfig);
            tableBuilder.AddTableConfiguration(processThreadActivityConfig);

            // Default - Process-Thread-NestedSlices-Name config
            var processThreadNameColumns = new List <ColumnConfiguration>(defaultColumns);

            processThreadNameColumns.Insert(4, ParentDepthLevelColConfig);
            processThreadNameColumns.Remove(EventNameColConfig);
            processThreadNameColumns.Insert(5, EventNameColConfig);
            var processThreadNestedNameConfig = new TableConfiguration("Process-Thread-NestedSlices-Name")
            {
                Columns = processThreadNameColumns,
            };

            SetGraphTableConfig(processThreadNestedNameConfig);
            tableBuilder.AddTableConfiguration(processThreadNestedNameConfig)
            .SetDefaultTableConfiguration(processThreadNestedNameConfig);

            // Process-Thread-EventName config
            var processThreadEventNameColumns = new List <ColumnConfiguration>(defaultColumns);

            processThreadEventNameColumns.Remove(EventNameColConfig);
            processThreadEventNameColumns.Insert(4, EventNameColConfig);
            var processThreadEventNameConfig = new TableConfiguration("Process-Thread-Name")
            {
                Columns = processThreadEventNameColumns,
            };

            SetGraphTableConfig(processThreadEventNameConfig);
            tableBuilder.AddTableConfiguration(processThreadEventNameConfig);

            // Process-Thread-Name by StartTime config
            var processThreadNameByStartTimeColumns = new List <ColumnConfiguration>(defaultColumns);

            processThreadNameByStartTimeColumns.Insert(4, ParentDepthLevelColConfig);
            processThreadNameByStartTimeColumns.Remove(EventNameColConfig);
            processThreadNameByStartTimeColumns.Insert(5, EventNameColConfig);
            processThreadNameByStartTimeColumns.Remove(EndTimestampColConfig);
            processThreadNameByStartTimeColumns.Insert(processThreadNameByStartTimeColumns.Count - 2, EndTimestampColConfig);

            var processThreadNameByStartTimeConfig = new TableConfiguration("Process-Thread-Name by Start Time")
            {
                Columns = processThreadNameByStartTimeColumns,
            };

            SetGraphTableConfig(processThreadNameByStartTimeConfig);
            tableBuilder.AddTableConfiguration(processThreadNameByStartTimeConfig);

            // Process-Thread-ParentTree config
            var processThreadNameTreeColumns = new List <ColumnConfiguration>(defaultColumns);

            processThreadNameTreeColumns.Insert(4, ParentEventNameTreeBranchColConfig);
            processThreadNameTreeColumns.Remove(DurationExSortedColConfig);
            processThreadNameTreeColumns.Insert(10, DurationExSortedSumColConfig);
            var processThreadParentNameTreeConfig = new TableConfiguration("Process-Thread-ParentTree")
            {
                Columns = processThreadNameTreeColumns,
            };

            ParentEventNameTreeBranchColConfig.DisplayHints.IsVisible = true;
            SetGraphTableConfig(processThreadParentNameTreeConfig);
            tableBuilder.AddTableConfiguration(processThreadParentNameTreeConfig);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            int maximumFieldCount = tableData.QueryOutput <int>(
                DataOutputPath.ForSource(LTTngConstants.SourceId, LTTngGenericEventDataCooker.Identifier, nameof(LTTngGenericEventDataCooker.MaximumEventFieldCount)));

            var events = tableData.QueryOutput <ProcessedEventData <LTTngGenericEvent> >(
                DataOutputPath.ForSource(LTTngConstants.SourceId, LTTngGenericEventDataCooker.Identifier, nameof(LTTngGenericEventDataCooker.Events)));

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

            var genericEventProjection = new EventProjection <LTTngGenericEvent>(events);

            var eventNameColumn = new DataColumn <string>(
                eventNameColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.EventName));

            tableGenerator.AddColumn(eventNameColumn);

            var eventIdColumn = new DataColumn <uint>(
                eventIdColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Id));

            tableGenerator.AddColumn(eventIdColumn);

            var cpuIdColumn = new DataColumn <uint>(
                cpuIdColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.CpuId));

            tableGenerator.AddColumn(cpuIdColumn);

            var discardedEventsColumn = new DataColumn <uint>(
                discardedEventsColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.DiscardedEvents));

            tableGenerator.AddColumn(discardedEventsColumn);

            var eventTimestampColumn = new DataColumn <Timestamp>(
                eventTimestampColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Timestamp));

            tableGenerator.AddColumn(eventTimestampColumn);

            tableGenerator.AddColumn(countColumnConfig, Projection.Constant(1));

            // Add the field columns, with column names depending on the given event
            for (int index = 0; index < maximumFieldCount; 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 genericEventFieldNameProjection = genericEventProjection.Compose((genericEvent) => colIndex < genericEvent.FieldNames.Count ? genericEvent.FieldNames[colIndex] : string.Empty);

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

                var genericEventFieldAsStringProjection = genericEventProjection.Compose((genericEvent) => colIndex < genericEvent.FieldNames.Count ? genericEvent.FieldValues[colIndex] : string.Empty);

                tableGenerator.AddColumn(fieldColumnConfiguration, genericEventFieldAsStringProjection);
            }
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var diskEvents = tableData.QueryOutput <IReadOnlyList <IDiskActivity> >(
                DataOutputPath.Create(LTTngDiskDataCooker.CookerPath + '/' + nameof(LTTngDiskDataCooker.DiskActivity)));

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

            var iosByDeviceThCmdConfig = new TableConfiguration("IOs by Device, ThreadId, Command")
            {
                Columns = new[]
                {
                    deviceIdColumn,
                    deviceNameColumn,
                    threadIdColumn,
                    commandColumn,
                    TableConfiguration.PivotColumn,
                    processIdColumn,
                    filepathColumn,
                    ioTimeSumColumn,
                    sectorNumberColumn,
                    diskOffsetColumn,
                    sizeColumn,
                    errorColumn,
                    TableConfiguration.GraphColumn,
                    insertTimeColumn,
                    issueTimeColumn,
                    completeTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            var ioTimesByDevFileConfig = new TableConfiguration("IOTime by Device, FilePath")
            {
                Columns = new[]
                {
                    deviceIdColumn,
                    deviceNameColumn,
                    TableConfiguration.PivotColumn,
                    filepathColumn,
                    threadIdColumn,
                    processIdColumn,
                    commandColumn,
                    sectorNumberColumn,
                    diskOffsetColumn,
                    sizeColumn,
                    errorColumn,
                    insertTimeColumn,
                    issueTimeColumn,
                    completeTimeColumn,
                    TableConfiguration.GraphColumn,
                    ioTimeAvgColumn,
                    ioTimeMaxColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            iosByDeviceThCmdConfig.AddColumnRole(ColumnRole.StartTime, insertTimeColumn);
            // config.AddColumnRole(ColumnRole.EndTime, completeTimeColumn);
            iosByDeviceThCmdConfig.AddColumnRole(ColumnRole.ResourceId, deviceIdColumn); // We have had past behavior where specifying this causes DevId 0 not to show?

            var table = tableBuilder.AddTableConfiguration(iosByDeviceThCmdConfig)
                        .AddTableConfiguration(ioTimesByDevFileConfig)
                        .SetDefaultTableConfiguration(iosByDeviceThCmdConfig)
                        .SetRowCount((int)diskEvents.Count);

            var diskActivities = Projection.CreateUsingFuncAdaptor((i) => diskEvents[i]);

            var defaultTime = default(Timestamp);


            var ioStartTimeProjection = diskActivities.Compose(da => da.InsertTime ?? defaultTime);
            var ioEndTimeProjection   = diskActivities.Compose(da => da.CompleteTime ?? defaultTime);
            var validIoTimeProjection =
                diskActivities.Compose(da => da.InsertTime.HasValue && da.CompleteTime.HasValue);

            table.AddColumn(deviceIdColumn, diskActivities.Compose(da => da.DeviceId));
            table.AddColumn(deviceNameColumn, diskActivities.Compose(da => da.DeviceName));
            table.AddColumn(filepathColumn, diskActivities.Compose(da => da.Filepath));
            table.AddColumn(threadIdColumn, diskActivities.Compose(da => da.ThreadId));
            table.AddColumn(processIdColumn, diskActivities.Compose(da => da.ProcessId));
            table.AddColumn(commandColumn, diskActivities.Compose(da => da.ProcessCommand));
            table.AddColumn(errorColumn, diskActivities.Compose(da => da.Error));
            table.AddColumn(ioTimeIsValidColumnConfiguration, validIoTimeProjection);
            table.AddColumn(sectorNumberColumn, diskActivities.Compose(da => da.SectorNumber));
            // todo:can we pick up the sector size from the trace?
            table.AddColumn(diskOffsetColumn, diskActivities.Compose(da => new Bytes(da.SectorNumber * 512)));
            table.AddColumn(insertTimeColumn, ioStartTimeProjection);
            table.AddColumn(issueTimeColumn, diskActivities.Compose(da => da.IssueTime ?? defaultTime));
            table.AddColumn(completeTimeColumn, ioEndTimeProjection);

            var diskActivitiesProj = diskActivities.Compose((da) =>
            {
                if (da.CompleteTime.HasValue)
                {
                    if (da.InsertTime.HasValue)
                    {
                        return(da.CompleteTime.Value - da.InsertTime.Value);
                    }
                }

                return(TimestampDelta.Zero);
            });

            table.AddColumn(ioTimeAvgColumn, diskActivitiesProj);

            {
                IProjection <int, Timestamp> viewportClippedStartTimeColumn =
                    Projection.ClipTimeToViewport.Create(ioStartTimeProjection);

                IProjection <int, Timestamp> viewportClippedEndTimeColumn =
                    Projection.ClipTimeToViewport.Create(ioEndTimeProjection);

                // Timestamp delta for the given disk activity during the viewport time range.
                IProjection <int, TimestampDelta> clippedTimeDeltaColumn = Projection.Select(
                    viewportClippedEndTimeColumn,
                    viewportClippedStartTimeColumn,
                    new ReduceTimeSinceLastDiff(validIoTimeProjection));

                table.AddColumn(clippedTimestampDeltaColumnConfiguration, clippedTimeDeltaColumn);

                // Percent of time consumed by the timestamp delta in the current viewport.

                /* IProjection<int, double> ioTimeWeightPercentColumn =
                 *   Projection.ClipTimeToViewport.CreatePercent(clippedTimeDeltaColumn);*/

                /// table.AddColumn(weightedIOTimeColumn, ioTimeWeightPercentColumn);
            }

            table.AddColumn(sizeColumn, new DiskActivitySizeProjection(diskActivities));

            // IOCount with no restriction on IOSize - Used to enable some of the graphs in analyzer
            table.AddColumn(countColumn, Projection.Constant <int>(1));

            // todo: should we move the Azure specific columns here?

            // IOCount when IOSize is 8KB (such as in Azure local SSD throttling)
            table.AddColumn(countColumn_IOSize8kb, diskActivities.Compose(da => da.Size.HasValue && da.Size.Value.Bytes > 0 ? Math.Ceiling((float)da.Size.Value.Bytes / (8 * 1024)) : 1));

            // IOCount when IOSize is 256KB (such as in Azure XStore throttling)
            table.AddColumn(countColumn_IOSize256kb, diskActivities.Compose(da => da.Size.HasValue && da.Size.Value.Bytes > 0 ? Math.Ceiling((float)da.Size.Value.Bytes / (256 * 1024)) : 1));  
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            int maximumFieldCount = tableData.QueryOutput <int>(
                DataOutputPath.Create("Perf/GenericEvents/MaximumEventFieldCount"));

            var events = tableData.QueryOutput <ProcessedEventData <PerfGenericEvent> >(
                DataOutputPath.Create("Perf/GenericEvents/Events"));

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

            var genericEventProjection = new GenericEventProjection(events);

            var eventNameColumn = new BaseDataColumn <string>(
                eventNameColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.EventName));

            tableGenerator.AddColumn(eventNameColumn);

            var eventIdColumn = new BaseDataColumn <uint>(
                eventIdColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Id));

            tableGenerator.AddColumn(eventIdColumn);

            var cpuIdColumn = new BaseDataColumn <uint>(
                cpuIdColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.CpuId));

            tableGenerator.AddColumn(cpuIdColumn);

            var eventTimestampColumn = new BaseDataColumn <Timestamp>(
                eventTimestampColumnConfig,
                genericEventProjection.Compose((genericEvent) => genericEvent.Timestamp));

            tableGenerator.AddColumn(eventTimestampColumn);

            tableGenerator.AddColumn(countColumnConfig, Projection.Constant(1));

            // Add the field columns, with column names depending on the given event
            for (int columnIndex = 0; columnIndex < maximumFieldCount; columnIndex++)
            {
                string fieldName = "Field " + (columnIndex + 1);

                var genericEventFieldProjection = new GenericEventFieldProjection(columnIndex, genericEventProjection);

                var genericEventFieldNameProjection =
                    genericEventFieldProjection.Compose((field) => field.HasValue ? field.Value.Name : string.Empty);

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

                var genericEventFieldAsStringProjection =
                    genericEventFieldProjection.Compose((field) => field.HasValue ? field.Value.Value : string.Empty);

                tableGenerator.AddColumn(fieldColumnConfiguration, genericEventFieldAsStringProjection);
            }
        }
Exemple #21
0
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            // Get data from the cooker
            var events = tableData.QueryOutput <ProcessedEventData <PerfettoCpuCountersEvent> >(
                new DataOutputPath(PerfettoPluginConstants.CpuCountersEventCookerPath, nameof(PerfettoCpuCountersEventCooker.CpuCountersEvents)));

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

            tableGenerator.AddColumn(CpuNumColumn, baseProjection.Compose(x => x.CpuNum));
            tableGenerator.AddColumn(StartTimestampColumn, baseProjection.Compose(x => x.StartTimestamp));
            tableGenerator.AddColumn(DurationColumn, baseProjection.Compose(x => x.Duration));
            tableGenerator.AddColumn(UserPercentColumn, baseProjection.Compose(x => x.UserPercent));
            tableGenerator.AddColumn(UserNicePercentColumn, baseProjection.Compose(x => x.UserNicePercent));
            tableGenerator.AddColumn(SystemModePercentColumn, baseProjection.Compose(x => x.SystemModePercent));
            tableGenerator.AddColumn(IdlePercentColumn, baseProjection.Compose(x => x.IdlePercent));
            tableGenerator.AddColumn(IoWaitPercentColumn, baseProjection.Compose(x => x.IoWaitPercent));
            tableGenerator.AddColumn(IrqPercentColumn, baseProjection.Compose(x => x.IrqPercent));
            tableGenerator.AddColumn(SoftIrqPercentColumn, baseProjection.Compose(x => x.SoftIrqPercent));
            tableGenerator.AddColumn(TotalCpuUsagePercentColumn, baseProjection.Compose(x => x.CpuPercent));
            tableGenerator.AddColumn(CountColumn, Projection.Constant <int>(1));

            // Only display the total CPU usage column
            var cpuUsageConfig = new TableConfiguration("CPU Usage %")
            {
                Columns = new[]
                {
                    CpuNumColumn,
                    TableConfiguration.PivotColumn, // Columns before this get pivotted on
                    CountColumn,
                    StartTimestampColumn,
                    DurationColumn,
                    UserPercentColumn,
                    UserNicePercentColumn,
                    SystemModePercentColumn,
                    IdlePercentColumn,
                    IoWaitPercentColumn,
                    IrqPercentColumn,
                    SoftIrqPercentColumn,
                    TableConfiguration.GraphColumn, // Columns after this get graphed
                    TotalCpuUsagePercentColumn
                },
                ChartType = ChartType.Line
            };

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

            // Display all CPU counter columns
            var allCountersConfig = new TableConfiguration("CPU Counters - All")
            {
                Columns = new[]
                {
                    CpuNumColumn,
                    TableConfiguration.PivotColumn, // Columns before this get pivotted on
                    CountColumn,
                    StartTimestampColumn,
                    DurationColumn,
                    TotalCpuUsagePercentColumn,
                    IdlePercentColumn,
                    TableConfiguration.GraphColumn, // Columns after this get graphed
                    UserPercentColumn,
                    UserNicePercentColumn,
                    SystemModePercentColumn,
                    IoWaitPercentColumn,
                    IrqPercentColumn,
                    SoftIrqPercentColumn,
                },
                ChartType = ChartType.Line
            };

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

            tableBuilder.AddTableConfiguration(cpuUsageConfig)
            .AddTableConfiguration(allCountersConfig)
            .SetDefaultTableConfiguration(cpuUsageConfig);
        }