コード例 #1
0
        public StackStatsResult GetErrorStackStatsByMinuteBlock(string errorStackId, TimeSpan utcOffset, DateTime? localStartDate = null, DateTime? localEndDate = null, DateTime? retentionStartDate = null) {
            if (localStartDate == null)
                localStartDate = new DateTime(2012, 1, 1);

            if (localEndDate == null)
                localEndDate = DateTime.UtcNow.Add(utcOffset);

            localStartDate = localStartDate.Value.Floor(TimeSpan.FromMinutes(15));
            localEndDate = localEndDate.Value.Ceiling(TimeSpan.FromMinutes(15));
            if (retentionStartDate.HasValue)
                retentionStartDate = retentionStartDate.Value.Floor(TimeSpan.FromMinutes(15));

            if (localEndDate.Value <= localStartDate.Value)
                throw new ArgumentException("End date must be greater than start date.", "localEndDate");

            DateTime utcStartDate = new DateTimeOffset(localStartDate.Value.Ticks, utcOffset).UtcDateTime;
            DateTime utcEndDate = new DateTimeOffset(localEndDate.Value.Ticks, utcOffset).UtcDateTime;

            List<DayStackStats> results = _dayStackStats.Collection.Find(Query.And(Query.GTE(MonthStackStatsRepository.FieldNames.Id, GetDayStackStatsId(errorStackId, utcStartDate)), Query.LTE(MonthStackStatsRepository.FieldNames.Id, GetDayStackStatsId(errorStackId, utcEndDate)))).ToList();

            if (results.Count > 0) {
                DayStackStats firstWithOccurrence = results.OrderBy(r => r.Id).FirstOrDefault(r => r.MinuteStats.Any(ds => ds.Value > 0));
                if (firstWithOccurrence != null) {
                    DateTime firstErrorDate = firstWithOccurrence.GetDateFromMinuteStatKey(firstWithOccurrence.MinuteStats.OrderBy(ds => Int32.Parse(ds.Key)).First(ds => ds.Value > 0).Key);
                    if (utcStartDate < firstErrorDate)
                        utcStartDate = firstErrorDate;
                }
            }

            var dayDocDates = new List<DateTime>();
            DateTime currentDay = utcStartDate;
            DateTime endOfDayEndDate = utcEndDate.ToEndOfDay();
            while (currentDay <= endOfDayEndDate) {
                dayDocDates.Add(currentDay);
                currentDay = currentDay.AddDays(1);
            }

            // add missing day documents
            foreach (DateTime dayDocDate in dayDocDates) {
                if (!results.Exists(d => d.Id == GetDayStackStatsId(errorStackId, dayDocDate)))
                    results.Add(CreateBlankDayStackStats(dayDocDate, errorStackId));
            }

            // fill out missing minute blocks with blank stats
            foreach (DayStackStats r in results) {
                const int minuteBlocksInDay = 96;
                for (int i = 0; i <= minuteBlocksInDay - 1; i++) {
                    int minuteBlock = i * 15;
                    if (!r.MinuteStats.ContainsKey(minuteBlock.ToString("0000")))
                        r.MinuteStats.Add(minuteBlock.ToString("0000"), 0);
                }
            }

            var minuteBlocks = new List<KeyValuePair<DateTime, int>>();
            minuteBlocks = results.Aggregate(minuteBlocks, (current, result) => current.Concat(result.MinuteStats.ToDictionary(kvp => result.GetDateFromMinuteStatKey(kvp.Key), kvp => kvp.Value)).ToList())
                .Where(kvp => kvp.Key >= utcStartDate && kvp.Key <= utcEndDate).OrderBy(kvp => kvp.Key).ToList();

            int totalLimitedByPlan = retentionStartDate != null && utcStartDate < retentionStartDate ? minuteBlocks.Count(kvp => kvp.Key < retentionStartDate) : 0;
            if (totalLimitedByPlan > 0)
                minuteBlocks = minuteBlocks.Where(kvp => kvp.Key >= retentionStartDate).ToList();

            // group data points by a timespan to limit the number of returned data points
            TimeSpan groupTimeSpan = TimeSpan.FromMinutes(15);
            if (minuteBlocks.Count > 50) {
                DateTime first = minuteBlocks.Min(m => m.Key);
                DateTime last = minuteBlocks.Max(m => m.Key);
                TimeSpan span = last - first;
                groupTimeSpan = TimeSpan.FromMinutes(((int)Math.Round(span.TotalMinutes / 50 / 15.0)) * 15);
            }

            var stats = new StackStatsResult {
                TotalLimitedByPlan = totalLimitedByPlan,
                StartDate = utcStartDate,
                EndDate = utcEndDate,
                Total = minuteBlocks.Sum(kvp => kvp.Value),
                Stats = minuteBlocks.GroupBy(s => s.Key.Floor(groupTimeSpan)).Select(kvp => new DateStackStatsResult {
                    Date = kvp.Key,
                    Total = kvp.Sum(b => b.Value)
                }).ToList()
            };

            stats.ApplyTimeOffset(utcOffset);

            return stats;
        }
