lib/reptile/replication_monitor.rb in reptile-0.0.1 vs lib/reptile/replication_monitor.rb in reptile-0.0.4
- old
+ new
@@ -1,9 +1,12 @@
+require 'logger'
+
module Reptile
class ReplicationMonitor
+
# Attempts to load the replication.yml configuration file.
- def self.load_config_file(databases_file)
+ def self.load_config_file(databases_file)
@databases_file = databases_file
yaml = YAML::load(File.read(@databases_file))
@configs = yaml.delete('config')
@users = Users.new(yaml.delete('users'))
@databases = Databases.new(yaml)
@@ -12,12 +15,12 @@
Runner.user = users.replication_user
Status.user = users.replication_user
DeltaMonitor.user = users.ro_user
Runner.databases = databases
- raise "Please specify a delay theshold 'delay_threshold_secs: 360'" if @configs['delay_threshold_secs'].nil?
- raise "Please specify a row delta theshold 'row_difference_threshold: 10'" if @configs['row_difference_threshold'].nil?
+ raise "Please specify a delay threshold 'delay_threshold_secs: 360'" if @configs['delay_threshold_secs'].nil?
+ raise "Please specify a row delta threshold 'row_difference_threshold: 10'" if @configs['row_difference_threshold'].nil?
rescue Errno::EACCES => e
puts "Unable to open config file: Permission Denied"
end
@@ -33,37 +36,46 @@
# Returns the +Users+ loaded from the replication.yml file
def self.users
@users
end
+
+ def self.errors
+ get_logger.sev_threshold = Logger::ERROR
+ check_slaves
+ heartbeat
+ diff_tables
+ end
def self.diff_tables
unsynced_dbs = 0
+ DeltaMonitor.logger = get_logger
- databases.each_pair do |name, roles|
+ databases.databases.each_pair do |name, roles|
master, slave = roles['master'], roles['slave']
deltas = DeltaMonitor.diff(name, master, slave)
egregious_deltas = deltas.select{|table, delta| delta > configs['row_difference_threshold'] }
if egregious_deltas.size > 0
- queue_replication_warning :host => master[:host], :database => master[:database], :deltas => egregious_deltas, :noticed_at => Time.now
+ queue_replication_warning :host => master["host"], :database => master["database"], :deltas => egregious_deltas, :noticed_at => Time.now
unsynced_dbs += 1
end
end
unsynced_dbs.zero?
end
def self.heartbeat
- databases.each_key do |name|
- Heartbeat.write(name, databases[name]['master'])
+ Heartbeat.logger = get_logger
+
+ databases.masters.each_pair do |name, configs|
+ Heartbeat.write(name, configs)
end
overdue_slaves = 0
- databases.each_key do |name|
- db_configs = databases[name]['slave']
+ databases.slaves.each_pair do |name, db_configs|
delay = Heartbeat.read(name, db_configs)
if delay.nil?
queue_replication_warning :host => name,
:database => configs[:database],
:general_error => "Error: No Heartbeats found.",
@@ -83,12 +95,13 @@
# Checks the status of each slave.
def self.check_slaves
databases.slaves.each do |slave_name, slave_configs|
status = Status.check_slave_status(slave_name, slave_configs)
+ get_logger.info "'#{slave_name}' is '#{status}'"
if status != Status.const_get(:RUNNING)
- queue_replication_warning :host => name,
+ queue_replication_warning :host => slave_name,
:database => configs[:database],
:status_error => Status.get_error_message(status),
:noticed_at => Time.now
end
end
@@ -99,11 +112,11 @@
email.recipients = get_recipients
email.subject = "A replication error occured on #{options[:host]} at #{Time.now}"
email.body = ''
if options[:delay]
- email.body += "There was a #{delay} second replication latency, which is greater than the allowed latency of #{configs['delay_threshold_secs']} seconds"
+ email.body += "There was a #{options[:delay]} second replication latency, which is greater than the allowed latency of #{configs['delay_threshold_secs']} seconds"
elsif options[:deltas]
email.body += "The following tables have master/slave row count difference greater than the allowed #{configs['row_difference_threshold']}\n\n"
options[:deltas].each do |table, delta|
email.body += " table '#{table}' was off by #{delta} rows\n"
end
@@ -113,12 +126,15 @@
email.body += " Error: #{options[:general_error]}"
end
email.body += "\n"
email.body += " Server: #{options[:host]}\n"
- email.body += " Databse: #{options[:database]}\n"
+ email.body += " Database: #{options[:database]}\n" unless options[:database].blank?
+ # Print out email body to STDOUT
+ get_logger.error email.body
+
send_email(email)
end
# Gets the 'email_to' value from the 'configs' section of the replication.yml file
def self.get_recipients
@@ -187,10 +203,13 @@
send_email(email)
end
def self.send_email(email)
+ return unless configs['email_server'] && configs['email_port'] && configs['email_domain'] &&
+ configs['email_password'] && configs['email_auth_type']
+
# TODO: could do Net::SMTP.respond_to?(enable_tls) ? enable_TLS : puts "Install TLS gem to use SSL/TLS"
Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
Net::SMTP.start(configs['email_server'],
configs['email_port'],
configs['email_domain'],
@@ -216,9 +235,15 @@
# has_tlsmail_gem = require 'tlsmail'
# raise "Please install the 'tlsmail' gem" unless has_tlsmail_gem
# Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
# send_email(email)
# end
+ end
+
+ private
+
+ def self.get_logger
+ @@logger ||= Logger.new(STDOUT)
end
end
end
\ No newline at end of file