Esempio n. 1
0
        public static string ToNamespace(this ProfilerResult profilerResult)
        {
            #region Argument exception

            if (profilerResult == null)
            {
                throw new ArgumentNullException("profilerResult");
            }

            #endregion

            return("{0}".FormatWith(ProfilerResult.Namespace));
        }
Esempio n. 2
0
        public static DataTable ToCachesReadTable(this ProfilerResult profilerResult)
        {
            var cachesRead = new DataTable("CachesRead", "Common");

            #region Columns
            cachesRead.Columns.Add("CacheType", typeof(string));
            cachesRead.Columns.Add("CacheSubType", typeof(string));
            #endregion

            if (profilerResult.ExecuteForPrepare)
            {
                return(cachesRead);
            }

            #region Calculation

            var getDataFromCache = profilerResult.Values
                                   .Where((e) => e.EventClass == TraceEventClass.GetDataFromCache);

            var measureGroupCache = getDataFromCache
                                    .Where((e) => e.EventSubclass == TraceEventSubclass.GetDataFromMeasureGroupCache)
                                    .Select((e) => new
            {
                CacheType    = "Measure Group Cache",
                CacheSubType = e.TextData
            });

            var persistedCache = getDataFromCache
                                 .Where((e) => e.EventSubclass == TraceEventSubclass.GetDataFromPersistedCache)
                                 .Select((e) => new
            {
                CacheType    = "Persisted Cache",
                CacheSubType = e.TextData
            });

            var flatCache = getDataFromCache
                            .Where((e) => e.EventSubclass == TraceEventSubclass.GetDataFromFlatCache)
                            .Select((e) => new
            {
                CacheType    = "Flat Cache",
                CacheSubType = e.TextData
            });

            var calculationCacheGlobalScope = getDataFromCache
                                              .Where((e) =>
                                                     e.EventSubclass == TraceEventSubclass.GetDataFromCalculationCache &&
                                                     e.TextData.Equals("Global Scope", StringComparison.InvariantCultureIgnoreCase))
                                              .Select((e) => new
            {
                CacheType    = "Calculation Cache - Global Scope",
                CacheSubType = e.TextData
            });

            var calculationCacheSessionScope = getDataFromCache
                                               .Where((e) =>
                                                      e.EventSubclass == TraceEventSubclass.GetDataFromCalculationCache &&
                                                      e.TextData.Equals("Session Scope", StringComparison.InvariantCultureIgnoreCase))
                                               .Select((e) => new
            {
                CacheType    = "Calculation Cache - Session Scope",
                CacheSubType = e.TextData
            });

            var calculationCacheQueryScope = getDataFromCache
                                             .Where((e) =>
                                                    e.EventSubclass == TraceEventSubclass.GetDataFromCalculationCache &&
                                                    e.TextData.Equals("Query Scope", StringComparison.InvariantCultureIgnoreCase))
                                             .Select((e) => new
            {
                CacheType    = "Calculation Cache - Query Scope",
                CacheSubType = e.TextData
            });

            #endregion

            #region Insert rows

            var caches = measureGroupCache
                         .Concat(persistedCache)
                         .Concat(flatCache)
                         .Concat(calculationCacheGlobalScope)
                         .Concat(calculationCacheSessionScope)
                         .Concat(calculationCacheQueryScope);

            foreach (var item in caches)
            {
                cachesRead.Rows.Add(item.CacheType, item.CacheSubType);
            }

            #endregion

            return(cachesRead);
        }
