@cryptotaxi247 / netdata-1 / commits / feb5e07a9

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