コード例 #2
0
        public ProjectErrorStatsResult GetProjectErrorStatsByMinuteBlock(string projectId, TimeSpan utcOffset, DateTime? localStartDate = null, DateTime? localEndDate = null, DateTime? retentionStartDate = null, bool includeHidden = false, bool includeFixed = false, bool includeNotFound = true) {
            if (localStartDate == null)
                localStartDate = new DateTime(2012, 1, 1);

            if (localEndDate == null)
                localEndDate = DateTime.UtcNow.Add(utcOffset);

            // round date range to blocks of 15 minutes since stats are per 15 minute block
            localStartDate = localStartDate.Value.Floor(TimeSpan.FromMinutes(15));
            localEndDate = localEndDate.Value.Ceiling(TimeSpan.FromMinutes(15));
            if (retentionStartDate.HasValue)
                retentionStartDate = retentionStartDate.Value.Floor(TimeSpan.FromMinutes(15));

            if (localEndDate.Value <= localStartDate.Value)
                throw new ArgumentException("End date must be greater than start date.", "localEndDate");

            DateTime utcStartDate = new DateTimeOffset(localStartDate.Value.Ticks, utcOffset).UtcDateTime;
            DateTime utcEndDate = new DateTimeOffset(localEndDate.Value.Ticks, utcOffset).UtcDateTime;

            List<DayProjectStats> results = _dayProjectStats.Collection.Find(Query.And(
                                                                                       Query.GTE(MonthProjectStatsRepository.FieldNames.Id, GetDayProjectStatsId(projectId, utcStartDate)),
                Query.LTE(MonthProjectStatsRepository.FieldNames.Id, GetDayProjectStatsId(projectId, utcEndDate))
                )).ToList();

            if (results.Count > 0) {
                DayProjectStats firstWithOccurrence = results.OrderBy(r => r.Id).FirstOrDefault(r => r.MinuteStats.Any(ds => ds.Value.Total > 0));
                if (firstWithOccurrence != null) {
                    DateTime firstErrorDate = firstWithOccurrence.GetDateFromMinuteStatKey(firstWithOccurrence.MinuteStats.OrderBy(ds => Int32.Parse(ds.Key)).First(ds => ds.Value.Total > 0).Key);
                    if (utcStartDate < firstErrorDate)
                        utcStartDate = firstErrorDate;
                }

                if (!includeHidden) {
                    // remove stats from hidden doc ids.
                    string[] hiddenIds = _errorStackRepository.GetHiddenIds(projectId);
                    if (hiddenIds.Length > 0)
                        DecrementDayProjectStatsByStackIds(results, hiddenIds);
                }

                if (!includeNotFound) {
                    // remove stats from not found doc ids.
                    string[] notFoundIds = _errorStackRepository.GetNotFoundIds(projectId);
                    if (notFoundIds.Length > 0)
                        DecrementDayProjectStatsByStackIds(results, notFoundIds);
                }

                if (!includeFixed) {
                    // remove stats from not found doc ids.
                    string[] fixedIds = _errorStackRepository.GetFixedIds(projectId);
                    if (fixedIds.Length > 0)
                        DecrementDayProjectStatsByStackIds(results, fixedIds);
                }
            }

            var dayDocDates = new List<DateTime>();
            DateTime currentDay = utcStartDate;
            DateTime endOfDayEndDate = utcEndDate.ToEndOfDay();
            while (currentDay <= endOfDayEndDate) {
                dayDocDates.Add(currentDay);
                currentDay = currentDay.AddDays(1);
            }

            // add missing day documents
            foreach (DateTime dayDocDate in dayDocDates) {
                if (!results.Exists(d => d.Id == GetDayProjectStatsId(projectId, dayDocDate)))
                    results.Add(CreateBlankDayProjectStats(dayDocDate, projectId));
            }

            // fill out missing minute blocks with blank stats
            foreach (DayProjectStats r in results) {
                const int minuteBlocksInDay = 96;
                for (int i = 0; i <= minuteBlocksInDay - 1; i++) {
                    int minuteBlock = i * 15;
                    if (!r.MinuteStats.ContainsKey(minuteBlock.ToString("0000")))
                        r.MinuteStats.Add(minuteBlock.ToString("0000"), new ErrorStatsWithStackIds());
                }
            }

            var minuteBlocks = new List<KeyValuePair<DateTime, ErrorStatsWithStackIds>>();
            minuteBlocks = results.Aggregate(minuteBlocks, (current, result) => current.Concat(result.MinuteStats.ToDictionary(kvp => result.GetDateFromMinuteStatKey(kvp.Key), kvp => kvp.Value)).ToList())
                .Where(kvp => kvp.Key >= utcStartDate && kvp.Key <= utcEndDate).OrderBy(kvp => kvp.Key).ToList();

            int totalLimitedByPlan = retentionStartDate != null && utcStartDate < retentionStartDate
                ? minuteBlocks.Where(kvp => kvp.Key < retentionStartDate).SelectMany(kvp => kvp.Value.ErrorStackIds.Select(s => s.Key)).Distinct()
                    .Except(minuteBlocks.Where(kvp => kvp.Key >= retentionStartDate).SelectMany(kvp => kvp.Value.ErrorStackIds.Select(s => s.Key)).Distinct())
                    .Count()
                : 0;

            if (totalLimitedByPlan > 0)
                minuteBlocks = minuteBlocks.Where(kvp => kvp.Key >= retentionStartDate).ToList();

            // group data points by a timespan to limit the number of returned data points
            TimeSpan groupTimeSpan = TimeSpan.FromMinutes(15);
            if (minuteBlocks.Count > 50) {
                DateTime first = minuteBlocks.Min(m => m.Key);
                DateTime last = minuteBlocks.Max(m => m.Key);
                TimeSpan span = last - first;
                groupTimeSpan = TimeSpan.FromMinutes(((int)Math.Round(span.TotalMinutes / 50 / 15.0)) * 15);
            }

            var stats = new ProjectErrorStatsResult {
                TotalLimitedByPlan = totalLimitedByPlan,
                StartDate = utcStartDate,
                EndDate = utcEndDate,
                Total = minuteBlocks.Sum(kvp => kvp.Value.Total),
                UniqueTotal = minuteBlocks.SelectMany(kvp => kvp.Value.ErrorStackIds.Select(s => s.Key)).Distinct().Count(),
                NewTotal = minuteBlocks.Sum(kvp => kvp.Value.NewTotal),
                MostFrequent = new PlanPagedResult<ErrorStackResult>(minuteBlocks.SelectMany(kvp => kvp.Value.ErrorStackIds).GroupBy(kvp => kvp.Key)
                    .Select(v => new ErrorStackResult {
                        Id = v.Key,
                        Total = v.Sum(kvp => kvp.Value),
                    }).OrderByDescending(s => s.Total).ToList(), totalLimitedByPlan),
                Stats = minuteBlocks.GroupBy(s => s.Key.Floor(groupTimeSpan)).Select(kvp => new DateProjectStatsResult {
                    Date = kvp.Key,
                    Total = kvp.Sum(b => b.Value.Total),
                    NewTotal = kvp.Sum(b => b.Value.NewTotal),
                    UniqueTotal = kvp.Select(b => b.Value.ErrorStackIds).Aggregate((current, result) => Merge(result, current)).Count()
                }).ToList()
            };

            stats.ApplyTimeOffset(utcOffset);

            return stats;
        }