Esempio n. 3
0
        public static DataTable ToAggregationsReadTable(this ProfilerResult profilerResult)
        {
            var aggregationsRead = new DataTable("AggregationsRead", "Common");

            #region Columns
            aggregationsRead.Columns.Add("CubeID", typeof(string));
            aggregationsRead.Columns.Add("MeasureGroupID", typeof(string));
            aggregationsRead.Columns.Add("PartitionID", typeof(string));
            aggregationsRead.Columns.Add("AggregationID", typeof(string));
            aggregationsRead.Columns.Add("AggregationName", typeof(string));
            aggregationsRead.Columns.Add("AggregationHit", typeof(int));
            aggregationsRead.Columns.Add("AggregationDuration", typeof(TimeSpan));
            aggregationsRead.Columns.Add("AggregationDurationRatio", typeof(double));
            #endregion

            if (profilerResult.ExecuteForPrepare)
            {
                return(aggregationsRead);
            }

            #region Calculation

            var progressReportEndQueryAggregationEvents = profilerResult.Values.FilterProgressReportEndQueryAggregationEvents().ToList();
            var durationTotal = progressReportEndQueryAggregationEvents.Sum((e) => e.Duration);

            var progressReportEndQueryAggregation = progressReportEndQueryAggregationEvents.GroupBy((e) => e.ObjectID)
                                                    .Select((g) =>
            {
                var fe     = g.First();
                var values = fe.ObjectPath.Split('.');

                return(new
                {
                    CubeID = values[2],
                    MeasureGroupID = values[3],
                    PartitionID = values[4],
                    AggregationID = values[5],
                    AggregationName = fe.ObjectName,
                    AggregationHit = g.Count(),
                    AggregationDuration = g.Sum((e) => e.Duration),
                    AggregationDurationRatio = durationTotal == 0L ? 0D : ((double)(g.Sum((e) => e.Duration) * 100D) / (double)durationTotal)
                });
            });

            #endregion

            #region Insert rows

            foreach (var item in progressReportEndQueryAggregation)
            {
                aggregationsRead.Rows.Add(
                    item.CubeID,
                    item.MeasureGroupID,
                    item.PartitionID,
                    item.AggregationID,
                    item.AggregationName,
                    item.AggregationHit,
                    TimeSpan.FromMilliseconds(item.AggregationDuration),
                    Math.Round(item.AggregationDurationRatio, 2)
                    );
            }

            #endregion

            return(aggregationsRead);
        }
