2024-02-23 11:20:32 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class ProblemCheck
|
|
|
|
include ActiveSupport::Configurable
|
|
|
|
|
2024-02-26 12:08:12 +08:00
|
|
|
config_accessor :priority, default: "low", instance_writer: false
|
|
|
|
|
2024-02-23 11:20:32 +08:00
|
|
|
# Determines if the check should be performed at a regular interval, and if
|
|
|
|
# so how often. If left blank, the check will be performed every time the
|
|
|
|
# admin dashboard is loaded, or the data is otherwise requested.
|
|
|
|
#
|
|
|
|
config_accessor :perform_every, default: nil, instance_writer: false
|
|
|
|
|
|
|
|
# How many times the check should retry before registering a problem. Only
|
|
|
|
# works for scheduled checks.
|
|
|
|
#
|
|
|
|
config_accessor :max_retries, default: 2, instance_writer: false
|
|
|
|
|
|
|
|
# The retry delay after a failed check. Only works for scheduled checks with
|
|
|
|
# more than one retry configured.
|
|
|
|
#
|
|
|
|
config_accessor :retry_after, default: 30.seconds, instance_writer: false
|
|
|
|
|
2024-03-27 10:07:56 +08:00
|
|
|
# How many consecutive times the check can fail without notifying admins.
|
|
|
|
# This can be used to give some leeway for transient problems. Note that
|
|
|
|
# retries are not counted. So a check that ultimately fails after e.g. two
|
|
|
|
# retries is counted as one "blip".
|
|
|
|
#
|
|
|
|
config_accessor :max_blips, default: 0, instance_writer: false
|
|
|
|
|
2024-03-28 14:00:47 +08:00
|
|
|
# Problem check classes need to be registered here in order to be enabled.
|
|
|
|
#
|
|
|
|
# Note: This list must come after the `config_accessor` declarations.
|
|
|
|
#
|
|
|
|
CORE_PROBLEM_CHECKS = [
|
|
|
|
ProblemCheck::EmailPollingErroredRecently,
|
|
|
|
ProblemCheck::FacebookConfig,
|
|
|
|
ProblemCheck::FailingEmails,
|
|
|
|
ProblemCheck::ForceHttps,
|
|
|
|
ProblemCheck::GithubConfig,
|
|
|
|
ProblemCheck::GoogleAnalyticsVersion,
|
|
|
|
ProblemCheck::GoogleOauth2Config,
|
|
|
|
ProblemCheck::GroupEmailCredentials,
|
|
|
|
ProblemCheck::HostNames,
|
|
|
|
ProblemCheck::ImageMagick,
|
|
|
|
ProblemCheck::MissingMailgunApiKey,
|
|
|
|
ProblemCheck::OutOfDateThemes,
|
|
|
|
ProblemCheck::RailsEnv,
|
|
|
|
ProblemCheck::Ram,
|
|
|
|
ProblemCheck::S3BackupConfig,
|
|
|
|
ProblemCheck::S3Cdn,
|
|
|
|
ProblemCheck::S3UploadConfig,
|
|
|
|
ProblemCheck::SidekiqCheck,
|
|
|
|
ProblemCheck::SubfolderEndsInSlash,
|
|
|
|
ProblemCheck::TranslationOverrides,
|
|
|
|
ProblemCheck::TwitterConfig,
|
|
|
|
ProblemCheck::TwitterLogin,
|
|
|
|
ProblemCheck::UnreachableThemes,
|
|
|
|
ProblemCheck::WatchedWords,
|
|
|
|
].freeze
|
|
|
|
|
2024-02-23 11:20:32 +08:00
|
|
|
def self.[](key)
|
|
|
|
key = key.to_sym
|
|
|
|
|
|
|
|
checks.find { |c| c.identifier == key }
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.checks
|
2024-03-28 14:00:47 +08:00
|
|
|
CORE_PROBLEM_CHECKS | DiscoursePluginRegistry.problem_checks
|
2024-02-23 11:20:32 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.scheduled
|
|
|
|
checks.select(&:scheduled?)
|
|
|
|
end
|
|
|
|
|
2024-03-14 10:55:01 +08:00
|
|
|
def self.realtime
|
|
|
|
checks.reject(&:scheduled?)
|
|
|
|
end
|
|
|
|
|
2024-02-23 11:20:32 +08:00
|
|
|
def self.identifier
|
|
|
|
name.demodulize.underscore.to_sym
|
|
|
|
end
|
|
|
|
delegate :identifier, to: :class
|
|
|
|
|
|
|
|
def self.scheduled?
|
|
|
|
perform_every.present?
|
|
|
|
end
|
|
|
|
delegate :scheduled?, to: :class
|
|
|
|
|
2024-03-14 10:55:01 +08:00
|
|
|
def self.realtime?
|
|
|
|
!scheduled?
|
|
|
|
end
|
|
|
|
delegate :realtime?, to: :class
|
|
|
|
|
|
|
|
def self.call(data = {})
|
|
|
|
new(data).call
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(data = {})
|
|
|
|
@data = OpenStruct.new(data)
|
2024-02-23 11:20:32 +08:00
|
|
|
end
|
|
|
|
|
2024-03-14 10:55:01 +08:00
|
|
|
attr_reader :data
|
|
|
|
|
2024-02-23 11:20:32 +08:00
|
|
|
def call
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
2024-02-26 12:08:12 +08:00
|
|
|
|
|
|
|
private
|
|
|
|
|
2024-03-20 08:52:25 +08:00
|
|
|
def problem(override_key = nil, override_data = {})
|
2024-02-26 12:08:12 +08:00
|
|
|
[
|
|
|
|
Problem.new(
|
2024-03-14 10:55:01 +08:00
|
|
|
message ||
|
|
|
|
I18n.t(
|
|
|
|
override_key || translation_key,
|
|
|
|
base_path: Discourse.base_path,
|
2024-03-20 08:52:25 +08:00
|
|
|
**override_data.merge(translation_data).symbolize_keys,
|
2024-03-14 10:55:01 +08:00
|
|
|
),
|
2024-02-26 12:08:12 +08:00
|
|
|
priority: self.config.priority,
|
|
|
|
identifier:,
|
|
|
|
),
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
|
|
|
def no_problem
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
|
2024-03-14 10:55:01 +08:00
|
|
|
def message
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2024-02-26 12:08:12 +08:00
|
|
|
def translation_key
|
|
|
|
# TODO: Infer a default based on class name, then move translations in locale file.
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
2024-03-14 10:55:01 +08:00
|
|
|
|
|
|
|
def translation_data
|
|
|
|
{}
|
|
|
|
end
|
2024-02-23 11:20:32 +08:00
|
|
|
end
|