Class: ChronoForge::Dashboard::AnalyticsQuery
- Inherits:
-
Object
- Object
- ChronoForge::Dashboard::AnalyticsQuery
- Defined in:
- app/queries/chrono_forge/dashboard/analytics_query.rb
Overview
Time-bucketed completion/failure/duration metrics over a window.
The aggregation runs in the database (GROUP BY a per-day bucket), so it returns one row per day regardless of how many workflows match — it never loads workflow rows into Ruby. The bucket and duration expressions are adapter-specific (SQLite / PostgreSQL / MySQL), chosen once per query.
Scale note: completed workflows are bucketed (and windowed) by ‘completed_at`, which is the leading-range column of the existing `[state, completed_at]` index, so the heavy path (millions of completed rows) is an index range scan. Failed workflows have no `completed_at`, so they are bucketed by `updated_at` (when they reached the failed state) —a tiny set in practice. The two terminal axes are merged per day.
Rates here are WORKFLOW-level, not execution-log level: a high count of failed *execution logs* is normal durably_repeat catch-up churn, whereas a failed workflow is a real incident. This query only ever counts workflows.
Defined Under Namespace
Classes: Bucket
Constant Summary collapse
- WINDOWS =
{"24h" => 1.day, "7d" => 7.days, "30d" => 30.days}.freeze
- DEFAULT_WINDOW =
"7d"
Instance Attribute Summary collapse
-
#job_class ⇒ Object
readonly
Returns the value of attribute job_class.
-
#since ⇒ Object
readonly
Returns the value of attribute since.
-
#window ⇒ Object
readonly
Returns the value of attribute window.
Instance Method Summary collapse
-
#buckets ⇒ Object
Per-day buckets within the window, oldest first.
-
#initialize(window: DEFAULT_WINDOW, job_class: nil, now: Time.current) ⇒ AnalyticsQuery
constructor
A new instance of AnalyticsQuery.
-
#top_errors(limit: 8) ⇒ Object
The most frequent error classes in the window, highest first, as an ordered => count hash.
-
#totals ⇒ Object
Roll-ups over the whole window: counts, workflow-level rates (nil when no terminal workflows), and average completed duration in seconds.
- #windows ⇒ Object
Constructor Details
#initialize(window: DEFAULT_WINDOW, job_class: nil, now: Time.current) ⇒ AnalyticsQuery
Returns a new instance of AnalyticsQuery.
29 30 31 32 33 34 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 29 def initialize(window: DEFAULT_WINDOW, job_class: nil, now: Time.current) @window = WINDOWS.key?(window.presence) ? window : DEFAULT_WINDOW @job_class = job_class.presence @now = now @since = now - WINDOWS.fetch(@window) end |
Instance Attribute Details
#job_class ⇒ Object (readonly)
Returns the value of attribute job_class.
36 37 38 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 36 def job_class @job_class end |
#since ⇒ Object (readonly)
Returns the value of attribute since.
36 37 38 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 36 def since @since end |
#window ⇒ Object (readonly)
Returns the value of attribute window.
36 37 38 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 36 def window @window end |
Instance Method Details
#buckets ⇒ Object
Per-day buckets within the window, oldest first.
41 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 41 def buckets = data[:buckets] |
#top_errors(limit: 8) ⇒ Object
The most frequent error classes in the window, highest first, as an ordered => count hash. Scoped to the class when set.
49 50 51 52 53 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 49 def top_errors(limit: 8) rel = ChronoForge::ErrorLog.where(created_at: @since..@now) rel = rel.joins(:workflow).where(ChronoForge::Workflow.table_name => {job_class: @job_class}) if @job_class rel.group(:error_class).order(Arel.sql("COUNT(*) DESC")).limit(limit).count end |
#totals ⇒ Object
Roll-ups over the whole window: counts, workflow-level rates (nil when no terminal workflows), and average completed duration in seconds.
45 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 45 def totals = data[:totals] |
#windows ⇒ Object
38 |
# File 'app/queries/chrono_forge/dashboard/analytics_query.rb', line 38 def windows = WINDOWS.keys |