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