Skip to content

Commit 80beb36

Browse files
committed
Add activity_stats method that mimics the SQL Server Activity Monitor.
1 parent e10adcd commit 80beb36

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,51 @@ def cs_equality_operator
358358
@@cs_equality_operator || 'COLLATE Latin1_General_CS_AS_WS'
359359
end
360360

361+
def activity_stats
362+
self.select(<<-EOSQL)
363+
SELECT
364+
[session_id] = s.session_id,
365+
[user_process] = CONVERT(CHAR(1), s.is_user_process),
366+
[login] = s.login_name,
367+
[database] = ISNULL(db_name(r.database_id), N''),
368+
[task_state] = ISNULL(t.task_state, N''),
369+
[command] = ISNULL(r.command, N''),
370+
[application] = ISNULL(s.program_name, N''),
371+
[wait_time_ms] = ISNULL(w.wait_duration_ms, 0),
372+
[wait_type] = ISNULL(w.wait_type, N''),
373+
[wait_resource] = ISNULL(w.resource_description, N''),
374+
[blocked_by] = ISNULL(CONVERT (varchar, w.blocking_session_id), ''),
375+
[head_blocker] =
376+
CASE
377+
-- session has an active request, is blocked, but is blocking others
378+
WHEN r2.session_id IS NOT NULL AND r.blocking_session_id = 0 THEN '1'
379+
-- session is idle but has an open tran and is blocking others
380+
WHEN r.session_id IS NULL THEN '1'
381+
ELSE ''
382+
END,
383+
[total_cpu_ms] = s.cpu_time,
384+
[total_physical_io_mb] = (s.reads + s.writes) * 8 / 1024,
385+
[memory_use_kb] = s.memory_usage * 8192 / 1024,
386+
[open_transactions] = ISNULL(r.open_transaction_count,0),
387+
[login_time] = s.login_time,
388+
[last_request_start_time] = s.last_request_start_time,
389+
[host_name] = ISNULL(s.host_name, N''),
390+
[net_address] = ISNULL(c.client_net_address, N''),
391+
[execution_context_id] = ISNULL(t.exec_context_id, 0),
392+
[request_id] = ISNULL(r.request_id, 0),
393+
[workload_group] = N''
394+
FROM sys.dm_exec_sessions s LEFT OUTER JOIN sys.dm_exec_connections c ON (s.session_id = c.session_id)
395+
LEFT OUTER JOIN sys.dm_exec_requests r ON (s.session_id = r.session_id)
396+
LEFT OUTER JOIN sys.dm_os_tasks t ON (r.session_id = t.session_id AND r.request_id = t.request_id)
397+
LEFT OUTER JOIN
398+
(SELECT *, ROW_NUMBER() OVER (PARTITION BY waiting_task_address ORDER BY wait_duration_ms DESC) AS row_num
399+
FROM sys.dm_os_waiting_tasks
400+
) w ON (t.task_address = w.waiting_task_address) AND w.row_num = 1
401+
LEFT OUTER JOIN sys.dm_exec_requests r2 ON (r.session_id = r2.blocking_session_id)
402+
WHERE db_name(r.database_id) = '#{current_database}'
403+
ORDER BY s.session_id
404+
EOSQL
405+
end
361406

362407
protected
363408

test/cases/connection_test_sqlserver.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,16 @@ def setup
117117

118118
end
119119

120+
context 'Diagnostics' do
121+
should 'testing #activity_stats' do
122+
stats = @connection.activity_stats
123+
assert stats.length > 0
124+
125+
assert stats.all? { |s| s.has_key?("session_id") }
126+
assert stats.all? { |s| s["database"] == @connection.current_database }
127+
end
128+
end
129+
120130

121131

122132
private

0 commit comments

Comments
 (0)