Fix MSSQL and improvements (#20032)
thiagoftsm committed
Apr 17, 2025 at 18:54 UTC
aff889011f29d1c9995cb20d9d879414d21efab2
3 files changed
+701
-267
CMakeLists.txt
+1
@@ -3037,6 +3037,7 @@ target_link_libraries(netdata PRIVATE
3037
"$<$<BOOL:${ENABLE_WEBRTC}>:LibDataChannel::LibDataChannelStatic>"
3038
"$<$<BOOL:${ENABLE_H2O}>:h2o>"
3039
"$<$<BOOL:${CURL_FOUND}>:PkgConfig::CURL>"
3040
+ "$<$<BOOL:${OS_WINDOWS}>:odbc32>"
3041
)
3042
3043
netdata_add_protobuf(netdata)
src/collectors/windows.plugin/README.md
+157
-6
@@ -5,13 +5,11 @@ This internal plugin is only available for Microsoft Windows operating systems.
5
## The Collector
6
7
This plugin primarily collects metrics from Microsoft Windows [Performance Counters](https://learn.microsoft.com/en-us/windows/win32/perfctrs/performance-counters-what-s-new). All detected metrics are automatically displayed without requiring additional configuration.
8
+=======
9
+Most of the metrics collected by this plugin originate from Microsoft Windows
10
+[Performance Counters](https://learn.microsoft.com/en-us/windows/win32/perfctrs/performance-counters-what-s-new).
11
9
-## Configuration File
10
-
11
-The Windows plugin doesn't use a separate configuration file. Instead, configure it through Netdata's main configuration file located at:
12
-`C:\Program Files\Netdata\etc\netdata\netdata.conf`.
13
-
14
-### Enabling or Disabling Collection
12
+These metrics are always displayed when detected, requiring no additional configuration.
13
14
By default, all collector threads are enabled except for `PerflibThermalZone` and `PerflibServices`. You can enable these or disable others by modifying options in the `[plugin:windows]` section of the configuration file.
15
@@ -31,9 +29,162 @@ To change a setting, remove the comment symbol (`#`) from the beginning of the l
29
# PerflibThermalZone = no
30
# PerflibWebService = yes
31
# PerflibServices = no
32
+ # PerflibMSSQL = yes
33
# PerflibNetFramework = yes
34
# PerflibAD = yes
35
# PerflibADCS = yes
36
# PerflibADFS = yes
37
```
38
39
+## Configuration
40
+
41
+To collect certain metrics for [Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server),
42
+Netdata needs access to internal server data. To collect this data, you need to configure both your server and Netdata.
43
+
44
+### Windows Defender Firewall with Advanced Security
45
+
46
+To connect to your SQL Server, Netdata uses TCP port 1433 (or any other configured port).
47
+This port is typically blocked by Windows Defender, so you must allow access before proceeding:
48
+
49
+1. Open `Windows Defender Firewall with Advanced Security` as an Adminstrator.
50
+2. Right-click `Inbound Rules` and select `New Rule...`.
51
+3. Select `Port`, then click `Next`.
52
+4. Choose `TCP`, then enter `1433` in the `Specific local ports:`. Click `Next`.
53
+5. Select an appropriate action based on your network policy. For example, `Allow the connection`.
54
+ Click `Next`.
55
+6. Choose where the rule will be applied (Domain, Private, or Public).
56
+7. Finally, provide a `Name` and an optional `Description` for the new rule,
57
+ then click `Finish`.
58
+
59
+You can use the same rule to allow connections to other instances. To do this,
60
+specify the ports for each instance in the `Port` field separated by commas.
61
+
62
+### Microsoft SQL Server (Configuration)
63
+
64
+After enabling access through the firewall, you will need to configure your SQL Server instance to accept TCP
65
+connections:
66
+
67
+1. Open `SQL Server Configuration Manager`.
68
+2. Expand `SQL Server Network Configuration`.
69
+3. In the console panel, select `Protocols for <instance name>.`.
70
+4. In the details panel, double-click the `TCP` protocol, and set `Yes` for `Enabled`.
71
+5. Go to the `IP Address` tab, locate the section labeled`IPAII`.
72
+ - Remove any value from the `TCP Dynamic Ports` field.
73
+ - Enter a value in the `TCP Port` field. By default, SQL Server uses `1433`.
74
+6. Finally, select `SQL Server Services`, and restart your SQL Server instance.
75
+
76
+You need to apply this configuration to every instance.
77
+
78
+### Microsoft SQL Server (User)
79
+
80
+If you want to allow connections using SQL Server authentication, you must modify the server configuration:
81
+
82
+1. Open `Microsoft Server Management Studio`.
83
+2. Right-click your server, and select `Properties`.
84
+3. In the left panel, select `Security`.
85
+4. Under `Server authentication`, choose `SQL Server and Windows Authentication mode`.
86
+5. Click `OK`.
87
+6. Finally, right-click your server, and select`Restart`.
88
+
89
+After that, you need to create a user with the `VIEW SERVER STATE` permission to collect data from the server.
90
+Once the user is created, it must also be granted access to the databases.
91
+
92
+```tsql
93
+USE master;
94
+CREATE LOGIN netdata_user WITH PASSWORD = 'netdata';
95
+CREATE USER netdata_user FOR LOGIN netdata_user;
96
+GRANT CONNECT SQL TO netdata_user;
97
+GRANT VIEW SERVER STATE TO netdata_user;
98
+GO
99
+```
100
+
101
+In addition to creating the user, you must enable the
102
+[query store](https://learn.microsoft.com/en-us/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store?view=sql-server-ver16),
103
+on each database you wish to monitor.
104
+
105
+```tsql
106
+DECLARE @dbname NVARCHAR(max)
107
+DECLARE nd_user_cursor CURSOR FOR SELECT name FROM master.dbo.sysdatabases WHERE NAME NOT IN ('master','msdb','tempdb','model')
108
+
109
+OPEN nd_user_cursor
110
+FETCH NEXT FROM nd_user_cursor INTO @dbname WHILE @@FETCH_STATUS = 0
111
+BEGIN
112
+ EXECUTE ("USE "+ @dbname+"; CREATE USER netdata_user FOR LOGIN netdata_user; ALTER DATABASE "+@dbname+" SET QUERY_STORE = ON ( QUERY_CAPTURE_MODE = ALL, DATA_FLUSH_INTERVAL_SECONDS = 900 )");
113
+ FETCH next FROM nd_user_cursor INTO @dbname;
114
+END
115
+CLOSE nd_user_cursor
116
+DEALLOCATE nd_user_cursor
117
+GO
118
+```
119
+
120
+You need to apply this configuration to every instance.
121
+
122
+### Netdata Configuration
123
+
124
+Now that the user has been created inside your server, update `netdata.conf` by adding the following section:
125
+
126
+```text
127
+[plugin:windows:PerflibMSSQL]
128
+ driver = SQL Server
129
+ server = 127.0.0.1\\Dev, 1433
130
+ #address = [protocol:]Address[,port |\pipe\pipename]
131
+ uid = netdata_user
132
+ pwd = AReallyStrongPasswordShouldBeInsertedHere
133
+ # additional instances = 0
134
+ #windows authentication = no
135
+```
136
+
137
+In next table, we give a short description about them:
138
+
139
+| Option | Description |
140
+|--------------------------|-----------------------------------------------------------------------------------|
141
+|`driver` | ODBC driver used to connect to the MSSQL server. |
142
+|`server` | Server address or instance name to connect to. |
143
+|`address` | Similar to `server`. You can also use named pipes if your server supports them. |
144
+|`uid` | User identifier (`uid`) created on your server. |
145
+|`pwd` | Password for the specified user. |
146
+|`additional instances` | Number of additional MSSQL instances to monitor. |
147
+|`windows authentications` | Use Windows credentials to connect to the MSSQL server. |
148
+
149
+For additional information on how to set these parameters, refer to the
150
+[Microsoft Official Documentation](https://learn.microsoft.com/en-us/sql/relational-databases/native-client/applications/using-connection-string-keywords-with-sql-server-native-client?view=sql-server-ver15&viewFallbackFrom=sql-server-ver16)
151
+
152
+#### Additional Instance
153
+
154
+Microsoft SQL Server can host multiple instances. To connect to them, you need to create additional sections in your
155
+`netdata.conf` file, specifying their respective connection options.
156
+
157
+Let’s suppose you have an additional instance named `Production`. To enable Netdata to monitor both the `Production`
158
+and `Dev` instances, you’ll need to add the following configuration section:
159
+
160
+```text
161
+[plugin:windows:PerflibMSSQL1]
162
+ driver = SQL Server
163
+ server = 127.0.0.1\\Production, 1434
164
+ uid = netdata_user
165
+ pwd = AnotherReallyStrongPasswordShouldBeInsertedHere
166
+```
167
+
168
+You must also update the main section to indicate how many additional instances you want to monitor:
169
+
170
+```text
171
+[plugin:windows:PerflibMSSQL]
172
+ additional instances = 1
173
+```
174
+
175
+Each additional instance section must follow the naming pattern `plugin:windows:PerflibMSSQL`, with a sequential number
176
+from 1 to 65535, based on the number of instances you want to monitor.
177
+
178
+### Errors
179
+
180
+When configuring Netdata to access SQL Server, some errors may occur. You can check your configuration using the
181
+Microsoft Event Viewer by looking for entries that begin with `MSSQL server error using the handle`.
182
+
183
+#### Data source name not found and no default driver
184
+
185
+This error occurs when the driver is not specified correctly. You can check the available drivers by following
186
+these steps:
187
+
188
+- Access `ODBC Data Sources`.
189
+- Go to `Drivers` tab.
190
+- Look for `Name` of the `ODBC` or `SQL Server` driver .
src/collectors/windows.plugin/perflib-mssql.c
+543
-261
@@ -3,12 +3,37 @@
3
#include "windows_plugin.h"
4
#include "windows-internals.h"
5
6
+#include <sqlext.h>
7
+#include <sqltypes.h>
8
+#include <sql.h>
9
+
10
+#define MEGA_FACTOR (1048576) // 1024 * 1024
11
// https://learn.microsoft.com/en-us/sql/sql-server/install/instance-configuration?view=sql-server-ver16
12
#define NETDATA_MAX_INSTANCE_NAME 32
13
#define NETDATA_MAX_INSTANCE_OBJECT 128
14
+// https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms191240(v=sql.105)#sysname
15
+#define SQLSERVER_MAX_NAME_LENGTH (128)
16
17
BOOL is_sqlexpress = FALSE;
18
19
+struct netdata_mssql_conn {
20
+ const char *driver;
21
+ const char *server;
22
+ const char *address;
23
+ const char *username;
24
+ const char *password;
25
+ int instances;
26
+ bool windows_auth;
27
+
28
+ SQLCHAR *connectionString;
29
+
30
+ SQLHENV netdataSQLEnv;
31
+ SQLHDBC netdataSQLHDBc;
32
+ SQLHSTMT dataFileSizeSTMT;
33
+
34
+ BOOL is_connected;
35
+};
36
+
37
enum netdata_mssql_metrics {
38
NETDATA_MSSQL_GENERAL_STATS,
39
NETDATA_MSSQL_SQL_ERRORS,
@@ -25,6 +50,8 @@ enum netdata_mssql_metrics {
50
struct mssql_instance {
51
char *instanceID;
52
53
+ struct netdata_mssql_conn conn;
54
+
55
char *objectName[NETDATA_MSSQL_METRICS_END];
56
57
RRDSET *st_user_connections;
@@ -116,7 +143,6 @@ struct mssql_lock_instance {
143
};
144
145
enum db_instance_idx {
119
- NETDATA_MSSQL_ENUM_MDI_IDX_FILE_SIZE,
146
NETDATA_MSSQL_ENUM_MDI_IDX_ACTIVE_TRANSACTIONS,
147
NETDATA_MSSQL_ENUM_MDI_IDX_BACKUP_RESTORE_OP,
148
NETDATA_MSSQL_ENUM_MDI_IDX_LOG_FLUSHED,
@@ -157,9 +183,181 @@ struct mssql_db_instance {
183
uint32_t updated;
184
};
185
186
+enum netdata_mssql_odbc_errors {
187
+ NETDATA_MSSQL_ODBC_NO_ERROR,
188
+ NETDATA_MSSQL_ODBC_CONNECT,
189
+ NETDATA_MSSQL_ODBC_BIND,
190
+ NETDATA_MSSQL_ODBC_PREPARE,
191
+ NETDATA_MSSQL_ODBC_QUERY,
192
+ NETDATA_MSSQL_ODBC_FETCH
193
+};
194
+
195
+static char *netdata_MSSQL_error_text(enum netdata_mssql_odbc_errors val)
196
+{
197
+ switch (val) {
198
+ case NETDATA_MSSQL_ODBC_NO_ERROR:
199
+ return "NO ERROR";
200
+ case NETDATA_MSSQL_ODBC_CONNECT:
201
+ return "CONNECTION";
202
+ case NETDATA_MSSQL_ODBC_BIND:
203
+ return "BIND PARAMETER";
204
+ case NETDATA_MSSQL_ODBC_PREPARE:
205
+ return "PREPARE PARAMETER";
206
+ case NETDATA_MSSQL_ODBC_QUERY:
207
+ return "QUERY PARAMETER";
208
+ case NETDATA_MSSQL_ODBC_FETCH:
209
+ default:
210
+ return "QUERY FETCH";
211
+ }
212
+}
213
+
214
+static char *netdata_MSSQL_type_text(uint32_t type)
215
+{
216
+ switch (type) {
217
+ case SQL_HANDLE_STMT:
218
+ return "STMT";
219
+ case SQL_HANDLE_DBC:
220
+ default:
221
+ return "DBC";
222
+ }
223
+}
224
+
225
+// Connection and SQL
226
+static void netdata_MSSQL_error(uint32_t type, SQLHANDLE handle, enum netdata_mssql_odbc_errors step)
227
+{
228
+ SQLCHAR state[1024];
229
+ SQLCHAR message[1024];
230
+ if (SQL_SUCCESS == SQLGetDiagRec((short)type, handle, 1, state, NULL, message, 1024, NULL)) {
231
+ char *str_step = netdata_MSSQL_error_text(step);
232
+ char *str_type = netdata_MSSQL_type_text(type);
233
+ nd_log(
234
+ NDLS_COLLECTORS,
235
+ NDLP_ERR,
236
+ "MSSQL server error using the handle %s running %s : %s, %s",
237
+ str_type,
238
+ str_step,
239
+ message,
240
+ state);
241
+ }
242
+}
243
+
244
+static ULONGLONG netdata_MSSQL_fill_data_file_size_dict(SQLHSTMT *stmt, SQLCHAR *query)
245
+{
246
+ static long db_size = 0;
247
+ static SQLLEN col_data_len = 0;
248
+
249
+ SQLRETURN ret;
250
+
251
+ ret = SQLExecDirect(stmt, query, SQL_NTS);
252
+ if (ret != SQL_SUCCESS) {
253
+ netdata_MSSQL_error(SQL_HANDLE_STMT, stmt, NETDATA_MSSQL_ODBC_QUERY);
254
+ return 0;
255
+ }
256
+
257
+ ret = SQLBindCol(stmt, 1, SQL_C_LONG, &db_size, sizeof(long), &col_data_len);
258
+
259
+ if (ret != SQL_SUCCESS) {
260
+ netdata_MSSQL_error(SQL_HANDLE_STMT, stmt, NETDATA_MSSQL_ODBC_PREPARE);
261
+ return 0;
262
+ }
263
+
264
+ ret = SQLFetch(stmt);
265
+ if (ret != SQL_SUCCESS) {
266
+ netdata_MSSQL_error(SQL_HANDLE_STMT, stmt, NETDATA_MSSQL_ODBC_FETCH);
267
+ return 0;
268
+ }
269
+
270
+ return (ULONGLONG)(db_size * MEGA_FACTOR);
271
+}
272
+
273
+ULONGLONG netdata_MSSQL_fill_data_file_size(struct netdata_mssql_conn *nmc, char *dbname)
274
+{
275
+ ULONGLONG value = 0;
276
+
277
+ // We cannot access data for these tables without additional changes.
278
+ // They should be blacklisted.
279
+ if (!strcmp(dbname, "model") || !!strcmp(dbname, "model_msdb") || !!strcmp(dbname, "model_replicatedmaster") || strcmp(dbname, "mssqlsystemresource"))
280
+ return ULONG_LONG_MAX;
281
+
282
+ // https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-database-files-transact-sql?view=sql-server-ver16
283
+ SQLCHAR query[512];
284
+ snprintfz((char *)query, 511, "SELECT size * 8/1024 FROM %s.sys.database_files WHERE type = 0;", dbname);
285
+
286
+ value = netdata_MSSQL_fill_data_file_size_dict(nmc->dataFileSizeSTMT, query);
287
+
288
+ SQLFreeStmt(nmc->dataFileSizeSTMT, SQL_CLOSE);
289
+ return value;
290
+}
291
+
292
+int dict_mssql_databases_run_query(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
293
+{
294
+ struct mssql_db_instance *mdi = value;
295
+ const char *dbname = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
296
+
297
+ mdi->MSSQLDatabaseDataFileSize.current.Data = netdata_MSSQL_fill_data_file_size(&mdi->parent->conn, (char *)dbname);
298
+}
299
+
300
+static bool netdata_MSSQL_initialize_conection(struct netdata_mssql_conn *nmc)
301
+{
302
+ SQLRETURN ret;
303
+ if (nmc->netdataSQLEnv == NULL) {
304
+ ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &nmc->netdataSQLEnv);
305
+ if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
306
+ return FALSE;
307
+
308
+ ret = SQLSetEnvAttr(nmc->netdataSQLEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
309
+ if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
310
+ return FALSE;
311
+ }
312
+ }
313
+
314
+ ret = SQLAllocHandle(SQL_HANDLE_DBC, nmc->netdataSQLEnv, &nmc->netdataSQLHDBc);
315
+ if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
316
+ return FALSE;
317
+ }
318
+
319
+ ret = SQLSetConnectAttr(nmc->netdataSQLHDBc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
320
+ if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
321
+ return FALSE;
322
+ }
323
+
324
+ ret = SQLSetConnectAttr(nmc->netdataSQLHDBc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)TRUE, 0);
325
+ if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
326
+ return FALSE;
327
+ }
328
+
329
+ SQLCHAR ret_conn_str[1024];
330
+ ret = SQLDriverConnect(
331
+ nmc->netdataSQLHDBc, NULL, nmc->connectionString, SQL_NTS, ret_conn_str, 1024, NULL, SQL_DRIVER_NOPROMPT);
332
+
333
+ BOOL retConn;
334
+ switch (ret) {
335
+ case SQL_NO_DATA_FOUND:
336
+ case SQL_INVALID_HANDLE:
337
+ case SQL_ERROR:
338
+ default:
339
+ netdata_MSSQL_error(SQL_HANDLE_DBC, nmc->netdataSQLHDBc, NETDATA_MSSQL_ODBC_CONNECT);
340
+ retConn = FALSE;
341
+ break;
342
+ case SQL_SUCCESS:
343
+ case SQL_SUCCESS_WITH_INFO:
344
+ retConn = TRUE;
345
+ break;
346
+ }
347
+
348
+ if (retConn) {
349
+ ret = SQLAllocHandle(SQL_HANDLE_STMT, nmc->netdataSQLHDBc, &nmc->dataFileSizeSTMT);
350
+ if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
351
+ retConn = FALSE;
352
+ }
353
+
354
+ return retConn;
355
+}
356
+
357
+// Dictionary
358
static DICTIONARY *mssql_instances = NULL;
359
162
-static void initialize_mssql_objects(struct mssql_instance *p, const char *instance)
360
+static void initialize_mssql_objects(struct mssql_instance *mi, const char *instance)
361
{
362
char prefix[NETDATA_MAX_INSTANCE_NAME];
363
if (!strcmp(instance, "MSSQLSERVER")) {
@@ -174,63 +372,63 @@ static void initialize_mssql_objects(struct mssql_instance *p, const char *insta
372
size_t length = strlen(prefix);
373
char name[NETDATA_MAX_INSTANCE_OBJECT];
374
snprintfz(name, sizeof(name) - 1, "%s%s", prefix, "General Statistics");
177
- p->objectName[NETDATA_MSSQL_GENERAL_STATS] = strdup(name);
375
+ mi->objectName[NETDATA_MSSQL_GENERAL_STATS] = strdupz(name);
376
377
strncpyz(&name[length], "SQL Errors", sizeof(name) - length);
180
- p->objectName[NETDATA_MSSQL_SQL_ERRORS] = strdup(name);
378
+ mi->objectName[NETDATA_MSSQL_SQL_ERRORS] = strdupz(name);
379
380
strncpyz(&name[length], "Databases", sizeof(name) - length);
183
- p->objectName[NETDATA_MSSQL_DATABASE] = strdup(name);
381
+ mi->objectName[NETDATA_MSSQL_DATABASE] = strdupz(name);
382
383
strncpyz(&name[length], "SQL Statistics", sizeof(name) - length);
186
- p->objectName[NETDATA_MSSQL_SQL_STATS] = strdup(name);
384
+ mi->objectName[NETDATA_MSSQL_SQL_STATS] = strdupz(name);
385
386
strncpyz(&name[length], "Buffer Manager", sizeof(name) - length);
189
- p->objectName[NETDATA_MSSQL_BUFFER_MANAGEMENT] = strdup(name);
387
+ mi->objectName[NETDATA_MSSQL_BUFFER_MANAGEMENT] = strdupz(name);
388
389
strncpyz(&name[length], "Memory Manager", sizeof(name) - length);
192
- p->objectName[NETDATA_MSSQL_MEMORY] = strdup(name);
390
+ mi->objectName[NETDATA_MSSQL_MEMORY] = strdupz(name);
391
392
strncpyz(&name[length], "Locks", sizeof(name) - length);
195
- p->objectName[NETDATA_MSSQL_LOCKS] = strdup(name);
393
+ mi->objectName[NETDATA_MSSQL_LOCKS] = strdupz(name);
394
395
strncpyz(&name[length], "Access Methods", sizeof(name) - length);
198
- p->objectName[NETDATA_MSSQL_ACCESS_METHODS] = strdup(name);
396
+ mi->objectName[NETDATA_MSSQL_ACCESS_METHODS] = strdupz(name);
397
200
- p->instanceID = strdup(instance);
398
+ mi->instanceID = strdupz(instance);
399
}
400
203
-static inline void initialize_mssql_keys(struct mssql_instance *p)
401
+static inline void initialize_mssql_keys(struct mssql_instance *mi)
402
{
403
// General Statistics (https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-general-statistics-object)
206
- p->MSSQLUserConnections.key = "User Connections";
207
- p->MSSQLBlockedProcesses.key = "Processes blocked";
404
+ mi->MSSQLUserConnections.key = "User Connections";
405
+ mi->MSSQLBlockedProcesses.key = "Processes blocked";
406
407
// SQL Statistics (https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-sql-statistics-object)
210
- p->MSSQLStatsAutoParameterization.key = "Auto-Param Attempts/sec";
211
- p->MSSQLStatsBatchRequests.key = "Batch Requests/sec";
212
- p->MSSQLStatSafeAutoParameterization.key = "Safe Auto-Params/sec";
213
- p->MSSQLCompilations.key = "SQL Compilations/sec";
214
- p->MSSQLRecompilations.key = "SQL Re-Compilations/sec";
408
+ mi->MSSQLStatsAutoParameterization.key = "Auto-Param Attempts/sec";
409
+ mi->MSSQLStatsBatchRequests.key = "Batch Requests/sec";
410
+ mi->MSSQLStatSafeAutoParameterization.key = "Safe Auto-Params/sec";
411
+ mi->MSSQLCompilations.key = "SQL Compilations/sec";
412
+ mi->MSSQLRecompilations.key = "SQL Re-Compilations/sec";
413
414
// Buffer Management (https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-buffer-manager-object)
217
- p->MSSQLBufferCacheHits.key = "Buffer cache hit ratio";
218
- p->MSSQLBufferPageLifeExpectancy.key = "Page life expectancy";
219
- p->MSSQLBufferCheckpointPages.key = "Checkpoint pages/sec";
220
- p->MSSQLBufferPageReads.key = "Page reads/sec";
221
- p->MSSQLBufferPageWrites.key = "Page writes/sec";
415
+ mi->MSSQLBufferCacheHits.key = "Buffer cache hit ratio";
416
+ mi->MSSQLBufferPageLifeExpectancy.key = "Page life expectancy";
417
+ mi->MSSQLBufferCheckpointPages.key = "Checkpoint pages/sec";
418
+ mi->MSSQLBufferPageReads.key = "Page reads/sec";
419
+ mi->MSSQLBufferPageWrites.key = "Page writes/sec";
420
421
// Access Methods (https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-access-methods-object)
224
- p->MSSQLAccessMethodPageSplits.key = "Page Splits/sec";
422
+ mi->MSSQLAccessMethodPageSplits.key = "Page Splits/sec";
423
424
// Errors (https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-sql-errors-object)
227
- p->MSSQLSQLErrorsTotal.key = "Errors/sec";
425
+ mi->MSSQLSQLErrorsTotal.key = "Errors/sec";
426
427
// Memory Management (https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-memory-manager-object)
230
- p->MSSQLConnectionMemoryBytes.key = "Connection Memory (KB)";
231
- p->MSSQLExternalBenefitOfMemory.key = "External benefit of memory";
232
- p->MSSQLPendingMemoryGrants.key = "Memory Grants Pending";
233
- p->MSSQLTotalServerMemory.key = "Total Server Memory (KB)";
428
+ mi->MSSQLConnectionMemoryBytes.key = "Connection Memory (KB)";
429
+ mi->MSSQLExternalBenefitOfMemory.key = "External benefit of memory";
430
+ mi->MSSQLPendingMemoryGrants.key = "Memory Grants Pending";
431
+ mi->MSSQLTotalServerMemory.key = "Total Server Memory (KB)";
432
}
433
434
void dict_mssql_insert_locks_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
@@ -249,7 +447,6 @@ void dict_mssql_insert_databases_cb(const DICTIONARY_ITEM *item __maybe_unused,
447
struct mssql_db_instance *ptr = value;
448
449
// https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-databases-object
252
- ptr->MSSQLDatabaseDataFileSize.key = "Data File(s) Size (KB)";
450
ptr->MSSQLDatabaseActiveTransactions.key = "Active Transactions";
451
ptr->MSSQLDatabaseBackupRestoreOperations.key = "Backup/Restore Throughput/sec";
452
ptr->MSSQLDatabaseLogFlushed.key = "Log Bytes Flushed/sec";
@@ -258,25 +455,111 @@ void dict_mssql_insert_databases_cb(const DICTIONARY_ITEM *item __maybe_unused,
455
ptr->MSSQLDatabaseWriteTransactions.key = "Write Transactions/sec";
456
}
457
458
+// Options
459
+void netdata_mount_mssql_connection_string(struct netdata_mssql_conn *dbInput)
460
+{
461
+ SQLCHAR conn[1024];
462
+ const char *serverAddress;
463
+ const char *serverAddressArg;
464
+ if (!dbInput) {
465
+ return;
466
+ }
467
+
468
+ char auth[512];
469
+ if (dbInput->server && dbInput->address) {
470
+ nd_log(
471
+ NDLS_COLLECTORS,
472
+ NDLP_ERR,
473
+ "Collector is not expecting server and address defined together, please, select one of them.");
474
+ dbInput->connectionString = NULL;
475
+ return;
476
+ }
477
+
478
+ if (dbInput->server) {
479
+ serverAddress = "Server";
480
+ serverAddressArg = dbInput->server;
481
+ } else {
482
+ serverAddressArg = "Address";
483
+ serverAddress = dbInput->address;
484
+ }
485
+
486
+ if (dbInput->windows_auth)
487
+ snprintfz(auth, sizeof(auth) - 1, "Trusted_Connection = yes");
488
+ else if (!dbInput->username || !dbInput->password) {
489
+ nd_log(
490
+ NDLS_COLLECTORS,
491
+ NDLP_ERR,
492
+ "You are not using Windows Authentication. Thus, it is necessary to specify user and password.");
493
+ dbInput->connectionString = NULL;
494
+ return;
495
+ } else {
496
+ snprintfz(auth, sizeof(auth) - 1, "UID=%s;PWD=%s;", dbInput->username, dbInput->password);
497
+ }
498
+
499
+ snprintfz(
500
+ (char *)conn, sizeof(conn) - 1, "Driver={%s};%s=%s;%s", dbInput->driver, serverAddress, serverAddressArg, auth);
501
+ dbInput->connectionString = (SQLCHAR *)strdupz((char *)conn);
502
+}
503
+
504
+static void netdata_read_config_options(struct netdata_mssql_conn *dbconn)
505
+{
506
+ dbconn->netdataSQLEnv = NULL;
507
+ dbconn->netdataSQLHDBc = NULL;
508
+ dbconn->dataFileSizeSTMT = NULL;
509
+
510
+ dbconn->is_connected = FALSE;
511
+
512
+ static uint16_t expected_instances = 1;
513
+ static uint16_t total_instances = 0;
514
+ if (total_instances > expected_instances)
515
+ return;
516
+
517
+#define NETDATA_MAX_MSSSQL_SECTION_LENGTH (40)
518
+#define NETDATA_DEFAULT_MSSQL_SECTION "plugin:windows:PerflibMSSQL"
519
+ char section_name[NETDATA_MAX_MSSSQL_SECTION_LENGTH + 1];
520
+ strncpyz(section_name, NETDATA_DEFAULT_MSSQL_SECTION, sizeof(NETDATA_DEFAULT_MSSQL_SECTION));
521
+ if (total_instances) {
522
+ snprintfz(§ion_name[sizeof(NETDATA_DEFAULT_MSSQL_SECTION) - 1], 5, "%d", total_instances);
523
+ }
524
+
525
+ dbconn->driver = inicfg_get(&netdata_config, section_name, "driver", "SQL Server");
526
+ dbconn->server = inicfg_get(&netdata_config, section_name, "server", NULL);
527
+ dbconn->address = inicfg_get(&netdata_config, section_name, "address", NULL);
528
+ dbconn->username = inicfg_get(&netdata_config, section_name, "uid", NULL);
529
+ dbconn->password = inicfg_get(&netdata_config, section_name, "pwd", NULL);
530
+ dbconn->instances = (int)inicfg_get_number(&netdata_config, section_name, "additional instances", 0);
531
+ dbconn->windows_auth = inicfg_get_boolean(&netdata_config, section_name, "windows authentication", false);
532
+
533
+ netdata_mount_mssql_connection_string(dbconn);
534
+ if (!total_instances)
535
+ expected_instances = dbconn->instances;
536
+
537
+ total_instances++;
538
+}
539
+
540
void dict_mssql_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
541
{
263
- struct mssql_instance *p = value;
542
+ struct mssql_instance *mi = value;
543
const char *instance = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
544
266
- if (!p->locks_instances) {
267
- p->locks_instances = dictionary_create_advanced(
545
+ if (!mi->locks_instances) {
546
+ mi->locks_instances = dictionary_create_advanced(
547
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct mssql_lock_instance));
269
- dictionary_register_insert_callback(p->locks_instances, dict_mssql_insert_locks_cb, NULL);
548
+ dictionary_register_insert_callback(mi->locks_instances, dict_mssql_insert_locks_cb, NULL);
549
}
550
272
- if (!p->databases) {
273
- p->databases = dictionary_create_advanced(
551
+ if (!mi->databases) {
552
+ mi->databases = dictionary_create_advanced(
553
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct mssql_db_instance));
275
- dictionary_register_insert_callback(p->databases, dict_mssql_insert_databases_cb, NULL);
554
+ dictionary_register_insert_callback(mi->databases, dict_mssql_insert_databases_cb, NULL);
555
}
556
278
- initialize_mssql_objects(p, instance);
279
- initialize_mssql_keys(p);
557
+ initialize_mssql_objects(mi, instance);
558
+ initialize_mssql_keys(mi);
559
+ netdata_read_config_options(&mi->conn);
560
+
561
+ if (mi->conn.connectionString)
562
+ mi->conn.is_connected = netdata_MSSQL_initialize_conection(&mi->conn);
563
}
564
565
static int mssql_fill_dictionary()
@@ -339,19 +622,20 @@ static int initialize(void)
622
return 0;
623
}
624
342
-static void do_mssql_general_stats(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
625
+static void do_mssql_general_stats(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
626
{
627
char id[RRD_ID_LENGTH_MAX + 1];
628
346
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_GENERAL_STATS]);
629
+ PERF_OBJECT_TYPE *pObjectType =
630
+ perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_GENERAL_STATS]);
631
if (!pObjectType)
632
return;
633
350
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLUserConnections)) {
351
- if (!p->st_user_connections) {
352
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_user_connections", p->instanceID);
634
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLUserConnections)) {
635
+ if (!mi->st_user_connections) {
636
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_user_connections", mi->instanceID);
637
netdata_fix_chart_name(id);
354
- p->st_user_connections = rrdset_create_localhost(
638
+ mi->st_user_connections = rrdset_create_localhost(
639
"mssql",
640
id,
641
NULL,
@@ -365,21 +649,21 @@ static void do_mssql_general_stats(PERF_DATA_BLOCK *pDataBlock, struct mssql_ins
649
update_every,
650
RRDSET_TYPE_LINE);
651
368
- p->rd_user_connections = rrddim_add(p->st_user_connections, "user", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
652
+ mi->rd_user_connections = rrddim_add(mi->st_user_connections, "user", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
653
370
- rrdlabels_add(p->st_user_connections->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
654
+ rrdlabels_add(mi->st_user_connections->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
655
}
656
657
rrddim_set_by_pointer(
374
- p->st_user_connections, p->rd_user_connections, (collected_number)p->MSSQLUserConnections.current.Data);
375
- rrdset_done(p->st_user_connections);
658
+ mi->st_user_connections, mi->rd_user_connections, (collected_number)mi->MSSQLUserConnections.current.Data);
659
+ rrdset_done(mi->st_user_connections);
660
}
661
378
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLBlockedProcesses)) {
379
- if (!p->st_process_blocked) {
380
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_blocked_process", p->instanceID);
662
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBlockedProcesses)) {
663
+ if (!mi->st_process_blocked) {
664
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_blocked_process", mi->instanceID);
665
netdata_fix_chart_name(id);
382
- p->st_process_blocked = rrdset_create_localhost(
666
+ mi->st_process_blocked = rrdset_create_localhost(
667
"mssql",
668
id,
669
NULL,
@@ -393,30 +677,30 @@ static void do_mssql_general_stats(PERF_DATA_BLOCK *pDataBlock, struct mssql_ins
677
update_every,
678
RRDSET_TYPE_LINE);
679
396
- p->rd_process_blocked = rrddim_add(p->st_process_blocked, "blocked", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
680
+ mi->rd_process_blocked = rrddim_add(mi->st_process_blocked, "blocked", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
681
398
- rrdlabels_add(p->st_process_blocked->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
682
+ rrdlabels_add(mi->st_process_blocked->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
683
}
684
685
rrddim_set_by_pointer(
402
- p->st_process_blocked, p->rd_process_blocked, (collected_number)p->MSSQLBlockedProcesses.current.Data);
403
- rrdset_done(p->st_process_blocked);
686
+ mi->st_process_blocked, mi->rd_process_blocked, (collected_number)mi->MSSQLBlockedProcesses.current.Data);
687
+ rrdset_done(mi->st_process_blocked);
688
}
689
}
690
407
-static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
691
+static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
692
{
693
char id[RRD_ID_LENGTH_MAX + 1];
694
411
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_SQL_STATS]);
695
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_SQL_STATS]);
696
if (!pObjectType)
697
return;
698
415
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLStatsAutoParameterization)) {
416
- if (!p->st_stats_auto_param) {
417
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_auto_parameterization_attempts", p->instanceID);
699
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLStatsAutoParameterization)) {
700
+ if (!mi->st_stats_auto_param) {
701
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_auto_parameterization_attempts", mi->instanceID);
702
netdata_fix_chart_name(id);
419
- p->st_stats_auto_param = rrdset_create_localhost(
703
+ mi->st_stats_auto_param = rrdset_create_localhost(
704
"mssql",
705
id,
706
NULL,
@@ -430,24 +714,24 @@ static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_in
714
update_every,
715
RRDSET_TYPE_LINE);
716
433
- p->rd_stats_auto_param =
434
- rrddim_add(p->st_stats_auto_param, "failed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
717
+ mi->rd_stats_auto_param =
718
+ rrddim_add(mi->st_stats_auto_param, "failed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
719
436
- rrdlabels_add(p->st_stats_auto_param->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
720
+ rrdlabels_add(mi->st_stats_auto_param->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
721
}
722
723
rrddim_set_by_pointer(
440
- p->st_stats_auto_param,
441
- p->rd_stats_auto_param,
442
- (collected_number)p->MSSQLStatsAutoParameterization.current.Data);
443
- rrdset_done(p->st_stats_auto_param);
724
+ mi->st_stats_auto_param,
725
+ mi->rd_stats_auto_param,
726
+ (collected_number)mi->MSSQLStatsAutoParameterization.current.Data);
727
+ rrdset_done(mi->st_stats_auto_param);
728
}
729
446
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLStatsBatchRequests)) {
447
- if (!p->st_stats_batch_request) {
448
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_batch_requests", p->instanceID);
730
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLStatsBatchRequests)) {
731
+ if (!mi->st_stats_batch_request) {
732
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_batch_requests", mi->instanceID);
733
netdata_fix_chart_name(id);
450
- p->st_stats_batch_request = rrdset_create_localhost(
734
+ mi->st_stats_batch_request = rrdset_create_localhost(
735
"mssql",
736
id,
737
NULL,
@@ -461,24 +745,25 @@ static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_in
745
update_every,
746
RRDSET_TYPE_LINE);
747
464
- p->rd_stats_batch_request =
465
- rrddim_add(p->st_stats_batch_request, "batch", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
748
+ mi->rd_stats_batch_request =
749
+ rrddim_add(mi->st_stats_batch_request, "batch", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
750
467
- rrdlabels_add(p->st_stats_batch_request->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
751
+ rrdlabels_add(mi->st_stats_batch_request->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
752
}
753
754
rrddim_set_by_pointer(
471
- p->st_stats_batch_request,
472
- p->rd_stats_batch_request,
473
- (collected_number)p->MSSQLStatsBatchRequests.current.Data);
474
- rrdset_done(p->st_stats_batch_request);
755
+ mi->st_stats_batch_request,
756
+ mi->rd_stats_batch_request,
757
+ (collected_number)mi->MSSQLStatsBatchRequests.current.Data);
758
+ rrdset_done(mi->st_stats_batch_request);
759
}
760
477
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLStatSafeAutoParameterization)) {
478
- if (!p->st_stats_safe_auto) {
479
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_safe_auto_parameterization_attempts", p->instanceID);
761
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLStatSafeAutoParameterization)) {
762
+ if (!mi->st_stats_safe_auto) {
763
+ snprintfz(
764
+ id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_safe_auto_parameterization_attempts", mi->instanceID);
765
netdata_fix_chart_name(id);
481
- p->st_stats_safe_auto = rrdset_create_localhost(
766
+ mi->st_stats_safe_auto = rrdset_create_localhost(
767
"mssql",
768
id,
769
NULL,
@@ -492,23 +777,23 @@ static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_in
777
update_every,
778
RRDSET_TYPE_LINE);
779
495
- p->rd_stats_safe_auto = rrddim_add(p->st_stats_safe_auto, "safe", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
780
+ mi->rd_stats_safe_auto = rrddim_add(mi->st_stats_safe_auto, "safe", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
781
497
- rrdlabels_add(p->st_stats_safe_auto->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
782
+ rrdlabels_add(mi->st_stats_safe_auto->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
783
}
784
785
rrddim_set_by_pointer(
501
- p->st_stats_safe_auto,
502
- p->rd_stats_safe_auto,
503
- (collected_number)p->MSSQLStatSafeAutoParameterization.current.Data);
504
- rrdset_done(p->st_stats_safe_auto);
786
+ mi->st_stats_safe_auto,
787
+ mi->rd_stats_safe_auto,
788
+ (collected_number)mi->MSSQLStatSafeAutoParameterization.current.Data);
789
+ rrdset_done(mi->st_stats_safe_auto);
790
}
791
507
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLCompilations)) {
508
- if (!p->st_stats_compilation) {
509
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_sql_compilations", p->instanceID);
792
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLCompilations)) {
793
+ if (!mi->st_stats_compilation) {
794
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_sql_compilations", mi->instanceID);
795
netdata_fix_chart_name(id);
511
- p->st_stats_compilation = rrdset_create_localhost(
796
+ mi->st_stats_compilation = rrdset_create_localhost(
797
"mssql",
798
id,
799
NULL,
@@ -522,22 +807,22 @@ static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_in
807
update_every,
808
RRDSET_TYPE_LINE);
809
525
- p->rd_stats_compilation =
526
- rrddim_add(p->st_stats_compilation, "compilations", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
810
+ mi->rd_stats_compilation =
811
+ rrddim_add(mi->st_stats_compilation, "compilations", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
812
528
- rrdlabels_add(p->st_stats_compilation->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
813
+ rrdlabels_add(mi->st_stats_compilation->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
814
}
815
816
rrddim_set_by_pointer(
532
- p->st_stats_compilation, p->rd_stats_compilation, (collected_number)p->MSSQLCompilations.current.Data);
533
- rrdset_done(p->st_stats_compilation);
817
+ mi->st_stats_compilation, mi->rd_stats_compilation, (collected_number)mi->MSSQLCompilations.current.Data);
818
+ rrdset_done(mi->st_stats_compilation);
819
}
820
536
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLRecompilations)) {
537
- if (!p->st_stats_recompiles) {
538
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_sql_recompilations", p->instanceID);
821
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLRecompilations)) {
822
+ if (!mi->st_stats_recompiles) {
823
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sqlstats_sql_recompilations", mi->instanceID);
824
netdata_fix_chart_name(id);
540
- p->st_stats_recompiles = rrdset_create_localhost(
825
+ mi->st_stats_recompiles = rrdset_create_localhost(
826
"mssql",
827
id,
828
NULL,
@@ -551,32 +836,32 @@ static void do_mssql_sql_statistics(PERF_DATA_BLOCK *pDataBlock, struct mssql_in
836
update_every,
837
RRDSET_TYPE_LINE);
838
554
- p->rd_stats_recompiles =
555
- rrddim_add(p->st_stats_recompiles, "recompiles", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
839
+ mi->rd_stats_recompiles =
840
+ rrddim_add(mi->st_stats_recompiles, "recompiles", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
841
557
- rrdlabels_add(p->st_stats_recompiles->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
842
+ rrdlabels_add(mi->st_stats_recompiles->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
843
}
844
845
rrddim_set_by_pointer(
561
- p->st_stats_recompiles, p->rd_stats_recompiles, (collected_number)p->MSSQLRecompilations.current.Data);
562
- rrdset_done(p->st_stats_recompiles);
846
+ mi->st_stats_recompiles, mi->rd_stats_recompiles, (collected_number)mi->MSSQLRecompilations.current.Data);
847
+ rrdset_done(mi->st_stats_recompiles);
848
}
849
}
850
566
-static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
851
+static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
852
{
853
char id[RRD_ID_LENGTH_MAX + 1];
854
855
PERF_OBJECT_TYPE *pObjectType =
571
- perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_BUFFER_MANAGEMENT]);
856
+ perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_BUFFER_MANAGEMENT]);
857
if (!pObjectType)
858
return;
859
575
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLBufferCacheHits)) {
576
- if (!p->st_buff_cache_hits) {
577
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_cache_hit_ratio", p->instanceID);
860
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBufferCacheHits)) {
861
+ if (!mi->st_buff_cache_hits) {
862
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_cache_hit_ratio", mi->instanceID);
863
netdata_fix_chart_name(id);
579
- p->st_buff_cache_hits = rrdset_create_localhost(
864
+ mi->st_buff_cache_hits = rrdset_create_localhost(
865
"mssql",
866
id,
867
NULL,
@@ -590,21 +875,22 @@ static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql
875
update_every,
876
RRDSET_TYPE_LINE);
877
593
- p->rd_buff_cache_hits = rrddim_add(p->st_buff_cache_hits, "hit_ratio", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
878
+ mi->rd_buff_cache_hits =
879
+ rrddim_add(mi->st_buff_cache_hits, "hit_ratio", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
880
595
- rrdlabels_add(p->st_buff_cache_hits->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
881
+ rrdlabels_add(mi->st_buff_cache_hits->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
882
}
883
884
rrddim_set_by_pointer(
599
- p->st_buff_cache_hits, p->rd_buff_cache_hits, (collected_number)p->MSSQLBufferCacheHits.current.Data);
600
- rrdset_done(p->st_buff_cache_hits);
885
+ mi->st_buff_cache_hits, mi->rd_buff_cache_hits, (collected_number)mi->MSSQLBufferCacheHits.current.Data);
886
+ rrdset_done(mi->st_buff_cache_hits);
887
}
888
603
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLBufferCheckpointPages)) {
604
- if (!p->st_buff_checkpoint_pages) {
605
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_bufman_checkpoint_pages", p->instanceID);
889
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBufferCheckpointPages)) {
890
+ if (!mi->st_buff_checkpoint_pages) {
891
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_bufman_checkpoint_pages", mi->instanceID);
892
netdata_fix_chart_name(id);
607
- p->st_buff_checkpoint_pages = rrdset_create_localhost(
893
+ mi->st_buff_checkpoint_pages = rrdset_create_localhost(
894
"mssql",
895
id,
896
NULL,
@@ -618,24 +904,24 @@ static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql
904
update_every,
905
RRDSET_TYPE_LINE);
906
621
- p->rd_buff_checkpoint_pages =
622
- rrddim_add(p->st_buff_checkpoint_pages, "log", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
907
+ mi->rd_buff_checkpoint_pages =
908
+ rrddim_add(mi->st_buff_checkpoint_pages, "log", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
909
624
- rrdlabels_add(p->st_buff_checkpoint_pages->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
910
+ rrdlabels_add(mi->st_buff_checkpoint_pages->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
911
}
912
913
rrddim_set_by_pointer(
628
- p->st_buff_checkpoint_pages,
629
- p->rd_buff_checkpoint_pages,
630
- (collected_number)p->MSSQLBufferCheckpointPages.current.Data);
631
- rrdset_done(p->st_buff_checkpoint_pages);
914
+ mi->st_buff_checkpoint_pages,
915
+ mi->rd_buff_checkpoint_pages,
916
+ (collected_number)mi->MSSQLBufferCheckpointPages.current.Data);
917
+ rrdset_done(mi->st_buff_checkpoint_pages);
918
}
919
634
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLBufferPageLifeExpectancy)) {
635
- if (!p->st_buff_cache_page_life_expectancy) {
636
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_bufman_page_life_expectancy", p->instanceID);
920
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBufferPageLifeExpectancy)) {
921
+ if (!mi->st_buff_cache_page_life_expectancy) {
922
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_bufman_page_life_expectancy", mi->instanceID);
923
netdata_fix_chart_name(id);
638
- p->st_buff_cache_page_life_expectancy = rrdset_create_localhost(
924
+ mi->st_buff_cache_page_life_expectancy = rrdset_create_localhost(
925
"mssql",
926
id,
927
NULL,
@@ -649,26 +935,26 @@ static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql
935
update_every,
936
RRDSET_TYPE_LINE);
937
652
- p->rd_buff_cache_page_life_expectancy = rrddim_add(
653
- p->st_buff_cache_page_life_expectancy, "life_expectancy", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
938
+ mi->rd_buff_cache_page_life_expectancy = rrddim_add(
939
+ mi->st_buff_cache_page_life_expectancy, "life_expectancy", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
940
941
rrdlabels_add(
656
- p->st_buff_cache_page_life_expectancy->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
942
+ mi->st_buff_cache_page_life_expectancy->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
943
}
944
945
rrddim_set_by_pointer(
660
- p->st_buff_cache_page_life_expectancy,
661
- p->rd_buff_cache_page_life_expectancy,
662
- (collected_number)p->MSSQLBufferPageLifeExpectancy.current.Data);
663
- rrdset_done(p->st_buff_cache_page_life_expectancy);
946
+ mi->st_buff_cache_page_life_expectancy,
947
+ mi->rd_buff_cache_page_life_expectancy,
948
+ (collected_number)mi->MSSQLBufferPageLifeExpectancy.current.Data);
949
+ rrdset_done(mi->st_buff_cache_page_life_expectancy);
950
}
951
666
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLBufferPageReads) &&
667
- perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLBufferPageWrites)) {
668
- if (!p->st_buff_page_iops) {
669
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_bufman_iops", p->instanceID);
952
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBufferPageReads) &&
953
+ perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLBufferPageWrites)) {
954
+ if (!mi->st_buff_page_iops) {
955
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_bufman_iops", mi->instanceID);
956
netdata_fix_chart_name(id);
671
- p->st_buff_page_iops = rrdset_create_localhost(
957
+ mi->st_buff_page_iops = rrdset_create_localhost(
958
"mssql",
959
id,
960
NULL,
@@ -682,36 +968,36 @@ static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql
968
update_every,
969
RRDSET_TYPE_LINE);
970
685
- p->rd_buff_page_reads = rrddim_add(p->st_buff_page_iops, "read", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
686
- p->rd_buff_page_writes =
687
- rrddim_add(p->st_buff_page_iops, "written", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
971
+ mi->rd_buff_page_reads = rrddim_add(mi->st_buff_page_iops, "read", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
972
+ mi->rd_buff_page_writes =
973
+ rrddim_add(mi->st_buff_page_iops, "written", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
974
689
- rrdlabels_add(p->st_buff_page_iops->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
975
+ rrdlabels_add(mi->st_buff_page_iops->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
976
}
977
978
rrddim_set_by_pointer(
693
- p->st_buff_page_iops, p->rd_buff_page_reads, (collected_number)p->MSSQLBufferPageReads.current.Data);
979
+ mi->st_buff_page_iops, mi->rd_buff_page_reads, (collected_number)mi->MSSQLBufferPageReads.current.Data);
980
rrddim_set_by_pointer(
695
- p->st_buff_page_iops, p->rd_buff_page_writes, (collected_number)p->MSSQLBufferPageWrites.current.Data);
981
+ mi->st_buff_page_iops, mi->rd_buff_page_writes, (collected_number)mi->MSSQLBufferPageWrites.current.Data);
982
697
- rrdset_done(p->st_buff_page_iops);
983
+ rrdset_done(mi->st_buff_page_iops);
984
}
985
}
986
701
-static void do_mssql_access_methods(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
987
+static void do_mssql_access_methods(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
988
{
989
char id[RRD_ID_LENGTH_MAX + 1];
990
991
PERF_OBJECT_TYPE *pObjectType =
706
- perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_ACCESS_METHODS]);
992
+ perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_ACCESS_METHODS]);
993
if (!pObjectType)
994
return;
995
710
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLAccessMethodPageSplits)) {
711
- if (!p->st_access_method_page_splits) {
712
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_accessmethods_page_splits", p->instanceID);
996
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLAccessMethodPageSplits)) {
997
+ if (!mi->st_access_method_page_splits) {
998
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_accessmethods_page_splits", mi->instanceID);
999
netdata_fix_chart_name(id);
714
- p->st_access_method_page_splits = rrdset_create_localhost(
1000
+ mi->st_access_method_page_splits = rrdset_create_localhost(
1001
"mssql",
1002
id,
1003
NULL,
@@ -725,34 +1011,34 @@ static void do_mssql_access_methods(PERF_DATA_BLOCK *pDataBlock, struct mssql_in
1011
update_every,
1012
RRDSET_TYPE_LINE);
1013
728
- p->rd_access_method_page_splits =
729
- rrddim_add(p->st_access_method_page_splits, "page", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1014
+ mi->rd_access_method_page_splits =
1015
+ rrddim_add(mi->st_access_method_page_splits, "page", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1016
1017
rrdlabels_add(
732
- p->st_access_method_page_splits->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1018
+ mi->st_access_method_page_splits->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1019
}
1020
1021
rrddim_set_by_pointer(
736
- p->st_access_method_page_splits,
737
- p->rd_access_method_page_splits,
738
- (collected_number)p->MSSQLAccessMethodPageSplits.current.Data);
739
- rrdset_done(p->st_access_method_page_splits);
1022
+ mi->st_access_method_page_splits,
1023
+ mi->rd_access_method_page_splits,
1024
+ (collected_number)mi->MSSQLAccessMethodPageSplits.current.Data);
1025
+ rrdset_done(mi->st_access_method_page_splits);
1026
}
1027
}
1028
743
-static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
1029
+static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
1030
{
1031
char id[RRD_ID_LENGTH_MAX + 1];
1032
747
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_SQL_ERRORS]);
1033
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_SQL_ERRORS]);
1034
if (!pObjectType)
1035
return;
1036
751
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLSQLErrorsTotal)) {
752
- if (!p->st_sql_errors) {
753
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sql_errors_total", p->instanceID);
1037
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLSQLErrorsTotal)) {
1038
+ if (!mi->st_sql_errors) {
1039
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_sql_errors_total", mi->instanceID);
1040
netdata_fix_chart_name(id);
755
- p->st_sql_errors = rrdset_create_localhost(
1041
+ mi->st_sql_errors = rrdset_create_localhost(
1042
"mssql",
1043
id,
1044
NULL,
@@ -766,14 +1052,14 @@ static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *
1052
update_every,
1053
RRDSET_TYPE_LINE);
1054
769
- p->rd_sql_errors = rrddim_add(p->st_sql_errors, "errors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1055
+ mi->rd_sql_errors = rrddim_add(mi->st_sql_errors, "errors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1056
771
- rrdlabels_add(p->st_sql_errors->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1057
+ rrdlabels_add(mi->st_sql_errors->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1058
}
1059
1060
rrddim_set_by_pointer(
775
- p->st_sql_errors, p->rd_sql_errors, (collected_number)p->MSSQLAccessMethodPageSplits.current.Data);
776
- rrdset_done(p->st_sql_errors);
1061
+ mi->st_sql_errors, mi->rd_sql_errors, (collected_number)mi->MSSQLAccessMethodPageSplits.current.Data);
1062
+ rrdset_done(mi->st_sql_errors);
1063
}
1064
}
1065
@@ -798,8 +1084,7 @@ void dict_mssql_locks_wait_charts(struct mssql_instance *mi, int update_every)
1084
update_every,
1085
RRDSET_TYPE_LINE);
1086
801
- rrdlabels_add(
802
- mi->st_lockWait->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1087
+ rrdlabels_add(mi->st_lockWait->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1088
}
1089
}
1090
@@ -812,8 +1097,7 @@ void dict_mssql_locks_wait_dimension(struct mssql_instance *mi, struct mssql_loc
1097
1098
mli->rd_lockWait = rrddim_add(mi->st_lockWait, id, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1099
}
815
- rrddim_set_by_pointer(
816
- mi->st_lockWait, mli->rd_lockWait, (collected_number)(mli->lockWait.current.Data));
1100
+ rrddim_set_by_pointer(mi->st_lockWait, mli->rd_lockWait, (collected_number)(mli->lockWait.current.Data));
1101
}
1102
1103
void dict_mssql_dead_locks_charts(struct mssql_instance *mi, int update_every)
@@ -837,8 +1121,7 @@ void dict_mssql_dead_locks_charts(struct mssql_instance *mi, int update_every)
1121
update_every,
1122
RRDSET_TYPE_LINE);
1123
840
- rrdlabels_add(
841
- mi->st_deadLocks->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1124
+ rrdlabels_add(mi->st_deadLocks->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1125
}
1126
}
1127
@@ -851,21 +1134,20 @@ void dict_mssql_deadlocks_dimension(struct mssql_instance *mi, struct mssql_lock
1134
1135
mli->rd_deadLocks = rrddim_add(mi->st_deadLocks, id, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1136
}
854
- rrddim_set_by_pointer(
855
- mi->st_deadLocks, mli->rd_deadLocks, (collected_number)mli->deadLocks.current.Data);
1137
+ rrddim_set_by_pointer(mi->st_deadLocks, mli->rd_deadLocks, (collected_number)mli->deadLocks.current.Data);
1138
}
1139
858
-static void do_mssql_locks(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
1140
+static void do_mssql_locks(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
1141
{
860
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_LOCKS]);
1142
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_LOCKS]);
1143
if (!pObjectType)
1144
return;
1145
1146
if (!pObjectType->NumInstances)
1147
return;
1148
867
- dict_mssql_locks_wait_charts(p, update_every);
868
- dict_mssql_dead_locks_charts(p, update_every);
1149
+ dict_mssql_locks_wait_charts(mi, update_every);
1150
+ dict_mssql_dead_locks_charts(mi, update_every);
1151
PERF_INSTANCE_DEFINITION *pi = NULL;
1152
for (LONG i = 0; i < pObjectType->NumInstances; i++) {
1153
pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
@@ -878,22 +1160,23 @@ static void do_mssql_locks(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p
1160
if (!strcasecmp(windows_shared_buffer, "_Total"))
1161
continue;
1162
881
- struct mssql_lock_instance *mli = dictionary_set(p->locks_instances, windows_shared_buffer, NULL, sizeof(*mli));
1163
+ struct mssql_lock_instance *mli =
1164
+ dictionary_set(mi->locks_instances, windows_shared_buffer, NULL, sizeof(*mli));
1165
if (!mli)
1166
continue;
1167
1168
if (perflibGetObjectCounter(pDataBlock, pObjectType, &mli->lockWait))
886
- dict_mssql_locks_wait_dimension(p, mli);
1169
+ dict_mssql_locks_wait_dimension(mi, mli);
1170
1171
if (perflibGetObjectCounter(pDataBlock, pObjectType, &mli->deadLocks))
889
- dict_mssql_deadlocks_dimension(p, mli);
1172
+ dict_mssql_deadlocks_dimension(mi, mli);
1173
}
1174
892
- if (p->st_lockWait)
893
- rrdset_done(p->st_lockWait);
1175
+ if (mi->st_lockWait)
1176
+ rrdset_done(mi->st_lockWait);
1177
895
- if (p->st_deadLocks)
896
- rrdset_done(p->st_deadLocks);
1178
+ if (mi->st_deadLocks)
1179
+ rrdset_done(mi->st_deadLocks);
1180
}
1181
1182
static void mssql_database_backup_restore_chart(struct mssql_db_instance *mli, const char *db, int update_every)
@@ -1142,9 +1425,12 @@ static void mssql_active_transactions_chart(struct mssql_db_instance *mli, const
1425
1426
static inline void mssql_data_file_size_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1427
{
1428
+ if (unlikely(!mli->parent->conn.is_connected) || mli->MSSQLDatabaseDataFileSize.current.Data == ULONG_LONG_MAX)
1429
+ return;
1430
+
1431
char id[RRD_ID_LENGTH_MAX + 1];
1432
1147
- if (!mli->st_db_data_file_size) {
1433
+ if (unlikely(!mli->st_db_data_file_size)) {
1434
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_data_files_size", db, mli->parent->instanceID);
1435
netdata_fix_chart_name(id);
1436
mli->st_db_data_file_size = rrdset_create_localhost(
@@ -1166,13 +1452,11 @@ static inline void mssql_data_file_size_chart(struct mssql_db_instance *mli, con
1452
rrdlabels_add(mli->st_db_data_file_size->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1453
}
1454
1169
- if (!mli->rd_db_data_file_size) {
1455
+ if (unlikely(!mli->rd_db_data_file_size)) {
1456
mli->rd_db_data_file_size = rrddim_add(mli->st_db_data_file_size, "size", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1457
}
1458
1173
- // FIXME: If the value cannot be retrieved, remove the chart instead of displaying a 0 value.
1174
- collected_number data =
1175
- (mli->updated & (1 << NETDATA_MSSQL_ENUM_MDI_IDX_FILE_SIZE)) ? mli->MSSQLDatabaseDataFileSize.current.Data : 0;
1459
+ collected_number data = mli->MSSQLDatabaseDataFileSize.current.Data;
1460
rrddim_set_by_pointer(mli->st_db_data_file_size, mli->rd_db_data_file_size, data);
1461
1462
rrdset_done(mli->st_db_data_file_size);
@@ -1186,9 +1470,7 @@ int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, v
1470
int *update_every = data;
1471
1472
void (*transaction_chart[])(struct mssql_db_instance *, const char *, int) = {
1189
- // FIXME: allegedly Netdata collects negative values (MSSQLDatabaseDataFileSize).
1190
- // something is wrong, perflibdump shows correct values.
1191
- // mssql_data_file_size_chart,
1473
+ mssql_data_file_size_chart,
1474
mssql_transactions_chart,
1475
mssql_database_backup_restore_chart,
1476
mssql_database_log_flushed_chart,
@@ -1207,9 +1489,9 @@ int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, v
1489
return 1;
1490
}
1491
1210
-static void do_mssql_databases(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
1492
+static void do_mssql_databases(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
1493
{
1212
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_DATABASE]);
1494
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_DATABASE]);
1495
if (!pObjectType)
1496
return;
1497
@@ -1225,19 +1507,13 @@ static void do_mssql_databases(PERF_DATA_BLOCK *pDataBlock, struct mssql_instanc
1507
if (!strcasecmp(windows_shared_buffer, "_Total"))
1508
continue;
1509
1228
- struct mssql_db_instance *mdi = dictionary_set(p->databases, windows_shared_buffer, NULL, sizeof(*mdi));
1510
+ struct mssql_db_instance *mdi = dictionary_set(mi->databases, windows_shared_buffer, NULL, sizeof(*mdi));
1511
if (!mdi)
1512
continue;
1513
1514
mdi->updated = 0;
1515
if (!mdi->parent) {
1234
- mdi->parent = p;
1235
- }
1236
-
1237
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseDataFileSize)) {
1238
- LONGLONG value = (LONGLONG)mdi->MSSQLDatabaseDataFileSize.current.Data;
1239
- if (value > 0)
1240
- mdi->updated |= (1 << NETDATA_MSSQL_ENUM_MDI_IDX_FILE_SIZE);
1516
+ mdi->parent = mi;
1517
}
1518
1519
if (perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseActiveTransactions))
@@ -1259,22 +1535,22 @@ static void do_mssql_databases(PERF_DATA_BLOCK *pDataBlock, struct mssql_instanc
1535
mdi->updated |= (1 << NETDATA_MSSQL_ENUM_MDI_IDX_WRITE_TRANSACTIONS);
1536
}
1537
1262
- dictionary_sorted_walkthrough_read(p->databases, dict_mssql_databases_charts_cb, &update_every);
1538
+ dictionary_sorted_walkthrough_read(mi->databases, dict_mssql_databases_charts_cb, &update_every);
1539
}
1540
1265
-static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
1541
+static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *mi, int update_every)
1542
{
1543
char id[RRD_ID_LENGTH_MAX + 1];
1544
1269
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_MEMORY]);
1545
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, mi->objectName[NETDATA_MSSQL_MEMORY]);
1546
if (!pObjectType)
1547
return;
1548
1273
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLConnectionMemoryBytes)) {
1274
- if (!p->st_conn_memory) {
1275
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_connection_memory_bytes", p->instanceID);
1549
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLConnectionMemoryBytes)) {
1550
+ if (!mi->st_conn_memory) {
1551
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_connection_memory_bytes", mi->instanceID);
1552
netdata_fix_chart_name(id);
1277
- p->st_conn_memory = rrdset_create_localhost(
1553
+ mi->st_conn_memory = rrdset_create_localhost(
1554
"mssql",
1555
id,
1556
NULL,
@@ -1288,23 +1564,23 @@ static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instan
1564
update_every,
1565
RRDSET_TYPE_LINE);
1566
1291
- p->rd_conn_memory = rrddim_add(p->st_conn_memory, "memory", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1567
+ mi->rd_conn_memory = rrddim_add(mi->st_conn_memory, "memory", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1568
1293
- rrdlabels_add(p->st_conn_memory->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1569
+ rrdlabels_add(mi->st_conn_memory->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1570
}
1571
1572
rrddim_set_by_pointer(
1297
- p->st_conn_memory,
1298
- p->rd_conn_memory,
1299
- (collected_number)(p->MSSQLConnectionMemoryBytes.current.Data * 1024));
1300
- rrdset_done(p->st_conn_memory);
1573
+ mi->st_conn_memory,
1574
+ mi->rd_conn_memory,
1575
+ (collected_number)(mi->MSSQLConnectionMemoryBytes.current.Data * 1024));
1576
+ rrdset_done(mi->st_conn_memory);
1577
}
1578
1303
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLExternalBenefitOfMemory)) {
1304
- if (!p->st_ext_benefit_mem) {
1305
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_external_benefit_of_memory", p->instanceID);
1579
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLExternalBenefitOfMemory)) {
1580
+ if (!mi->st_ext_benefit_mem) {
1581
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_external_benefit_of_memory", mi->instanceID);
1582
netdata_fix_chart_name(id);
1307
- p->st_ext_benefit_mem = rrdset_create_localhost(
1583
+ mi->st_ext_benefit_mem = rrdset_create_localhost(
1584
"mssql",
1585
id,
1586
NULL,
@@ -1318,23 +1594,23 @@ static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instan
1594
update_every,
1595
RRDSET_TYPE_LINE);
1596
1321
- p->rd_ext_benefit_mem = rrddim_add(p->st_ext_benefit_mem, "benefit", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1597
+ mi->rd_ext_benefit_mem = rrddim_add(mi->st_ext_benefit_mem, "benefit", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1598
1323
- rrdlabels_add(p->st_ext_benefit_mem->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1599
+ rrdlabels_add(mi->st_ext_benefit_mem->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1600
}
1601
1602
rrddim_set_by_pointer(
1327
- p->st_ext_benefit_mem,
1328
- p->rd_ext_benefit_mem,
1329
- (collected_number)p->MSSQLExternalBenefitOfMemory.current.Data);
1330
- rrdset_done(p->st_ext_benefit_mem);
1603
+ mi->st_ext_benefit_mem,
1604
+ mi->rd_ext_benefit_mem,
1605
+ (collected_number)mi->MSSQLExternalBenefitOfMemory.current.Data);
1606
+ rrdset_done(mi->st_ext_benefit_mem);
1607
}
1608
1333
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLPendingMemoryGrants)) {
1334
- if (!p->st_pending_mem_grant) {
1335
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_pending_memory_grants", p->instanceID);
1609
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLPendingMemoryGrants)) {
1610
+ if (!mi->st_pending_mem_grant) {
1611
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_pending_memory_grants", mi->instanceID);
1612
netdata_fix_chart_name(id);
1337
- p->st_pending_mem_grant = rrdset_create_localhost(
1613
+ mi->st_pending_mem_grant = rrdset_create_localhost(
1614
"mssql",
1615
id,
1616
NULL,
@@ -1348,25 +1624,25 @@ static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instan
1624
update_every,
1625
RRDSET_TYPE_LINE);
1626
1351
- p->rd_pending_mem_grant =
1352
- rrddim_add(p->st_pending_mem_grant, "pending", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1627
+ mi->rd_pending_mem_grant =
1628
+ rrddim_add(mi->st_pending_mem_grant, "pending", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1629
1354
- rrdlabels_add(p->st_pending_mem_grant->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1630
+ rrdlabels_add(mi->st_pending_mem_grant->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1631
}
1632
1633
rrddim_set_by_pointer(
1358
- p->st_pending_mem_grant,
1359
- p->rd_pending_mem_grant,
1360
- (collected_number)p->MSSQLPendingMemoryGrants.current.Data);
1634
+ mi->st_pending_mem_grant,
1635
+ mi->rd_pending_mem_grant,
1636
+ (collected_number)mi->MSSQLPendingMemoryGrants.current.Data);
1637
1362
- rrdset_done(p->st_pending_mem_grant);
1638
+ rrdset_done(mi->st_pending_mem_grant);
1639
}
1640
1365
- if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLTotalServerMemory)) {
1366
- if (!p->st_mem_tot_server) {
1367
- snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_server_memory", p->instanceID);
1641
+ if (perflibGetObjectCounter(pDataBlock, pObjectType, &mi->MSSQLTotalServerMemory)) {
1642
+ if (!mi->st_mem_tot_server) {
1643
+ snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_server_memory", mi->instanceID);
1644
netdata_fix_chart_name(id);
1369
- p->st_mem_tot_server = rrdset_create_localhost(
1645
+ mi->st_mem_tot_server = rrdset_create_localhost(
1646
"mssql",
1647
id,
1648
NULL,
@@ -1380,25 +1656,29 @@ static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instan
1656
update_every,
1657
RRDSET_TYPE_LINE);
1658
1383
- p->rd_mem_tot_server = rrddim_add(p->st_mem_tot_server, "memory", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1659
+ mi->rd_mem_tot_server = rrddim_add(mi->st_mem_tot_server, "memory", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1660
1385
- rrdlabels_add(p->st_mem_tot_server->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1661
+ rrdlabels_add(mi->st_mem_tot_server->rrdlabels, "mssql_instance", mi->instanceID, RRDLABEL_SRC_AUTO);
1662
}
1663
1664
rrddim_set_by_pointer(
1389
- p->st_mem_tot_server,
1390
- p->rd_mem_tot_server,
1391
- (collected_number)(p->MSSQLTotalServerMemory.current.Data * 1024));
1665
+ mi->st_mem_tot_server,
1666
+ mi->rd_mem_tot_server,
1667
+ (collected_number)(mi->MSSQLTotalServerMemory.current.Data * 1024));
1668
1393
- rrdset_done(p->st_mem_tot_server);
1669
+ rrdset_done(mi->st_mem_tot_server);
1670
}
1671
}
1672
1673
int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
1674
{
1399
- struct mssql_instance *p = value;
1675
+ struct mssql_instance *mi = value;
1676
int *update_every = data;
1677
1678
+ if (mi->conn.is_connected) {
1679
+ dictionary_sorted_walkthrough_read(mi->databases, dict_mssql_databases_run_query, NULL);
1680
+ }
1681
+
1682
static void (*doMSSQL[])(PERF_DATA_BLOCK *, struct mssql_instance *, int) = {
1683
do_mssql_general_stats,
1684
do_mssql_errors,
@@ -1414,7 +1694,7 @@ int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value
1694
if (!doMSSQL[i])
1695
continue;
1696
1417
- DWORD id = RegistryFindIDByName(p->objectName[i]);
1697
+ DWORD id = RegistryFindIDByName(mi->objectName[i]);
1698
if (id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
1699
return -1;
1700
@@ -1422,12 +1702,14 @@ int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value
1702
if (!pDataBlock)
1703
return -1;
1704
1425
- doMSSQL[i](pDataBlock, p, *update_every);
1705
+ doMSSQL[i](pDataBlock, mi, *update_every);
1706
}
1707
1708
return 1;
1709
}
1710
1711
+// Entry point
1712
+
1713
int do_PerflibMSSQL(int update_every, usec_t dt __maybe_unused)
1714
{
1715
static bool initialized = false;