mirror of
https://github.com/discourse/discourse.git
synced 2025-05-06 14:34:42 +08:00

introduces comprehensive statistics tracking for the Discourse Automation plugin, allowing users to monitor the performance and execution patterns of their automations: - Add `discourse_automation_stats` table to track execution metrics including run counts, execution times, and performance data - Create a new `Stat` model to handle tracking and retrieving automation statistics - Update the admin UI to display automation stats (runs today/this week/month and last run time) - Modernize the automation list interface using Glimmer components - Replace the older enable/disable icon with a toggle switch for better UX - Add schema annotations to existing models for better code documentation - Include extensive test coverage for the new statistics functionality This helps administrators understand how their automations are performing and identify potential bottlenecks or optimization opportunities. --------- Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com> Co-authored-by: Ted Johansson <ted@discourse.org>
129 lines
4.1 KiB
Ruby
129 lines
4.1 KiB
Ruby
# frozen_string_literal: true
|
|
#
|
|
module DiscourseAutomation
|
|
class Stat < ActiveRecord::Base
|
|
self.table_name = "discourse_automation_stats"
|
|
|
|
def self.log(automation_id, run_time = nil)
|
|
if block_given? && run_time.nil?
|
|
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
result = yield
|
|
run_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
|
result
|
|
end
|
|
ensure
|
|
update_stats(automation_id, run_time)
|
|
end
|
|
|
|
def self.fetch_period_summaries
|
|
today = Date.current
|
|
|
|
# Define our time periods
|
|
periods = {
|
|
last_day: {
|
|
start_date: today - 1.day,
|
|
end_date: today,
|
|
},
|
|
last_week: {
|
|
start_date: today - 1.week,
|
|
end_date: today,
|
|
},
|
|
last_month: {
|
|
start_date: today - 1.month,
|
|
end_date: today,
|
|
},
|
|
}
|
|
|
|
result = {}
|
|
|
|
periods.each do |period_name, date_range|
|
|
builder = DB.build <<~SQL
|
|
SELECT
|
|
automation_id,
|
|
SUM(total_runs) AS total_runs,
|
|
SUM(total_time) AS total_time,
|
|
CASE WHEN SUM(total_runs) > 0
|
|
THEN SUM(total_time) / SUM(total_runs)
|
|
ELSE 0
|
|
END AS average_run_time,
|
|
MIN(min_run_time) AS min_run_time,
|
|
MAX(max_run_time) AS max_run_time
|
|
FROM discourse_automation_stats
|
|
WHERE date >= :start_date AND date <= :end_date
|
|
GROUP BY automation_id
|
|
SQL
|
|
|
|
stats = builder.query(start_date: date_range[:start_date], end_date: date_range[:end_date])
|
|
|
|
last_run_stats = DB.query_array <<~SQL
|
|
SELECT
|
|
automation_id,
|
|
MAX(last_run_at) AS last_run_at
|
|
FROM discourse_automation_stats
|
|
GROUP BY automation_id
|
|
SQL
|
|
last_run_stats = Hash[*last_run_stats.flatten]
|
|
|
|
stats.each do |stat|
|
|
automation_id = stat.automation_id
|
|
result[automation_id] ||= {}
|
|
result[automation_id][:last_run_at] = last_run_stats[automation_id]
|
|
result[automation_id][period_name] = {
|
|
total_runs: stat.total_runs,
|
|
total_time: stat.total_time,
|
|
average_run_time: stat.average_run_time,
|
|
min_run_time: stat.min_run_time,
|
|
max_run_time: stat.max_run_time,
|
|
}
|
|
end
|
|
end
|
|
|
|
result
|
|
end
|
|
|
|
def self.update_stats(automation_id, run_time)
|
|
today = Date.current
|
|
current_time = Time.now
|
|
|
|
builder = DB.build <<~SQL
|
|
INSERT INTO discourse_automation_stats
|
|
(automation_id, date, last_run_at, total_time, average_run_time, min_run_time, max_run_time, total_runs)
|
|
VALUES (:automation_id, :date, :current_time, :run_time, :run_time, :run_time, :run_time, 1)
|
|
ON CONFLICT (automation_id, date) DO UPDATE SET
|
|
last_run_at = :current_time,
|
|
total_time = discourse_automation_stats.total_time + :run_time,
|
|
total_runs = discourse_automation_stats.total_runs + 1,
|
|
average_run_time = (discourse_automation_stats.total_time + :run_time) / (discourse_automation_stats.total_runs + 1),
|
|
min_run_time = LEAST(discourse_automation_stats.min_run_time, :run_time),
|
|
max_run_time = GREATEST(discourse_automation_stats.max_run_time, :run_time)
|
|
SQL
|
|
|
|
builder.exec(
|
|
automation_id: automation_id,
|
|
date: today,
|
|
current_time: current_time,
|
|
run_time: run_time,
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: discourse_automation_stats
|
|
#
|
|
# id :bigint not null, primary key
|
|
# automation_id :bigint not null
|
|
# date :date not null
|
|
# last_run_at :datetime not null
|
|
# total_time :float not null
|
|
# average_run_time :float not null
|
|
# min_run_time :float not null
|
|
# max_run_time :float not null
|
|
# total_runs :integer not null
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_discourse_automation_stats_on_automation_id_and_date (automation_id,date) UNIQUE
|
|
#
|