MSSQL Collection (windows.plugin) (#21478)
thiagoftsm committed
Dec 18, 2025 at 17:21 UTC
b04a863e6746adf458fcf5259cf385eafd599586
3 files changed
+40
-26
src/collectors/windows.plugin/MonitorSQL.c
+33
-19
@@ -7,7 +7,7 @@
7
8
DICTIONARY *conn_options;
9
10
-static inline int netdata_mssql_check_result(SQLRETURN ret)
10
+static inline bool netdata_mssql_check_result(SQLRETURN ret)
11
{
12
return (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO);
13
}
@@ -63,12 +63,17 @@ static void netdata_MSSQL_error(uint32_t type, SQLHANDLE handle, enum netdata_ms
63
}
64
}
65
66
-static inline void netdata_MSSQL_release_results(SQLHSTMT *stmt)
66
+static inline void netdata_MSSQL_release_results(SQLHSTMT stmt)
67
{
68
+ if (stmt == SQL_NULL_HSTMT)
69
+ return;
70
+
71
SQLCloseCursor(stmt);
72
+ SQLFreeStmt(stmt, SQL_UNBIND);
73
+ SQLFreeStmt(stmt, SQL_RESET_PARAMS);
74
}
75
71
-static ULONGLONG netdata_MSSQL_fill_long_value(SQLHSTMT *stmt, const char *mask, const char *dbname, char *instance)
76
+static ULONGLONG netdata_MSSQL_fill_long_value(SQLHSTMT stmt, const char *mask, const char *dbname, char *instance)
77
{
78
long db_size = 0;
79
SQLLEN col_data_len = 0;
@@ -81,18 +86,21 @@ static ULONGLONG netdata_MSSQL_fill_long_value(SQLHSTMT *stmt, const char *mask,
86
ret = SQLExecDirect(stmt, query, SQL_NTS);
87
if (likely(netdata_mssql_check_result(ret))) {
88
netdata_MSSQL_error(SQL_HANDLE_STMT, stmt, NETDATA_MSSQL_ODBC_QUERY, instance);
89
+ netdata_MSSQL_release_results(stmt);
90
return (ULONGLONG)ULONG_LONG_MAX;
91
}
92
93
ret = SQLBindCol(stmt, 1, SQL_C_LONG, &db_size, sizeof(long), &col_data_len);
94
if (likely(netdata_mssql_check_result(ret))) {
95
netdata_MSSQL_error(SQL_HANDLE_STMT, stmt, NETDATA_MSSQL_ODBC_PREPARE, instance);
96
+ netdata_MSSQL_release_results(stmt);
97
return (ULONGLONG)ULONG_LONG_MAX;
98
}
99
100
ret = SQLFetch(stmt);
101
if (likely(netdata_mssql_check_result(ret))) {
102
netdata_MSSQL_error(SQL_HANDLE_STMT, stmt, NETDATA_MSSQL_ODBC_FETCH, instance);
103
+ netdata_MSSQL_release_results(stmt);
104
return (ULONGLONG)ULONG_LONG_MAX;
105
}
106
@@ -351,7 +359,7 @@ void dict_mssql_fill_locks(struct mssql_db_instance *mdi, const char *dbname)
359
SQLCHAR query[sizeof(NETDATA_QUERY_LOCKS_MASK) + 2 * NETDATA_MAX_INSTANCE_OBJECT + 1];
360
snprintfz(
361
(char *)query,
354
- sizeof(NETDATA_QUERY_TRANSACTIONS_MASK) + 2 * NETDATA_MAX_INSTANCE_OBJECT,
362
+ sizeof(NETDATA_QUERY_LOCKS_MASK) + 2 * NETDATA_MAX_INSTANCE_OBJECT,
363
NETDATA_QUERY_LOCKS_MASK,
364
dbname,
365
dbname);
@@ -439,33 +447,33 @@ int dict_mssql_fill_waits(struct mssql_instance *mi)
447
goto endwait;
448
}
449
442
- ret = SQLBindCol(mi->conn->dbWaitsSTMT, 2, SQL_C_LONG, &total_wait, sizeof(total_wait), &col_total_wait_len);
450
+ ret = SQLBindCol(mi->conn->dbWaitsSTMT, 2, SQL_C_SBIGINT, &total_wait, sizeof(total_wait), &col_total_wait_len);
451
if (likely(netdata_mssql_check_result(ret))) {
452
netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbWaitsSTMT, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
453
goto endwait;
454
}
455
456
ret =
449
- SQLBindCol(mi->conn->dbWaitsSTMT, 3, SQL_C_LONG, &resource_wait, sizeof(resource_wait), &col_resource_wait_len);
457
+ SQLBindCol(mi->conn->dbWaitsSTMT, 3, SQL_C_SBIGINT, &resource_wait, sizeof(resource_wait), &col_resource_wait_len);
458
if (likely(netdata_mssql_check_result(ret))) {
459
netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbWaitsSTMT, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
460
goto endwait;
461
}
462
455
- ret = SQLBindCol(mi->conn->dbWaitsSTMT, 4, SQL_C_LONG, &signal_wait, sizeof(signal_wait), &col_signal_wait_len);
463
+ ret = SQLBindCol(mi->conn->dbWaitsSTMT, 4, SQL_C_SBIGINT, &signal_wait, sizeof(signal_wait), &col_signal_wait_len);
464
if (likely(netdata_mssql_check_result(ret))) {
465
netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbWaitsSTMT, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
466
goto endwait;
467
}
468
461
- ret = SQLBindCol(mi->conn->dbWaitsSTMT, 5, SQL_C_LONG, &max_wait, sizeof(max_wait), &col_max_wait_len);
469
+ ret = SQLBindCol(mi->conn->dbWaitsSTMT, 5, SQL_C_SBIGINT, &max_wait, sizeof(max_wait), &col_max_wait_len);
470
if (likely(netdata_mssql_check_result(ret))) {
471
netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbWaitsSTMT, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
472
goto endwait;
473
}
474
475
ret =
468
- SQLBindCol(mi->conn->dbWaitsSTMT, 6, SQL_C_LONG, &waiting_tasks, sizeof(waiting_tasks), &col_waiting_tasks_len);
476
+ SQLBindCol(mi->conn->dbWaitsSTMT, 6, SQL_C_SBIGINT, &waiting_tasks, sizeof(waiting_tasks), &col_waiting_tasks_len);
477
if (likely(netdata_mssql_check_result(ret))) {
478
netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbWaitsSTMT, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
479
goto endwait;
@@ -510,10 +518,9 @@ int dict_mssql_fill_waits(struct mssql_instance *mi)
518
continue;
519
520
mdw->MSSQLDatabaseTotalWait.current.Data = (ULONGLONG)total_wait;
513
- // Variable mdw->MSSQLDatabaseResourceWaitMSec.current.Data stores a mathematical operation
514
- // that can be negative sometimes. This is the reason we have this if
515
- if (likely(resource_wait > mdw->MSSQLDatabaseResourceWaitMSec.current.Data))
516
- mdw->MSSQLDatabaseResourceWaitMSec.current.Data = (ULONGLONG)resource_wait;
521
+ if (unlikely(resource_wait < 0))
522
+ resource_wait = 0;
523
+ mdw->MSSQLDatabaseResourceWaitMSec.current.Data = (ULONGLONG)resource_wait;
524
mdw->MSSQLDatabaseSignalWaitMSec.current.Data = (ULONGLONG)signal_wait;
525
mdw->MSSQLDatabaseMaxWaitTimeMSec.current.Data = (ULONGLONG)max_wait;
526
mdw->MSSQLDatabaseWaitingTasks.current.Data = (ULONGLONG)waiting_tasks;
@@ -853,8 +860,7 @@ void netdata_mssql_fill_mssql_status(struct mssql_instance *mi)
860
char dbname[SQLSERVER_MAX_NAME_LENGTH + 1];
861
int readonly = 0;
862
BYTE state = 0;
856
- SQLLEN col_data_len = 0;
857
-
863
+ SQLLEN col_data_len = 0, col_state_len = 0, col_readonly_len = 0;
864
static int next_try = NETDATA_MSSQL_NEXT_TRY - 1;
865
866
if (unlikely(++next_try != NETDATA_MSSQL_NEXT_TRY))
@@ -870,9 +876,13 @@ void netdata_mssql_fill_mssql_status(struct mssql_instance *mi)
876
goto enddbstate;
877
}
878
873
- SQLLEN col_state_len = 0, col_readonly_len = 0;
879
+ ret = SQLBindCol(mi->conn->dbSQLState, 1, SQL_C_CHAR, dbname, sizeof(dbname), &col_data_len);
880
+ if (likely(netdata_mssql_check_result(ret))) {
881
+ netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbSQLState, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
882
+ goto enddbstate;
883
+ }
884
875
- ret = SQLBindCol(mi->conn->dbSQLState, 1, SQL_C_TINYINT, &state, sizeof(state), &col_state_len);
885
+ ret = SQLBindCol(mi->conn->dbSQLState, 2, SQL_C_TINYINT, &state, sizeof(state), &col_state_len);
886
if (likely(netdata_mssql_check_result(ret))) {
887
netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbSQLState, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
888
goto enddbstate;
@@ -880,7 +890,7 @@ void netdata_mssql_fill_mssql_status(struct mssql_instance *mi)
890
891
ret = SQLBindCol(mi->conn->dbSQLState, 3, SQL_C_BIT, &readonly, sizeof(readonly), &col_readonly_len);
892
if (likely(netdata_mssql_check_result(ret))) {
883
- netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbWaitsSTMT, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
893
+ netdata_MSSQL_error(SQL_HANDLE_STMT, mi->conn->dbSQLState, NETDATA_MSSQL_ODBC_PREPARE, mi->instanceID);
894
goto enddbstate;
895
}
896
@@ -890,6 +900,8 @@ void netdata_mssql_fill_mssql_status(struct mssql_instance *mi)
900
goto enddbstate;
901
}
902
903
+ if (col_data_len == SQL_NULL_DATA)
904
+ continue;
905
if (col_state_len == SQL_NULL_DATA)
906
state = 0;
907
if (col_readonly_len == SQL_NULL_DATA)
@@ -1107,6 +1119,7 @@ void netdata_mssql_fill_dictionary_from_db(struct mssql_instance *mi)
1119
if (unlikely(!i)) {
1120
mdi->collect_instance = true;
1121
}
1122
+ i++;
1123
} while (true);
1124
1125
enddblist:
@@ -1514,6 +1527,7 @@ void dict_mssql_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *valu
1527
mssql_fill_initial_instances(mi);
1528
}
1529
1530
+
1531
if (unlikely(!mi->databases)) {
1532
mi->databases = dictionary_create_advanced(
1533
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct mssql_db_instance));
@@ -3002,7 +3016,7 @@ static void mssql_db_state_chart_loop(struct mssql_db_instance *mdi, const char
3016
collected_number set_value =
3017
(mdi->MSSQLDBState.current.Data < 5) ? (collected_number)mdi->MSSQLDBState.current.Data : 5;
3018
mssql_db_states_chart(mdi, db, update_every);
3005
- for (collected_number i; i < NETDATA_DB_STATES; i++) {
3019
+ for (collected_number i = 0; i < NETDATA_DB_STATES; i++) {
3020
rrddim_set_by_pointer(mdi->st_db_state, mdi->rd_db_state[i], i == set_value);
3021
}
3022
rrdset_done(mdi->st_db_state);
src/collectors/windows.plugin/perflib-memory.c
+2
-1
@@ -239,7 +239,8 @@ int do_PerflibMemory(int update_every, usec_t dt __maybe_unused)
239
if (!pDataBlock)
240
return -1;
241
242
- do_memory(pDataBlock, update_every);
242
+ if (!do_memory(pDataBlock, update_every))
243
+ return -1;
244
245
return 0;
246
}
src/collectors/windows.plugin/perflib-mssql.c
+5
-6
@@ -422,14 +422,13 @@ void do_mssql_general_stats(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *
422
if (unlikely(!pObjectType))
423
return;
424
425
- if (unlikely(!mi->conn) || unlikely(!mi->conn->collect_user_connections)) {
426
- if (likely(perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLUserConnections))) {
425
+ if (unlikely(!mi->conn || !mi->conn->collect_user_connections)) {
426
+ if (likely(perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLUserConnections)))
427
do_mssql_user_connections(mi, update_every);
428
- }
428
}
429
431
- if (unlikely(!mi || !mi->conn || !mi->conn->collect_blocked_processes) &&
432
- likely(perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBlockedProcesses))) {
433
- netdata_mssql_blocked_processes_chart(mi, update_every);
430
+ if (unlikely(!mi->conn || !mi->conn->collect_blocked_processes)) {
431
+ if (likely(perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBlockedProcesses)))
432
+ netdata_mssql_blocked_processes_chart(mi, update_every);
433
}
434
}