Skip to content

Commit

Permalink
only collect SqlDbFileSpaceUsage for tempdb (#15906)
Browse files Browse the repository at this point in the history
* only collect SqlDbFileSpaceUsage for tempdb

* update changelog

* tempdb file space usage is part of default metrics

* by default we collect tempdb file space usage

* optional restore to previous db if current_db is not None

* update config option

* fix lint

* fix model
  • Loading branch information
lu-zhengda authored Sep 27, 2023
1 parent 4a77c39 commit 08326c2
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 67 deletions.
1 change: 1 addition & 0 deletions sqlserver/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

***Added***:

* Only collect `SqlDbFileSpaceUsage` metrics for `tempdb` ([#15906](https://github.com/DataDog/integrations-core/pull/15906))
* Add TempDB version store performance counters ([#15879](https://github.com/DataDog/integrations-core/pull/15879))
* Add TempDB page counts metrics ([#15873](https://github.com/DataDog/integrations-core/pull/15873))
* Add `index_name` tag to `.database.avg_fragmentation_in_percent`, `.database.fragment_count`, `.database.avg_fragment_size_in_pages` metrics. Also add a new metric `sqlserver.database.index_page_count`, tagged by `database_name`, `object_name`, `index_id` and `index_name`. ([#15721](https://github.com/DataDog/integrations-core/pull/15721))
Expand Down
7 changes: 3 additions & 4 deletions sqlserver/assets/configuration/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,12 @@ files:
type: array
items:
type: string
- name: include_db_file_space_usage_metrics
- name: include_tempdb_file_space_usage_metrics
description: |
Include database file space usage metrics for how space is used by data files in a specific database.
Note this view is especially relevant for the tempdb database.
Include tempdb file space usage metrics for how space is used in tempdb data files.
value:
type: boolean
example: false
example: true
- name: adoprovider
description: |
Choose the ADO provider. Note that the (default) provider
Expand Down
8 changes: 4 additions & 4 deletions sqlserver/datadog_checks/sqlserver/config_models/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ def instance_include_ao_metrics():
return False


def instance_include_db_file_space_usage_metrics():
return False


def instance_include_db_fragmentation_metrics():
return False

Expand All @@ -88,6 +84,10 @@ def instance_include_task_scheduler_metrics():
return False


def instance_include_tempdb_file_space_usage_metrics():
return True


def instance_log_unobfuscated_plans():
return False

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ class InstanceConfig(BaseModel):
host: str
ignore_missing_database: Optional[bool] = None
include_ao_metrics: Optional[bool] = None
include_db_file_space_usage_metrics: Optional[bool] = None
include_db_fragmentation_metrics: Optional[bool] = None
include_fci_metrics: Optional[bool] = None
include_instance_metrics: Optional[bool] = None
include_master_files_metrics: Optional[bool] = None
include_task_scheduler_metrics: Optional[bool] = None
include_tempdb_file_space_usage_metrics: Optional[bool] = None
log_unobfuscated_plans: Optional[bool] = None
log_unobfuscated_queries: Optional[bool] = None
managed_identity: Optional[ManagedIdentity] = None
Expand Down
12 changes: 6 additions & 6 deletions sqlserver/datadog_checks/sqlserver/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,22 +205,22 @@
('sqlserver.database.master_files.state', 'sys.master_files', 'state'),
]

DATABASE_FILE_SPACE_USAGE_METRICS = [
('sqlserver.database.file_space_usage.free_space', 'sys.dm_db_file_space_usage', 'free_space'),
TEMPDB_FILE_SPACE_USAGE_METRICS = [
('sqlserver.tempdb.file_space_usage.free_space', 'sys.dm_db_file_space_usage', 'free_space'),
(
'sqlserver.database.file_space_usage.used_space_by_version_store',
'sqlserver.tempdb.file_space_usage.version_store_space',
'sys.dm_db_file_space_usage',
'used_space_by_version_store',
),
(
'sqlserver.database.file_space_usage.used_space_by_internal_object',
'sqlserver.tempdb.file_space_usage.internal_object_space',
'sys.dm_db_file_space_usage',
'used_space_by_internal_object',
),
(
'sqlserver.database.file_space_usage.used_space_by_user_object',
'sqlserver.tempdb.file_space_usage.user_object_space',
'sys.dm_db_file_space_usage',
'used_space_by_user_object',
),
('sqlserver.database.file_space_usage.mixed_extent_space', 'sys.dm_db_file_space_usage', 'mixed_extent_space'),
('sqlserver.tempdb.file_space_usage.mixed_extent_space', 'sys.dm_db_file_space_usage', 'mixed_extent_space'),
]
7 changes: 3 additions & 4 deletions sqlserver/datadog_checks/sqlserver/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,10 @@ instances:
#
# db_fragmentation_object_names: []

## @param include_db_file_space_usage_metrics - boolean - optional - default: false
## Include database file space usage metrics for how space is used by data files in a specific database.
## Note this view is especially relevant for the tempdb database.
## @param include_tempdb_file_space_usage_metrics - boolean - optional - default: true
## Include tempdb file space usage metrics for how space is used in tempdb data files.
#
# include_db_file_space_usage_metrics: false
# include_tempdb_file_space_usage_metrics: true

## @param adoprovider - string - optional - default: SQLOLEDB
## Choose the ADO provider. Note that the (default) provider
Expand Down
54 changes: 30 additions & 24 deletions sqlserver/datadog_checks/sqlserver/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,34 +949,40 @@ class SqlDbFileSpaceUsage(BaseSqlServerMetric):
def fetch_all_values(cls, cursor, counters_list, logger, databases=None):
rows = []
columns = []
if databases is None:
databases = []

logger.debug("%s: gathering db file space usage metrics for these databases: %s", cls.__name__, databases)
cursor.execute('select DB_NAME()') # This can return None in some implementations, so it cannot be chained
data = cursor.fetchall()
current_db = data[0][0]
logger.debug("%s: current db is %s", cls.__name__, current_db)

for db in databases:
ctx = construct_use_statement(db)
start = get_precise_time()
try:
logger.debug("%s: changing cursor context via use statement: %s", cls.__name__, ctx)
cursor.execute(ctx)
logger.debug("%s: fetch_all executing query: %s", cls.__name__, cls.QUERY_BASE)
cursor.execute(cls.QUERY_BASE)
data = cursor.fetchall()
except Exception as e:
logger.warning("Error when trying to query db %s - skipping. Error: %s", db, e)
continue
elapsed = get_precise_time() - start
logger.debug("%s: gathering db file space usage metrics for tempdb", cls.__name__)
db = 'tempdb' # we are only interested in tempdb
ctx = construct_use_statement(db)
start = get_precise_time()
try:
logger.debug("%s: changing cursor context via use statement: %s", cls.__name__, ctx)
cursor.execute(ctx)
logger.debug("%s: fetch_all executing query: %s", cls.__name__, cls.QUERY_BASE)
cursor.execute(cls.QUERY_BASE)
data = cursor.fetchall()
except Exception as e:
logger.warning("Error when trying to query db %s - skipping. Error: %s", db, e)
elapsed = get_precise_time() - start

query_columns = [i[0] for i in cursor.description]
if columns:
if columns != query_columns:
raise CheckException('Assertion error: {} != {}'.format(columns, query_columns))
else:
columns = query_columns

query_columns = [i[0] for i in cursor.description]
if columns:
if columns != query_columns:
raise CheckException('Assertion error: {} != {}'.format(columns, query_columns))
else:
columns = query_columns
rows.extend(data)
logger.debug("%s: received %d rows for db %s, elapsed time: %.4f sec", cls.__name__, len(data), db, elapsed)

rows.extend(data)
logger.debug("%s: received %d rows for db %s, elapsed time: %.4f sec", cls.__name__, len(data), db, elapsed)
# reset back to previous db
if current_db:
logger.debug("%s: reverting cursor context via use statement to %s", cls.__name__, current_db)
cursor.execute(construct_use_statement(current_db))

return rows, columns

Expand Down
14 changes: 5 additions & 9 deletions sqlserver/datadog_checks/sqlserver/sqlserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
AZURE_DEPLOYMENT_TYPE_TO_RESOURCE_TYPES,
BASE_NAME_QUERY,
COUNTER_TYPE_QUERY,
DATABASE_FILE_SPACE_USAGE_METRICS,
DATABASE_FRAGMENTATION_METRICS,
DATABASE_MASTER_FILES,
DATABASE_METRICS,
Expand All @@ -60,6 +59,7 @@
STATIC_INFO_MAJOR_VERSION,
STATIC_INFO_VERSION,
TASK_SCHEDULER_METRICS,
TEMPDB_FILE_SPACE_USAGE_METRICS,
VALID_METRIC_TYPES,
expected_sys_databases_columns,
)
Expand Down Expand Up @@ -583,14 +583,10 @@ def _make_metric_list_to_collect(self, custom_metrics):
metrics_to_collect.append(self.typed_metric(cfg_inst=cfg, table=table, column=column))

# Load DB File Space Usage metrics
if is_affirmative(self.instance.get('include_db_file_space_usage_metrics', False)):
db_names = [d.name for d in self.databases] or [
self.instance.get('database', self.connection.DEFAULT_DATABASE)
]
for db_name in db_names:
for name, table, column in DATABASE_FILE_SPACE_USAGE_METRICS:
cfg = {'name': name, 'table': table, 'column': column, 'instance_name': db_name, 'tags': tags}
metrics_to_collect.append(self.typed_metric(cfg_inst=cfg, table=table, column=column))
if is_affirmative(self.instance.get('include_tempdb_file_space_usage_metrics', True)):
for name, table, column in TEMPDB_FILE_SPACE_USAGE_METRICS:
cfg = {'name': name, 'table': table, 'column': column, 'instance_name': 'tempdb', 'tags': tags}
metrics_to_collect.append(self.typed_metric(cfg_inst=cfg, table=table, column=column))

# Load any custom metrics from conf.d/sqlserver.yaml
for cfg in custom_metrics:
Expand Down
10 changes: 5 additions & 5 deletions sqlserver/metadata.csv
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ sqlserver.database.avg_fragmentation_in_percent,gauge,,,,"Logical fragmentation
sqlserver.database.backup_count,gauge,,,,"The total count of successful backups made for a database.",0,sql_server,backup count,
sqlserver.database.fragment_count,gauge,,,,"The number of fragments in the leaf level of an IN_ROW_DATA allocation unit.",0,sql_server,fragment count,
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.",0,sql_server,is sync with backup,
sqlserver.database.file_space_usage.free_space,gauge,,mebibyte,,The amount of free space in the database file,0,sql_server,database file free space,
sqlserver.database.file_space_usage.used_space_by_version_store,gauge,,mebibyte,,The amount of space used by the version store in the database file,0,sql_server,database file used space by version store,
sqlserver.database.file_space_usage.used_space_by_internal_object,gauge,,mebibyte,,The amount of space used by internal objects in the database file,0,sql_server,database file used space by internal object,
sqlserver.database.file_space_usage.used_space_by_user_object,gauge,,mebibyte,,The amount of space used by user objects in the database file,0,sql_server,database file used space by user object,
sqlserver.database.file_space_usage.mixed_extent_space,gauge,,mebibyte,,The amount of space used by mixed extents in the database file,0,sql_server,database file mixed extent space,
sqlserver.tempdb.file_space_usage.free_space,gauge,,mebibyte,,The amount of free space in the tempdb database file,0,sql_server,tempdb database file free space,
sqlserver.tempdb.file_space_usage.version_store_space,gauge,,mebibyte,,The amount of space used by the version store in the tempdb database file,0,sql_server,tempdb database file used space by version store,
sqlserver.tempdb.file_space_usage.internal_object_space,gauge,,mebibyte,,The amount of space used by internal objects in the tempdb database file,0,sql_server,tempdb database file used space by internal object,
sqlserver.tempdb.file_space_usage.user_object_space,gauge,,mebibyte,,The amount of space used by user objects in the tempdb database file,0,sql_server,tempdb database file used space by user object,
sqlserver.tempdb.file_space_usage.mixed_extent_space,gauge,,mebibyte,,The amount of space used by mixed extents in the tempdb database file,0,sql_server,tempdb database file mixed extent space,
sqlserver.files.reads,count,,read,second,"Number of reads issued on the file. Tags: `logical_name`, `file_location`, `db`, `state`",0,sql_server,reads on database file,
sqlserver.files.read_bytes,count,,byte,second,"Bytes read from the file. Tags: `logical_name`, `file_location`, `db`, `state`",0,sql_server,bytes read from database file,
sqlserver.files.read_io_stall,count,,millisecond,,"Total time that users waited for reads on the file. Tags: `logical_name`, `file_location`, `db`, `state`",-1,sql_server,read wait time on database file,
Expand Down
5 changes: 2 additions & 3 deletions sqlserver/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
AO_METRICS,
AO_METRICS_PRIMARY,
AO_METRICS_SECONDARY,
DATABASE_FILE_SPACE_USAGE_METRICS,
DATABASE_FRAGMENTATION_METRICS,
DATABASE_MASTER_FILES,
DATABASE_METRICS,
DBM_MIGRATED_METRICS,
INSTANCE_METRICS,
INSTANCE_METRICS_DATABASE,
TASK_SCHEDULER_METRICS,
TEMPDB_FILE_SPACE_USAGE_METRICS,
)
from datadog_checks.sqlserver.queries import get_query_file_stats

Expand Down Expand Up @@ -81,6 +81,7 @@ def get_expected_file_stats_metrics():
DBM_MIGRATED_METRICS,
INSTANCE_METRICS_DATABASE,
DATABASE_METRICS,
TEMPDB_FILE_SPACE_USAGE_METRICS,
)
]
+ SERVER_METRICS
Expand All @@ -94,7 +95,6 @@ def get_expected_file_stats_metrics():
TASK_SCHEDULER_METRICS,
DATABASE_FRAGMENTATION_METRICS,
DATABASE_MASTER_FILES,
DATABASE_FILE_SPACE_USAGE_METRICS,
)
]
+ CUSTOM_METRICS
Expand Down Expand Up @@ -154,7 +154,6 @@ def get_expected_file_stats_metrics():
'include_ao_metrics': False,
'include_master_files_metrics': True,
'disable_generic_tags': True,
'include_db_file_space_usage_metrics': True,
}
)

Expand Down
1 change: 0 additions & 1 deletion sqlserver/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ def instance_docker(instance_docker_defaults):
'include_ao_metrics': False,
'include_master_files_metrics': True,
'disable_generic_tags': True,
'include_db_file_space_usage_metrics': True,
}
)
return instance_docker_defaults
Expand Down
8 changes: 2 additions & 6 deletions sqlserver/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,16 +440,12 @@ def test_file_space_usage_metrics(aggregator, dd_run_check, instance_docker, dat
sqlserver_check = SQLServer(CHECK_NAME, {}, [instance_docker])
dd_run_check(sqlserver_check)
seen_databases = set()
for m in aggregator.metrics("sqlserver.database.file_space_usage.free_space"):
for m in aggregator.metrics("sqlserver.tempdb.file_space_usage.free_space"):
tags_by_key = {k: v for k, v in [t.split(':') for t in m.tags if not t.startswith('dd.internal')]}
seen_databases.add(tags_by_key['database'])
assert tags_by_key['database_id']

assert 'master' in seen_databases

if database_autodiscovery:
assert 'datadog_test' in seen_databases
assert 'tempdb' in seen_databases
assert 'tempdb' in seen_databases


@pytest.mark.integration
Expand Down

0 comments on commit 08326c2

Please sign in to comment.