FEATURE: Add PostgreSQL availability checks.

FEATURE: Add PostgreSQL availability checks.

From c6820579d42cda036aac9178379708c14038f6c6 Mon Sep 17 00:00:00 2001
From: Guo Xiang Tan <tgx_world@hotmail.com>
Date: Tue, 27 Nov 2018 21:03:38 +0800
Subject: [PATCH] FEATURE: Add PostgreSQL availability checks.


diff --git a/lib/internal_metric/global.rb b/lib/internal_metric/global.rb
index c51f607..4dc91c3 100644
--- a/lib/internal_metric/global.rb
+++ b/lib/internal_metric/global.rb
@@ -86,15 +86,23 @@ module DiscoursePrometheus::InternalMetric
     def test_postgresql(master: true)
       config = ActiveRecord::Base.connection_config
 
-      if !master
-        config = config.dup.merge(
-          host: config[:replica_host],
-          port: config[:replica_port]
-        )
+      unless master
+        if config[:replica_host]
+          config = config.dup.merge(
+            host: config[:replica_host],
+            port: config[:replica_port]
+          )
+        else
+          return 0
+        end
       end
 
       connection = ActiveRecord::Base.postgresql_connection(config)
       connection.active? ? 1 : 0
+    rescue => ex
+      role = master ? 'master' : 'replica'
+      conditionally_log_fault(:"test_postgresql_#{role}", (["Declared PostgreSQL #{role} down due to exception: #{ex.message} (#{ex.class})"] + ex.backtrace).join("\n  "))
+      0
     ensure
       connection&.disconnect!
     end
diff --git a/spec/lib/internal_metric/global_spec.rb b/spec/lib/internal_metric/global_spec.rb
index 98f1b0e..b528c62 100644
--- a/spec/lib/internal_metric/global_spec.rb
+++ b/spec/lib/internal_metric/global_spec.rb
@@ -7,6 +7,35 @@ module DiscoursePrometheus::InternalMetric
       metric.collect
 
       expect(metric.sidekiq_processes).not_to eq(nil)
+      expect(metric.postgresql_master_available).to eq(1)
+      expect(metric.postgresql_replica_available).to eq(0)
+    end
+
+    describe 'when a replica has been configured' do
+      before do
+        @orig_logger = Rails.logger
+        Rails.logger = @fake_logger = FakeLogger.new
+
+        config = ActiveRecord::Base.connection_config
+
+        config.merge!(
+          replica_host: 'localhost',
+          replica_port: 1111
+        )
+      end
+
+      after do
+        Rails.logger = @orig_logger
+      end
+
+      it 'should collect the right metrics' do
+        metric = Global.new
+        metric.collect
+
+        expect(metric.postgresql_master_available).to eq(1)
+        expect(metric.postgresql_replica_available).to eq(0)
+        expect(@fake_logger.errors.first).to match(/Connection refused/)
+      end
     end
   end
 end

GitHub

1 Like