tuple_stats.rb 1.68 KB
Newer Older
1
module GitLab
2
  module Exporter
3
    module Database
Ahmad Sherif's avatar
Ahmad Sherif committed
4
      # A helper class to collect tuple stats from the database
5 6
      #
      # It takes a connection string (e.g. "dbname=test port=5432")
Ahmad Sherif's avatar
Ahmad Sherif committed
7
      class TupleStatsCollector < Base
8
        COLUMNS = %w(relname seq_tup_read idx_tup_fetch n_tup_ins n_tup_upd n_tup_del n_tup_hot_upd n_dead_tup seq_scan)
9 10 11 12 13 14 15
                  .join(",")
        QUERY   = <<-SQL.freeze
          SELECT #{COLUMNS}
          FROM pg_stat_user_tables
          WHERE relname IN (SELECT tablename FROM pg_tables WHERE tableowner = 'gitlab')
          GROUP BY #{COLUMNS}
        SQL
Ahmad Sherif's avatar
Ahmad Sherif committed
16

17
        def run
18
          with_connection_pool do |conn|
19 20 21
            conn.exec(QUERY).each.with_object({}) do |row, stats|
              stats[row.delete("relname")] = row
            end
22 23 24 25
          end
        end
      end

Ahmad Sherif's avatar
Ahmad Sherif committed
26 27
      # Probes the DB specified by opts[:connection_string] for tuple stats, then converts them to metrics
      class TuplesProber
28
        def initialize(opts, metrics: PrometheusMetrics.new)
29
          @metrics   = metrics
Ahmad Sherif's avatar
Ahmad Sherif committed
30
          @collector = TupleStatsCollector.new(connection_string: opts[:connection_string])
31 32 33 34 35
        end

        def probe_db
          result = @collector.run

Ahmad Sherif's avatar
Ahmad Sherif committed
36 37
          result.each do |table_name, tuple_stats|
            tuple_stats.each do |column_name, value|
Ben Kochie's avatar
Ben Kochie committed
38 39 40
              @metrics.add("gitlab_database_stat_table_#{column_name}",
                           value,
                           table_name: table_name) unless value.is_a?(Numeric)
Ahmad Sherif's avatar
Ahmad Sherif committed
41
            end
42 43
          end

44 45
          self
        rescue PG::ConnectionBad
46 47 48 49 50 51 52 53 54 55
          self
        end

        def write_to(target)
          target.write(@metrics.to_s)
        end
      end
    end
  end
end