Esempio n. 4
0
        public static DataTable ToEnginePerformanceTable(this ProfilerResult profilerResult)
        {
            var enginePerformance = new DataTable("EnginePerformance", "Common");

            #region Columns
            enginePerformance.Columns.Add("QueryDuration", typeof(TimeSpan));
            enginePerformance.Columns.Add("FormulaEngineDuration", typeof(TimeSpan));
            enginePerformance.Columns.Add("StorageEngineDuration", typeof(TimeSpan));
            enginePerformance.Columns.Add("QuerySubcubeExecutionsCacheData", typeof(int));
            enginePerformance.Columns.Add("QuerySubcubeExecutionsNonCacheData", typeof(int));
            enginePerformance.Columns.Add("CachesRead", typeof(int));
            enginePerformance.Columns.Add("PartitionsRead", typeof(int));
            enginePerformance.Columns.Add("PartitionsHit", typeof(int));
            enginePerformance.Columns.Add("PartitionsDuration", typeof(TimeSpan));
            enginePerformance.Columns.Add("AggregationsRead", typeof(int));
            enginePerformance.Columns.Add("AggregationsHit", typeof(int));
            enginePerformance.Columns.Add("AggregationsDuration", typeof(TimeSpan));
            enginePerformance.Columns.Add("ResourceUsageReads", typeof(int));
            enginePerformance.Columns.Add("ResourceUsageReadKB", typeof(long));
            enginePerformance.Columns.Add("ResourceUsageWrites", typeof(int));
            enginePerformance.Columns.Add("ResourceUsageWriteKB", typeof(long));
            enginePerformance.Columns.Add("ResourceUsageCpuTimeMS", typeof(long));
            enginePerformance.Columns.Add("ResourceUsageRowsScanned", typeof(int));
            enginePerformance.Columns.Add("ResourceUsageRowsReturned", typeof(int));
            #endregion

            if (profilerResult.ExecuteForPrepare)
            {
                return(enginePerformance);
            }

            #region Calculation

            #region QueryEnd events
            var queryEndEvents = profilerResult.Values.Where((e) => e.EventClass == TraceEventClass.QueryEnd);
            if (queryEndEvents.Count() != 1)
            {
                throw new ApplicationException("Invalid QueryEnd events count [{0}]".FormatWith(queryEndEvents.Count()));
            }
            #endregion

            var queryDuration = queryEndEvents.Single().Duration;

            #region QuerySubCube events
            var querySubCubeEvents = profilerResult.Values.Where((e) => e.EventClass == TraceEventClass.QuerySubcube);
            #endregion

            var storageEngineDuration = querySubCubeEvents.Sum((e) => e.Duration);
            if (storageEngineDuration > queryDuration)
            {
                storageEngineDuration = queryDuration;
            }
            var formulaEngineDuration = queryDuration - storageEngineDuration;

            var querySubcubeExecutionsCacheData    = querySubCubeEvents.Count((e) => e.EventSubclass == TraceEventSubclass.CacheData);
            var querySubcubeExecutionsNonCacheData = querySubCubeEvents.Count((e) => e.EventSubclass == TraceEventSubclass.NonCacheData);

            #region ProgressReportEnd events
            var progressReportEndQueryPartitionEvents   = profilerResult.Values.FilterProgressReportEndQueryPartitionEvents();
            var progressReportEndQueryAggregationEvents = profilerResult.Values.FilterProgressReportEndQueryAggregationEvents();
            #endregion

            var partitionsRead     = progressReportEndQueryPartitionEvents.GroupBy((e) => e.ObjectID).Count();
            var partitionsDuration = progressReportEndQueryPartitionEvents.Sum((e) => e.Duration);
            var partitionsHit      = progressReportEndQueryPartitionEvents.Count();

            var aggregationsRead     = progressReportEndQueryAggregationEvents.GroupBy((e) => e.ObjectID).Count();
            var aggregationsDuration = progressReportEndQueryAggregationEvents.Sum((e) => e.Duration);
            var aggregationsHit      = progressReportEndQueryAggregationEvents.Count();

            #region GetDataFromCache events
            var getDataFromCacheEvents = profilerResult.Values.Where((e) => e.EventClass == TraceEventClass.GetDataFromCache);
            #endregion

            var cachesRead = getDataFromCacheEvents.Count();

            #region ResourceUsage events
            var resourceUsageEvents = profilerResult.Values.Where((e) => e.EventClass == TraceEventClass.ResourceUsage);
            if (resourceUsageEvents.Count() != 1)
            {
                throw new ApplicationException("Invalid ResourceUsage events count");
            }
            #endregion

            var resourceUsage = resourceUsageEvents.Select((e) =>
            {
                if (e.TextData == null)
                {
                    throw new ApplicationException("Invalid ResourceUsage.TextData [null]");
                }

                var values = e.TextData.Split('\n')
                             .Select((v) => v.Split(',').Last().Trim())
                             .ToArray();

                if (values.Length != 8)
                {
                    throw new ApplicationException("Invalid ResourceUsage.TextData [{0}]".FormatWith(values.Length));
                }

                return(new
                {
                    ResourceUsageReads = int.Parse(values[0]),
                    ResourceUsageReadKB = long.Parse(values[1]),
                    ResourceUsageWrites = int.Parse(values[2]),
                    ResourceUsageWriteKB = long.Parse(values[3]),
                    ResourceUsageCpuTimeMS = long.Parse(values[4]),
                    ResourceUsageRowsScanned = int.Parse(values[5]),
                    ResourceUsageRowsReturned = int.Parse(values[6]),
                });
            })
                                .Single();

            #endregion

            #region Insert row
            enginePerformance.Rows.Add(
                TimeSpan.FromMilliseconds(queryDuration),
                TimeSpan.FromMilliseconds(formulaEngineDuration),
                TimeSpan.FromMilliseconds(storageEngineDuration),
                querySubcubeExecutionsCacheData,
                querySubcubeExecutionsNonCacheData,
                cachesRead,
                partitionsRead,
                partitionsHit,
                TimeSpan.FromMilliseconds(partitionsDuration),
                aggregationsRead,
                aggregationsHit,
                TimeSpan.FromMilliseconds(aggregationsDuration),
                resourceUsage.ResourceUsageReads,
                resourceUsage.ResourceUsageReadKB,
                resourceUsage.ResourceUsageWrites,
                resourceUsage.ResourceUsageWriteKB,
                resourceUsage.ResourceUsageCpuTimeMS,
                resourceUsage.ResourceUsageRowsScanned,
                resourceUsage.ResourceUsageRowsReturned
                );
            #endregion

            return(enginePerformance);
        }
        public static Task <ProfilerResult> StartAsync(ProcedureContext procedureContext, CollectorsSynchronizer collectorsSynchronizer, CancellationToken cancellationToken)
        {
            #region Argument exceptions

            if (procedureContext == null)
            {
                throw new ArgumentNullException("procedureContext");
            }
            if (collectorsSynchronizer == null)
            {
                throw new ArgumentNullException("collectorsSynchronizer");
            }
            if (cancellationToken == null)
            {
                throw new ArgumentNullException("cancellationToken");
            }

            #endregion

            var started = new ManualResetEvent(false);
            var faulted = new ManualResetEvent(false);

            var traceTask = new Task <ProfilerResult>(() =>
            {
                #region task

                var profilerResult = ProfilerResult.Create(procedureContext, collectorsSynchronizer);

                using (var server = new Server())
                {
                    server.Connect(procedureContext.ConnectionString);

                    var trace = server.Traces.Find(ProfilerCollector.TraceId);
                    if (trace == null)
                    {
                        throw new ApplicationException("Trace not found [{0}]".FormatWith(ProfilerCollector.TraceName));
                    }

                    var onTraceEventException = default(Exception);
#if ASQASSAS13 || ASQASSAS14
                    var clientActivityID = procedureContext.ClientActivityID.ToString("D");
#endif
                    trace.OnEvent += (s, e) =>
                    {
                        #region OnEvent

                        try
                        {
#if ASQASSAS11 || ASQASSAS12
                            var found = e.ConnectionID == procedureContext.CurrentConnectionID;
#else
                            var found = clientActivityID.Equals(e[TraceColumn.ActivityID], StringComparison.OrdinalIgnoreCase);
#endif
                            if (found)
                            {
                                profilerResult.Add(e);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (onTraceEventException == null)
                            {
                                onTraceEventException = ex;
                            }

                            profilerResult.CollectCompleted.Set();
                        }

                        #endregion
                    };

                    trace.Start();

                    while (!trace.IsStarted)
                    {
                        Thread.Sleep(50);
                    }
                    started.Set();

                    cancellationToken.WaitHandle.WaitOne(Timeout.Infinite);

                    WaitHandle.WaitAny(new []
                    {
                        profilerResult.CollectCompleted,
                        procedureContext.CancellationToken.WaitHandle
                    });

                    if (onTraceEventException != null)
                    {
                        throw onTraceEventException;
                    }

                    if (procedureContext.ExecutionMode == ProcedureExecutionMode.Batch && !procedureContext.IsCancellationRequested)
                    {
                        profilerResult.FlushBatch(completion: true);
                    }

                    trace.Stop();
                }

                return(profilerResult);

                #endregion
            },
                                                      cancellationToken, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);

            traceTask.ContinueWith((previousTask) => faulted.Set(), TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.OnlyOnFaulted);
            traceTask.ContinueWith((previousTask) => collectorsSynchronizer.CompleteAdding(), TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.ExecuteSynchronously);

            traceTask.Start();

            WaitHandle.WaitAny(new []
            {
                started,
                faulted
            });

            return(traceTask);
        }