@cryptotaxi247 / netdata-1 / commits / 3badfe6bd

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);