MSSQL Options (windows.plugin) (#21301)
thiagoftsm committed
Nov 18, 2025 at 13:32 UTC
feb5e07a948e3e8e02b32b93b42a743aa61ab663
3 files changed
+110
-37
src/collectors/windows.plugin/MonitorSQL.c
+73
-36
@@ -113,18 +113,14 @@ static ULONGLONG netdata_MSSQL_fill_long_value(SQLHSTMT *stmt, const char *mask,
113
114
void dict_mssql_fill_instance_transactions(struct mssql_db_instance *mdi)
115
{
116
+ if (unlikely(!mdi || !mdi->parent || !mdi->parent->conn || !mdi->parent->conn->collect_buffer))
117
+ return;
118
+
119
char object_name[NETDATA_MAX_INSTANCE_OBJECT + 1] = {};
120
long value = 0;
121
SQLLEN col_object_len = 0, col_value_len = 0;
122
120
- SQLCHAR query[sizeof(NETDATA_QUERY_TRANSACTIONS_PER_INSTANCE_MASK) + NETDATA_MAX_INSTANCE_OBJECT + 1];
121
- snprintfz(
122
- (char *)query,
123
- sizeof(NETDATA_QUERY_TRANSACTIONS_PER_INSTANCE_MASK) + NETDATA_MAX_INSTANCE_OBJECT,
124
- NETDATA_QUERY_TRANSACTIONS_PER_INSTANCE_MASK,
125
- mdi->parent->instanceID);
126
-
127
- SQLRETURN ret = SQLExecDirect(mdi->parent->conn->dbInstanceTransactionSTMT, (SQLCHAR *)query, SQL_NTS);
123
+ SQLRETURN ret = SQLExecDirect(mdi->parent->conn->dbInstanceTransactionSTMT, (SQLCHAR *)NETDATA_QUERY_BUFFER_STATS, SQL_NTS);
124
if (likely(netdata_mssql_check_result(ret))) {
125
mdi->collecting_data = false;
126
netdata_MSSQL_error(
@@ -235,7 +231,10 @@ void dict_mssql_fill_transactions(struct mssql_db_instance *mdi, const char *dbn
231
long value = 0;
232
SQLLEN col_object_len = 0, col_value_len = 0;
233
238
- if (mdi->collect_instance)
234
+ if (unlikely(!mdi->parent->conn->collect_transactions))
235
+ goto endtransactions;
236
+
237
+ if (likely(mdi->collect_instance))
238
dict_mssql_fill_instance_transactions(mdi);
239
240
SQLCHAR query[sizeof(NETDATA_QUERY_TRANSACTIONS_MASK) + 2 * NETDATA_MAX_INSTANCE_OBJECT + 1];
@@ -390,6 +389,9 @@ endlocks:
389
390
int dict_mssql_fill_waits(struct mssql_instance *mi)
391
{
392
+ if (unlikely(!mi->conn->collect_waits))
393
+ return 1;
394
+
395
char wait_type[NETDATA_MAX_INSTANCE_OBJECT + 1] = {};
396
char wait_category[NETDATA_MAX_INSTANCE_OBJECT + 1] = {};
397
SQLBIGINT total_wait = 0;
@@ -709,20 +711,20 @@ endreplication:
711
(void)netdata_select_db(mdi->parent->conn->netdataSQLHDBc, "master");
712
netdata_MSSQL_release_results(mdi->parent->conn->dbReplicationPublisher);
713
}
712
-int dict_mssql_databases_run_queries(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
713
-{
714
+int dict_mssql_databases_run_queries(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
715
struct mssql_db_instance *mdi = value;
715
- const char *dbname = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
716
+ const char *dbname = dictionary_acquired_item_name((DICTIONARY_ITEM *) item);
717
718
if (unlikely(!mdi->collecting_data || !mdi->parent || !mdi->parent->conn)) {
719
goto enddrunquery;
720
}
721
722
// We failed to collect this for the database, so we are not going to try again
722
- if (unlikely(mdi->MSSQLDatabaseDataFileSize.current.Data != ULONG_LONG_MAX))
723
- mdi->MSSQLDatabaseDataFileSize.current.Data = netdata_MSSQL_fill_long_value(
723
+ if (unlikely(mdi->MSSQLDatabaseDataFileSize.current.Data != ULONG_LONG_MAX)) {
724
+ if (likely(mdi->parent->conn->collect_data_size))
725
+ mdi->MSSQLDatabaseDataFileSize.current.Data = netdata_MSSQL_fill_long_value(
726
mdi->parent->conn->dataFileSizeSTMT, NETDATA_QUERY_DATA_FILE_SIZE_MASK, dbname, mdi->parent->instanceID);
725
- else {
727
+ } else {
728
mdi->collecting_data = false;
729
goto enddrunquery;
730
}
@@ -730,7 +732,7 @@ int dict_mssql_databases_run_queries(const DICTIONARY_ITEM *item __maybe_unused,
732
dict_mssql_fill_transactions(mdi, dbname);
733
dict_mssql_fill_locks(mdi, dbname);
734
733
- if (likely(mdi->running_replication))
735
+ if (likely(mdi->running_replication && mdi->parent->conn->collect_replication))
736
dict_mssql_fill_replication(mdi);
737
738
enddrunquery:
@@ -1264,6 +1266,20 @@ static void netdata_read_config_options()
1266
dbconn->instances = additional_instances;
1267
dbconn->windows_auth = inicfg_get_boolean(&netdata_config, section_name, "windows authentication", false);
1268
dbconn->is_sqlexpress = inicfg_get_boolean(&netdata_config, section_name, "express", false);
1269
+ dbconn->collect_transactions = inicfg_get_boolean(
1270
+ &netdata_config, section_name, "collect transactions", true);
1271
+ dbconn->collect_waits = inicfg_get_boolean(
1272
+ &netdata_config, section_name, "collect waits", true);
1273
+ dbconn->collect_locks = inicfg_get_boolean(
1274
+ &netdata_config, section_name, "collect lock metrics", true);
1275
+ dbconn->collect_replication = inicfg_get_boolean(
1276
+ &netdata_config, section_name, "collect replication", true);
1277
+ dbconn->collect_jobs = inicfg_get_boolean(
1278
+ &netdata_config, section_name, "collect jobs", true);
1279
+ dbconn->collect_buffer = inicfg_get_boolean(
1280
+ &netdata_config, section_name, "collect buffer stats", true);
1281
+ dbconn->collect_data_size = inicfg_get_boolean(
1282
+ &netdata_config, section_name, "collect database size", true);
1283
dbconn->is_connected = FALSE;
1284
1285
netdata_mount_mssql_connection_string(dbconn);
@@ -1772,6 +1788,9 @@ int dict_mssql_waits_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void
1788
1789
static void do_mssql_waits(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
1790
{
1791
+ if (unlikely(!mi->conn->collect_waits))
1792
+ return;
1793
+
1794
dictionary_sorted_walkthrough_read(mi->waits, dict_mssql_waits_charts_cb, mi);
1795
}
1796
@@ -2058,6 +2077,9 @@ int dict_mssql_buffman_stats_charts_cb(
2077
2078
static void do_mssql_bufferman_stats_sql(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
2079
{
2080
+ if (unlikely(!mi->conn->collect_buffer))
2081
+ return;
2082
+
2083
dictionary_sorted_walkthrough_read(mi->databases, dict_mssql_buffman_stats_charts_cb, mi);
2084
}
2085
@@ -2107,6 +2129,9 @@ int dict_mssql_sysjobs_chart_cb(const DICTIONARY_ITEM *item __maybe_unused, void
2129
2130
static void do_mssql_job_status_sql(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
2131
{
2132
+ if (unlikely(!mi->conn->collect_jobs))
2133
+ return;
2134
+
2135
dictionary_sorted_walkthrough_read(mi->sysjobs, dict_mssql_sysjobs_chart_cb, mi);
2136
}
2137
@@ -2420,6 +2445,9 @@ int dict_mssql_replication_chart_cb(const DICTIONARY_ITEM *item __maybe_unused,
2445
2446
static void do_mssql_replication(struct mssql_instance *mi, int update_every)
2447
{
2448
+ if (unlikely(!mi->conn->collect_replication))
2449
+ return;
2450
+
2451
dictionary_sorted_walkthrough_read(mi->publisher_publication, dict_mssql_replication_chart_cb, &update_every);
2452
}
2453
@@ -2896,30 +2924,39 @@ int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, v
2924
}
2925
2926
int *update_every = data;
2927
+ struct mssql_instance *mi = mdi->parent;
2928
+ if (unlikely(!mi))
2929
+ goto endchartcb;
2930
2900
- void (*transaction_chart[])(struct mssql_db_instance *, const char *, int) = {
2901
- mssql_data_file_size_chart,
2902
- mssql_transactions_chart,
2903
- mssql_database_backup_restore_chart,
2904
- mssql_database_log_flushed_chart,
2905
- mssql_database_log_flushes_chart,
2906
- mssql_active_transactions_chart,
2907
- mssql_write_transactions_chart,
2908
- mssql_lockwait_chart,
2909
- mssql_deadlock_chart,
2910
- mssql_is_readonly_chart,
2911
- mssql_db_state_chart_loop,
2912
- mssql_lock_timeout_chart,
2913
- mssql_lock_request_chart,
2914
-
2915
- // Last function pointer must be NULL
2916
- NULL};
2931
+ struct netdata_mssql_conn *conn = mi->conn;
2932
+ if (unlikely(!conn))
2933
+ goto endchartcb;
2934
+
2935
+ if (likely(conn->collect_data_size))
2936
+ mssql_data_file_size_chart(mdi, db, *update_every);
2937
+
2938
+ if (likely(conn->collect_transactions)) {
2939
+ mssql_transactions_chart(mdi, db, *update_every);
2940
+ mssql_active_transactions_chart(mdi, db, *update_every);
2941
+ mssql_write_transactions_chart(mdi, db, *update_every);
2942
+ }
2943
2918
- int i;
2919
- for (i = 0; transaction_chart[i]; i++) {
2920
- transaction_chart[i](mdi, db, *update_every);
2944
+ if (likely(conn->collect_waits)) {
2945
+ mssql_lockwait_chart(mdi, db, *update_every);
2946
}
2947
2948
+ if (likely(conn->collect_locks)) {
2949
+ mssql_deadlock_chart(mdi, db, *update_every);
2950
+ mssql_lock_timeout_chart(mdi, db, *update_every);
2951
+ mssql_lock_request_chart(mdi, db, *update_every);
2952
+ }
2953
+
2954
+ mssql_is_readonly_chart(mdi, db, *update_every);
2955
+ mssql_db_state_chart_loop(mdi, db, *update_every);
2956
+ mssql_database_log_flushed_chart(mdi, db, *update_every);
2957
+ mssql_database_log_flushes_chart(mdi, db, *update_every);
2958
+ mssql_database_backup_restore_chart(mdi, db, *update_every);
2959
+
2960
endchartcb:
2961
return 1;
2962
}
src/collectors/windows.plugin/metadata.yaml
+28
@@ -2229,6 +2229,34 @@ modules:
2229
description: Set to yes when running SQL Express version.
2230
default_value: no
2231
required: false
2232
+ - name: collect transactions
2233
+ description: Run queries to collect information from the server's transactions.
2234
+ default_value: yes
2235
+ required: false
2236
+ - name: collect waits
2237
+ description: Run queries to collect information from the server's lock waits.
2238
+ default_value: yes
2239
+ required: false
2240
+ - name: collect lock metrics
2241
+ description: Run queries to collect information from the server's overall locks.
2242
+ default_value: yes
2243
+ required: false
2244
+ - name: collect replication
2245
+ description: Run queries to collect information from the server's replication.
2246
+ default_value: yes
2247
+ required: false
2248
+ - name: collect jobs
2249
+ description: Run queries to collect information from the server's jobs.
2250
+ default_value: yes
2251
+ required: false
2252
+ - name: collect buffer stats
2253
+ description: Run queries to collect information from the server's buffer statistics.
2254
+ default_value: yes
2255
+ required: false
2256
+ - name: collect database size
2257
+ description: Run queries to collect information from the server's database size.
2258
+ default_value: yes
2259
+ required: false
2260
examples:
2261
folding:
2262
enabled: true
src/collectors/windows.plugin/perflib-mssql-queries.h
+9
-1
@@ -26,7 +26,7 @@
26
#define NETDATA_QUERY_TRANSACTIONS_MASK \
27
"SELECT counter_name, cntr_value FROM %s.sys.dm_os_performance_counters WHERE instance_name = '%s' AND counter_name IN ('Active Transactions', 'Transactions/sec', 'Write Transactions/sec', 'Backup/Restore Throughput/sec', 'Log Bytes Flushed/sec', 'Log Flushes/sec', 'Number of Deadlocks/sec', 'Lock Waits/sec', 'Lock Timeouts/sec', 'Lock Requests/sec');"
28
29
-#define NETDATA_QUERY_TRANSACTIONS_PER_INSTANCE_MASK \
29
+#define NETDATA_QUERY_BUFFER_STATS \
30
"SELECT counter_name, cntr_value FROM sys.dm_os_performance_counters WHERE (object_name like '%%Buffer Manager%%' or object_name like '%%SQL Statistics%%') AND counter_name IN ('Page reads/sec', 'Page writes/sec', 'Buffer cache hit ratio', 'Checkpoint pages/sec', 'Page life expectancy', 'Lazy writes/sec', 'Page Lookups/sec', 'SQL Compilations/sec', 'SQL Re-Compilations/sec');"
31
32
#define NETDATA_QUERY_CHECK_PERM \
@@ -672,6 +672,14 @@ struct netdata_mssql_conn {
672
SQLHSTMT dbSQLJobs;
673
SQLHSTMT dbReplicationPublisher;
674
675
+ BOOL collect_transactions;
676
+ BOOL collect_waits;
677
+ BOOL collect_locks;
678
+ BOOL collect_replication;
679
+ BOOL collect_jobs;
680
+ BOOL collect_buffer;
681
+ BOOL collect_data_size;
682
+
683
BOOL is_connected;
684
};
685