Skip to content

Commit 06cae5a

Browse files
committed
Made sp_HumanEventsBlockViewer not error out when system_health is used. Updated documentation, printing, and debug output to reflect this. Also automatically selected event_file if no target type is specified for system_health, since our usual default of table is no good. Closes erikdarlingdata#617.
1 parent 59d9c9d commit 06cae5a

File tree

2 files changed

+98
-48
lines changed

2 files changed

+98
-48
lines changed

sp_HumanEvents/README.md

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ EXECUTE dbo.sp_HumanEvents
122122

123123
This was originally a companion script to analyze the blocked process report Extended Event created by sp_HumanEvents, but has since turned into its own monster.
124124

125-
It will work on any Extended Event that captures the blocked process report. If you need to set that up, run these two pieces of code.
125+
It will work on any Extended Event that captures the blocked process report. If you need to set that up, run the next two pieces of code.
126+
127+
The system_health Extended Event works, but its blocked process report is much less comprehensive than the real thing. I do not allow logging to a table from this, because the set of columns and available data is too incomplete, and I don't want to juggle multiple table definitions.
126128

127129
## Setup
128130

@@ -172,28 +174,28 @@ ON SERVER
172174

173175
## Parameters
174176

175-
| parameter_name | data_type | description | valid_inputs | defaults |
176-
|-----------------------|-----------|-------------------------------------------------|------------------------------------------------------------------------|------------------------------------|
177-
| @session_name | sysname | name of the extended event session to pull from | extended event session name capturing sqlserver.blocked_process_report | keeper_HumanEvents_blocking |
178-
| @target_type | sysname | target of the extended event session | event_file or ring_buffer | NULL |
179-
| @start_date | datetime2 | filter by date | a reasonable date | NULL; will shortcut to last 7 days |
180-
| @end_date | datetime2 | filter by date | a reasonable date | NULL |
181-
| @database_name | sysname | filter by database name | a database that exists on this server | NULL |
182-
| @object_name | sysname | filter by table name | a schema-prefixed table name | NULL |
183-
| @target_database | sysname | database containing the table with BPR data | a valid database name | NULL |
184-
| @target_schema | sysname | schema of the table | a valid schema name | NULL |
185-
| @target_table | sysname | table name | a valid table name | NULL |
186-
| @target_column | sysname | column containing XML data | a valid column name | NULL |
187-
| @timestamp_column | sysname | column containing timestamp (optional) | a valid column name | NULL |
188-
| @log_to_table | bit | enable logging to permanent tables | 0 or 1 | 0 |
189-
| @log_database_name | sysname | database to store logging tables | a valid database name | NULL |
190-
| @log_schema_name | sysname | schema to store logging tables | a valid schema name | NULL |
191-
| @log_table_name_prefix| sysname | prefix for all logging tables | a valid table name prefix | 'HumanEventsBlockViewer' |
192-
| @log_retention_days | integer | Number of days to keep logs, 0 = keep indefinitely | a valid integer | 30 |
193-
| @help | bit | how you got here | 0 or 1 | 0 |
194-
| @debug | bit | dumps raw temp table contents | 0 or 1 | 0 |
195-
| @version | varchar | OUTPUT; for support | none; OUTPUT | none; OUTPUT |
196-
| @version_date | datetime | OUTPUT; for support | none; OUTPUT | none; OUTPUT |
177+
| parameter_name | data_type | description | valid_inputs | defaults |
178+
|-----------------------|-----------|----------------------------------------------------|--------------------------------------------------------------------------------------------------|------------------------------------|
179+
| @session_name | sysname | name of the extended event session to pull from | extended event session name capturing sqlserver.blocked_process_report, system_health also works | keeper_HumanEvents_blocking |
180+
| @target_type | sysname | target of the extended event session | event_file or ring_buffer or table | NULL |
181+
| @start_date | datetime2 | filter by date | a reasonable date | NULL; will shortcut to last 7 days |
182+
| @end_date | datetime2 | filter by date | a reasonable date | NULL |
183+
| @database_name | sysname | filter by database name | a database that exists on this server | NULL |
184+
| @object_name | sysname | filter by table name | a schema-prefixed table name | NULL |
185+
| @target_database | sysname | database containing the table with BPR data | a valid database name | NULL |
186+
| @target_schema | sysname | schema of the table | a valid schema name | NULL |
187+
| @target_table | sysname | table name | a valid table name | NULL |
188+
| @target_column | sysname | column containing XML data | a valid column name | NULL |
189+
| @timestamp_column | sysname | column containing timestamp (optional) | a valid column name | NULL |
190+
| @log_to_table | bit | enable logging to permanent tables | 0 or 1 | 0 |
191+
| @log_database_name | sysname | database to store logging tables | a valid database name | NULL |
192+
| @log_schema_name | sysname | schema to store logging tables | a valid schema name | NULL |
193+
| @log_table_name_prefix| sysname | prefix for all logging tables | a valid table name prefix | 'HumanEventsBlockViewer' |
194+
| @log_retention_days | integer | Number of days to keep logs, 0 = keep indefinitely | a valid integer | 30 |
195+
| @help | bit | how you got here | 0 or 1 | 0 |
196+
| @debug | bit | dumps raw temp table contents | 0 or 1 | 0 |
197+
| @version | varchar | OUTPUT; for support | none; OUTPUT | none; OUTPUT |
198+
| @version_date | datetime | OUTPUT; for support | none; OUTPUT | none; OUTPUT |
197199

