Skip to content

Commit 9b0f81e

Browse files
committed
Track DB queries per request
1 parent 0e57b51 commit 9b0f81e

File tree

13 files changed

+76
-6
lines changed

13 files changed

+76
-6
lines changed

lib/cloud_controller/db.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'cloud_controller/db_connection/options_factory'
44
require 'cloud_controller/db_connection/finalizer'
55
require 'sequel/extensions/query_length_logging'
6+
require 'sequel/extensions/request_query_counter'
67

78
module VCAP::CloudController
89
class DB
@@ -37,6 +38,7 @@ def self.connect(opts, logger)
3738

3839
db.extension(:query_length_logging)
3940
db.opts[:query_size_log_threshold] = opts[:query_size_log_threshold]
41+
db.extension(:request_query_counter)
4042
end
4143
db.default_collate = 'utf8_bin' if db.database_type == :mysql
4244
add_connection_expiration_extension(db, opts)

lib/cloud_controller/logs/request_logs.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ def complete_request(request_id, status, env, time_taken)
3030
return if @incomplete_requests.delete(request_id).nil?
3131

3232
request = ActionDispatch::Request.new(env)
33+
query_count = Thread.current[:db_query_count]
3334
@logger.info("Completed #{status} vcap-request-id: #{request_id}",
3435
{ status_code: status,
3536
time_taken_in_ms: time_taken,
37+
db_query_count: query_count,
3638
request_method: request.request_method,
3739
request_fullpath: request.filtered_path })
3840
end

lib/cloud_controller/metrics/prometheus_updater.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def self.allow_pid_label
1818

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
21+
QUERY_COUNT_BUCKETS = [1, 5, 10, 25, 50, 100, 200].freeze
2122
DELAYED_JOB_METRIC_BUCKETS = [0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10, 30, 60, 120, 300, 600].freeze
2223

2324
METRICS = [
@@ -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_db_queries_per_request, docstring: 'DB queries per request', buckets: QUERY_COUNT_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 },
@@ -189,6 +191,10 @@ def report_staging_failure_metrics(duration_ns)
189191
update_histogram_metric(:cc_staging_failed_duration_seconds, nanoseconds_to_seconds(duration_ns))
190192
end
191193

194+
def record_db_query_count(count)
195+
update_histogram_metric(:cc_db_queries_per_request, count)
196+
end
197+
192198
private
193199

194200
def register(metric)

lib/cloud_controller/metrics/request_metrics.rb

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

16-
def complete_request(status)
16+
def complete_request(status, query_count)
1717
@statsd_updater.complete_request(status)
18+
@statsd_updater.record_db_query_count(query_count)
1819

1920
@prometheus_updater.increment_counter_metric(:cc_requests_completed_total)
2021
@prometheus_updater.decrement_gauge_metric(:cc_requests_outstanding_total)
22+
@prometheus_updater.record_db_query_count(query_count)
2123
end
2224
end
2325
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(count)
114+
@statsd.gauge('cc.requests.db_query_count', count)
115+
end
116+
113117
private
114118

115119
def nanoseconds_to_milliseconds(time_ns)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module Sequel
2+
module RequestQueryCounter
3+
def log_connection_yield(sql, conn, args=nil)
4+
Thread.current[:db_query_count] ||= 0
5+
Thread.current[:db_query_count] += 1
6+
super
7+
end
8+
end
9+
10+
Database.register_extension(:request_query_counter) { |db| db.extend(RequestQueryCounter) }
11+
end

middleware/request_metrics.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ def initialize(app, request_metrics)
77
end
88

99
def call(env)
10+
Thread.current[:db_query_count] = 0
1011
@request_metrics.start_request
1112

1213
status, headers, body = @app.call(env)
@@ -17,7 +18,9 @@ def call(env)
1718
status = 500
1819
raise e
1920
ensure
20-
@request_metrics.complete_request(status)
21+
query_count = Thread.current[:db_query_count]
22+
Thread.current[:db_query_count] = nil
23+
@request_metrics.complete_request(status, query_count)
2124
end
2225
end
2326
end

spec/unit/lib/cloud_controller/logs/request_logs_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ module VCAP::CloudController::Logs
5050
expect(logger).to have_received(:info).with(
5151
/\ACompleted 200 vcap-request-id: ID/,
5252
time_taken_in_ms: 30,
53+
db_query_count: nil,
5354
request_method: 'request_method',
5455
request_fullpath: 'filtered_path',
5556
status_code: 200

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,5 +278,14 @@ module VCAP::CloudController::Metrics
278278
expect(metric.get).to eq({ '5' => 0.0, '10' => 0.0, '30' => 0.0, '60' => 0.0, '300' => 0.0, '600' => 0.0, '890' => 0.0, 'sum' => 900.0, '+Inf' => 1.0 })
279279
end
280280
end
281+
282+
describe '#record_db_query_count' do
283+
it 'records db query count histogram' do
284+
updater.record_db_query_count(3)
285+
286+
metric = prom_client.get :cc_db_queries_per_request
287+
expect(metric.get).to eq({ '1' => 0.0, '5' => 1.0, '10' => 1.0, '25' => 1.0, '50' => 1.0, '100' => 1.0, '200' => 1.0, 'sum' => 3.0, '+Inf' => 1.0 })
288+
end
289+
end
281290
end
282291
end

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ module VCAP::CloudController::Metrics
1212
allow(prometheus_client).to receive(:decrement_gauge_metric)
1313
allow(prometheus_client).to receive(:increment_gauge_metric)
1414
allow(prometheus_client).to receive(:increment_counter_metric)
15+
allow(prometheus_client).to receive(:record_db_query_count)
1516
allow(statsd_updater).to receive(:start_request)
1617
allow(statsd_updater).to receive(:complete_request)
18+
allow(statsd_updater).to receive(:record_db_query_count)
1719
end
1820

1921
describe '#start_request' do
@@ -32,15 +34,17 @@ module VCAP::CloudController::Metrics
3234
let(:status) { 204 }
3335

3436
it 'increments completed, decrements outstanding, increments status for statsd' do
35-
request_metrics.complete_request(status)
37+
request_metrics.complete_request(status, 5)
3638
expect(statsd_updater).to have_received(:complete_request).with(status)
39+
expect(statsd_updater).to have_received(:record_db_query_count).with(5)
3740
end
3841

3942
it 'increments completed and decrements outstanding for prometheus' do
40-
request_metrics.complete_request(status)
43+
request_metrics.complete_request(status, 5)
4144

4245
expect(prometheus_client).to have_received(:decrement_gauge_metric).with(:cc_requests_outstanding_total)
4346
expect(prometheus_client).to have_received(:increment_counter_metric).with(:cc_requests_completed_total)
47+
expect(prometheus_client).to have_received(:record_db_query_count).with(5)
4448
end
4549
end
4650
end

0 commit comments

Comments
 (0)