Commit c6e254ef authored by Ahmad Sherif's avatar Ahmad Sherif
Browse files

Collect number of slow queries

parent dfffc21e
......@@ -158,8 +158,55 @@ module GitLab
end
end
# Database slow queries runner.
#
# It will take a database connection string and print results to STDOUT
class DatabaseSlowQueries
COMMAND_NAME = "db-slow-queries".freeze
def initialize(args)
@options = options(args)
@options.parse!
@target = args.shift || STDOUT
@target = File.open(@target, "a") if @target.is_a?(String)
end
def options(args)
args.options do |opts|
opts.banner = "Usage: #{EXECUTABLE_NAME} #{COMMAND_NAME} [options]"
opts.on("--db-conn=\"dbname=test port=5432\"", "Database connection string") do |val|
@db_connection_string = val
end
end
end
def help
@options.help
end
def run
validate!
::GitLab::Monitor::Database::SlowQueriesProber.new(connection_string: @db_connection_string)
.probe_db
.write_to(@target)
end
private
def validate!
fail InvalidCLICommand.new(help) unless @db_connection_string
end
end
def self.commands
[GIT, DatabaseDeadTuples, DatabaseBlockedQueries].each_with_object({}) do |command_class, commands|
[
GIT,
DatabaseDeadTuples,
DatabaseBlockedQueries,
DatabaseSlowQueries
].each_with_object({}) do |command_class, commands|
commands[command_class::COMMAND_NAME] = command_class
commands
end
......
......@@ -4,6 +4,7 @@ module GitLab
module Database
autoload :Base, "gitlab_monitor/database/base"
autoload :BlockedQueriesProber, "gitlab_monitor/database/blocked_queries"
autoload :SlowQueriesProber, "gitlab_monitor/database/slow_queries"
autoload :DeadTuplesProber, "gitlab_monitor/database/dead_tuples"
end
end
......
module GitLab
module Monitor
module Database
# A helper class to collect slow queries
#
# It takes a connection string (e.g. "dbname=test port=5432")
class SlowQueriesCollector < Base
def run
result = connection.exec(
<<-SQL
SELECT COUNT(*) AS slow_count
FROM pg_stat_activity
WHERE state = 'active' AND (now() - query_start) > '1 seconds'::interval;
SQL
)
result[0]["slow_count"].to_i
end
end
# Probes the DB specified by opts[:connection_string] for slow queries, then converts them to metrics
class SlowQueriesProber
def initialize(opts, metrics = PrometheusMetrics.new)
@metrics = metrics
@collector = SlowQueriesCollector.new(connection_string: opts[:connection_string])
end
def probe_db
return self unless @collector.connected?
@metrics.add("pg_slow_queries_total", @collector.run)
self
end
def write_to(target)
target.write(@metrics.to_s)
end
end
end
end
end
Markdown is supported
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