198200
## Usage Examples
199201

@@ -219,4 +221,4 @@ EXECUTE dbo.sp_HumanEventsBlockViewer
219221
@log_to_table = 1,
220222
@log_database_name = 'DBA',
221223
@log_schema_name = 'dbo';
222-
```
224+
```

sp_HumanEvents/sp_HumanEventsBlockViewer.sql

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ BEGIN
105105
SELECT 'it will also work with any other extended event session that captures blocking' UNION ALL
106106
SELECT 'just use the @session_name parameter to point me there' UNION ALL
107107
SELECT 'EXECUTE dbo.sp_HumanEventsBlockViewer @session_name = N''blocked_process_report'';' UNION ALL
108+
SELECT 'the system_health session also works, if you are okay with its lousy blocked process report'
108109
SELECT 'all scripts and documentation are available here: https://code.erikdarling.com' UNION ALL
109110
SELECT 'from your loving sql server consultant, erik darling: https://erikdarling.com';
110111

@@ -137,8 +138,8 @@ BEGIN
137138
END,
138139
valid_inputs =
139140
CASE ap.name
140-
WHEN N'@session_name' THEN 'extended event session name capturing sqlserver.blocked_process_report'
141-
WHEN N'@target_type' THEN 'event_file or ring_buffer'
141+
WHEN N'@session_name' THEN 'extended event session name capturing sqlserver.blocked_process_report, system_health also works'
142+
WHEN N'@target_type' THEN 'event_file or ring_buffer or table'
142143
WHEN N'@start_date' THEN 'a reasonable date'
143144
WHEN N'@end_date' THEN 'a reasonable date'
144145
WHEN N'@database_name' THEN 'a database that exists on this server'
@@ -195,7 +196,7 @@ BEGIN
195196
N'check the messages tab for setup commands';
196197