コード例 #3
0
        public StackStatsResult GetStackStatsByMinuteBlock(string stackId, TimeSpan utcOffset, DateTime?localStartDate = null, DateTime?localEndDate = null, DateTime?retentionStartDate = null)
        {
            // Round date range to blocks of 15 minutes since stats are per 15 minute block.
            var range = GetDateRange(localStartDate, localEndDate, utcOffset, TimeSpan.FromMinutes(15));

            if (range.Item1 == range.Item2)
            {
                return(new StackStatsResult());
            }

            DateTime utcStartDate = new DateTimeOffset(range.Item1.Ticks, utcOffset).UtcDateTime;
            DateTime utcEndDate   = new DateTimeOffset(range.Item2.Ticks, utcOffset).UtcDateTime;


            var results = _dayStackStats.GetRange(GetDayStackStatsId(stackId, utcStartDate), GetDayStackStatsId(stackId, utcEndDate));

            if (results.Count > 0)
            {
                DayStackStats firstWithOccurrence = results.OrderBy(r => r.Id).FirstOrDefault(r => r.MinuteStats.Any(ds => ds.Value > 0));
                if (firstWithOccurrence != null)
                {
                    DateTime firstErrorDate = firstWithOccurrence.GetDateFromMinuteStatKey(firstWithOccurrence.MinuteStats.OrderBy(ds => Int32.Parse(ds.Key)).First(ds => ds.Value > 0).Key);
                    if (utcStartDate < firstErrorDate)
                    {
                        utcStartDate = firstErrorDate;
                    }
                }
            }

            var      dayDocDates     = new List <DateTime>();
            DateTime currentDay      = utcStartDate;
            DateTime endOfDayEndDate = utcEndDate.ToEndOfDay();

            while (currentDay <= endOfDayEndDate)
            {
                dayDocDates.Add(currentDay);
                currentDay = currentDay.AddDays(1);
            }

            // add missing day documents
            foreach (DateTime dayDocDate in dayDocDates)
            {
                if (!results.Any(d => d.Id == GetDayStackStatsId(stackId, dayDocDate)))
                {
                    results.Add(CreateBlankDayStackStats(dayDocDate, stackId));
                }
            }

            // fill out missing minute blocks with blank stats
            foreach (DayStackStats r in results)
            {
                const int minuteBlocksInDay = 96;
                for (int i = 0; i <= minuteBlocksInDay - 1; i++)
                {
                    int minuteBlock = i * 15;
                    if (!r.MinuteStats.ContainsKey(minuteBlock.ToString("0000")))
                    {
                        r.MinuteStats.Add(minuteBlock.ToString("0000"), 0);
                    }
                }
            }

            if (retentionStartDate.HasValue)
            {
                retentionStartDate = retentionStartDate.Value.Floor(TimeSpan.FromMinutes(15));
            }

            var minuteBlocks = new List <KeyValuePair <DateTime, int> >();

            minuteBlocks = results.Aggregate(minuteBlocks, (current, result) => current.Concat(result.MinuteStats.ToDictionary(kvp => result.GetDateFromMinuteStatKey(kvp.Key), kvp => kvp.Value)).ToList())
                           .Where(kvp => kvp.Key >= utcStartDate && kvp.Key <= utcEndDate).OrderBy(kvp => kvp.Key).ToList();

            int totalLimitedByPlan = retentionStartDate != null && utcStartDate < retentionStartDate?minuteBlocks.Count(kvp => kvp.Key < retentionStartDate) : 0;

            if (totalLimitedByPlan > 0)
            {
                minuteBlocks = minuteBlocks.Where(kvp => kvp.Key >= retentionStartDate).ToList();
            }

            // group data points by a timespan to limit the number of returned data points
            TimeSpan groupTimeSpan = TimeSpan.FromMinutes(15);

            if (minuteBlocks.Count > 50)
            {
                DateTime first = minuteBlocks.Min(m => m.Key);
                DateTime last  = minuteBlocks.Max(m => m.Key);
                TimeSpan span  = last - first;
                groupTimeSpan = TimeSpan.FromMinutes(((int)Math.Round(span.TotalMinutes / 50 / 15.0)) * 15);
            }

            var stats = new StackStatsResult {
                TotalLimitedByPlan = totalLimitedByPlan,
                StartDate          = utcStartDate,
                EndDate            = utcEndDate,
                Total = minuteBlocks.Sum(kvp => kvp.Value),
                Stats = minuteBlocks.GroupBy(s => s.Key.Floor(groupTimeSpan)).Select(kvp => new DateStackStatsResult {
                    Date  = kvp.Key,
                    Total = kvp.Sum(b => b.Value)
                }).ToList()
            };

            stats.ApplyTimeOffset(utcOffset);

            return(stats);
        }
