From db0d950b3ad6dcedee4eec975a14d215a5295076 Mon Sep 17 00:00:00 2001 From: Giovanni Luisotto Date: Thu, 7 May 2020 20:25:03 +0200 Subject: [PATCH] Add cpu query to sqlserver input (#7359) --- plugins/inputs/sqlserver/README.md | 6 ++-- plugins/inputs/sqlserver/sqlserver.go | 36 ++++++++++++++++++++++ plugins/inputs/sqlserver/sqlserver_test.go | 4 +-- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/plugins/inputs/sqlserver/README.md b/plugins/inputs/sqlserver/README.md index 9d55955d1..320fee275 100644 --- a/plugins/inputs/sqlserver/README.md +++ b/plugins/inputs/sqlserver/README.md @@ -65,6 +65,7 @@ GO ## - Schedulers ## - SqlRequests ## - VolumeSpace + ## - Cpu ## Version 1: ## - PerformanceCounters ## - WaitStatsCategorized @@ -81,13 +82,13 @@ GO # include_query = [] ## A list of queries to explicitly ignore. - exclude_query = [ 'Schedulers' , 'SqlRequests'] + exclude_query = [ 'Schedulers' , 'SqlRequests' ] ``` ### Metrics: To provide backwards compatibility, this plugin support two versions of metrics queries. -**Note**: Version 2 queries are not backwards compatible with the old queries. Any dashboards or queries based on the old query format will not work with the new format. The version 2 queries are written in such a way as to only gather SQL specific metrics (no overall CPU related metrics) and they only report raw metrics, no math has been done to calculate deltas. To graph this data you must calculate deltas in your dashboarding software. +**Note**: Version 2 queries are not backwards compatible with the old queries. Any dashboards or queries based on the old query format will not work with the new format. The version 2 queries only report raw metrics, no math has been done to calculate deltas. To graph this data you must calculate deltas in your dashboarding software. #### Version 1 (deprecated in 1.6): The original metrics queries provide: @@ -124,6 +125,7 @@ The new (version 2) metrics provide: dm_exec_sessions that gives you running requests as well as wait types and blocking sessions. - *VolumeSpace* - uses sys.dm_os_volume_stats to get total, used and occupied space on every disk that contains a data or log file. (Note that even if enabled it won't get any data from Azure SQL Database or SQL Managed Instance). It is pointless to run this with high frequency (ie: every 10s), but it won't cause any problem. +- *Cpu* - uses the buffer ring (sys.dm_os_ring_buffers) to get CPU data, the table is updated once per minute. (Note that even if enabled it won't get any data from Azure SQL Database or SQL Managed Instance). In order to allow tracking on a per statement basis this query produces a unique tag for each query. Depending on the database workload, this may diff --git a/plugins/inputs/sqlserver/sqlserver.go b/plugins/inputs/sqlserver/sqlserver.go index 6214ee237..cb70686e2 100644 --- a/plugins/inputs/sqlserver/sqlserver.go +++ b/plugins/inputs/sqlserver/sqlserver.go @@ -117,6 +117,7 @@ func initQueries(s *SQLServer) error { queries["Schedulers"] = Query{Script: sqlServerSchedulersV2, ResultByRow: false} queries["SqlRequests"] = Query{Script: sqlServerRequestsV2, ResultByRow: false} queries["VolumeSpace"] = Query{Script: sqlServerVolumeSpaceV2, ResultByRow: false} + queries["Cpu"] = Query{Script: sqlServerCpuV2, ResultByRow: false} } else { queries["PerformanceCounters"] = Query{Script: sqlPerformanceCounters, ResultByRow: true} queries["WaitStatsCategorized"] = Query{Script: sqlWaitStatsCategorized, ResultByRow: false} @@ -1593,6 +1594,41 @@ IF SERVERPROPERTY('EngineEdition') NOT IN (5,8) END ` +const sqlServerCpuV2 string = ` +/*The ring buffer has a new value every minute*/ +IF SERVERPROPERTY('EngineEdition') NOT IN (5,8) /*No azure DB and managed instance*/ +BEGIN +SELECT + 'sqlserver_cpu' AS [measurement] + ,REPLACE(@@SERVERNAME,'\',':') AS [sql_instance] + ,[SQLProcessUtilization] AS [sqlserver_process_cpu] + ,[SystemIdle] AS [system_idle_cpu] + ,100 - [SystemIdle] - [SQLProcessUtilization] AS [other_process_cpu] +FROM ( + SELECT TOP 1 + [record_id] + /*,dateadd(ms, (y.[timestamp] - (SELECT CAST([ms_ticks] AS BIGINT) FROM sys.dm_os_sys_info)), GETDATE()) AS [EventTime] --use for check/debug purpose*/ + ,[SQLProcessUtilization] + ,[SystemIdle] + FROM ( + SELECT record.value('(./Record/@id)[1]', 'int') AS [record_id] + ,record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') AS [SystemIdle] + ,record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') AS [SQLProcessUtilization] + ,[TIMESTAMP] + FROM ( + SELECT [TIMESTAMP] + ,convert(XML, [record]) AS [record] + FROM sys.dm_os_ring_buffers + WHERE [ring_buffer_type] = N'RING_BUFFER_SCHEDULER_MONITOR' + AND [record] LIKE '%%' + ) AS x + ) AS y + ORDER BY record_id DESC +) as z + +END +` + // Queries V1 const sqlPerformanceMetrics string = `SET DEADLOCK_PRIORITY -10; SET NOCOUNT ON; diff --git a/plugins/inputs/sqlserver/sqlserver_test.go b/plugins/inputs/sqlserver/sqlserver_test.go index ea638ef20..c92353783 100644 --- a/plugins/inputs/sqlserver/sqlserver_test.go +++ b/plugins/inputs/sqlserver/sqlserver_test.go @@ -16,13 +16,13 @@ func TestSqlServer_QueriesInclusionExclusion(t *testing.T) { cases := []map[string]interface{}{ { "IncludeQuery": []string{}, - "ExcludeQuery": []string{"WaitStatsCategorized", "DatabaseIO", "ServerProperties", "MemoryClerk", "Schedulers", "VolumeSpace"}, + "ExcludeQuery": []string{"WaitStatsCategorized", "DatabaseIO", "ServerProperties", "MemoryClerk", "Schedulers", "VolumeSpace", "Cpu"}, "queries": []string{"PerformanceCounters", "SqlRequests"}, "queriesTotal": 2, }, { "IncludeQuery": []string{"PerformanceCounters", "SqlRequests"}, - "ExcludeQuery": []string{"SqlRequests", "WaitStatsCategorized", "DatabaseIO", "VolumeSpace"}, + "ExcludeQuery": []string{"SqlRequests", "WaitStatsCategorized", "DatabaseIO", "VolumeSpace", "Cpu"}, "queries": []string{"PerformanceCounters"}, "queriesTotal": 1, },