197198
RAISERROR('
198-
The blocked process report needs to be enabled:
199+
Unless you want to use the lousy version in system_health, the blocked process report needs to be enabled:
199200
EXECUTE sys.sp_configure ''show advanced options'', 1;
200201
EXECUTE sys.sp_configure ''blocked process threshold'', 5; /* Seconds of blocking before a report is generated */
201202
RECONFIGURE;', 0, 1) WITH NOWAIT;
@@ -264,6 +265,65 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
264265
RETURN;
265266
END;
266267

268+
IF @debug = 1
269+
BEGIN
270+
RAISERROR('Check if we are using system_health', 0, 1) WITH NOWAIT;
271+
END;
272+
DECLARE
273+
@is_system_health bit = 0,
274+
@is_system_health_msg nchar(1);
275+
276+
SELECT
277+
@is_system_health =
278+
CASE
279+
WHEN @session_name LIKE N'system%health'
280+
THEN 1
281+
ELSE 0
282+
END,
283+
@is_system_health_msg =
284+
CONVERT(nchar(1), @is_system_health);
285+
286+
IF @debug = 1
287+
AND @is_system_health = 0
288+
BEGIN
289+
RAISERROR('We are not using system_health', 0, 1) WITH NOWAIT;
290+
END;
291+
292+
IF @is_system_health = 1
293+
BEGIN
294+
RAISERROR('For best results, consider not using system_health as your target. Re-run with @help = 1 for guidance.', 0, 1) WITH NOWAIT;
295+
END
296+
297+
/*
298+
Note: I do not allow logging to a table from system_health, because the set of columns
299+
and available data is too incomplete, and I don't want to juggle multiple
300+
table definitions.
301+
302+
Logging to a table is only allowed from a blocked_process_report Extended Event,
303+
but it can either be ring buffer or file target. I don't care about that.
304+
*/
305+
IF @is_system_health = 1
306+
AND
307+
(
308+
LOWER(@target_type) = N'table'
309+
OR @log_to_table = 1
310+
)
311+
BEGIN
312+
RAISERROR('Logging system_health to a table is not supported.
313+
Either pick a different session or change both
314+
@target_type to be ''event_file'' or ''ring_buffer''
315+
and @log_to_table to be 0.', 11, 0) WITH NOWAIT;
316+
RETURN;
317+
END
318+
319+
IF @is_system_health = 1
320+
AND @target_type IS NULL
321+
BEGIN
322+
RAISERROR('No @target_type specified, using ''event_file''.', 0, 1) WITH NOWAIT;
323+
SELECT
324+
@target_type = 'event_file';
325+
END
326+
267327
/*Check if the blocked process report is on at all*/
268328
IF EXISTS
269329
(
@@ -272,9 +332,10 @@ IF EXISTS
272332
FROM sys.configurations AS c
273333
WHERE c.name = N'blocked process threshold (s)'
274334
AND CONVERT(int, c.value_in_use) = 0
335+
AND @is_system_health = 0
275336
)
276337
BEGIN
277-
RAISERROR(N'The blocked process report needs to be enabled:
338+
RAISERROR(N'Unless you want to use the lousy version in system_health, the blocked process report needs to be enabled:
278339
EXECUTE sys.sp_configure ''show advanced options'', 1;
279340
EXECUTE sys.sp_configure ''blocked process threshold'', 5; /* Seconds of blocking before a report is generated */
280341
RECONFIGURE;',
@@ -290,6 +351,7 @@ IF EXISTS
290351
FROM sys.configurations AS c
291352
WHERE c.name = N'blocked process threshold (s)'
292353
AND CONVERT(int, c.value_in_use) <> 5
354+
AND @is_system_health = 0
293355
)
294356
BEGIN
295357
RAISERROR(N'For best results, set up the blocked process report like this:
@@ -319,8 +381,6 @@ DECLARE
319381
@session_id integer,
320382
@target_session_id integer,
321383
@file_name nvarchar(4000),
322-
@is_system_health bit = 0,
323-
@is_system_health_msg nchar(1),
324384
@inputbuf_bom nvarchar(1) =
325385
CONVERT(nvarchar(1), 0x0a00, 0),
326386
@start_date_original datetime2 = @start_date,
@@ -405,12 +465,6 @@ SELECT
405465
@end_date
406466
)
407467
END,
408-
@is_system_health =
409-
CASE
410-
WHEN @session_name LIKE N'system%health'
411-
THEN 1
412-
ELSE 0
413-
END,
414468
@mdsql = N'
415469
IF OBJECT_ID(''{table_check}'', ''U'') IS NOT NULL
416470
BEGIN
@@ -441,15 +495,14 @@ END;';
441495

442496
SELECT
443497
@azure_msg =
444-
CONVERT(nchar(1), @azure),
445-
@is_system_health_msg =
446-
CONVERT(nchar(1), @is_system_health);
498+
CONVERT(nchar(1), @azure);
447499

448500
/*Change this here in case someone leave it NULL*/
449501
IF ISNULL(@target_database, DB_NAME()) IS NOT NULL
450502
AND ISNULL(@target_schema, N'dbo') IS NOT NULL
451503
AND @target_table IS NOT NULL
452504
AND @target_column IS NOT NULL
505+
AND @is_system_health = 0
453506
BEGIN
454507
SET @target_type = N'table';
455508
END;
@@ -1125,18 +1178,13 @@ END;
11251178

11261179
/*
11271180
This section is special for the well-hidden and much less comprehensive blocked
1128-
process report stored in the system health extended event session
1129-
1130-
Note: I do not allow logging to a table from this, because the set of columns
1131-
and available data is too incomplete, and I don't want to juggle multiple
1132-
table definitions.
1181+
process report stored in the system health extended event session.
11331182
1134-
Logging to a table is only allowed from the a blocked_process_report Extended Event,
1135-
but it can either be ring buffer or file target. I don't care about that.
1183+
We disallow many features here.
1184+
See where @is_system_health was declared for details.
1185+
That is also where we error out if somebody tries to use an unsupported feature.
11361186
*/
11371187
IF @is_system_health = 1
1138-
AND LOWER(@target_type) <> N'table'
1139-
AND @log_to_table = 0
11401188
BEGIN
11411189
IF @debug = 1
11421190
BEGIN

0 commit comments

Comments
 (0)