コード例 #4
0
        public void ToEndOfDay_does_set_hour_minute_and_second_23_59_59()
        {
            var middleOfDay = new DateTimeOffset(2017, 7, 31, 1, 2, 3, TimeSpan.FromHours(5));

            Assert.Equal(new DateTimeOffset(2017, 7, 31, 23, 59, 59, TimeSpan.FromHours(5)), middleOfDay.ToEndOfDay());
        }
コード例 #5
0
        public ProjectEventStatsResult GetProjectEventStatsByMinuteBlock(string projectId, TimeSpan utcOffset, DateTime?localStartDate = null, DateTime?localEndDate = null, DateTime?retentionStartDate = null, bool includeHidden = false, bool includeFixed = false, bool includeNotFound = true)
        {
            // Round date range to blocks of 15 minutes since stats are per 15 minute block.
            var range = GetDateRange(localStartDate, localEndDate, utcOffset, TimeSpan.FromMinutes(15));

            if (range.Item1 == range.Item2)
            {
                return(new ProjectEventStatsResult());
            }

            DateTime utcStartDate = new DateTimeOffset(range.Item1.Ticks, utcOffset).UtcDateTime;
            DateTime utcEndDate   = new DateTimeOffset(range.Item2.Ticks, utcOffset).UtcDateTime;

            var results = _dayProjectStats.GetRange(GetDayProjectStatsId(projectId, utcStartDate), GetDayProjectStatsId(projectId, utcEndDate));

            if (results.Count > 0)
            {
                DayProjectStats firstWithOccurrence = results.OrderBy(r => r.Id).FirstOrDefault(r => r.MinuteStats.Any(ds => ds.Value.Total > 0));
                if (firstWithOccurrence != null)
                {
                    DateTime firstErrorDate = firstWithOccurrence.GetDateFromMinuteStatKey(firstWithOccurrence.MinuteStats.OrderBy(ds => Int32.Parse(ds.Key)).First(ds => ds.Value.Total > 0).Key);
                    if (utcStartDate < firstErrorDate)
                    {
                        utcStartDate = firstErrorDate;
                    }
                }

                if (!includeHidden)
                {
                    // remove stats from hidden doc ids.
                    string[] hiddenIds = _stackRepository.GetHiddenIds(projectId);
                    if (hiddenIds.Length > 0)
                    {
                        DecrementDayProjectStatsByStackIds(results, hiddenIds);
                    }
                }

                if (!includeNotFound)
                {
                    // remove stats from not found doc ids.
                    string[] notFoundIds = _stackRepository.GetNotFoundIds(projectId);
                    if (notFoundIds.Length > 0)
                    {
                        DecrementDayProjectStatsByStackIds(results, notFoundIds);
                    }
                }

                if (!includeFixed)
                {
                    // remove stats from not found doc ids.
                    string[] fixedIds = _stackRepository.GetFixedIds(projectId);
                    if (fixedIds.Length > 0)
                    {
                        DecrementDayProjectStatsByStackIds(results, fixedIds);
                    }
                }
            }

            var      dayDocDates     = new List <DateTime>();
            DateTime currentDay      = utcStartDate;
            DateTime endOfDayEndDate = utcEndDate.ToEndOfDay();

            while (currentDay <= endOfDayEndDate)
            {
                dayDocDates.Add(currentDay);
                currentDay = currentDay.AddDays(1);
            }

            // add missing day documents
            foreach (DateTime dayDocDate in dayDocDates)
            {
                if (!results.Any(d => d.Id == GetDayProjectStatsId(projectId, dayDocDate)))
                {
                    results.Add(CreateBlankDayProjectStats(dayDocDate, projectId));
                }
            }

            // fill out missing minute blocks with blank stats
            foreach (DayProjectStats r in results)
            {
                const int minuteBlocksInDay = 96;
                for (int i = 0; i <= minuteBlocksInDay - 1; i++)
                {
                    int minuteBlock = i * 15;
                    if (!r.MinuteStats.ContainsKey(minuteBlock.ToString("0000")))
                    {
                        r.MinuteStats.Add(minuteBlock.ToString("0000"), new EventStatsWithStackIds());
                    }
                }
            }

            if (retentionStartDate.HasValue)
            {
                retentionStartDate = retentionStartDate.Value.Floor(TimeSpan.FromMinutes(15));
            }

            var minuteBlocks = new List <KeyValuePair <DateTime, EventStatsWithStackIds> >();

            minuteBlocks = results.Aggregate(minuteBlocks, (current, result) => current.Concat(result.MinuteStats.ToDictionary(kvp => result.GetDateFromMinuteStatKey(kvp.Key), kvp => kvp.Value)).ToList())
                           .Where(kvp => kvp.Key >= utcStartDate && kvp.Key <= utcEndDate).OrderBy(kvp => kvp.Key).ToList();

            int totalLimitedByPlan = retentionStartDate != null && utcStartDate < retentionStartDate
                ? minuteBlocks.Where(kvp => kvp.Key < retentionStartDate).SelectMany(kvp => kvp.Value.StackIds.Select(s => s.Key)).Distinct()
                                     .Except(minuteBlocks.Where(kvp => kvp.Key >= retentionStartDate).SelectMany(kvp => kvp.Value.StackIds.Select(s => s.Key)).Distinct())
                                     .Count()
                : 0;

            if (totalLimitedByPlan > 0)
            {
                minuteBlocks = minuteBlocks.Where(kvp => kvp.Key >= retentionStartDate).ToList();
            }

            // group data points by a timespan to limit the number of returned data points
            TimeSpan groupTimeSpan = TimeSpan.FromMinutes(15);

            if (minuteBlocks.Count > 50)
            {
                DateTime first = minuteBlocks.Min(m => m.Key);
                DateTime last  = minuteBlocks.Max(m => m.Key);
                TimeSpan span  = last - first;
                groupTimeSpan = TimeSpan.FromMinutes(((int)Math.Round(span.TotalMinutes / 50 / 15.0)) * 15);
            }

            var stats = new ProjectEventStatsResult {
                TotalLimitedByPlan = totalLimitedByPlan,
                StartDate          = utcStartDate,
                EndDate            = utcEndDate,
                Total        = minuteBlocks.Sum(kvp => kvp.Value.Total),
                UniqueTotal  = minuteBlocks.SelectMany(kvp => kvp.Value.StackIds.Select(s => s.Key)).Distinct().Count(),
                NewTotal     = minuteBlocks.Sum(kvp => kvp.Value.NewTotal),
                MostFrequent = new PlanPagedResult <EventStackResult>(minuteBlocks.SelectMany(kvp => kvp.Value.StackIds).GroupBy(kvp => kvp.Key)
                                                                      .Select(v => new EventStackResult {
                    Id    = v.Key,
                    Total = v.Sum(kvp => kvp.Value),
                }).OrderByDescending(s => s.Total).ToList(), totalLimitedByPlan: totalLimitedByPlan, totalCount: minuteBlocks.Count),
                Stats = minuteBlocks.GroupBy(s => s.Key.Floor(groupTimeSpan)).Select(kvp => new DateProjectStatsResult {
                    Date        = kvp.Key,
                    Total       = kvp.Sum(b => b.Value.Total),
                    NewTotal    = kvp.Sum(b => b.Value.NewTotal),
                    UniqueTotal = kvp.Select(b => b.Value.StackIds).Aggregate((current, result) => Merge(result, current)).Count()
                }).ToList()
            };

            stats.ApplyTimeOffset(utcOffset);

            return(stats);
        }