Advertisement
Guest User

Untitled

a guest
May 24th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.88 KB | None | 0 0
  1. require 'time'
  2. require 'date'
  3.  
  4. class MysqlReplicationMonitor < Scout::Plugin
  5. needs 'mysql2'
  6.  
  7. OPTIONS=<<-EOS
  8. host:
  9. name: Host
  10. notes: The slave host to monitor
  11. default: 127.0.0.1
  12. port:
  13. name: Port
  14. notes: The port number on the slave host
  15. default: 3306
  16. username:
  17. name: Username
  18. notes: The MySQL username to use
  19. default: root
  20. password:
  21. name: Password
  22. notes: The password for the mysql user
  23. default:
  24. attributes: password
  25. socket:
  26. name: MySQL socket
  27. notes: Specify the location of the MySQL socket
  28. ignore_window_start:
  29. name: Ignore Window Start
  30. notes: Time to start ignoring replication failures. Useful for disabling replication for backups. For Example, 7:00pm
  31. default:
  32. ignore_window_end:
  33. name: Ignore Window End
  34. notes: Time to resume notifications on replication failure. For Example, 2:00am
  35. default:
  36. default_file:
  37. name: Mysql Default File
  38. notes: Optional path to the MySQL default file. For Example, /home/scout/.my.cnf
  39. default:
  40. fail_count:
  41. name: Maximum failed polls
  42. notes: Number of failed polls that have to happen before alerting
  43. default: 1
  44. EOS
  45.  
  46. attr_accessor :connection
  47.  
  48. def build_report
  49. res={"Seconds Behind Master" => -1, "Replication Running"=>0}
  50. begin
  51. self.connection=Mysql2::Client.new(
  52. :host => option(:host),
  53. :username => option(:username),
  54. :password => option(:password),
  55. :port => (option(:port).nil? ? nil : option(:port).to_i),
  56. :socket => option(:socket),
  57. :default_file => (option(:default_file) unless option(:default_file).nil? || option(:default_file).empty?)
  58. )
  59.  
  60. y = connection.query("show slave status")
  61.  
  62. down_at = memory(:down_at)
  63.  
  64. # There's no Replication
  65. if y.count == 0
  66. error("Replication not configured")
  67. else
  68. h = y.each {|r| r}[0]
  69. if h["Seconds_Behind_Master"].nil? && !down_at
  70. if in_ignore_window?
  71. res["Replication Running"] = replication_check("up")
  72. else
  73. res["Replication Running"] = replication_check("down")
  74. down_at = Time.now
  75. end
  76. elsif h["Slave_IO_Running"] == "Yes" && h["Slave_SQL_Running"] == "Yes"
  77.  
  78. res["Seconds Behind Master"] = h["Seconds_Behind_Master"]
  79. res["Replication Running"] = replication_check("up")
  80. down_at = nil if down_at
  81. elsif !down_at
  82. if in_ignore_window?
  83. res["Replication Running"] = replication_check("up")
  84. else
  85. down_at = Time.now
  86. res["Replication Running"] = replication_check("down")
  87. end
  88. end
  89. end
  90. remember(:down_at,down_at)
  91. rescue Mysql2::Error=>e
  92. if in_ignore_window?
  93. res["Replication Running"] = replication_check("up")
  94. else
  95. error("Unable to connect to MySQL",e.to_s)
  96. end
  97. end
  98. report(res)
  99. end
  100.  
  101. def replication_check(status)
  102.  
  103. failed_poll_count = memory(:failed_poll_count)
  104.  
  105. # Replication's running, return 1 and clean failed_poll_count
  106. if status == "up"
  107. failed_poll_count = 0
  108. return_code = 1
  109.  
  110. else # Bump up fail count, check if we're over the maximum allowed and fail if so.
  111. failed_poll_count += 1
  112. if (failed_poll_count >= option(:fail_count))
  113. return_code = 0
  114. else
  115. return_code = 1
  116. end
  117. end
  118. # Remember the failures for next run
  119. remember(:failed_poll_count,failed_poll_count)
  120. return return_code
  121. end
  122.  
  123. def in_ignore_window?
  124. if (s = option(:ignore_window_start)) && (e = option(:ignore_window_end))
  125. start_time = Time.parse("#{Date.today} #{s}")
  126. end_time = Time.parse("#{Date.today} #{e}")
  127.  
  128. if start_time < end_time
  129. return Time.now > start_time && Time.now < end_time
  130. else
  131. return Time.now > start_time || Time.now < end_time
  132. end
  133. else
  134. false
  135. end
  136. end
  137. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement