Skip to content

Commit 9c26373

Browse files
committed
Log DB query count per request
1 parent 0e57b51 commit 9c26373

File tree

10 files changed

+52
-6
lines changed

10 files changed

+52
-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
@@ -25,6 +26,7 @@ def self.connect(opts, logger)
2526
connection_options = VCAP::CloudController::DbConnection::OptionsFactory.build(opts)
2627

2728
db = get_connection(opts, connection_options)
29+
db.extension(:request_query_counter)
2830

2931
if opts[:log_db_queries]
3032
db.logger = logger

lib/cloud_controller/logs/request_logs.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ def start_request(request_id, env)
2626
@incomplete_requests.store(request_id, env)
2727
end
2828

29-
def complete_request(request_id, status, env, time_taken)
29+
def complete_request(request_id, status, env, time_taken, query_count)
3030
return if @incomplete_requests.delete(request_id).nil?
3131

3232
request = ActionDispatch::Request.new(env)
3333
@logger.info("Completed #{status} vcap-request-id: #{request_id}",
3434
{ status_code: status,
3535
time_taken_in_ms: time_taken,
36+
db_query_count: query_count,
3637
request_method: request.request_method,
3738
request_fullpath: request.filtered_path })
3839
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Sequel
2+
module RequestQueryCounter
3+
def log_connection_yield(sql, conn, args=nil)
4+
VCAP::Request.increment_db_query_count
5+
super
6+
end
7+
end
8+
9+
Database.register_extension(:request_query_counter) { |db| db.extend(RequestQueryCounter) }
10+
end

lib/vcap/request.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ def b3_span_id=(span_id)
5555
def b3_span_id
5656
Thread.current[:b3_span_id]
5757
end
58+
59+
def db_query_count
60+
Thread.current[:db_query_count]
61+
end
62+
63+
def increment_db_query_count
64+
Thread.current[:db_query_count] ||= 0
65+
Thread.current[:db_query_count] += 1
66+
end
67+
68+
def reset_db_query_count
69+
Thread.current[:db_query_count] = 0
70+
end
5871
end
5972
end
6073
end

middleware/request_logs.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ def call(env)
1515
# convert to milliseconds
1616
time_taken = (Time.now - start_time) * 1000
1717
time_taken = time_taken.to_i
18-
@request_logs.complete_request(request_id, status, env, time_taken)
18+
query_count = ::VCAP::Request.db_query_count
19+
@request_logs.complete_request(request_id, status, env, time_taken, query_count)
1920

2021
[status, headers, body]
2122
end

middleware/request_metrics.rb

Lines changed: 1 addition & 0 deletions
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+
::VCAP::Request.reset_db_query_count
1011
@request_metrics.start_request
1112

1213
status, headers, body = @app.call(env)

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module VCAP::CloudController::Logs
1010
let(:fake_request) { double('request', request_method: 'request_method', ip: fake_ip, filtered_path: 'filtered_path', fullpath: fake_fullpath) }
1111
let(:request_id) { 'ID' }
1212
let(:time_taken) { 30 }
13+
let(:query_count) { 5 }
1314
let(:env) { { 'cf.user_guid' => 'user-guid' } }
1415
let(:status) { 200 }
1516

@@ -46,10 +47,11 @@ module VCAP::CloudController::Logs
4647
end
4748

4849
it 'logs the completion of the request' do
49-
request_logs.complete_request(request_id, status, env, time_taken)
50+
request_logs.complete_request(request_id, status, env, time_taken, query_count)
5051
expect(logger).to have_received(:info).with(
5152
/\ACompleted 200 vcap-request-id: ID/,
5253
time_taken_in_ms: 30,
54+
db_query_count: 5,
5355
request_method: 'request_method',
5456
request_fullpath: 'filtered_path',
5557
status_code: 200
@@ -59,7 +61,7 @@ module VCAP::CloudController::Logs
5961

6062
context 'without a matching start request' do
6163
it 'does not log the completion of the request' do
62-
request_logs.complete_request(request_id, status, env, time_taken)
64+
request_logs.complete_request(request_id, status, env, time_taken, query_count)
6365
expect(logger).not_to have_received(:info)
6466
end
6567
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe Sequel::RequestQueryCounter do
4+
let(:db) { DbConfig.new.connection }
5+
6+
before do
7+
db.extension(:request_query_counter)
8+
end
9+
10+
it 'increments the thread local query count on each query' do
11+
expect do
12+
db.fetch('SELECT 1').all
13+
end.to change(VCAP::Request, :db_query_count).by(1)
14+
end
15+
end

spec/unit/middleware/request_logs_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module Middleware
2121

2222
it 'calls complete request on request logs after the request' do
2323
middleware.call(env)
24-
expect(request_logs).to have_received(:complete_request).with('ID', 200, { 'cf.request_id' => 'ID' }, be_a(Numeric))
24+
expect(request_logs).to have_received(:complete_request).with('ID', 200, { 'cf.request_id' => 'ID' }, be_a(Numeric), be_a(Numeric))
2525
end
2626
end
2727
end

spec/unit/middleware/request_metrics_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ module Middleware
99
let(:request_metrics) { instance_double(VCAP::CloudController::Metrics::RequestMetrics, start_request: nil, complete_request: nil) }
1010

1111
describe 'handling the request' do
12-
it 'calls start request on request metrics before the request' do
12+
it 'resets the db query count and calls start request on request metrics before the request' do
13+
expect(VCAP::Request).to receive(:reset_db_query_count)
1314
middleware.call({})
1415
expect(request_metrics).to have_received(:start_request)
1516
end

0 commit comments

Comments
 (0)