Class: Sentiero::Analytics::StatsAggregator

Inherits:
Analyzer
  • Object
show all
Defined in:
lib/sentiero/analytics/stats_aggregator.rb,
lib/sentiero/analytics/stats_aggregator/result_builder.rb

Defined Under Namespace

Classes: Accumulator, ResultBuilder

Constant Summary collapse

TOP_LIST_LIMIT =
10
TOP_TAGS_LIMIT =
20
TOP_PROBLEMS_LIMIT =
5
"navigation"
SCAN_TYPES =

With native aggregates (SQLite) the scan reads only Meta + Custom; the type histogram, total count and per-day series come from the store in #finalize. Other stores keep the single all-types scan — the aggregate fallbacks would each re-scan the store.

[META, CUSTOM].freeze
INTERNAL_METADATA_KEYS =
%w[userAgent url referrer viewport has_errors entry_url entry_referrer
geo_country geo_city geo_region geo_timezone].freeze
MAX_NAV_KEYS =
200
MAX_METADATA_KEYS =
50
MAX_METADATA_VALUES_PER_KEY =
50
MAX_TAG_SERIES_KEYS =
200
MAX_OVERLAY_PROBLEMS =
200
MAX_OCCURRENCES_PER_PROBLEM =
500
MAX_GEO_VALUES =
200
DURATION_BUCKETS =
[
  ["0-30s", 30_000],
  ["30s-2m", 120_000],
  ["2-5m", 300_000],
  ["5-15m", 900_000],
  ["15m+", nil]
].freeze
WEEK_BUCKET_THRESHOLD_DAYS =
45

Constants included from Events

Events::CUSTOM, Events::INCREMENTAL, Events::META, Events::SOURCE_INPUT, Events::SOURCE_MOUSE_INTERACTION, Events::SOURCE_SCROLL

Instance Attribute Summary

Attributes inherited from Analyzer

#store

Instance Method Summary collapse

Methods inherited from Analyzer

#initialize

Methods included from EntryAttribution

#earlier?, #first_meta_href, #same_origin?, #update_entry_candidate

Methods included from Bounded

#bounded_fetch, #bounded_increment

Methods included from Stats

#mean, #offset_ms, #percentile, #top_counts

Constructor Details

This class inherits a constructor from Sentiero::Analytics::Analyzer

Instance Method Details

#aggregate(range_days: 30, since: nil, until_time: nil, server_exception_overlay: false) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/sentiero/analytics/stats_aggregator.rb', line 48

def aggregate(range_days: 30, since: nil, until_time: nil, server_exception_overlay: false)
  scan_cap = store.limits.analytics_max_scan_sessions
  since ||= default_since(range_days, until_time)

  acc = new_accumulator(since, until_time)
  seen_sessions = {}

  store.each_session_events(limit: scan_cap, since: since, until_time: until_time, types: scan_types) do |summary, _window_id, events|
    accumulate_window(acc, seen_sessions, summary, events)
  end

  finalize(acc, seen_sessions, scan_cap, overlay: server_exception_overlay)
end

#aggregate_with_prior(range_days: 30, since: nil, until_time: nil) ⇒ Object

Derives BOTH the current-window aggregate and the equal-length prior-window aggregate from a SINGLE widened scan over [prior_since, until_time], partitioning each session into the current or prior bucket by its updated_at. Returns prior:; prior is nil when no comparison is possible (zero-length window) or when the widened scan is truncated — in which case the current aggregate is recomputed from an exact single-window scan so the displayed numbers stay correct (deltas are dropped on truncation anyway).



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/sentiero/analytics/stats_aggregator.rb', line 70

def aggregate_with_prior(range_days: 30, since: nil, until_time: nil)
  scan_cap = store.limits.analytics_max_scan_sessions
  since ||= default_since(range_days, until_time)
  window_until = until_time || Time.now.to_f
  span = window_until - since

  return {current: aggregate(since: since, until_time: until_time, server_exception_overlay: true), prior: nil} unless span > 0

  prior_since = since - span
  prior_until = since - 0.001

  current = {acc: new_accumulator(since, until_time), seen: {}}
  prior = {acc: new_accumulator(prior_since, prior_until), seen: {}}

  store.each_session_events(limit: scan_cap, since: prior_since, until_time: until_time, types: scan_types) do |summary, _window_id, events|
    bucket = (summary[:updated_at] >= since) ? current : prior
    accumulate_window(bucket[:acc], bucket[:seen], summary, events)
  end

  if current[:seen].size + prior[:seen].size >= scan_cap
    return {current: aggregate(since: since, until_time: until_time, server_exception_overlay: true), prior: nil}
  end

  {
    current: finalize(current[:acc], current[:seen], scan_cap, overlay: true),
    prior: finalize(prior[:acc], prior[:seen], scan_cap, overlay: false)
  }
end