Commit 9936ae38 authored by Ahmad Sherif's avatar Ahmad Sherif
Browse files

Collect more DB tuple stats

Closes #12
parent 91eb74ad
Pipeline #182298 passed with stage
in 1 minute
PATH PATH
remote: . remote: .
specs: specs:
gitlab-monitor (0.0.22) gitlab-monitor (0.0.25)
pg (~> 0.18.4) pg (~> 0.18.4)
quantile (~> 0.2.0) quantile (~> 0.2.0)
redis-namespace (~> 1.5.2) redis-namespace (~> 1.5.2)
......
...@@ -13,7 +13,7 @@ frequency. ...@@ -13,7 +13,7 @@ frequency.
### Supported Probes ### Supported Probes
1. Database 1. Database
* Dead tuples * Per-table tuple stats
* Slow queries * Slow queries
* Blocked queries * Blocked queries
* Vacuum queries * Vacuum queries
......
...@@ -5,8 +5,8 @@ server: ...@@ -5,8 +5,8 @@ server:
probes: probes:
database: database:
multiple: true multiple: true
dead_tuples_count: tuple_stats:
class_name: Database::DeadTuplesProber class_name: Database::TuplesProber
methods: methods:
- probe_db - probe_db
opts: opts:
......
...@@ -76,11 +76,11 @@ module GitLab ...@@ -76,11 +76,11 @@ module GitLab
end end
end end
# Database dead tuples runner. # Database tuple stats runner.
# #
# It will take a database connection string and print results to STDOUT # It will take a database connection string and print results to STDOUT
class DatabaseDeadTuples class DatabaseTupleStats
COMMAND_NAME = "db-dead-tuples".freeze COMMAND_NAME = "db-tuple-stats".freeze
def initialize(args) def initialize(args)
@options = options(args) @options = options(args)
...@@ -106,7 +106,7 @@ module GitLab ...@@ -106,7 +106,7 @@ module GitLab
def run def run
validate! validate!
::GitLab::Monitor::Database::DeadTuplesProber.new(connection_string: @db_connection_string) ::GitLab::Monitor::Database::TuplesProber.new(connection_string: @db_connection_string)
.probe_db .probe_db
.write_to(@target) .write_to(@target)
end end
...@@ -451,7 +451,7 @@ module GitLab ...@@ -451,7 +451,7 @@ module GitLab
def self.commands def self.commands
[ [
GIT, GIT,
DatabaseDeadTuples, DatabaseTupleStats,
DatabaseBlockedQueries, DatabaseBlockedQueries,
DatabaseSlowQueries, DatabaseSlowQueries,
DatabaseVacuumQueries, DatabaseVacuumQueries,
......
...@@ -6,7 +6,7 @@ module GitLab ...@@ -6,7 +6,7 @@ module GitLab
autoload :BlockedQueriesProber, "gitlab_monitor/database/blocked_queries" autoload :BlockedQueriesProber, "gitlab_monitor/database/blocked_queries"
autoload :CiBuildsProber, "gitlab_monitor/database/ci_builds" autoload :CiBuildsProber, "gitlab_monitor/database/ci_builds"
autoload :SlowQueriesProber, "gitlab_monitor/database/slow_queries" autoload :SlowQueriesProber, "gitlab_monitor/database/slow_queries"
autoload :DeadTuplesProber, "gitlab_monitor/database/dead_tuples" autoload :TuplesProber, "gitlab_monitor/database/tuple_stats"
autoload :VacuumQueriesProber, "gitlab_monitor/database/vacuum_queries" autoload :VacuumQueriesProber, "gitlab_monitor/database/vacuum_queries"
autoload :RowCountProber, "gitlab_monitor/database/row_count" autoload :RowCountProber, "gitlab_monitor/database/row_count"
end end
......
module GitLab module GitLab
module Monitor module Monitor
module Database module Database
# A helper class to collect dead tuples stats from the database # A helper class to collect tuple stats from the database
# #
# It takes a connection string (e.g. "dbname=test port=5432") # It takes a connection string (e.g. "dbname=test port=5432")
class DeadTuplesCollector < Base class TupleStatsCollector < Base
def run def run
table_names = connection.exec("SELECT tablename FROM pg_tables WHERE tableowner = 'gitlab'").values.flatten table_names = connection.exec("SELECT tablename FROM pg_tables WHERE tableowner = 'gitlab'").values.flatten
stats = {} stats = {}
table_names.each do |table_name| table_names.each do |table_name|
result = connection.exec("SELECT n_dead_tup FROM pg_stat_user_tables WHERE relname = '#{table_name}'") result = connection.exec(
stats[table_name] = result[0]["n_dead_tup"].to_i <<-SQL
SELECT seq_tup_read, idx_tup_fetch, n_tup_ins, n_tup_upd, n_tup_del, n_tup_hot_upd, n_dead_tup
FROM pg_stat_user_tables
WHERE relname = '#{table_name}'
SQL
)
next if result.count.zero?
stats[table_name] = result[0]
end end
stats stats
end end
end end
# Probes the DB specified by opts[:connection_string] for dead tubles stats, then converts them to metrics # Probes the DB specified by opts[:connection_string] for tuple stats, then converts them to metrics
class DeadTuplesProber class TuplesProber
def initialize(opts, metrics: PrometheusMetrics.new) def initialize(opts, metrics: PrometheusMetrics.new)
@metrics = metrics @metrics = metrics
@collector = DeadTuplesCollector.new(connection_string: opts[:connection_string]) @collector = TupleStatsCollector.new(connection_string: opts[:connection_string])
end end
def probe_db def probe_db
...@@ -30,8 +38,10 @@ module GitLab ...@@ -30,8 +38,10 @@ module GitLab
result = @collector.run result = @collector.run
result.each do |table_name, dead_tuples_count| result.each do |table_name, tuple_stats|
@metrics.add("pg_dead_tuples", dead_tuples_count, table_name: table_name) tuple_stats.each do |column_name, value|
@metrics.add("pg_stat_table_#{column_name}", value.to_s, table_name: table_name)
end
end end
self self
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment