Skip to content

Commit 85ce416

Browse files
committed
Track and report DB query counts
1 parent ce8cd7f commit 85ce416

File tree

11 files changed

+65
-7
lines changed

11 files changed

+65
-7
lines changed

lib/cloud_controller/metrics/prometheus_updater.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def self.allow_pid_label
1919
DURATION_BUCKETS = [5, 10, 30, 60, 300, 600, 890].freeze
2020
CONNECTION_DURATION_BUCKETS = [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10].freeze
2121
DELAYED_JOB_METRIC_BUCKETS = [0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10, 30, 60, 120, 300, 600].freeze
22+
DB_QUERY_BUCKETS = [1, 2, 5, 10, 20, 50, 100].freeze
2223

2324
METRICS = [
2425
{ type: :gauge, name: :cc_job_queues_length_total, docstring: 'Job queues length of worker processes', labels: [:queue], aggregation: :most_recent },
@@ -29,6 +30,7 @@ def self.allow_pid_label
2930
{ type: :histogram, name: :cc_staging_failed_duration_seconds, docstring: 'Durations of failed staging events', buckets: DURATION_BUCKETS },
3031
{ type: :gauge, name: :cc_requests_outstanding_total, docstring: 'Requests outstanding', aggregation: :sum },
3132
{ type: :counter, name: :cc_requests_completed_total, docstring: 'Requests completed' },
33+
{ type: :histogram, name: :cc_request_db_queries_total, docstring: 'Database queries per request', buckets: DB_QUERY_BUCKETS },
3234
{ type: :gauge, name: :cc_vitals_started_at, docstring: 'CloudController Vitals: started_at', aggregation: :most_recent },
3335
{ type: :gauge, name: :cc_vitals_mem_bytes, docstring: 'CloudController Vitals: mem_bytes', aggregation: :most_recent },
3436
{ type: :gauge, name: :cc_vitals_cpu_load_avg, docstring: 'CloudController Vitals: cpu_load_avg', aggregation: :most_recent },
@@ -124,6 +126,10 @@ def update_user_count(user_count)
124126
update_gauge_metric(:cc_users_total, user_count)
125127
end
126128

129+
def update_db_query_count(query_count)
130+
update_histogram_metric(:cc_request_db_queries_total, query_count)
131+
end
132+
127133
def update_job_queue_length(pending_job_count_by_queue)
128134
pending_job_count_by_queue.each do |key, value|
129135
update_gauge_metric(:cc_job_queues_length_total, value, labels: { queue: key.to_s.underscore })

lib/cloud_controller/metrics/request_metrics.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ def start_request
1313
@prometheus_updater.increment_gauge_metric(:cc_requests_outstanding_total)
1414
end
1515

16-
def complete_request(status, query_count)
16+
def complete_request(status)
17+
query_count = VCAP::Request.db_query_count
1718
@statsd_updater.complete_request(status)
19+
@statsd_updater.record_db_query_count(query_count) if query_count
1820

1921
@prometheus_updater.increment_counter_metric(:cc_requests_completed_total)
2022
@prometheus_updater.decrement_gauge_metric(:cc_requests_outstanding_total)
23+
@prometheus_updater.update_db_query_count(query_count) if query_count
2124
end
2225
end
2326
end

lib/cloud_controller/metrics/statsd_updater.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ def complete_request(status)
110110
end
111111
end
112112

113+
def record_db_query_count(query_count)
114+
@statsd.gauge('cc.request.db_query_count', query_count)
115+
end
116+
113117
private
114118

115119
def nanoseconds_to_milliseconds(time_ns)

lib/sequel/extensions/request_query_counter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Sequel
22
module RequestQueryCounter
33
def log_connection_yield(sql, conn, args=nil)
4-
VCAP::Request.db_query_count = (VCAP::Request.db_query_count || 0) + 1
4+
VCAP::Request.increment_db_query_count
55
super
66
end
77
end

lib/vcap/request.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ def db_query_count=(count)
6363
def db_query_count
6464
Thread.current[:db_query_count]
6565
end
66+
67+
def increment_db_query_count
68+
Thread.current[:db_query_count] ||= 0
69+
Thread.current[:db_query_count] += 1
70+
end
71+
72+
def reset_db_query_count
73+
Thread.current[:db_query_count] = 0
74+
end
6675
end
6776
end
6877
end

middleware/request_logs.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def initialize(app, request_logs)
88

99
def call(env)
1010
request_id = env['cf.request_id']
11+
VCAP::Request.reset_db_query_count
1112
@request_logs.start_request(request_id, env)
1213
start_time = Time.now
1314

spec/unit/lib/cloud_controller/metrics/prometheus_updater_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ module VCAP::CloudController::Metrics
6060
end
6161
end
6262

63+
describe '#update_db_query_count' do
64+
it 'records queries per request' do
65+
updater.update_db_query_count(7)
66+
67+
metric = prom_client.metrics.find { |m| m.name == :cc_request_db_queries_total }
68+
expect(metric).to be_present
69+
expect(metric.get['sum']).to eq 7.0
70+
end
71+
end
72+
6373
describe '#update_job_queue_length' do
6474
it 'records the length of the delayed job queues and total' do
6575
expected_local_length = 5

spec/unit/lib/cloud_controller/metrics/request_metrics_spec.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,29 @@ module VCAP::CloudController::Metrics
3232
let(:status) { 204 }
3333

3434
it 'increments completed, decrements outstanding, increments status for statsd' do
35-
request_metrics.complete_request(status, 5)
35+
allow(statsd_updater).to receive(:record_db_query_count)
36+
allow(prometheus_client).to receive(:update_db_query_count)
37+
38+
VCAP::Request.reset_db_query_count
39+
VCAP::Request.increment_db_query_count
40+
41+
request_metrics.complete_request(status)
3642
expect(statsd_updater).to have_received(:complete_request).with(status)
43+
expect(statsd_updater).to have_received(:record_db_query_count).with(1)
3744
end
3845

3946
it 'increments completed and decrements outstanding for prometheus' do
40-
request_metrics.complete_request(status, 5)
47+
allow(statsd_updater).to receive(:record_db_query_count)
48+
allow(prometheus_client).to receive(:update_db_query_count)
49+
50+
VCAP::Request.reset_db_query_count
51+
VCAP::Request.increment_db_query_count
52+
53+
request_metrics.complete_request(status)
4154

4255
expect(prometheus_client).to have_received(:decrement_gauge_metric).with(:cc_requests_outstanding_total)
4356
expect(prometheus_client).to have_received(:increment_counter_metric).with(:cc_requests_completed_total)
57+
expect(prometheus_client).to have_received(:update_db_query_count).with(1)
4458
end
4559
end
4660
end

spec/unit/lib/cloud_controller/metrics/statsd_updater_spec.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ module VCAP::CloudController::Metrics
300300
end
301301
end
302302

303-
describe '#complete_request' do
303+
describe '#complete_request' do
304304
let(:batch) { double(:batch) }
305305
let(:status) { 204 }
306306

@@ -457,4 +457,15 @@ module VCAP::CloudController::Metrics
457457
end
458458
end
459459
end
460+
461+
describe '#record_db_query_count' do
462+
before do
463+
allow(statsd_client).to receive(:gauge)
464+
end
465+
466+
it 'records database query counts' do
467+
updater.record_db_query_count(3)
468+
expect(statsd_client).to have_received(:gauge).with('cc.request.db_query_count', 3)
469+
end
470+
end
460471
end

spec/unit/lib/sequel/extensions/request_query_counter_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
end
99

1010
it 'increments the thread local query count on each query' do
11-
VCAP::Request.db_query_count = 0
11+
VCAP::Request.reset_db_query_count
1212
db.fetch('SELECT 1').all
1313
expect(VCAP::Request.db_query_count).to eq(1)
1414
end

0 commit comments

Comments
 (0)