I needed to collect sp_WhoIsActive into a table, but the twist was that it is on my Azure Managed Database, so I had to get creative with how I did it. We needed an Azure Pipeline to run it, but we wanted to record it every minute and firing a pipeline every minute adds up fast. So we decided that we would kick it off once an hour and have the process wait for a minute and then fire until the hour ended. Then it fire again at the top of the next hour and the same process would happen.
First, I created my table in my special dba schema because this is for me:
CREATE TABLE [dba].[whoisactiveLog](
[dd hh:mm:ss.mss] [varchar](20) NULL,
[percent_complete] [varchar](30) NULL,
[host_name] [nvarchar](128) NULL,
[session_id] [smallint] NOT NULL,
[login_name] [nvarchar](128) NOT NULL,
[status] [varchar](30) NOT NULL,
[sql_text] [xml] NULL,
[wait_info] [nvarchar](4000) NULL,
[blocking_session_id] [smallint] NULL,
[blocked_session_count] [varchar](30) NULL,
[reads] [varchar](30) NULL,
[physical_reads] [varchar](30) NULL,
[writes] [varchar](30) NULL,
[tempdb_allocations] [varchar](30) NULL,
[tempdb_current] [varchar](30) NULL,
[CPU] [varchar](30) NULL,
[used_memory] [varchar](30) NULL,
[open_tran_count] [varchar](30) NULL,
[sql_command] [xml] NULL,
[database_name] [nvarchar](128) NULL,
[program_name] [nvarchar](128) NULL,
[start_time] [datetime] NOT NULL,
[login_time] [datetime] NULL,
[request_id] [int] NULL,
[collection_time] [datetime] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Then I built my procedure to collect the value of the hour and set up a while loop for as long as the hour matches this collected value, I want it to load my results from sp_whoisactive into my table. Then I have it wait for one minute and do it again.
CREATE PROCEDURE [dba].[LoadWhoIsActiveLog]
AS
DECLARE @Hour INT
SET @Hour= (SELECT DATEPART(HOUR,GETDATE()))
WHILE ( @Hour = (SELECT DATEPART(HOUR,GETDATE())))
BEGIN
EXEC sp_whoisactive
@get_outer_command = 1
, @find_block_leaders = 1
, @output_column_list = '[dd hh:mm:ss.mss][percent_complete][host_name][session_id][login_name][status][sql_text][wait_info][blocking_session_id][blocked_session_count][%]'
, @sort_order = '[blocked_session_count] DESC, [start_time] ASC'
, @destination_table = 'dba.whoisactiveLog'
BEGIN
WAITFOR DELAY '0:01'
END
END;
It runs exactly as I wanted. I put it in an Azure Pipeline and have it fire at the top of the hour during our busy hours so we can collect usage.
The song for this post is Call the Moondust by Glen Phillips.