From 5a82ab2a37b69c2927c4548a86e92bf9b4f2125b Mon Sep 17 00:00:00 2001 From: Allen Zhou Date: Tue, 17 Dec 2024 15:37:41 -0500 Subject: [PATCH] Add schema tag to db_fragmentation metrics for sqlserver (#19277) * Add schema tag to db_fragmentation metrics * ran linter * Add changelog --- sqlserver/changelog.d/19277.added | 1 + .../db_fragmentation_metrics.py | 2 + sqlserver/metadata.csv | 8 ++-- sqlserver/tests/test_database_metrics.py | 37 ++++++++++++------- sqlserver/tests/test_metrics.py | 2 +- 5 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 sqlserver/changelog.d/19277.added diff --git a/sqlserver/changelog.d/19277.added b/sqlserver/changelog.d/19277.added new file mode 100644 index 0000000000000..527d2697cc0d2 --- /dev/null +++ b/sqlserver/changelog.d/19277.added @@ -0,0 +1 @@ +Add schema tag to db_fragmentation metrics for sqlserver diff --git a/sqlserver/datadog_checks/sqlserver/database_metrics/db_fragmentation_metrics.py b/sqlserver/datadog_checks/sqlserver/database_metrics/db_fragmentation_metrics.py index 1411449ac5e21..3e31f85d219b4 100644 --- a/sqlserver/datadog_checks/sqlserver/database_metrics/db_fragmentation_metrics.py +++ b/sqlserver/datadog_checks/sqlserver/database_metrics/db_fragmentation_metrics.py @@ -14,6 +14,7 @@ "query": """SELECT DB_NAME(DDIPS.database_id) as database_name, OBJECT_NAME(DDIPS.object_id, DDIPS.database_id) as object_name, + OBJECT_SCHEMA_NAME(DDIPS.object_id, DDIPS.database_id) as "schema", DDIPS.index_id as index_id, I.name as index_name, DDIPS.fragment_count as fragment_count, @@ -28,6 +29,7 @@ "columns": [ {"name": "database_name", "type": "tag"}, {"name": "object_name", "type": "tag"}, + {"name": "schema", "type": "tag"}, {"name": "index_id", "type": "tag"}, {"name": "index_name", "type": "tag"}, {"name": "database.fragment_count", "type": "gauge"}, diff --git a/sqlserver/metadata.csv b/sqlserver/metadata.csv index 2c222b7181d86..2a8c134ad37d6 100644 --- a/sqlserver/metadata.csv +++ b/sqlserver/metadata.csv @@ -36,15 +36,15 @@ sqlserver.buffer.page_writes,gauge,,page,,Indicates the number of physical datab sqlserver.cache.object_counts,gauge,,object,,Number of cache objects in the cache. (Perf. Counter: `Plan Cache - Cache Object Counts`),0,sql_server,cache obj counts,, sqlserver.cache.pages,gauge,,object,,Number of 8-kilobyte (KB) pages used by cache objects. (Perf. Counter: `Plan Cache - Cache Pages`),0,sql_server,cache pages,, sqlserver.database.active_transactions,gauge,,transaction,,Number of active transactions across all databases on the SQL Server instance. Tags: `db`. (Perf. Counter: `Databases - Active Transactions`).,0,sql_server,database trans active,, -sqlserver.database.avg_fragment_size_in_pages,gauge,,,,"The average number of pages in one fragment on the leaf level of an IN_ROW_DATA allocation unit. Tags: `db`, `object_name`, `index_id`, `index_name`",0,sql_server,avg fragment size in pages,, -sqlserver.database.avg_fragmentation_in_percent,gauge,,,,"Logical fragmentation for indexes, or extent fragmentation for heaps in the IN_ROW_DATA allocation unit. Tags: `db`, `object_name`, `index_id`, `index_name`",0,sql_server,avg fragmentation percent,, +sqlserver.database.avg_fragment_size_in_pages,gauge,,,,"The average number of pages in one fragment on the leaf level of an IN_ROW_DATA allocation unit. Tags: `db`, `object_name`, `schema`, `index_id`, `index_name`",0,sql_server,avg fragment size in pages,, +sqlserver.database.avg_fragmentation_in_percent,gauge,,,,"Logical fragmentation for indexes, or extent fragmentation for heaps in the IN_ROW_DATA allocation unit. Tags: `db`, `object_name`, `schema`, `index_id`, `index_name`",0,sql_server,avg fragmentation percent,, sqlserver.database.backup_count,gauge,,,,The total count of successful backups made for a database. **Note:** This metric is not emitted on Azure managed databases. Tags: `db`,0,sql_server,backup count,, sqlserver.database.backup_restore_throughput,gauge,,,,Read/write throughput for backup and restore operations of a database per second. Tags: `db`. (Perf. Counter: `Databases - Backup/Restore Throughput/sec`),0,sql_server,database restore throughput,, sqlserver.database.files.size,gauge,,kibibyte,,"Current size of the database file. Tags: `db`, `file_id`, `file_type`, `file_name`, `file_location`, `database_files_state_desc`",0,sql_server,database file size,, sqlserver.database.files.space_used,gauge,,kibibyte,,"Current used space of the database file. Tags: `db`, `file_id`, `file_type`, `file_name`, `file_location`, `database_files_state_desc`",0,sql_server,database file used size,, sqlserver.database.files.state,gauge,,,,"Database file state: 0 = Online, 1 = Restoring, 2 = Recovering, 3 = Recovery_Pending, 4 = Suspect, 5 = Unknown, 6 = Offline, 7 = Defunct. Tags: `db`, `file_id`, `file_type`, `file_name`, `file_location`, `database_files_state_desc`",0,sql_server,database file status,, -sqlserver.database.fragment_count,gauge,,,,"The number of fragments in the leaf level of an IN_ROW_DATA allocation unit. Tags: `db`, `object_name`, `index_id`, `index_name`",0,sql_server,fragment count,, -sqlserver.database.index_page_count,gauge,,,,"Total number of index or data pages. Tags: `db`, `object_name`, `index_id`, `index_name`",0,sql_server,page count per index,, +sqlserver.database.fragment_count,gauge,,,,"The number of fragments in the leaf level of an IN_ROW_DATA allocation unit. Tags: `db`, `object_name`, `schema`, `index_id`, `index_name`",0,sql_server,fragment count,, +sqlserver.database.index_page_count,gauge,,,,"Total number of index or data pages. Tags: `db`, `object_name`, `schema`, `index_id`, `index_name`",0,sql_server,page count per index,, sqlserver.database.is_in_standby,gauge,,,,"Whether or not the database is read-only for restore log. Tags: `db`, `database_state_desc`, `database_recovery_model_desc`",0,sql_server,is in standby,, sqlserver.database.is_read_only,gauge,,,,"Whether or not the database is marked as READ_ONLY. 0 = READ_WRITE, 1 = READ_ONLY. Tags: `db`, `database_state_desc`, `database_recovery_model_desc`",0,sql_server,is read-only,, sqlserver.database.is_sync_with_backup,gauge,,,,"Whether or not the database is marked for replication synchronization with backup. 0 = Not marked for replication sync, 1 = Marked for replication sync. Tags: `db`, `database_state_desc`, `database_recovery_model_desc`",0,sql_server,is sync with backup,, diff --git a/sqlserver/tests/test_database_metrics.py b/sqlserver/tests/test_database_metrics.py index 244da35a296d3..2bc74f953681d 100644 --- a/sqlserver/tests/test_database_metrics.py +++ b/sqlserver/tests/test_database_metrics.py @@ -922,29 +922,39 @@ def test_sqlserver_db_fragmentation_metrics( print(instance_docker_metrics) mocked_results = [ [ - ('master', 'spt_fallback_db', 0, None, 0, 0.0, 0, 0.0), - ('master', 'spt_fallback_dev', 0, None, 0, 0.0, 0, 0.0), - ('master', 'spt_fallback_usg', 0, None, 0, 0.0, 0, 0.0), - ('master', 'spt_monitor', 0, None, 1, 1.0, 1, 0.0), - ('master', 'MSreplication_options', 0, None, 1, 1.0, 1, 0.0), + ('master', 'spt_fallback_db', 'dbo', 0, None, 0, 0.0, 0, 0.0), + ('master', 'spt_fallback_dev', 'dbo', 0, None, 0, 0.0, 0, 0.0), + ('master', 'spt_fallback_usg', 'dbo', 0, None, 0, 0.0, 0, 0.0), + ('master', 'spt_monitor', 'dbo', 0, None, 1, 1.0, 1, 0.0), + ('master', 'MSreplication_options', 'dbo', 0, None, 1, 1.0, 1, 0.0), ], [ - ('msdb', 'syscachedcredentials', 1, 'PK__syscache__F6D56B562DA81DC6', 0, 0.0, 0, 0.0), - ('msdb', 'syscollector_blobs_internal', 1, 'PK_syscollector_blobs_internal_paremeter_name', 0, 0.0, 0, 0.0), + ('msdb', 'syscachedcredentials', 'dbo', 1, 'PK__syscache__F6D56B562DA81DC6', 0, 0.0, 0, 0.0), + ( + 'msdb', + 'syscollector_blobs_internal', + 'dbo', + 1, + 'PK_syscollector_blobs_internal_paremeter_name', + 0, + 0.0, + 0, + 0.0, + ), ], - [('datadog_test-1', 'ϑings', 1, 'thingsindex', 1, 1.0, 1, 0.0)], + [('datadog_test-1', 'ϑings', 'dbo', 1, 'thingsindex', 1, 1.0, 1, 0.0)], ] mocked_results_tempdb = [ - [('tempdb', '#TempExample__000000000008', 1, 'PK__#TempExa__3214EC278A26D67E', 1, 1.0, 1, 0.0)], + [('tempdb', '#TempExample__000000000008', 'dbo', 1, 'PK__#TempExa__3214EC278A26D67E', 1, 1.0, 1, 0.0)], ] if db_fragmentation_object_names: instance_docker_metrics['db_fragmentation_object_names'] = db_fragmentation_object_names mocked_results = [ [ - ('master', 'spt_fallback_db', 0, None, 0, 0.0, 0, 0.0), - ('master', 'spt_fallback_dev', 0, None, 0, 0.0, 0, 0.0), - ('master', 'spt_fallback_usg', 0, None, 0, 0.0, 0, 0.0), + ('master', 'spt_fallback_db', 'dbo', 0, None, 0, 0.0, 0, 0.0), + ('master', 'spt_fallback_dev', 'dbo', 0, None, 0, 0.0, 0, 0.0), + ('master', 'spt_fallback_usg', 'dbo', 0, None, 0, 0.0, 0, 0.0), ], [], [], @@ -983,12 +993,13 @@ def test_sqlserver_db_fragmentation_metrics( tags = sqlserver_check._config.tags for result in mocked_results: for row in result: - database_name, object_name, index_id, index_name, *metric_values = row + database_name, object_name, schema, index_id, index_name, *metric_values = row metrics = zip(db_fragmentation_metrics.metric_names()[0], metric_values) expected_tags = [ f'db:{database_name}', f'database_name:{database_name}', f'object_name:{object_name}', + f'schema:{schema}', f'index_id:{index_id}', f'index_name:{index_name}', ] + tags diff --git a/sqlserver/tests/test_metrics.py b/sqlserver/tests/test_metrics.py index a1c342c2f7412..0513e96660b43 100644 --- a/sqlserver/tests/test_metrics.py +++ b/sqlserver/tests/test_metrics.py @@ -353,7 +353,7 @@ def test_check_db_fragmentation_metrics( for metric_name, _, _ in DATABASE_FRAGMENTATION_METRICS: for tag in db_tags: aggregator.assert_metric_has_tag(metric_name, tag=tag) - for tag_prefix in ('index_id', 'index_name', 'object_name'): + for tag_prefix in ('index_id', 'index_name', 'object_name', 'schema'): aggregator.assert_metric_has_tag_prefix(metric_name, tag_prefix=tag_prefix)