public PageReportCache(string cacheKey, DateTime lastAccessedUtc, PageReportSummary pageReport, string selectedPageType, PageReportType pageReportType, DateTime dateFrom, DateTime dateTo) { CacheKey = cacheKey; LastAccessedUtc = lastAccessedUtc; ReportSummary = pageReport; SelectedPageType = selectedPageType; PageReportType = pageReportType; DateFrom = dateFrom; DateTo = dateTo; }
public PageReportCache() { SelectedPageType = string.Empty; PageReportType = Report.ReportSummary.PageReportType.DAY; DateFrom = DateTime.MinValue; DateTo = DateTime.MinValue; CacheKey = string.Empty; LastAccessedUtc = DateTime.MinValue; ReportSummary = new PageReportSummary(); }
/// <summary> /// Generate the all page report summary to create a line chart /// </summary> /// <param name="pageReportType"></param> /// <param name="dateFrom"></param> /// <param name="dateTo"></param> /// <returns></returns> public static PageReportSummary GeneratePageReport(PageReportType pageReportType, DateTime dateFrom, DateTime dateTo, string selectedPage = "") { dateFrom = new DateTime(dateFrom.Year, dateFrom.Month, dateFrom.Day, 0, 0, 1); dateTo = new DateTime(dateTo.Year, dateTo.Month, dateTo.Day, 23, 59, 59); PageReportSummary PageReportSummary = new PageReportSummary(); //add 3 lists to represent the all categories if (string.IsNullOrWhiteSpace(selectedPage) || "all".Equals(selectedPage)) { PageReportSummary.PageReportSeriesList.Add(new PageReportSeries { name = "Page Views", data = new List<int>() }); PageReportSummary.PageReportSeriesList.Add(new PageReportSeries { name = "Website Visits", data = new List<int>() }); PageReportSummary.PageReportSeriesList.Add(new PageReportSeries { name = "Unique Website Visits", data = new List<int>() }); } else { PageReportSummary.PageReportSeriesList.Add(new PageReportSeries { name = "Page Views", data = new List<int>() }); } List<PageView> PageViewList = ReportDAO.LoadPageViews(dateFrom, dateTo, selectedPage); if (PageViewList != null && PageViewList.Count > 0) { while (dateFrom <= dateTo) { string DateTimeFormat = GetDateTimeCategoryToString(pageReportType); string Category = dateFrom.ToString(DateTimeFormat); PageReportSummary.MasterCategoryList.Add(Category); if (string.IsNullOrWhiteSpace(selectedPage) || "all".Equals(selectedPage)) { ProcessAllPageReportRow(PageReportSummary, PageViewList, DateTimeFormat, Category); } else { ProcessSpecificPageReportRow(PageReportSummary, PageViewList, DateTimeFormat, Category); } dateFrom = IncreaseDateTime(pageReportType, dateFrom); } ProcessBasicStatistics(PageReportSummary, PageViewList); ProcessBrowserSummary(PageReportSummary, PageViewList); ProcessOperatingSystemSummary(PageReportSummary, PageViewList); } return PageReportSummary; }
/// <summary> /// Check the app cache and see if this report cache has expired. /// </summary> /// <param name="selectedPageType"></param> /// <param name="pageReportType"></param> /// <param name="dateFrom"></param> /// <param name="dateTo"></param> /// <returns></returns> public static PageReportCache GetPageReportSummary(string selectedPageType, PageReportType pageReportType, DateTime dateFrom, DateTime dateTo) { string CacheKey = String.Format("{0}|{1}|{2}|{3}", selectedPageType.ToUpper(), pageReportType, dateFrom.ToString("MM/dd/yyyy"), dateTo.ToString("MM/dd/yyyy")); PageReportSummary ReportSummary = new PageReportSummary(); Dictionary<string, PageReportCache> PageReportDictionary = (Dictionary<string, PageReportCache>)HttpContext.Current.Application[PAGE_REPORT_APP_CACHE] ?? new Dictionary<string, PageReportCache>(); bool RunNewReport = false; if (PageReportDictionary.ContainsKey(CacheKey)) { if (PageReportDictionary[CacheKey].LastAccessedUtc <= DateTime.UtcNow) { RunNewReport = true; } else { ReportSummary = PageReportDictionary[CacheKey].ReportSummary; } } else { RunNewReport = true; } if (RunNewReport) { ReportSummary = PageReport.GeneratePageReport(pageReportType, dateFrom, dateTo, selectedPageType); PageReportDictionary[CacheKey] = new PageReportCache(CacheKey, DateTime.UtcNow.AddHours(1), ReportSummary, selectedPageType, pageReportType, dateFrom, dateTo); HttpContext.Current.Application[PAGE_REPORT_APP_CACHE] = PageReportDictionary; } return PageReportDictionary[CacheKey]; }
/// <summary> /// Only process page views for a specific page report /// </summary> /// <param name="pageReportSummary"></param> /// <param name="pageViewList"></param> /// <param name="dateTimeFormat"></param> /// <param name="category"></param> private static void ProcessSpecificPageReportRow(PageReportSummary pageReportSummary, List<PageView> pageViewList, string dateTimeFormat, string category) { //total count of users this day int PageViewCount = pageViewList.Count(e => e.PageOpenedDateUTC.ToString(dateTimeFormat).Equals(category)); pageReportSummary.PageReportSeriesList[0].data.Add(PageViewCount); }
/// <summary> /// # of different ip addresses per operating system, user is locked into an operating system per ip address /// </summary> /// <param name="pageReportSummary"></param> /// <param name="pageViewList"></param> private static void ProcessOperatingSystemSummary(PageReportSummary pageReportSummary, List<PageView> pageViewList) { List<string> EntityList = pageViewList.Select(e => e.OperatingSystem).Distinct().ToList(); foreach (var Entity in EntityList.OrderBy(e => e)) { if (!pageReportSummary.OperatingSystemSummary.ContainsKey(Entity)) { pageReportSummary.OperatingSystemSummary.Add(Entity, pageViewList.Where(e => e.OperatingSystem.Equals(Entity)).Select(e => e.IpAddress).Distinct().Count()); } } }
/// <summary> /// # of sessions created per browser, user can switch browsers on the same ip address /// </summary> /// <param name="pageReportSummary"></param> /// <param name="pageViewList"></param> private static void ProcessBrowserSummary(PageReportSummary pageReportSummary, List<PageView> pageViewList) { List<string> EntityList = pageViewList.Select(e => e.BrowserNameAndVersion).Distinct().ToList(); foreach (var Entity in EntityList.OrderBy(e => e)) { if (!pageReportSummary.BrowserSummary.ContainsKey(Entity)) { pageReportSummary.BrowserSummary.Add(Entity, pageViewList.Where(e => e.BrowserNameAndVersion.Equals(Entity)).Select(e => e.SessionId).Distinct().Count()); } } }
/// <summary> /// Get the total visits, total page views, total unique visitors, avg pages per session, avg session time /// </summary> /// <param name="pageReportSummary"></param> /// <param name="pageViewList"></param> private static void ProcessBasicStatistics(PageReportSummary pageReportSummary, List<PageView> pageViewList, string selectedPage = "") { pageReportSummary.TotalPageVisits = pageViewList.Count; pageReportSummary.TotalVisits = pageViewList.Select(e => e.SessionId).Distinct().Count(); pageReportSummary.TotalUniqueVistors = pageViewList.Select(e => e.IpAddress).Distinct().Count(); if (string.IsNullOrWhiteSpace(selectedPage) || "all".Equals(selectedPage)) { ProcessAverageSessionTime(pageReportSummary, pageViewList); } else { ProcessAveragePageViewTime(pageReportSummary, pageViewList); } }
/// <summary> /// When viewing an "all" page report process the average session time and pages per visit /// </summary> /// <param name="pageReportSummary"></param> /// <param name="pageViewList"></param> private static void ProcessAverageSessionTime(PageReportSummary pageReportSummary, List<PageView> pageViewList) { Dictionary<Guid, int> PageVisitsPerSession = new Dictionary<Guid, int>(); foreach (var PageV in pageViewList) { if (!PageVisitsPerSession.ContainsKey(PageV.SessionId)) { PageVisitsPerSession.Add(PageV.SessionId, 0); } PageVisitsPerSession[PageV.SessionId]++; } pageReportSummary.PageViewsPerVisit = PageVisitsPerSession.Values.Average(); List<TimeSpan> TimeSpanList = new List<TimeSpan>(); foreach (var SessionId in PageVisitsPerSession.Keys) { DateTime StartDate = pageViewList.Where(e => e.SessionId.Equals(SessionId)).OrderBy(e => e.PageOpenedDateUTC).Select(e => e.PageOpenedDateUTC).FirstOrDefault(); DateTime EndDate = pageViewList.Where(e => e.SessionId.Equals(SessionId) && !e.PageExitDateUTC.Equals(DateTime.MinValue)).OrderByDescending(e => e.PageExitDateUTC).Select(e => e.PageExitDateUTC).FirstOrDefault(); if (!StartDate.Equals(DateTime.MinValue) && !EndDate.Equals(DateTime.MinValue)) { TimeSpanList.Add(EndDate.Subtract(StartDate)); } } pageReportSummary.AverageVisitDuration = new TimeSpan(Convert.ToInt64(TimeSpanList.Average(timeSpan => timeSpan.Ticks))); }
/// <summary> /// When a specific page is selected process its average page view time /// </summary> private static void ProcessAveragePageViewTime(PageReportSummary pageReportSummary, List<PageView> pageViewList) { List<TimeSpan> TimeSpanList = new List<TimeSpan>(); foreach(var PageV in pageViewList) { if (!PageV.PageOpenedDateUTC.Equals(DateTime.MinValue) && !PageV.PageExitDateUTC.Equals(DateTime.MinValue)) { TimeSpanList.Add(PageV.PageExitDateUTC.Subtract(PageV.PageOpenedDateUTC)); } } pageReportSummary.AverageVisitDuration = new TimeSpan(Convert.ToInt64(TimeSpanList.Average(timeSpan => timeSpan.Ticks))); }
/// <summary> /// Process a category row for the all page report /// </summary> /// <param name="pageReportSummary"></param> /// <param name="pageViewList"></param> /// <param name="dateTimeFormat"></param> /// <param name="category"></param> private static void ProcessAllPageReportRow(PageReportSummary pageReportSummary, List<PageView> pageViewList, string dateTimeFormat, string category) { //total count of users this day int PageViewCount = pageViewList.Count(e => e.PageOpenedDateUTC.ToString(dateTimeFormat).Equals(category)); //website visits (count # sessions on that day) int WebsiteVisitCount = pageViewList.Where(e => e.PageOpenedDateUTC.ToString(dateTimeFormat).Equals(category)).Select(e => e.SessionId).Distinct().Count(); //unique website vists (count # distnct sessions by ip on that day) int UniqueWebsiteVisitCount = pageViewList.Where(e => e.PageOpenedDateUTC.ToString(dateTimeFormat).Equals(category)).Select(e => e.IpAddress).Distinct().Count(); pageReportSummary.PageReportSeriesList[0].data.Add(PageViewCount); pageReportSummary.PageReportSeriesList[1].data.Add(WebsiteVisitCount); pageReportSummary.PageReportSeriesList[2].data.Add(UniqueWebsiteVisitCount); }