Active Directory Metrics (Windows.plugin) (#19461)
thiagoftsm committed
Jan 30, 2025 at 07:47 UTC
3badfe6bdb1d2f719b40be69e82221c4e025cff1
4 files changed
+858
-1
CMakeLists.txt
+1
@@ -1777,6 +1777,7 @@ set(WINDOWS_PLUGIN_FILES
1777
src/collectors/windows.plugin/GetSystemCPU.c
1778
src/collectors/windows.plugin/perflib-rrd.c
1779
src/collectors/windows.plugin/perflib-rrd.h
1780
+ src/collectors/windows.plugin/perflib-ad.c
1781
src/collectors/windows.plugin/perflib-mssql.c
1782
src/collectors/windows.plugin/perflib-storage.c
1783
src/collectors/windows.plugin/perflib-processor.c
src/collectors/windows.plugin/perflib-ad.c
new
+836
@@ -0,0 +1,836 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#include "windows_plugin.h"
4
+#include "windows-internals.h"
5
+
6
+static void initialize(void) {
7
+ ;
8
+}
9
+
10
+static void netdata_ad_directory(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
11
+ static COUNTER_DATA directoryPercReadsFromDCA = { .key = "DS % Reads from DRA" };
12
+ static COUNTER_DATA directoryPercReadsFromKCC = { .key = "DS % Reads from KCC" };
13
+ static COUNTER_DATA directoryPercReadsFromLSA = { .key = "DS % Reads from LSA" };
14
+ static COUNTER_DATA directoryPercReadsFromNSPI = { .key = "DS % Reads from NSPI" };
15
+ static COUNTER_DATA directoryPercReadsFromNTDSAPI = { .key = "DS % Reads from NTDSAPI" };
16
+ static COUNTER_DATA directoryPercReadsFromSAM = { .key = "DS % Reads from SAM" };
17
+ static COUNTER_DATA directoryPercReadsOther = { .key = "DS % Reads from Other" };
18
+
19
+ static COUNTER_DATA directoryPercSearchesFromDCA = { .key = "DS % Searches from DRA" };
20
+ static COUNTER_DATA directoryPercSearchesFromKCC = { .key = "DS % Searches from KCC" };
21
+ static COUNTER_DATA directoryPercSearchesFromLSA = { .key = "DS % Searches from LSA" };
22
+ static COUNTER_DATA directoryPercSearchesFromNSPI = { .key = "DS % Searches from NSPI" };
23
+ static COUNTER_DATA directoryPercSearchesFromNTDSAPI = { .key = "DS % Searches from NTDSAPI" };
24
+ static COUNTER_DATA directoryPercSearchesFromSAM = { .key = "DS % Searches from SAM" };
25
+ static COUNTER_DATA directoryPercSearchesOther = { .key = "DS % Searches from Other" };
26
+
27
+ static COUNTER_DATA directoryPercWritesFromDCA = { .key = "DS % Writes from DRA" };
28
+ static COUNTER_DATA directoryPercWritesFromKCC = { .key = "DS % Writes from KCC" };
29
+ static COUNTER_DATA directoryPercWritesFromLSA = { .key = "DS % Writes from LSA" };
30
+ static COUNTER_DATA directoryPercWritesFromNSPI = { .key = "DS % Writes from NSPI" };
31
+ static COUNTER_DATA directoryPercWritesFromNTDSAPI = { .key = "DS % Writes from NTDSAPI" };
32
+ static COUNTER_DATA directoryPercWritesFromSAM = { .key = "DS % Writes from SAM" };
33
+ static COUNTER_DATA directoryPercWritesOther = { .key = "DS % Writes from Other" };
34
+
35
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsFromDCA);
36
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsFromKCC);
37
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsFromLSA);
38
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsFromNSPI);
39
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsFromNTDSAPI);
40
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsFromSAM);
41
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercReadsOther);
42
+
43
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesFromDCA);
44
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesFromKCC);
45
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesFromLSA);
46
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesFromNSPI);
47
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesFromNTDSAPI);
48
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesFromSAM);
49
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercSearchesOther);
50
+
51
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesFromDCA);
52
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesFromKCC);
53
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesFromLSA);
54
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesFromNSPI);
55
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesFromNTDSAPI);
56
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesFromSAM);
57
+ perflibGetObjectCounter(pDataBlock, pObjectType, &directoryPercWritesOther);
58
+
59
+ static RRDSET *st_directory_operation_total = NULL;
60
+ static RRDDIM *rd_directory_operation_total_read = NULL;
61
+ static RRDDIM *rd_directory_operation_total_write = NULL;
62
+ static RRDDIM *rd_directory_operation_total_search = NULL;
63
+
64
+
65
+ if (unlikely(!st_directory_operation_total)) {
66
+ st_directory_operation_total = rrdset_create_localhost("ad"
67
+ , "directory_operations_read"
68
+ , NULL
69
+ , "database"
70
+ , "ad.directory_operations"
71
+ , "AD directory operations"
72
+ , "operations/s"
73
+ , PLUGIN_WINDOWS_NAME
74
+ , "PerflibAD"
75
+ , PRIO_AD_DIROPERATIONS_TOTAL
76
+ , update_every
77
+ , RRDSET_TYPE_LINE);
78
+
79
+ rd_directory_operation_total_read = rrddim_add(st_directory_operation_total,
80
+ "read",
81
+ NULL,
82
+ 1,
83
+ 1,
84
+ RRD_ALGORITHM_INCREMENTAL);
85
+
86
+ rd_directory_operation_total_write = rrddim_add(st_directory_operation_total,
87
+ "write",
88
+ NULL,
89
+ 1,
90
+ 1,
91
+ RRD_ALGORITHM_INCREMENTAL);
92
+
93
+ rd_directory_operation_total_search = rrddim_add(st_directory_operation_total,
94
+ "search",
95
+ NULL,
96
+ 1,
97
+ 1,
98
+ RRD_ALGORITHM_INCREMENTAL);
99
+ }
100
+ collected_number readValue = directoryPercReadsFromDCA.current.Data +
101
+ directoryPercReadsFromKCC.current.Data +
102
+ directoryPercReadsFromLSA.current.Data +
103
+ directoryPercReadsFromNSPI.current.Data +
104
+ directoryPercReadsFromNTDSAPI.current.Data +
105
+ directoryPercReadsFromSAM.current.Data +
106
+ directoryPercReadsOther.current.Data ;
107
+
108
+ collected_number writeValue = directoryPercWritesFromDCA.current.Data +
109
+ directoryPercWritesFromKCC.current.Data +
110
+ directoryPercWritesFromLSA.current.Data +
111
+ directoryPercWritesFromNSPI.current.Data +
112
+ directoryPercWritesFromNTDSAPI.current.Data +
113
+ directoryPercWritesFromSAM.current.Data +
114
+ directoryPercWritesOther.current.Data ;
115
+
116
+ collected_number searchValue = directoryPercSearchesFromDCA.current.Data +
117
+ directoryPercSearchesFromKCC.current.Data +
118
+ directoryPercSearchesFromLSA.current.Data +
119
+ directoryPercSearchesFromNSPI.current.Data +
120
+ directoryPercSearchesFromNTDSAPI.current.Data +
121
+ directoryPercSearchesFromSAM.current.Data +
122
+ directoryPercSearchesOther.current.Data ;
123
+
124
+ rrddim_set_by_pointer(st_directory_operation_total,
125
+ rd_directory_operation_total_read,
126
+ readValue);
127
+
128
+ rrddim_set_by_pointer(st_directory_operation_total,
129
+ rd_directory_operation_total_write,
130
+ writeValue);
131
+
132
+ rrddim_set_by_pointer(st_directory_operation_total,
133
+ rd_directory_operation_total_search,
134
+ searchValue);
135
+
136
+ rrdset_done(st_directory_operation_total);
137
+}
138
+
139
+static void netdata_ad_cache_lookups(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
140
+ static COUNTER_DATA nameCacheLookupsTotal = { .key = "DS Name Cache hit rate,secondvalue" };
141
+
142
+ static RRDSET *st_name_cache_lookups_total = NULL;
143
+ static RRDDIM *rd_name_cache_lookups_total = NULL;
144
+
145
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &nameCacheLookupsTotal)) {
146
+ if (unlikely(!st_name_cache_lookups_total)) {
147
+ st_name_cache_lookups_total = rrdset_create_localhost("ad"
148
+ , "name_cache_lookups"
149
+ , NULL
150
+ , "database"
151
+ , "ad.name_cache_lookups"
152
+ , "Name cache lookups"
153
+ , "lookups/s"
154
+ , PLUGIN_WINDOWS_NAME
155
+ , "PerflibAD"
156
+ , PRIO_AD_CACHE_LOOKUP_TOTAL
157
+ , update_every
158
+ , RRDSET_TYPE_LINE
159
+ );
160
+
161
+ rd_name_cache_lookups_total = rrddim_add(st_name_cache_lookups_total,
162
+ "lookups",
163
+ NULL,
164
+ 1,
165
+ 1,
166
+ RRD_ALGORITHM_INCREMENTAL);
167
+ }
168
+
169
+ rrddim_set_by_pointer(st_name_cache_lookups_total,
170
+ rd_name_cache_lookups_total,
171
+ (collected_number)nameCacheLookupsTotal.current.Data);
172
+ rrdset_done(st_name_cache_lookups_total);
173
+ }
174
+}
175
+
176
+static void netdata_ad_cache_hits(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
177
+ static COUNTER_DATA nameCacheHitsTotal = { .key = "DS Name Cache hit rate" };
178
+
179
+ static RRDSET *st_name_cache_hits_total = NULL;
180
+ static RRDDIM *rd_name_cache_hits_total = NULL;
181
+
182
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &nameCacheHitsTotal)) {
183
+ if (unlikely(!st_name_cache_hits_total)) {
184
+ st_name_cache_hits_total = rrdset_create_localhost("ad"
185
+ , "name_cache_hits"
186
+ , NULL
187
+ , "database"
188
+ , "ad.name_cache_hits"
189
+ , "Name cache hits"
190
+ , "hits/s"
191
+ , PLUGIN_WINDOWS_NAME
192
+ , "PerflibAD"
193
+ , PRIO_AD_CACHE_HITS_TOTAL
194
+ , update_every
195
+ , RRDSET_TYPE_LINE
196
+ );
197
+
198
+ rd_name_cache_hits_total = rrddim_add(st_name_cache_hits_total,
199
+ "hits",
200
+ NULL,
201
+ 1,
202
+ 1,
203
+ RRD_ALGORITHM_INCREMENTAL);
204
+ }
205
+
206
+ rrddim_set_by_pointer(st_name_cache_hits_total,
207
+ rd_name_cache_hits_total,
208
+ (collected_number)nameCacheHitsTotal.current.Data);
209
+ rrdset_done(st_name_cache_hits_total);
210
+ }
211
+}
212
+
213
+static void netdata_ad_searches(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
214
+ static COUNTER_DATA ldapSearchesTotal = { .key = "LDAP Searches/sec" };
215
+
216
+ static RRDSET *st_ldap_searches_total = NULL;
217
+ static RRDDIM *rd_ldap_searches_total = NULL;
218
+
219
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &ldapSearchesTotal)) {
220
+ if (unlikely(!st_ldap_searches_total)) {
221
+ st_ldap_searches_total = rrdset_create_localhost("ad"
222
+ , "ldap_searches"
223
+ , NULL
224
+ , "ldap"
225
+ , "ad.ldap_searches"
226
+ , "LDAP client search operations"
227
+ , "searches/s"
228
+ , PLUGIN_WINDOWS_NAME
229
+ , "PerflibAD"
230
+ , PRIO_AD_LDAP_SEARCHES_TOTAL
231
+ , update_every
232
+ , RRDSET_TYPE_LINE
233
+ );
234
+
235
+ rd_ldap_searches_total = rrddim_add(st_ldap_searches_total,
236
+ "searches",
237
+ NULL,
238
+ 1,
239
+ 1,
240
+ RRD_ALGORITHM_INCREMENTAL);
241
+ }
242
+
243
+ rrddim_set_by_pointer(st_ldap_searches_total,
244
+ rd_ldap_searches_total,
245
+ (collected_number)ldapSearchesTotal.current.Data);
246
+ rrdset_done(st_ldap_searches_total);
247
+ }
248
+}
249
+
250
+static void netdata_ad_properties(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
251
+ static COUNTER_DATA replicationInboundPropertiesUpdatedTotal = { .key = "DRA Inbound Properties Applied/sec" };
252
+ static COUNTER_DATA replicationInboundPropertiesFilteredTotal = { .key = "DRA Inbound Properties Filtered/sec" };
253
+
254
+ static RRDSET *st_dra_replication_properties_updated = NULL;
255
+ static RRDDIM *rd_dra_replication_properties_updated = NULL;
256
+ static RRDSET *st_dra_replication_properties_filtered = NULL;
257
+ static RRDDIM *rd_dra_replication_properties_filtered = NULL;
258
+
259
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationInboundPropertiesUpdatedTotal)) {
260
+ goto totalPropertyChart;
261
+ }
262
+
263
+ if (unlikely(!st_dra_replication_properties_updated)) {
264
+ st_dra_replication_properties_updated = rrdset_create_localhost("ad"
265
+ , "dra_replication_properties_updated"
266
+ , NULL
267
+ , "replication"
268
+ , "ad.dra_replication_properties_updated"
269
+ , "DRA replication properties updated"
270
+ , "properties/s"
271
+ , PLUGIN_WINDOWS_NAME
272
+ , "PerflibAD"
273
+ , PRIO_AD_REPLICATION_PROPERTY_UPDATED
274
+ , update_every
275
+ , RRDSET_TYPE_LINE);
276
+
277
+ rd_dra_replication_properties_updated = rrddim_add(st_dra_replication_properties_updated,
278
+ "inbound",
279
+ NULL,
280
+ 1,
281
+ 1,
282
+ RRD_ALGORITHM_INCREMENTAL);
283
+ }
284
+
285
+ rrddim_set_by_pointer(st_dra_replication_properties_updated,
286
+ rd_dra_replication_properties_updated,
287
+ (collected_number)replicationInboundPropertiesUpdatedTotal.current.Data);
288
+ rrdset_done(st_dra_replication_properties_updated);
289
+
290
+totalPropertyChart:
291
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationInboundPropertiesFilteredTotal)) {
292
+ return;
293
+ }
294
+
295
+ if (unlikely(!st_dra_replication_properties_filtered)) {
296
+ st_dra_replication_properties_filtered = rrdset_create_localhost("ad"
297
+ , "dra_replication_properties_filtered"
298
+ , NULL
299
+ , "replication"
300
+ , "ad.dra_replication_properties_filtered"
301
+ , "DRA replication properties filtered"
302
+ , "properties/s"
303
+ , PLUGIN_WINDOWS_NAME
304
+ , "PerflibAD"
305
+ , PRIO_AD_REPLICATION_PROPERTY_FILTERED
306
+ , update_every
307
+ , RRDSET_TYPE_LINE);
308
+
309
+ rd_dra_replication_properties_filtered = rrddim_add(st_dra_replication_properties_filtered,
310
+ "inbound",
311
+ NULL,
312
+ 1,
313
+ 1,
314
+ RRD_ALGORITHM_INCREMENTAL);
315
+ }
316
+
317
+ rrddim_set_by_pointer(st_dra_replication_properties_filtered,
318
+ rd_dra_replication_properties_filtered,
319
+ (collected_number)replicationInboundPropertiesFilteredTotal.current.Data);
320
+ rrdset_done(st_dra_replication_properties_filtered);
321
+}
322
+
323
+static void netdata_ad_compressed_traffic(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
324
+ static COUNTER_DATA replicationInboundDataInterSiteBytesTotal = { .key = "DRA Inbound Bytes Compressed (Between Sites, After Compression)/sec" };
325
+ static COUNTER_DATA replicationOutboundDataInterSiteBytesTotal = { .key = "DRA Outbound Bytes Compressed (Between Sites, After Compression)/sec" };
326
+
327
+ static COUNTER_DATA replicationDataInboundIntraSiteBytesTotal = { .key = "DRA Outbound Bytes Compressed (Between Sites, After Compression)/sec"};
328
+ static COUNTER_DATA replicationDataOutboundIntraSiteBytesTotal = { .key = "DRA Outbound Bytes Not Compressed (Within Site)/sec"};
329
+
330
+ static RRDSET *st_dra_replication_intersite_compressed_traffic = NULL;
331
+ static RRDDIM *rd_replication_data_intersite_bytes_total_inbound = NULL;
332
+ static RRDDIM *rd_replication_data_intersite_bytes_total_outbound = NULL;
333
+
334
+ static RRDSET *st_dra_replication_intrasite_compressed_traffic = NULL;
335
+ static RRDDIM *rd_replication_data_intrasite_bytes_total_inbound = NULL;
336
+ static RRDDIM *rd_replication_data_intrasite_bytes_total_outbound = NULL;
337
+
338
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationInboundDataInterSiteBytesTotal) ||
339
+ !perflibGetObjectCounter(pDataBlock, pObjectType, &replicationOutboundDataInterSiteBytesTotal)) {
340
+ goto intraChart;
341
+ }
342
+
343
+ if (unlikely(!st_dra_replication_intersite_compressed_traffic)) {
344
+ st_dra_replication_intersite_compressed_traffic = rrdset_create_localhost("ad"
345
+ , "dra_replication_intersite_compressed_traffic"
346
+ , NULL
347
+ , "replication"
348
+ , "ad.dra_replication_intersite_compressed_traffic"
349
+ , "DRA replication compressed traffic withing site"
350
+ , "bytes/s"
351
+ , PLUGIN_WINDOWS_NAME
352
+ , "PerflibAD"
353
+ , PRIO_AD_REPLICATION_INTERSITE_COMPRESSED
354
+ , update_every
355
+ , RRDSET_TYPE_AREA);
356
+
357
+ rd_replication_data_intersite_bytes_total_inbound = rrddim_add(st_dra_replication_intersite_compressed_traffic,
358
+ "inbound",
359
+ NULL,
360
+ 1,
361
+ 1,
362
+ RRD_ALGORITHM_INCREMENTAL);
363
+
364
+ rd_replication_data_intersite_bytes_total_outbound = rrddim_add(st_dra_replication_intersite_compressed_traffic,
365
+ "outbound",
366
+ NULL,
367
+ -1,
368
+ 1,
369
+ RRD_ALGORITHM_INCREMENTAL);
370
+ }
371
+
372
+ rrddim_set_by_pointer(st_dra_replication_intersite_compressed_traffic,
373
+ rd_replication_data_intersite_bytes_total_inbound,
374
+ (collected_number)replicationInboundDataInterSiteBytesTotal.current.Data);
375
+ rrddim_set_by_pointer(st_dra_replication_intersite_compressed_traffic,
376
+ rd_replication_data_intersite_bytes_total_outbound,
377
+ (collected_number)replicationOutboundDataInterSiteBytesTotal.current.Data);
378
+ rrdset_done(st_dra_replication_intersite_compressed_traffic);
379
+
380
+intraChart:
381
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationDataInboundIntraSiteBytesTotal) ||
382
+ !perflibGetObjectCounter(pDataBlock, pObjectType, &replicationDataOutboundIntraSiteBytesTotal)) {
383
+ return;
384
+ }
385
+
386
+ if (unlikely(!st_dra_replication_intrasite_compressed_traffic)) {
387
+ st_dra_replication_intrasite_compressed_traffic = rrdset_create_localhost("ad"
388
+ , "dra_replication_intrasite_compressed_traffic"
389
+ , NULL
390
+ , "replication"
391
+ , "ad.dra_replication_intrasite_compressed_traffic"
392
+ , "DRA replication compressed traffic between sites"
393
+ , "bytes/s"
394
+ , PLUGIN_WINDOWS_NAME
395
+ , "PerflibAD"
396
+ , PRIO_AD_REPLICATION_INTRASITE_COMPRESSED
397
+ , update_every
398
+ , RRDSET_TYPE_LINE);
399
+
400
+ rd_replication_data_intrasite_bytes_total_inbound = rrddim_add(st_dra_replication_intrasite_compressed_traffic,
401
+ "inbound",
402
+ NULL,
403
+ 1,
404
+ 1,
405
+ RRD_ALGORITHM_INCREMENTAL);
406
+
407
+ rd_replication_data_intrasite_bytes_total_outbound = rrddim_add(st_dra_replication_intrasite_compressed_traffic,
408
+ "outbound",
409
+ NULL,
410
+ -1,
411
+ 1,
412
+ RRD_ALGORITHM_INCREMENTAL);
413
+ }
414
+
415
+ rrddim_set_by_pointer(st_dra_replication_intrasite_compressed_traffic,
416
+ rd_replication_data_intrasite_bytes_total_inbound,
417
+ (collected_number)replicationDataInboundIntraSiteBytesTotal.current.Data);
418
+ rrddim_set_by_pointer(st_dra_replication_intrasite_compressed_traffic,
419
+ rd_replication_data_intrasite_bytes_total_outbound,
420
+ (collected_number)replicationDataOutboundIntraSiteBytesTotal.current.Data);
421
+ rrdset_done(st_dra_replication_intrasite_compressed_traffic);
422
+}
423
+
424
+static void netdata_ad_sync(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
425
+ static COUNTER_DATA replicationSyncPending = { .key = "DRA Pending Replication Synchronizations" };
426
+ static COUNTER_DATA replicationSyncRequestsTotal = { .key = "DRA Sync Requests Made" };
427
+ static COUNTER_DATA replicationPendingSyncs = { .key = "DRA Pending Replication Synchronizations" };
428
+
429
+ static RRDSET *st_dra_replication_pending_syncs = NULL;
430
+ static RRDDIM *rd_dra_replication_pending_syncs = NULL;
431
+ static RRDSET *st_dra_replication_sync_requests = NULL;
432
+ static RRDDIM *rd_dra_replication_sync_requests = NULL;
433
+ static RRDSET *st_dra_replication_sync_objects_remaining = NULL;
434
+ static RRDDIM *rd_dra_replication_sync_objects_remaining = NULL;
435
+
436
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationSyncPending)) {
437
+ goto totalSyncChart;
438
+ }
439
+
440
+ if (unlikely(!st_dra_replication_pending_syncs)) {
441
+ st_dra_replication_pending_syncs = rrdset_create_localhost("ad"
442
+ , "dra_replication_pending_syncs"
443
+ , NULL
444
+ , "replication"
445
+ , "ad.dra_replication_pending_syncs"
446
+ , "DRA replication pending syncs"
447
+ , "syncs"
448
+ , PLUGIN_WINDOWS_NAME
449
+ , "PerflibAD"
450
+ , PRIO_AD_SYNC_PENDING
451
+ , update_every
452
+ , RRDSET_TYPE_LINE);
453
+
454
+ rd_dra_replication_pending_syncs = rrddim_add(st_dra_replication_pending_syncs,
455
+ "pending",
456
+ NULL,
457
+ 1,
458
+ 1,
459
+ RRD_ALGORITHM_ABSOLUTE);
460
+ }
461
+
462
+ rrddim_set_by_pointer(st_dra_replication_pending_syncs,
463
+ rd_dra_replication_pending_syncs,
464
+ (collected_number)replicationSyncPending.current.Data);
465
+ rrdset_done(st_dra_replication_pending_syncs);
466
+
467
+totalSyncChart:
468
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationSyncRequestsTotal)) {
469
+ goto RemainingSyncChart;
470
+ }
471
+
472
+ if (unlikely(!st_dra_replication_sync_requests)) {
473
+ st_dra_replication_sync_requests = rrdset_create_localhost("ad"
474
+ , "dra_replication_sync_requests"
475
+ , NULL
476
+ , "replication"
477
+ , "ad.dra_replication_sync_requests"
478
+ , "DRA replication sync requests"
479
+ , "requests/s"
480
+ , PLUGIN_WINDOWS_NAME
481
+ , "PerflibAD"
482
+ , PRIO_AD_SYNC_TOTAL
483
+ , update_every
484
+ , RRDSET_TYPE_LINE);
485
+
486
+ rd_dra_replication_sync_requests = rrddim_add(st_dra_replication_sync_requests,
487
+ "request",
488
+ NULL,
489
+ 1,
490
+ 1,
491
+ RRD_ALGORITHM_INCREMENTAL);
492
+ }
493
+
494
+ rrddim_set_by_pointer(st_dra_replication_sync_requests,
495
+ rd_dra_replication_sync_requests,
496
+ (collected_number)replicationSyncRequestsTotal.current.Data);
497
+ rrdset_done(st_dra_replication_sync_requests);
498
+
499
+RemainingSyncChart:
500
+ if (!perflibGetObjectCounter(pDataBlock, pObjectType, &replicationPendingSyncs)) {
501
+ return;
502
+ }
503
+
504
+ if (unlikely(!st_dra_replication_sync_objects_remaining)) {
505
+ st_dra_replication_sync_objects_remaining = rrdset_create_localhost("ad"
506
+ , "dra_replication_sync_objects_remaining"
507
+ , NULL
508
+ , "replication"
509
+ , "ad.dra_replication_sync_objects_remaining"
510
+ , "DRA replication full sync objects remaining"
511
+ , "objects"
512
+ , PLUGIN_WINDOWS_NAME
513
+ , "PerflibAD"
514
+ , PRIO_AD_SYNC_OBJECTS_REMAINING
515
+ , update_every
516
+ , RRDSET_TYPE_LINE);
517
+
518
+ rd_dra_replication_sync_objects_remaining = rrddim_add(st_dra_replication_sync_objects_remaining,
519
+ "request",
520
+ NULL,
521
+ 1,
522
+ 1,
523
+ RRD_ALGORITHM_INCREMENTAL);
524
+ }
525
+
526
+ rrddim_set_by_pointer(st_dra_replication_sync_objects_remaining,
527
+ rd_dra_replication_sync_objects_remaining,
528
+ (collected_number)replicationPendingSyncs.current.Data);
529
+ rrdset_done(st_dra_replication_sync_objects_remaining);
530
+}
531
+
532
+static void netdata_ad_service_threads_in_use(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
533
+ static COUNTER_DATA directoryServiceThreads = { .key = "DS Threads in Use" };
534
+
535
+ static RRDSET *st_directory_services_threads = NULL;
536
+ static RRDDIM *rd_directory_services_threads = NULL;
537
+
538
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &directoryServiceThreads)) {
539
+ if (unlikely(!st_directory_services_threads)) {
540
+ st_directory_services_threads = rrdset_create_localhost("ad"
541
+ , "ds_threads"
542
+ , NULL
543
+ , "threads"
544
+ , "ad.ds_threads"
545
+ , "Directory Service threads"
546
+ , "threads"
547
+ , PLUGIN_WINDOWS_NAME
548
+ , "PerflibAD"
549
+ , PRIO_AD_THREADS_IN_USE
550
+ , update_every
551
+ , RRDSET_TYPE_LINE
552
+ );
553
+
554
+ rd_directory_services_threads = rrddim_add(st_directory_services_threads,
555
+ "in_use",
556
+ NULL,
557
+ 1,
558
+ 1,
559
+ RRD_ALGORITHM_ABSOLUTE);
560
+ }
561
+
562
+ rrddim_set_by_pointer(st_directory_services_threads,
563
+ rd_directory_services_threads,
564
+ (collected_number)directoryServiceThreads.current.Data);
565
+ rrdset_done(st_directory_services_threads);
566
+ }
567
+}
568
+
569
+static void netdata_ad_bind(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
570
+ static COUNTER_DATA ldapLastBindTimeSecondsTotal = { .key = "DAP Bind Time" };
571
+ static COUNTER_DATA bindsTotal = { .key = "DS Server Binds/sec" };
572
+
573
+ static RRDSET *st_ldap_last_bind_time_seconds_total = NULL;
574
+ static RRDDIM *rd_ldap_last_bind_time_seconds_total = NULL;
575
+ static RRDSET *st_binds_total = NULL;
576
+ static RRDDIM *rd_binds_total = NULL;
577
+
578
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &ldapLastBindTimeSecondsTotal)) {
579
+ if (unlikely(!st_ldap_last_bind_time_seconds_total)) {
580
+ st_ldap_last_bind_time_seconds_total = rrdset_create_localhost("ad"
581
+ , "ldap_last_bind_time"
582
+ , NULL
583
+ , "bind"
584
+ , "ad.ldap_last_bind_time"
585
+ , "LDAP last successful bind time"
586
+ , "seconds"
587
+ , PLUGIN_WINDOWS_NAME
588
+ , "PerflibAD"
589
+ , PRIO_AD_BIND_TIME
590
+ , update_every
591
+ , RRDSET_TYPE_LINE
592
+ );
593
+
594
+ rd_ldap_last_bind_time_seconds_total = rrddim_add(st_ldap_last_bind_time_seconds_total,
595
+ "last_bind",
596
+ NULL,
597
+ 1,
598
+ 1,
599
+ RRD_ALGORITHM_ABSOLUTE);
600
+ }
601
+
602
+ rrddim_set_by_pointer(st_ldap_last_bind_time_seconds_total,
603
+ rd_ldap_last_bind_time_seconds_total,
604
+ (collected_number)ldapLastBindTimeSecondsTotal.current.Data);
605
+ rrdset_done(st_ldap_last_bind_time_seconds_total);
606
+ }
607
+
608
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &bindsTotal)) {
609
+ if (unlikely(!st_binds_total)) {
610
+ st_binds_total = rrdset_create_localhost("ad"
611
+ , "binds"
612
+ , NULL
613
+ , "bind"
614
+ , "ad.binds"
615
+ , "Successful binds"
616
+ , "bind/s"
617
+ , PLUGIN_WINDOWS_NAME
618
+ , "PerflibAD"
619
+ , PRIO_AD_BIND_TOTAL
620
+ , update_every
621
+ , RRDSET_TYPE_LINE);
622
+
623
+ rd_binds_total = rrddim_add(st_binds_total,
624
+ "binds",
625
+ NULL,
626
+ 1,
627
+ 1,
628
+ RRD_ALGORITHM_INCREMENTAL);
629
+ }
630
+
631
+ rrddim_set_by_pointer(st_binds_total,
632
+ rd_binds_total,
633
+ (collected_number)bindsTotal.current.Data);
634
+ rrdset_done(st_binds_total);
635
+ }
636
+}
637
+
638
+static void netdata_ad_atq(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
639
+ static COUNTER_DATA atqAverageRequestLatency = { .key = "ATQ Request Latency" };
640
+ //static COUNTER_DATA atqOutstandingRequests = { .key = "ATQ Outstanding Queued Requests" };
641
+
642
+ static RRDSET *st_atq_average_request_latency = NULL;
643
+ static RRDDIM *rd_atq_average_request_latency = NULL;
644
+ /* TODO: Check why values are growing forever in our setup
645
+ static RRDSET *st_atq_outstanding_requests = NULL;
646
+ static RRDDIM *rd_atq_outstanding_requests = NULL;
647
+ */
648
+
649
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &atqAverageRequestLatency)) {
650
+ if (unlikely(!st_atq_average_request_latency)) {
651
+ st_atq_average_request_latency = rrdset_create_localhost("ad"
652
+ , "atq_average_request_latency"
653
+ , NULL
654
+ , "queue"
655
+ , "ad.atq_average_request_latency"
656
+ , "Average request processing time"
657
+ , "seconds"
658
+ , PLUGIN_WINDOWS_NAME
659
+ , "PerflibAD"
660
+ , PRIO_AD_AVG_REQUEST_LATENCY
661
+ , update_every
662
+ , RRDSET_TYPE_LINE
663
+ );
664
+
665
+ rd_atq_average_request_latency = rrddim_add(st_atq_average_request_latency,
666
+ "time",
667
+ NULL,
668
+ 1,
669
+ 1000,
670
+ RRD_ALGORITHM_ABSOLUTE);
671
+ }
672
+
673
+ rrddim_set_by_pointer(st_atq_average_request_latency,
674
+ rd_atq_average_request_latency,
675
+ (collected_number)atqAverageRequestLatency.current.Data);
676
+ rrdset_done(st_atq_average_request_latency);
677
+ }
678
+
679
+ /*
680
+ if(perflibGetObjectCounter(pDataBlock, pObjectType, &atqOutstandingRequests)) {
681
+ if (unlikely(!st_atq_outstanding_requests)) {
682
+ st_atq_outstanding_requests = rrdset_create_localhost("ad"
683
+ , "atq_outstanding_requests"
684
+ , NULL
685
+ , "queue"
686
+ , "ad.atq_outstanding_requests"
687
+ , "Outstanding requests"
688
+ , "requests"
689
+ , PLUGIN_WINDOWS_NAME
690
+ , "PerflibAD"
691
+ , PRIO_AD_OUTSTANDING_REQUEST
692
+ , update_every
693
+ , RRDSET_TYPE_LINE);
694
+
695
+ rd_atq_outstanding_requests = rrddim_add(st_atq_outstanding_requests,
696
+ "outstanding",
697
+ NULL,
698
+ 1,
699
+ 1,
700
+ RRD_ALGORITHM_ABSOLUTE);
701
+ }
702
+
703
+ rrddim_set_by_pointer(st_atq_outstanding_requests,
704
+ rd_atq_outstanding_requests,
705
+ (collected_number)atqOutstandingRequests.current.Data);
706
+ rrdset_done(st_atq_outstanding_requests);
707
+ } */
708
+}
709
+
710
+static void netdata_ad_op_total(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) {
711
+ static COUNTER_DATA databaseAddsPerSec = { .key = "Database adds/sec" };
712
+ static COUNTER_DATA databaseDeletesPerSec = { .key = "Database deletes/sec" };
713
+ static COUNTER_DATA databaseModifiesPerSec = { .key = "Database modifys/sec" };
714
+ static COUNTER_DATA databaseRecyclesPerSec = { .key = "Database recycles/sec" };
715
+
716
+ static RRDSET *st_database_operation_total = NULL;
717
+ static RRDDIM *rd_database_operation_total_add = NULL;
718
+ static RRDDIM *rd_database_operation_total_delete = NULL;
719
+ static RRDDIM *rd_database_operation_total_modify = NULL;
720
+ static RRDDIM *rd_database_operation_total_recycle = NULL;
721
+
722
+ perflibGetObjectCounter(pDataBlock, pObjectType, &databaseAddsPerSec);
723
+ perflibGetObjectCounter(pDataBlock, pObjectType, &databaseDeletesPerSec);
724
+ perflibGetObjectCounter(pDataBlock, pObjectType, &databaseModifiesPerSec);
725
+ perflibGetObjectCounter(pDataBlock, pObjectType, &databaseRecyclesPerSec);
726
+
727
+ if (unlikely(!st_database_operation_total)) {
728
+ st_database_operation_total = rrdset_create_localhost("ad"
729
+ , "database_operations"
730
+ , NULL
731
+ , "database"
732
+ , "ad.database_operations"
733
+ , "AD database operations"
734
+ , "operations/s"
735
+ , PLUGIN_WINDOWS_NAME
736
+ , "PerflibAD"
737
+ , PRIO_AD_OPERATIONS_TOTAL
738
+ , update_every
739
+ , RRDSET_TYPE_LINE);
740
+
741
+ rd_database_operation_total_add = rrddim_add(st_database_operation_total,
742
+ "add",
743
+ NULL,
744
+ 1,
745
+ 1,
746
+ RRD_ALGORITHM_INCREMENTAL);
747
+
748
+ rd_database_operation_total_delete = rrddim_add(st_database_operation_total,
749
+ "delete",
750
+ NULL,
751
+ 1,
752
+ 1,
753
+ RRD_ALGORITHM_INCREMENTAL);
754
+
755
+ rd_database_operation_total_modify = rrddim_add(st_database_operation_total,
756
+ "modify",
757
+ NULL,
758
+ 1,
759
+ 1,
760
+ RRD_ALGORITHM_INCREMENTAL);
761
+
762
+ rd_database_operation_total_recycle = rrddim_add(st_database_operation_total,
763
+ "recycle",
764
+ NULL,
765
+ 1,
766
+ 1,
767
+ RRD_ALGORITHM_INCREMENTAL);
768
+ }
769
+
770
+ rrddim_set_by_pointer(st_database_operation_total,
771
+ rd_database_operation_total_add,
772
+ (collected_number)databaseAddsPerSec.current.Data);
773
+
774
+ rrddim_set_by_pointer(st_database_operation_total,
775
+ rd_database_operation_total_delete,
776
+ (collected_number)databaseDeletesPerSec.current.Data);
777
+
778
+ rrddim_set_by_pointer(st_database_operation_total,
779
+ rd_database_operation_total_modify,
780
+ (collected_number)databaseModifiesPerSec.current.Data);
781
+
782
+ rrddim_set_by_pointer(st_database_operation_total,
783
+ rd_database_operation_total_recycle,
784
+ (collected_number)databaseRecyclesPerSec.current.Data);
785
+
786
+ rrdset_done(st_database_operation_total);
787
+
788
+}
789
+
790
+static bool do_AD(PERF_DATA_BLOCK *pDataBlock, int update_every) {
791
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "DirectoryServices");
792
+ if (!pObjectType)
793
+ return false;
794
+
795
+ static void (*doAD[])(PERF_DATA_BLOCK *, PERF_OBJECT_TYPE *, int) = {
796
+ netdata_ad_directory,
797
+ netdata_ad_cache_lookups,
798
+ netdata_ad_properties,
799
+ netdata_ad_compressed_traffic,
800
+ netdata_ad_sync,
801
+ netdata_ad_cache_hits,
802
+ netdata_ad_service_threads_in_use,
803
+ netdata_ad_bind,
804
+ netdata_ad_searches,
805
+ netdata_ad_atq,
806
+ netdata_ad_op_total,
807
+
808
+ // This must be the end
809
+ NULL
810
+ };
811
+
812
+ for (int i = 0; doAD[i]; i++)
813
+ doAD[i](pDataBlock, pObjectType, update_every);
814
+
815
+ return true;
816
+}
817
+
818
+int do_PerflibAD(int update_every, usec_t dt __maybe_unused) {
819
+ static bool initialized = false;
820
+
821
+ if(unlikely(!initialized)) {
822
+ initialize();
823
+ initialized = true;
824
+ }
825
+
826
+ DWORD id = RegistryFindIDByName("DirectoryServices");
827
+ if(id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
828
+ return -1;
829
+
830
+ PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
831
+ if(!pDataBlock) return -1;
832
+
833
+ do_AD(pDataBlock, update_every);
834
+
835
+ return 0;
836
+}
src/collectors/windows.plugin/windows_plugin.c
+1
@@ -33,6 +33,7 @@ static struct proc_module {
33
{.name = "PerflibMSSQL", .dim = "PerflibMSSQL", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibMSSQL},
34
35
{.name = "PerflibNetFramework", .dim = "PerflibNetFramework", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibNetFramework},
36
+ {.name = "PerflibAD", .dim = "PerflibAD", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibAD},
37
38
// the terminator of this array
39
{.name = NULL, .dim = NULL, .func = NULL}
src/collectors/windows.plugin/windows_plugin.h
+20
-1
@@ -28,6 +28,7 @@ int do_PerflibThermalZone(int update_every, usec_t dt);
28
int do_PerflibWebService(int update_every, usec_t dt);
29
int do_PerflibMSSQL(int update_every, usec_t dt);
30
int do_PerflibNetFramework(int update_every, usec_t dt);
31
+int do_PerflibAD(int update_every, usec_t dt);
32
33
enum PERFLIB_PRIO {
34
PRIO_WEBSITE_IIS_REQUESTS_RATE = 21000, // PRIO selected, because APPS is using 20YYY
@@ -97,7 +98,25 @@ enum PERFLIB_PRIO {
98
PRIO_NETFRAMEWORK_CLR_LOADING_APP_DOMAINS_UNLOADED,
99
PRIO_NETFRAMEWORK_CLR_LOADING_ASSEMBLIES_LOADED,
100
PRIO_NETFRAMEWORK_CLR_LOADING_CLASSES_LOADED,
100
- PRIO_NETFRAMEWORK_CLR_LOADING_CLASS_LOAD_FAILURE
101
+ PRIO_NETFRAMEWORK_CLR_LOADING_CLASS_LOAD_FAILURE,
102
+
103
+ PRIO_AD_OPERATIONS_TOTAL,
104
+ PRIO_AD_DIROPERATIONS_TOTAL,
105
+ PRIO_AD_CACHE_LOOKUP_TOTAL,
106
+ PRIO_AD_CACHE_HITS_TOTAL,
107
+ PRIO_AD_REPLICATION_INTERSITE_COMPRESSED,
108
+ PRIO_AD_REPLICATION_INTRASITE_COMPRESSED,
109
+ PRIO_AD_SYNC_OBJECTS_REMAINING,
110
+ PRIO_AD_REPLICATION_PROPERTY_UPDATED,
111
+ PRIO_AD_REPLICATION_PROPERTY_FILTERED,
112
+ PRIO_AD_SYNC_PENDING,
113
+ PRIO_AD_SYNC_TOTAL,
114
+ PRIO_AD_THREADS_IN_USE,
115
+ PRIO_AD_BIND_TIME,
116
+ PRIO_AD_BIND_TOTAL,
117
+ PRIO_AD_LDAP_SEARCHES_TOTAL,
118
+ PRIO_AD_AVG_REQUEST_LATENCY,
119
+ PRIO_AD_OUTSTANDING_REQUEST
120
};
121
122
int do_PerflibHyperV(int update_every, usec_t dt);