Guest User

Untitled

a guest
Apr 11th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.62 KB | None | 0 0
  1. #! /usr/bin/env ruby
  2. #
  3. # check-postgres-replication
  4. #
  5. # DESCRIPTION:
  6. #
  7. # This plugin checks postgresql replication lag
  8. #
  9. # OUTPUT:
  10. # plain text
  11. #
  12. # PLATFORMS:
  13. # Linux
  14. #
  15. # DEPENDENCIES:
  16. # gem: sensu-plugin
  17. # gem: pg
  18. #
  19. # USAGE:
  20. # ./check-postgres-replication.rb -m master_host -s slave_host -P port -d db -u db_user -p db_pass -w warn_threshold -c crit_threshold
  21. #
  22. # NOTES:
  23. #
  24. # LICENSE:
  25. # Released under the same terms as Sensu (the MIT license); see LICENSE
  26. # for details.
  27. #
  28.  
  29. require 'sensu-plugins-postgres/pgpass'
  30. require 'sensu-plugin/check/cli'
  31. require 'pg'
  32.  
  33. class CheckPostgresReplicationStatus < Sensu::Plugin::Check::CLI
  34. option :pgpass,
  35. description: 'Pgpass file',
  36. short: '-f FILE',
  37. long: '--pgpass',
  38. default: ENV['PGPASSFILE'] || "#{ENV['HOME']}/.pgpass"
  39.  
  40. option(:master_host,
  41. short: '-m',
  42. long: '--master-host=HOST',
  43. description: 'PostgreSQL master HOST')
  44.  
  45. option(:slave_host,
  46. short: '-s',
  47. long: '--slave-host=HOST',
  48. description: 'PostgreSQL slave HOST',
  49. default: 'localhost')
  50.  
  51. option(:port,
  52. short: '-P',
  53. long: '--port=PORT',
  54. description: 'PostgreSQL port')
  55.  
  56. option(:database,
  57. short: '-d',
  58. long: '--database=NAME',
  59. description: 'Database NAME')
  60.  
  61. option(:user,
  62. short: '-u',
  63. long: '--user=USER',
  64. description: 'Database USER')
  65.  
  66. option(:password,
  67. short: '-p',
  68. long: '--password=PASSWORD',
  69. description: 'Database PASSWORD')
  70.  
  71. option(:ssl,
  72. short: '-S',
  73. long: '--ssl',
  74. boolean: true,
  75. description: 'Require SSL')
  76.  
  77. option(:warn,
  78. short: '-w',
  79. long: '--warning=VALUE',
  80. description: 'Warning threshold for replication lag (in MB)',
  81. default: 900,
  82. # #YELLOW
  83. proc: lambda { |s| s.to_i }) # rubocop:disable Lambda
  84.  
  85. option(:crit,
  86. short: '-c',
  87. long: '--critical=VALUE',
  88. description: 'Critical threshold for replication lag (in MB)',
  89. default: 1800,
  90. # #YELLOW
  91. proc: lambda { |s| s.to_i }) # rubocop:disable Lambda
  92.  
  93. option(:timeout,
  94. short: '-T',
  95. long: '--timeout',
  96. default: nil,
  97. description: 'Connection timeout (seconds)')
  98.  
  99. include Pgpass
  100.  
  101. def compute_lag(master, slave, m_segbytes)
  102. m_segment, m_offset = master.split('/')
  103. s_segment, s_offset = slave.split('/')
  104. ((m_segment.hex - s_segment.hex) * m_segbytes) + (m_offset.hex - s_offset.hex)
  105. end
  106.  
  107. def check_vsn(conn)
  108. pg_vsn = conn.exec("SELECT current_setting('server_version')").getvalue(0, 0)
  109. Gem::Version.new(pg_vsn) < Gem::Version.new('10.0') && Gem::Version.new(pg_vsn) >= Gem::Version.new('9.0')
  110. end
  111.  
  112. def run
  113. ssl_mode = config[:ssl] ? 'require' : 'prefer'
  114.  
  115. # Establishing connection to the master
  116. pgpass
  117. conn_master = PG.connect(host: config[:master_host],
  118. dbname: config[:database],
  119. user: config[:user],
  120. password: config[:password],
  121. port: config[:port],
  122. sslmode: ssl_mode,
  123. connect_timeout: config[:timeout])
  124.  
  125. master = if check_vsn(conn_master)
  126. conn_master.exec('SELECT pg_current_xlog_location()').getvalue(0, 0)
  127. else
  128. conn_master.exec('SELECT pg_current_wal_lsn()').getvalue(0, 0)
  129. end
  130. m_segbytes = conn_master.exec('SHOW wal_segment_size').getvalue(0, 0).sub(/\D+/, '').to_i << 20
  131. conn_master.close
  132.  
  133. # Establishing connection to the slave
  134. conn_slave = PG.connect(host: config[:slave_host],
  135. dbname: config[:database],
  136. user: config[:user],
  137. password: config[:password],
  138. port: config[:port],
  139. sslmode: ssl_mode,
  140. connect_timeout: config[:timeout])
  141.  
  142. slave = i
  143. f check_vsn(conn_slave)
  144. conn_slave.exec('SELECT pg_last_xlog_receive_location()').getvalue(0, 0)
  145. else
  146. conn_slave.exec('SELECT pg_last_wal_replay_lsn()').getvalue(0, 0)
  147. end
  148. conn_slave.close
  149.  
  150. # Computing lag
  151. lag = compute_lag(master, slave, m_segbytes)
  152. lag_in_mb = (lag.to_f / 1024 / 1024).abs
  153.  
  154. message = "replication delayed by #{lag_in_mb}MB :: master:#{master} slave:#{slave} m_segbytes:#{m_segbytes}"
  155.  
  156. if lag_in_mb >= config[:crit]
  157. critical message
  158. elsif lag_in_mb >= config[:warn]
  159. warning message
  160. else
  161. ok message
  162. end
  163. end
  164. end
Add Comment
Please, Sign In to add comment