@cryptotaxi247 / netdata / commits / a2fa59995

Monitor Exchange Server (Window.plugin) (#20454)

thiagoftsm committed Jun 17, 2025 at 14:45 UTC a2fa5999550ab0fdd8e6e3d543ef93c24a464255
6 files changed +1593 -1
CMakeLists.txt
+1
@@ -2060,6 +2060,7 @@ set(WINDOWS_PLUGIN_FILES
2060 src/collectors/windows.plugin/perflib-web-service.c
2061 src/collectors/windows.plugin/perflib-services.c
2062 src/collectors/windows.plugin/perflib-hyperv.c
2063 + src/collectors/windows.plugin/perflib-exchange.c
2064 )
2065
2066 set(PROC_PLUGIN_FILES
src/collectors/windows.plugin/README.md
+1
@@ -31,6 +31,7 @@ To change a setting, remove the comment symbol (`#`) from the beginning of the l
31 # PerflibAD = yes
32 # PerflibADCS = yes
33 # PerflibADFS = yes
34 + # PerflibExchange = yes
35 ```
36
37 ## Microsoft SQL Server Integration
src/collectors/windows.plugin/metadata.yaml
+265
@@ -3094,3 +3094,268 @@ modules:
3094 - name: pause_pending
3095 - name: paused
3096 - name: unknown
3097 + - meta:
3098 + plugin_name: windows.plugin
3099 + module_name: PerflibExchange
3100 + monitored_instance:
3101 + name: MS Exchange
3102 + link: "https://www.microsoft.com/en-us/microsoft-365/exchange/email"
3103 + categories:
3104 + - data-collection.windows-systems
3105 + icon_filename: "exchange.svg"
3106 + related_resources:
3107 + integrations:
3108 + list: []
3109 + info_provided_to_referring_integrations:
3110 + description: ""
3111 + keywords:
3112 + - windows
3113 + - microsoft
3114 + - exchange
3115 + - mail
3116 + most_popular: false
3117 + overview:
3118 + data_collection:
3119 + metrics_description: |
3120 + This collector monitors Microsoft Exchange.
3121 + method_description: |
3122 + It queries different Exchange objects from Perflib in order to gather the metrics.
3123 + supported_platforms:
3124 + include: ["windows"]
3125 + exclude: []
3126 + multi_instance: false
3127 + additional_permissions:
3128 + description: ""
3129 + default_behavior:
3130 + auto_detection:
3131 + description: |
3132 + The collector automatically detects all of the metrics, no further configuration is required.
3133 + limits:
3134 + description: ""
3135 + performance_impact:
3136 + description: ""
3137 + setup:
3138 + prerequisites:
3139 + list: []
3140 + configuration:
3141 + file:
3142 + name: "netdata.conf"
3143 + section_name: "[plugin:windows]"
3144 + description: "The Netdata main configuration file"
3145 + options:
3146 + description: ""
3147 + folding:
3148 + title: "Config option"
3149 + enabled: false
3150 + list:
3151 + - name: PerflibExchange
3152 + description: An option to enable or disable the data collection.
3153 + default_value: yes
3154 + required: false
3155 + examples:
3156 + folding:
3157 + enabled: true
3158 + title: ""
3159 + list: []
3160 + troubleshooting:
3161 + problems:
3162 + list: []
3163 + alerts: []
3164 + metrics:
3165 + folding:
3166 + title: Metrics
3167 + enabled: false
3168 + description: ""
3169 + availability: []
3170 + scopes:
3171 + - name: Windows Exchange
3172 + description: "These metrics refer to Windows Exchange."
3173 + labels: []
3174 + metrics:
3175 + - name: exchange.transport_queues_active_mail_box_delivery
3176 + description: Active Mailbox Delivery Queue length.
3177 + unit: messages
3178 + chart_type: line
3179 + dimensions:
3180 + - name: active
3181 + - name: exchange.transport_queues_external_active_remote_delivery
3182 + description: External Active Remote Delivery Queue length.
3183 + unit: messages
3184 + chart_type: line
3185 + dimensions:
3186 + - name: active
3187 + - name: exchange.transport_queues_internal_active_remote_delivery
3188 + description: Internal Active Remote Delivery Queue length.
3189 + unit: messages
3190 + chart_type: line
3191 + dimensions:
3192 + - name: active
3193 + - name: exchange.transport_queues_unreachable
3194 + description: Unreachable Queue length.
3195 + unit: messages
3196 + chart_type: line
3197 + dimensions:
3198 + - name: unreachable
3199 + - name: exchange.transport_queues_poison
3200 + description: Poison Queue Length.
3201 + unit: messages
3202 + chart_type: line
3203 + dimensions:
3204 + - name: unreachable
3205 + - name: exchange.activesync_ping_cmds_pending
3206 + description: Ping commands pending in queue.
3207 + unit: commands
3208 + chart_type: line
3209 + dimensions:
3210 + - name: pending
3211 + - name: exchange.activesync_requests
3212 + description: HTTP requests received from ASP.NET.
3213 + unit: requests/s
3214 + chart_type: line
3215 + dimensions:
3216 + - name: received
3217 + - name: exchange.activesync_sync_cmds
3218 + description: Sync commands processed.
3219 + unit: commands/s
3220 + chart_type: line
3221 + dimensions:
3222 + - name: processed
3223 + - name: exchange.rpc_active_user_count
3224 + description: Active unique users in the last 2 minutes.
3225 + unit: users
3226 + chart_type: line
3227 + dimensions:
3228 + - name: active
3229 + - name: exchange.rpc_avg_latency
3230 + description: Average latency.
3231 + unit: seconds
3232 + chart_type: line
3233 + dimensions:
3234 + - name: latency
3235 + - name: exchange.rpc_connection_count
3236 + description: Client connections.
3237 + unit: connections
3238 + chart_type: line
3239 + dimensions:
3240 + - name: connections
3241 + - name: exchange.rpc_requests
3242 + description: Clients requests currently being processed.
3243 + unit: requests
3244 + chart_type: line
3245 + dimensions:
3246 + - name: processed
3247 + - name: exchange.rpc_active_user
3248 + description: Active unique users in the last 2 minutes.
3249 + unit: users
3250 + chart_type: line
3251 + dimensions:
3252 + - name: users
3253 + - name: exchange.rpc_connection
3254 + description: Client connections.
3255 + unit: connections
3256 + chart_type: line
3257 + dimensions:
3258 + - name: connections
3259 + - name: exchange.rpc_operations
3260 + description: RPC operations.
3261 + unit: operations/s
3262 + chart_type: line
3263 + dimensions:
3264 + - name: operations
3265 + - name: exchange.rpc_user_count
3266 + description: RPC users.
3267 + unit: users
3268 + chart_type: line
3269 + dimensions:
3270 + - name: users
3271 + - name: exchange.owa_current_unique_users
3272 + description: Unique users currently logged on to Outlook Web App.
3273 + unit: users
3274 + chart_type: line
3275 + dimensions:
3276 + - name: logged-in
3277 + - name: exchange.owa_requests_total
3278 + description: Requests handled by Outlook Web App.
3279 + unit: requests/s
3280 + chart_type: line
3281 + dimensions:
3282 + - name: handled
3283 + - name: exchange.workload_active_tasks
3284 + description: Workload active tasks.
3285 + unit: tasks
3286 + chart_type: line
3287 + dimensions:
3288 + - name: active
3289 + - name: exchange.workload_completed_tasks
3290 + description: Workload completed tasks.
3291 + unit: tasks/s
3292 + chart_type: line
3293 + dimensions:
3294 + - name: completed
3295 + - name: exchange.workload_queued_tasks
3296 + description: Workload queued tasks.
3297 + unit: tasks/s
3298 + chart_type: line
3299 + dimensions:
3300 + - name: queued
3301 + - name: exchange.workload_yielded_tasks
3302 + description: Workload yielded tasks.
3303 + unit: tasks/s
3304 + chart_type: line
3305 + dimensions:
3306 + - name: yielded
3307 + - name: exchange.workload_activity_status
3308 + description: Workload activity status
3309 + unit: status
3310 + chart_type: line
3311 + dimensions:
3312 + - name: active
3313 + - name: paused
3314 + - name: exchange.http_proxy_avg_auth_latency
3315 + description: Average time spent authenticating CAS requests.
3316 + unit: seconds
3317 + chart_type: line
3318 + dimensions:
3319 + - name: latency
3320 + - name: exchange.http_proxy_avg_cas_processing_latency_sec
3321 + description: Average latency (sec) of CAS processing time.
3322 + unit: seconds
3323 + chart_type: line
3324 + dimensions:
3325 + - name: latency
3326 + - name: exchange.http_proxy_mailbox_proxy_failure_rate
3327 + description: Percentage of failures between this CAS and MBX servers.
3328 + unit: seconds
3329 + chart_type: line
3330 + dimensions:
3331 + - name: failures
3332 + - name: exchange.http_proxy_mailbox_server_locator_avg_latency_sec
3333 + description: Average latency of MailboxServerLocator web service calls.
3334 + unit: seconds
3335 + chart_type: line
3336 + dimensions:
3337 + - name: latency
3338 + - name: exchange.http_proxy_outstanding_proxy_requests
3339 + description: Concurrent outstanding proxy requests.
3340 + unit: seconds
3341 + chart_type: line
3342 + dimensions:
3343 + - name: requests
3344 + - name: exchange.http_proxy_requests
3345 + description: Number of proxy requests processed each second.
3346 + unit: seconds
3347 + chart_type: line
3348 + dimensions:
3349 + - name: requests
3350 + - name: exchange.autodiscover_requests
3351 + description: Autodiscover service requests processed
3352 + unit: requests/s
3353 + chart_type: line
3354 + dimensions:
3355 + - name: processed
3356 + - name: exchange.avail_service_requests
3357 + description: Requests serviced
3358 + unit: requests/s
3359 + chart_type: line
3360 + dimensions:
3361 + - name: serviced
src/collectors/windows.plugin/perflib-exchange.c new
+1286
@@ -0,0 +1,1286 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#include "windows_plugin.h"
4 +#include "windows-internals.h"
5 +
6 +struct exchange_proxy {
7 + RRDSET *st_exchange_http_proxy_avg_auth_latency;
8 + RRDSET *st_exchange_http_proxy_avg_cas_processing_latency;
9 + RRDSET *st_exchange_http_proxy_mailbox_proxy_failure;
10 + RRDSET *st_exchange_http_proxy_server_location_avg_latency;
11 + RRDSET *st_exchange_http_proxy_outstanding_proxy_requests;
12 + RRDSET *st_exchange_http_proxy_requests_total;
13 +
14 + RRDDIM *rd_exchange_http_proxy_avg_auth_latency;
15 + RRDDIM *rd_exchange_http_proxy_avg_cas_processing_latency;
16 + RRDDIM *rd_exchange_http_proxy_mailbox_proxy_failure;
17 + RRDDIM *rd_exchange_http_proxy_server_location_avg_latency;
18 + RRDDIM *rd_exchange_http_proxy_outstanding_proxy_requests;
19 + RRDDIM *rd_exchange_http_proxy_requests_total;
20 +
21 + COUNTER_DATA exchangeProxyAvgAuthLatency;
22 + COUNTER_DATA exchangeProxyAvgCasProcessingLatency;
23 + COUNTER_DATA exchangeProxyMailboxProxyFailure;
24 + COUNTER_DATA exchangeProxyMailboxServerLocator;
25 + COUNTER_DATA exchangeProxyOutstandingProxy;
26 + COUNTER_DATA exchangeProxyRequestsTotal;
27 +};
28 +
29 +struct exchange_workload {
30 + RRDSET *st_exchange_workload_active_tasks;
31 + RRDSET *st_exchange_workload_complete_tasks;
32 + RRDSET *st_exchange_workload_queued_tasks;
33 + RRDSET *st_exchange_workload_yielded_tasks;
34 + RRDSET *st_exchange_workload_activity_status;
35 +
36 + RRDDIM *rd_exchange_workload_active_tasks;
37 + RRDDIM *rd_exchange_workload_complete_tasks;
38 + RRDDIM *rd_exchange_workload_queued_tasks;
39 + RRDDIM *rd_exchange_workload_yielded_tasks;
40 + RRDDIM *rd_exchange_workload_activity_active_status;
41 + RRDDIM *rd_exchange_workload_activity_paused_status;
42 +
43 + COUNTER_DATA exchangeWorkloadActiveTasks;
44 + COUNTER_DATA exchangeWorkloadCompleteTasks;
45 + COUNTER_DATA exchangeWorkloadQueueTasks;
46 + COUNTER_DATA exchangeWorkloadYieldedTasks;
47 + COUNTER_DATA exchangeWorkloadActivityStatus;
48 +};
49 +
50 +struct exchange_queue {
51 + RRDSET *st_exchange_queue_active_mailbox;
52 + RRDSET *st_exchange_queue_external_active_remote_delivery;
53 + RRDSET *st_exchange_queue_internal_active_remote_delivery;
54 + RRDSET *st_exchange_queue_unreachable;
55 + RRDSET *st_exchange_queue_poison;
56 +
57 + RRDDIM *rd_exchange_queue_active_mailbox;
58 + RRDDIM *rd_exchange_queue_external_active_remote_delivery;
59 + RRDDIM *rd_exchange_queue_internal_active_remote_delivery;
60 + RRDDIM *rd_exchange_queue_unreachable;
61 + RRDDIM *rd_exchange_queue_poison;
62 +
63 + COUNTER_DATA exchangeTransportQueuesActiveMailboxDelivery;
64 + COUNTER_DATA exchangeTransportQueuesExternalActiveRemoteDelivery;
65 + COUNTER_DATA exchangeTransportQueuesInternalActiveRemoteDeliery;
66 + COUNTER_DATA exchangeTransportQueuesUnreachable;
67 + COUNTER_DATA exchangeTransportQueuesPoison;
68 +};
69 +
70 +DICTIONARY *exchange_proxies;
71 +DICTIONARY *exchange_workloads;
72 +DICTIONARY *exchange_queues;
73 +
74 +static void exchange_proxy_initialize_variables(struct exchange_proxy *ep)
75 +{
76 + ep->exchangeProxyAvgAuthLatency.key = "Average Authentication Latency";
77 + ep->exchangeProxyAvgCasProcessingLatency.key = "Average ClientAccess Server Processing Latency";
78 + ep->exchangeProxyMailboxProxyFailure.key = "Mailbox Server Proxy Failure Rate";
79 + ep->exchangeProxyMailboxServerLocator.key = "MailboxServerLocator Average Latency (Moving Average)";
80 + ep->exchangeProxyOutstandingProxy.key = "Outstanding Proxy Requests";
81 + ep->exchangeProxyRequestsTotal.key = "Proxy Requests/Sec";
82 +}
83 +
84 +static void
85 +dict_exchange_insert_proxy_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
86 +{
87 + struct exchange_proxy *ep = value;
88 +
89 + exchange_proxy_initialize_variables(ep);
90 +}
91 +
92 +static void exchange_workload_initialize_variables(struct exchange_workload *ew)
93 +{
94 + ew->exchangeWorkloadActiveTasks.key = "ActiveTasks";
95 + ew->exchangeWorkloadCompleteTasks.key = "CompletedTasks";
96 + ew->exchangeWorkloadQueueTasks.key = "QueuedTasks";
97 + ew->exchangeWorkloadYieldedTasks.key = "YieldedTasks";
98 + ew->exchangeWorkloadActivityStatus.key = "Active";
99 +}
100 +
101 +static void
102 +dict_exchange_insert_worload_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
103 +{
104 + struct exchange_workload *ew = value;
105 +
106 + exchange_workload_initialize_variables(ew);
107 +}
108 +
109 +static void exchange_queue_initialize_variables(struct exchange_queue *eq)
110 +{
111 + eq->exchangeTransportQueuesActiveMailboxDelivery.key = "Active Mailbox Delivery Queue Length";
112 + eq->exchangeTransportQueuesExternalActiveRemoteDelivery.key = "External Active Remote Delivery Queue Length";
113 + eq->exchangeTransportQueuesInternalActiveRemoteDeliery.key = "Internal Active Remote Delivery Queue Length";
114 + eq->exchangeTransportQueuesPoison.key = "Poison Queue Length";
115 + eq->exchangeTransportQueuesUnreachable.key = "Unreachable Queue Length";
116 +}
117 +
118 +static void
119 +dict_exchange_insert_queue_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
120 +{
121 + struct exchange_queue *eq = value;
122 +
123 + exchange_queue_initialize_variables(eq);
124 +}
125 +
126 +static void initialize(void)
127 +{
128 + exchange_proxies = dictionary_create_advanced(
129 + DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct exchange_proxy));
130 + dictionary_register_insert_callback(exchange_proxies, dict_exchange_insert_proxy_cb, NULL);
131 +
132 + exchange_workloads = dictionary_create_advanced(
133 + DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct exchange_workload));
134 + dictionary_register_insert_callback(exchange_workloads, dict_exchange_insert_worload_cb, NULL);
135 +
136 + exchange_queues = dictionary_create_advanced(
137 + DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct exchange_queue));
138 + dictionary_register_insert_callback(exchange_queues, dict_exchange_insert_queue_cb, NULL);
139 +}
140 +
141 +static void netdata_exchange_owa_current_unique_users(COUNTER_DATA *value, int update_every)
142 +{
143 + static RRDSET *st_exchange_owa_unique_users = NULL;
144 + static RRDDIM *rd_exchange_owa_unique_users = NULL;
145 +
146 + if (unlikely(!st_exchange_owa_unique_users)) {
147 + st_exchange_owa_unique_users = rrdset_create_localhost(
148 + "exchange",
149 + "owa_current_unique_users",
150 + NULL,
151 + "owa",
152 + "exchange.owa_current_unique_users",
153 + "Unique users currently logged on to Outlook Web App",
154 + "users",
155 + PLUGIN_WINDOWS_NAME,
156 + "PerflibExchange",
157 + PRIO_EXCHANGE_OWA_UNIQUE_USERS,
158 + update_every,
159 + RRDSET_TYPE_LINE);
160 +
161 + rd_exchange_owa_unique_users =
162 + rrddim_add(st_exchange_owa_unique_users, "logged-in", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
163 + }
164 +
165 + rrddim_set_by_pointer(
166 + st_exchange_owa_unique_users, rd_exchange_owa_unique_users, (collected_number)value->current.Data);
167 + rrdset_done(st_exchange_owa_unique_users);
168 +}
169 +
170 +static void netdata_exchange_owa_request_total(COUNTER_DATA *value, int update_every)
171 +{
172 + static RRDSET *st_exchange_owa_request_total = NULL;
173 + static RRDDIM *rd_exchange_owa_request_total = NULL;
174 +
175 + if (unlikely(!st_exchange_owa_request_total)) {
176 + st_exchange_owa_request_total = rrdset_create_localhost(
177 + "exchange",
178 + "owa_requests_total",
179 + NULL,
180 + "owa",
181 + "exchange.owa_requests_total",
182 + "Requests handled by Outlook Web App.",
183 + "requests/s",
184 + PLUGIN_WINDOWS_NAME,
185 + "PerflibExchange",
186 + PRIO_EXCHANGE_OWA_REQUESTS_TOTAL,
187 + update_every,
188 + RRDSET_TYPE_LINE);
189 +
190 + rd_exchange_owa_request_total =
191 + rrddim_add(st_exchange_owa_request_total, "handled", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
192 + }
193 +
194 + rrddim_set_by_pointer(
195 + st_exchange_owa_request_total, rd_exchange_owa_request_total, (collected_number)value->current.Data);
196 + rrdset_done(st_exchange_owa_request_total);
197 +}
198 +
199 +static void netdata_exchange_owa(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
200 +{
201 + static COUNTER_DATA exchangeOWACurrentUniqueUser = {.key = "Current Unique Users"};
202 + static COUNTER_DATA exchangeOWARequestsTotal = {.key = "Requests/sec"};
203 +
204 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeOWACurrentUniqueUser))
205 + netdata_exchange_owa_current_unique_users(&exchangeOWACurrentUniqueUser, update_every);
206 +
207 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeOWARequestsTotal))
208 + netdata_exchange_owa_request_total(&exchangeOWARequestsTotal, update_every);
209 +}
210 +
211 +static void netdata_exchange_active_ping_cmd(COUNTER_DATA *value, int update_every)
212 +{
213 + static RRDSET *st_exchange_active_ping_cmds = NULL;
214 + static RRDDIM *rd_exchange_active_ping_cmds = NULL;
215 +
216 + if (unlikely(!st_exchange_active_ping_cmds)) {
217 + st_exchange_active_ping_cmds = rrdset_create_localhost(
218 + "exchange",
219 + "activesync_ping_cmds_pending",
220 + NULL,
221 + "sync",
222 + "exchange.activesync_ping_cmds_pending",
223 + "Ping commands pending in queue.",
224 + "commands",
225 + PLUGIN_WINDOWS_NAME,
226 + "PerflibExchange",
227 + PRIO_EXCHANGE_ACTIVE_SYNC_PING_CMDS_PENDING,
228 + update_every,
229 + RRDSET_TYPE_LINE);
230 +
231 + rd_exchange_active_ping_cmds =
232 + rrddim_add(st_exchange_active_ping_cmds, "pending", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
233 + }
234 +
235 + rrddim_set_by_pointer(
236 + st_exchange_active_ping_cmds, rd_exchange_active_ping_cmds, (collected_number)value->current.Data);
237 + rrdset_done(st_exchange_active_ping_cmds);
238 +}
239 +
240 +static void netdata_exchange_active_requests(COUNTER_DATA *value, int update_every)
241 +{
242 + static RRDSET *st_exchange_received_requests = NULL;
243 + static RRDDIM *rd_exchange_received_requests = NULL;
244 +
245 + if (unlikely(!st_exchange_received_requests)) {
246 + st_exchange_received_requests = rrdset_create_localhost(
247 + "exchange",
248 + "activesync_requests",
249 + NULL,
250 + "sync",
251 + "exchange.activesync_requests",
252 + "HTTP requests received from ASP.NET.",
253 + "requests/s",
254 + PLUGIN_WINDOWS_NAME,
255 + "PerflibExchange",
256 + PRIO_EXCHANGE_ACTIVE_SYNC_REQUESTS,
257 + update_every,
258 + RRDSET_TYPE_LINE);
259 +
260 + rd_exchange_received_requests =
261 + rrddim_add(st_exchange_received_requests, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
262 + }
263 +
264 + rrddim_set_by_pointer(
265 + st_exchange_received_requests, rd_exchange_received_requests, (collected_number)value->current.Data);
266 + rrdset_done(st_exchange_received_requests);
267 +}
268 +
269 +static void netdata_exchange_sync_cmds(COUNTER_DATA *value, int update_every)
270 +{
271 + static RRDSET *st_exchange_sync_cmds = NULL;
272 + static RRDDIM *rd_exchange_sync_cmds = NULL;
273 +
274 + if (unlikely(!st_exchange_sync_cmds)) {
275 + st_exchange_sync_cmds = rrdset_create_localhost(
276 + "exchange",
277 + "activesync_sync_cmds",
278 + NULL,
279 + "sync",
280 + "exchange.activesync_sync_cmds",
281 + "Sync commands processed.",
282 + "commands/s",
283 + PLUGIN_WINDOWS_NAME,
284 + "PerflibExchange",
285 + PRIO_EXCHANGE_ACTIVE_SYNC_CMDS,
286 + update_every,
287 + RRDSET_TYPE_LINE);
288 +
289 + rd_exchange_sync_cmds = rrddim_add(st_exchange_sync_cmds, "processed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
290 + }
291 +
292 + rrddim_set_by_pointer(st_exchange_sync_cmds, rd_exchange_sync_cmds, (collected_number)value->current.Data);
293 + rrdset_done(st_exchange_sync_cmds);
294 +}
295 +
296 +static void netdata_exchange_active_sync(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
297 +{
298 + static COUNTER_DATA exchangePingCommands = {.key = "Ping Commands Pending"};
299 + static COUNTER_DATA exchangeSyncCommands = {.key = "Sync Commands/sec"};
300 + static COUNTER_DATA exchangeActiveRequests = {.key = "Requests/sec"};
301 +
302 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangePingCommands))
303 + netdata_exchange_active_ping_cmd(&exchangePingCommands, update_every);
304 +
305 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeSyncCommands))
306 + netdata_exchange_sync_cmds(&exchangeSyncCommands, update_every);
307 +
308 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeActiveRequests))
309 + netdata_exchange_active_requests(&exchangeActiveRequests, update_every);
310 +}
311 +
312 +static void netdata_exchange_auto_discover(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
313 +{
314 + static COUNTER_DATA exchangeAutoDiscoverRequestsTotal = {.key = "Requests/sec"};
315 +
316 + static RRDSET *st_exchange_auto_discover_request_total = NULL;
317 + static RRDDIM *rd_exchange_auto_discover_request_total = NULL;
318 +
319 + if (!perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeAutoDiscoverRequestsTotal)) {
320 + return;
321 + }
322 +
323 + if (unlikely(!st_exchange_auto_discover_request_total)) {
324 + st_exchange_auto_discover_request_total = rrdset_create_localhost(
325 + "exchange",
326 + "autodiscover_requests",
327 + NULL,
328 + "requests",
329 + "exchange.autodiscover_requests",
330 + "Autodiscover service requests processed.",
331 + "requests/s",
332 + PLUGIN_WINDOWS_NAME,
333 + "PerflibExchange",
334 + PRIO_EXCHANGE_AUTO_DISCOVER_REQUESTS,
335 + update_every,
336 + RRDSET_TYPE_LINE);
337 +
338 + rd_exchange_auto_discover_request_total =
339 + rrddim_add(st_exchange_auto_discover_request_total, "processed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
340 + }
341 +
342 + rrddim_set_by_pointer(
343 + st_exchange_auto_discover_request_total,
344 + rd_exchange_auto_discover_request_total,
345 + (collected_number)exchangeAutoDiscoverRequestsTotal.current.Data);
346 + rrdset_done(st_exchange_auto_discover_request_total);
347 +}
348 +
349 +static void
350 +netdata_exchange_availability_service(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
351 +{
352 + static COUNTER_DATA exchangeAvailServiceRequests = {.key = "Availability Requests (sec)"};
353 +
354 + static RRDSET *st_exchange_avail_service_requests = NULL;
355 + static RRDDIM *rd_exchange_avail_service_requests = NULL;
356 +
357 + if (!perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeAvailServiceRequests)) {
358 + return;
359 + }
360 +
361 + if (unlikely(!st_exchange_avail_service_requests)) {
362 + st_exchange_avail_service_requests = rrdset_create_localhost(
363 + "exchange",
364 + "avail_service_requests",
365 + NULL,
366 + "requests",
367 + "exchange.avail_service_requests",
368 + "Requests serviced.",
369 + "requests/s",
370 + PLUGIN_WINDOWS_NAME,
371 + "PerflibExchange",
372 + PRIO_EXCHANGE_AUTO_AVAILABILITY_SERVICES,
373 + update_every,
374 + RRDSET_TYPE_LINE);
375 +
376 + rd_exchange_avail_service_requests =
377 + rrddim_add(st_exchange_avail_service_requests, "serviced", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
378 + }
379 +
380 + rrddim_set_by_pointer(
381 + st_exchange_avail_service_requests,
382 + rd_exchange_avail_service_requests,
383 + (collected_number)exchangeAvailServiceRequests.current.Data);
384 + rrdset_done(st_exchange_avail_service_requests);
385 +}
386 +
387 +static void netdata_exchange_rpc_avg_latency(COUNTER_DATA *value, int update_every)
388 +{
389 + static RRDSET *st_exchange_rpc_avg_latency = NULL;
390 + static RRDDIM *rd_exchange_rpc_avg_latency = NULL;
391 +
392 + if (unlikely(!st_exchange_rpc_avg_latency)) {
393 + st_exchange_rpc_avg_latency = rrdset_create_localhost(
394 + "exchange",
395 + "rpc_avg_latency",
396 + NULL,
397 + "rpc",
398 + "exchange.rpc_avg_latency",
399 + "Average latency.",
400 + "seconds",
401 + PLUGIN_WINDOWS_NAME,
402 + "PerflibExchange",
403 + PRIO_EXCHANGE_RPC_AVG_LATENCY,
404 + update_every,
405 + RRDSET_TYPE_LINE);
406 +
407 + rd_exchange_rpc_avg_latency =
408 + rrddim_add(st_exchange_rpc_avg_latency, "latency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
409 + }
410 +
411 + rrddim_set_by_pointer(
412 + st_exchange_rpc_avg_latency, rd_exchange_rpc_avg_latency, (collected_number)value->current.Data);
413 + rrdset_done(st_exchange_rpc_avg_latency);
414 +}
415 +
416 +static void netdata_exchange_rpc_requests(COUNTER_DATA *value, int update_every)
417 +{
418 + static RRDSET *st_exchange_rpc_requests = NULL;
419 + static RRDDIM *rd_exchange_rpc_requests = NULL;
420 +
421 + if (unlikely(!st_exchange_rpc_requests)) {
422 + st_exchange_rpc_requests = rrdset_create_localhost(
423 + "exchange",
424 + "rpc_requests_total",
425 + NULL,
426 + "rpc",
427 + "exchange.rpc_requests",
428 + "Clients requests currently being processed.",
429 + "requests",
430 + PLUGIN_WINDOWS_NAME,
431 + "PerflibExchange",
432 + PRIO_EXCHANGE_RPC_REQUESTS,
433 + update_every,
434 + RRDSET_TYPE_LINE);
435 +
436 + rd_exchange_rpc_requests =
437 + rrddim_add(st_exchange_rpc_requests, "processed", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
438 + }
439 +
440 + rrddim_set_by_pointer(st_exchange_rpc_requests, rd_exchange_rpc_requests, (collected_number)value->current.Data);
441 + rrdset_done(st_exchange_rpc_requests);
442 +}
443 +
444 +static void netdata_exchange_rpc_active_user_count(COUNTER_DATA *value, int update_every)
445 +{
446 + static RRDSET *st_exchange_active_user_account = NULL;
447 + static RRDDIM *rd_exchange_active_user_account = NULL;
448 +
449 + if (unlikely(!st_exchange_active_user_account)) {
450 + st_exchange_active_user_account = rrdset_create_localhost(
451 + "exchange",
452 + "rpc_active_user",
453 + NULL,
454 + "rpc",
455 + "exchange.rpc_active_user",
456 + "Active unique users in the last 2 minutes.",
457 + "users",
458 + PLUGIN_WINDOWS_NAME,
459 + "PerflibExchange",
460 + PRIO_EXCHANGE_RPC_ACTIVE_USERS_COUNT,
461 + update_every,
462 + RRDSET_TYPE_LINE);
463 +
464 + rd_exchange_active_user_account =
465 + rrddim_add(st_exchange_active_user_account, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
466 + }
467 +
468 + rrddim_set_by_pointer(
469 + st_exchange_active_user_account, rd_exchange_active_user_account, (collected_number)value->current.Data);
470 + rrdset_done(st_exchange_active_user_account);
471 +}
472 +
473 +static void netdata_exchange_rpc_connection_count(COUNTER_DATA *value, int update_every)
474 +{
475 + static RRDSET *st_exchange_rpc_connection_count = NULL;
476 + static RRDDIM *rd_exchange_rpc_connection_count = NULL;
477 +
478 + if (unlikely(!st_exchange_rpc_connection_count)) {
479 + st_exchange_rpc_connection_count = rrdset_create_localhost(
480 + "exchange",
481 + "rpc_connection",
482 + NULL,
483 + "rpc",
484 + "exchange.rpc_connection",
485 + "Client connections.",
486 + "connections",
487 + PLUGIN_WINDOWS_NAME,
488 + "PerflibExchange",
489 + PRIO_EXCHANGE_RPC_CONNECTION_COUNT,
490 + update_every,
491 + RRDSET_TYPE_LINE);
492 +
493 + rd_exchange_rpc_connection_count =
494 + rrddim_add(st_exchange_rpc_connection_count, "connections", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
495 + }
496 +
497 + rrddim_set_by_pointer(
498 + st_exchange_rpc_connection_count, rd_exchange_rpc_connection_count, (collected_number)value->current.Data);
499 + rrdset_done(st_exchange_rpc_connection_count);
500 +}
501 +
502 +static void netdata_exchange_rpc_op_per_sec(COUNTER_DATA *value, int update_every)
503 +{
504 + static RRDSET *st_exchange_rpc_opc_per_sec = NULL;
505 + static RRDDIM *rd_exchange_rpc_opc_per_sec = NULL;
506 +
507 + if (unlikely(!st_exchange_rpc_opc_per_sec)) {
508 + st_exchange_rpc_opc_per_sec = rrdset_create_localhost(
509 + "exchange",
510 + "rpc_operations",
511 + NULL,
512 + "rpc",
513 + "exchange.rpc_operations",
514 + "RPC operations.",
515 + "operations/s",
516 + PLUGIN_WINDOWS_NAME,
517 + "PerflibExchange",
518 + PRIO_EXCHANGE_RPC_OPERATIONS_TOTAL,
519 + update_every,
520 + RRDSET_TYPE_LINE);
521 +
522 + rd_exchange_rpc_opc_per_sec =
523 + rrddim_add(st_exchange_rpc_opc_per_sec, "operations", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
524 + }
525 +
526 + rrddim_set_by_pointer(
527 + st_exchange_rpc_opc_per_sec, rd_exchange_rpc_opc_per_sec, (collected_number)value->current.Data);
528 + rrdset_done(st_exchange_rpc_opc_per_sec);
529 +}
530 +
531 +static void netdata_exchange_rpc_user_count(COUNTER_DATA *value, int update_every)
532 +{
533 + static RRDSET *st_exchange_rpc_user_count = NULL;
534 + static RRDDIM *rd_exchange_rpc_user_count = NULL;
535 +
536 + if (unlikely(!st_exchange_rpc_user_count)) {
537 + st_exchange_rpc_user_count = rrdset_create_localhost(
538 + "exchange",
539 + "rpc_user",
540 + NULL,
541 + "rpc",
542 + "exchange.rpc_user_count",
543 + "RPC users.",
544 + "users",
545 + PLUGIN_WINDOWS_NAME,
546 + "PerflibExchange",
547 + PRIO_EXCHANGE_RPC_USER_COUNT,
548 + update_every,
549 + RRDSET_TYPE_LINE);
550 +
551 + rd_exchange_rpc_user_count =
552 + rrddim_add(st_exchange_rpc_user_count, "users", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
553 + }
554 +
555 + rrddim_set_by_pointer(
556 + st_exchange_rpc_user_count, rd_exchange_rpc_user_count, (collected_number)value->current.Data);
557 + rrdset_done(st_exchange_rpc_user_count);
558 +}
559 +
560 +static void netdata_exchange_rpc(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
561 +{
562 + static COUNTER_DATA exchangeRPCAveragedLatency = {.key = "RPC Averaged Latency"};
563 + static COUNTER_DATA exchangeRPCRequest = {.key = "RPC Requests"};
564 + static COUNTER_DATA exchangeRPCActiveUserCount = {.key = "Active User Count"};
565 + static COUNTER_DATA exchangeRPCConnectionCount = {.key = "Connection Count"};
566 + static COUNTER_DATA exchangeRPCOperationPerSec = {.key = "RPC Operations/sec"};
567 + static COUNTER_DATA exchangeRPCUserCount = {.key = "User Count"};
568 +
569 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeRPCAveragedLatency))
570 + netdata_exchange_rpc_avg_latency(&exchangeRPCAveragedLatency, update_every);
571 +
572 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeRPCRequest))
573 + netdata_exchange_rpc_requests(&exchangeRPCRequest, update_every);
574 +
575 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeRPCActiveUserCount))
576 + netdata_exchange_rpc_active_user_count(&exchangeRPCRequest, update_every);
577 +
578 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeRPCConnectionCount))
579 + netdata_exchange_rpc_connection_count(&exchangeRPCConnectionCount, update_every);
580 +
581 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeRPCOperationPerSec))
582 + netdata_exchange_rpc_op_per_sec(&exchangeRPCOperationPerSec, update_every);
583 +
584 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &exchangeRPCUserCount))
585 + netdata_exchange_rpc_user_count(&exchangeRPCUserCount, update_every);
586 +}
587 +
588 +static void netdata_exchange_proxy_avg_auth_latency(struct exchange_proxy *ep, char *proxy, int update_every)
589 +{
590 + if (unlikely(!ep->st_exchange_http_proxy_avg_auth_latency)) {
591 + char id[RRD_ID_LENGTH_MAX + 1];
592 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_proxy_%s_avg_auth_latency", proxy);
593 +
594 + ep->st_exchange_http_proxy_avg_auth_latency = rrdset_create_localhost(
595 + "exchange",
596 + id,
597 + NULL,
598 + "proxy",
599 + "exchange.http_proxy_avg_auth_latency",
600 + "Average time spent authenticating CAS requests.",
601 + "seconds",
602 + PLUGIN_WINDOWS_NAME,
603 + "PerflibExchange",
604 + PRIO_EXCHANGE_PROXY_AVG_AUTH_LATENCY,
605 + update_every,
606 + RRDSET_TYPE_LINE);
607 +
608 + ep->rd_exchange_http_proxy_avg_auth_latency =
609 + rrddim_add(ep->st_exchange_http_proxy_avg_auth_latency, "latency", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
610 +
611 + rrdlabels_add(ep->st_exchange_http_proxy_avg_auth_latency->rrdlabels, "http_proxy", proxy, RRDLABEL_SRC_AUTO);
612 + }
613 +
614 + rrddim_set_by_pointer(
615 + ep->st_exchange_http_proxy_avg_auth_latency,
616 + ep->rd_exchange_http_proxy_avg_auth_latency,
617 + (collected_number)ep->exchangeProxyAvgAuthLatency.current.Data);
618 + rrdset_done(ep->st_exchange_http_proxy_avg_auth_latency);
619 +}
620 +
621 +static void netdata_exchange_proxy_avg_cas_processing_latency(struct exchange_proxy *ep, char *proxy, int update_every)
622 +{
623 + if (unlikely(!ep->st_exchange_http_proxy_avg_cas_processing_latency)) {
624 + char id[RRD_ID_LENGTH_MAX + 1];
625 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_proxy_%s_avg_cas_processing_latency_sec", proxy);
626 +
627 + ep->st_exchange_http_proxy_avg_cas_processing_latency = rrdset_create_localhost(
628 + "exchange",
629 + id,
630 + NULL,
631 + "proxy",
632 + "exchange.http_proxy_avg_cas_processing_latency_sec",
633 + "Average latency (sec) of CAS processing time.",
634 + "seconds",
635 + PLUGIN_WINDOWS_NAME,
636 + "PerflibExchange",
637 + PRIO_EXCHANGE_PROXY_AVG_CAS_PROCESSING_LATENCY,
638 + update_every,
639 + RRDSET_TYPE_LINE);
640 +
641 + ep->rd_exchange_http_proxy_avg_cas_processing_latency = rrddim_add(
642 + ep->st_exchange_http_proxy_avg_cas_processing_latency, "latency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
643 +
644 + rrdlabels_add(
645 + ep->st_exchange_http_proxy_avg_cas_processing_latency->rrdlabels, "http_proxy", proxy, RRDLABEL_SRC_AUTO);
646 + }
647 +
648 + rrddim_set_by_pointer(
649 + ep->st_exchange_http_proxy_avg_cas_processing_latency,
650 + ep->rd_exchange_http_proxy_avg_cas_processing_latency,
651 + (collected_number)ep->exchangeProxyAvgCasProcessingLatency.current.Data);
652 + rrdset_done(ep->st_exchange_http_proxy_avg_cas_processing_latency);
653 +}
654 +
655 +static void netdata_exchange_proxy_mailbox_proxy_failure(struct exchange_proxy *ep, char *proxy, int update_every)
656 +{
657 + if (unlikely(!ep->st_exchange_http_proxy_mailbox_proxy_failure)) {
658 + char id[RRD_ID_LENGTH_MAX + 1];
659 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_proxy_%s_mailbox_proxy_failure_rate", proxy);
660 +
661 + ep->st_exchange_http_proxy_mailbox_proxy_failure = rrdset_create_localhost(
662 + "exchange",
663 + id,
664 + NULL,
665 + "proxy",
666 + "exchange.http_proxy_mailbox_proxy_failure_rate",
667 + "Percentage of failures between this CAS and MBX servers.",
668 + "percentage",
669 + PLUGIN_WINDOWS_NAME,
670 + "PerflibExchange",
671 + PRIO_EXCHANGE_PROXY_MAILBOX_PROXY_FAILURE,
672 + update_every,
673 + RRDSET_TYPE_LINE);
674 +
675 + ep->rd_exchange_http_proxy_mailbox_proxy_failure = rrddim_add(
676 + ep->st_exchange_http_proxy_mailbox_proxy_failure, "failures", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
677 +
678 + rrdlabels_add(
679 + ep->st_exchange_http_proxy_mailbox_proxy_failure->rrdlabels, "http_proxy", proxy, RRDLABEL_SRC_AUTO);
680 + }
681 +
682 + rrddim_set_by_pointer(
683 + ep->st_exchange_http_proxy_mailbox_proxy_failure,
684 + ep->rd_exchange_http_proxy_mailbox_proxy_failure,
685 + (collected_number)ep->exchangeProxyMailboxProxyFailure.current.Data);
686 + rrdset_done(ep->st_exchange_http_proxy_mailbox_proxy_failure);
687 +}
688 +
689 +static void netdata_exchange_proxy_mailbox_server_locator(struct exchange_proxy *ep, char *proxy, int update_every)
690 +{
691 + if (unlikely(!ep->st_exchange_http_proxy_server_location_avg_latency)) {
692 + char id[RRD_ID_LENGTH_MAX + 1];
693 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_proxy_%s_mailbox_server_locator_avg_latency_sec", proxy);
694 +
695 + ep->st_exchange_http_proxy_server_location_avg_latency = rrdset_create_localhost(
696 + "exchange",
697 + id,
698 + NULL,
699 + "proxy",
700 + "exchange.http_proxy_mailbox_server_locator_avg_latency_sec",
701 + "Average latency of MailboxServerLocator web service calls.",
702 + "seconds",
703 + PLUGIN_WINDOWS_NAME,
704 + "PerflibExchange",
705 + PRIO_EXCHANGE_PROXY_SERVER_LOCATIOR_AVG_LATENCY,
706 + update_every,
707 + RRDSET_TYPE_LINE);
708 +
709 + ep->rd_exchange_http_proxy_server_location_avg_latency = rrddim_add(
710 + ep->st_exchange_http_proxy_server_location_avg_latency, "latency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
711 +
712 + rrdlabels_add(
713 + ep->st_exchange_http_proxy_server_location_avg_latency->rrdlabels, "http_proxy", proxy, RRDLABEL_SRC_AUTO);
714 + }
715 +
716 + rrddim_set_by_pointer(
717 + ep->st_exchange_http_proxy_server_location_avg_latency,
718 + ep->rd_exchange_http_proxy_server_location_avg_latency,
719 + (collected_number)ep->exchangeProxyMailboxServerLocator.current.Data);
720 + rrdset_done(ep->st_exchange_http_proxy_server_location_avg_latency);
721 +}
722 +
723 +static void netdata_exchange_proxy_outstanding_proxy(struct exchange_proxy *ep, char *proxy, int update_every)
724 +{
725 + if (unlikely(!ep->st_exchange_http_proxy_outstanding_proxy_requests)) {
726 + char id[RRD_ID_LENGTH_MAX + 1];
727 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_proxy_%s_outstanding_proxy_requests", proxy);
728 +
729 + ep->st_exchange_http_proxy_outstanding_proxy_requests = rrdset_create_localhost(
730 + "exchange",
731 + id,
732 + NULL,
733 + "proxy",
734 + "exchange.http_proxy_outstanding_proxy_requests",
735 + "Concurrent outstanding proxy requests.",
736 + "requests",
737 + PLUGIN_WINDOWS_NAME,
738 + "PerflibExchange",
739 + PRIO_EXCHANGE_PROXY_OUTSTANDING_PROXY_REQUESTS,
740 + update_every,
741 + RRDSET_TYPE_LINE);
742 +
743 + ep->rd_exchange_http_proxy_outstanding_proxy_requests = rrddim_add(
744 + ep->st_exchange_http_proxy_outstanding_proxy_requests, "requests", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
745 +
746 + rrdlabels_add(
747 + ep->st_exchange_http_proxy_outstanding_proxy_requests->rrdlabels, "http_proxy", proxy, RRDLABEL_SRC_AUTO);
748 + }
749 +
750 + rrddim_set_by_pointer(
751 + ep->st_exchange_http_proxy_outstanding_proxy_requests,
752 + ep->rd_exchange_http_proxy_outstanding_proxy_requests,
753 + (collected_number)ep->exchangeProxyOutstandingProxy.current.Data);
754 + rrdset_done(ep->st_exchange_http_proxy_outstanding_proxy_requests);
755 +}
756 +
757 +static void netdata_exchange_proxy_request_total(struct exchange_proxy *ep, char *proxy, int update_every)
758 +{
759 + if (unlikely(!ep->st_exchange_http_proxy_requests_total)) {
760 + char id[RRD_ID_LENGTH_MAX + 1];
761 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_proxy_%s_requests_total", proxy);
762 +
763 + ep->st_exchange_http_proxy_requests_total = rrdset_create_localhost(
764 + "exchange",
765 + id,
766 + NULL,
767 + "proxy",
768 + "exchange.http_proxy_requests",
769 + "Number of proxy requests processed each second.",
770 + "requests",
771 + PLUGIN_WINDOWS_NAME,
772 + "PerflibExchange",
773 + PRIO_EXCHANGE_PROXY_PROXY_REQUESTS_TOTAL,
774 + update_every,
775 + RRDSET_TYPE_LINE);
776 +
777 + ep->rd_exchange_http_proxy_requests_total =
778 + rrddim_add(ep->st_exchange_http_proxy_requests_total, "requests", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
779 +
780 + rrdlabels_add(ep->st_exchange_http_proxy_requests_total->rrdlabels, "http_proxy", proxy, RRDLABEL_SRC_AUTO);
781 + }
782 +
783 + rrddim_set_by_pointer(
784 + ep->st_exchange_http_proxy_requests_total,
785 + ep->rd_exchange_http_proxy_requests_total,
786 + (collected_number)ep->exchangeProxyRequestsTotal.current.Data);
787 + rrdset_done(ep->st_exchange_http_proxy_requests_total);
788 +}
789 +
790 +static void netdata_exchange_proxy(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
791 +{
792 + PERF_INSTANCE_DEFINITION *pi = NULL;
793 + for (LONG i = 0; i < pObjectType->NumInstances; i++) {
794 + pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
795 + if (!pi)
796 + break;
797 +
798 + if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
799 + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
800 +
801 + if (strcasecmp(windows_shared_buffer, "_Total") == 0)
802 + continue;
803 +
804 + struct exchange_proxy *ep = dictionary_set(exchange_proxies, windows_shared_buffer, NULL, sizeof(*ep));
805 + if (!ep)
806 + continue;
807 +
808 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ep->exchangeProxyAvgAuthLatency))
809 + netdata_exchange_proxy_avg_auth_latency(ep, windows_shared_buffer, update_every);
810 +
811 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ep->exchangeProxyAvgCasProcessingLatency))
812 + netdata_exchange_proxy_avg_cas_processing_latency(ep, windows_shared_buffer, update_every);
813 +
814 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ep->exchangeProxyMailboxProxyFailure))
815 + netdata_exchange_proxy_mailbox_proxy_failure(ep, windows_shared_buffer, update_every);
816 +
817 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ep->exchangeProxyMailboxServerLocator))
818 + netdata_exchange_proxy_mailbox_server_locator(ep, windows_shared_buffer, update_every);
819 +
820 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ep->exchangeProxyOutstandingProxy))
821 + netdata_exchange_proxy_outstanding_proxy(ep, windows_shared_buffer, update_every);
822 +
823 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ep->exchangeProxyRequestsTotal))
824 + netdata_exchange_proxy_request_total(ep, windows_shared_buffer, update_every);
825 + }
826 +}
827 +
828 +static void netdata_exchange_workload_active_tasks(struct exchange_workload *ew, char *workload, int update_every)
829 +{
830 + if (unlikely(!ew->st_exchange_workload_active_tasks)) {
831 + char id[RRD_ID_LENGTH_MAX + 1];
832 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_workload_%s_tasks", workload);
833 +
834 + ew->st_exchange_workload_active_tasks = rrdset_create_localhost(
835 + "exchange",
836 + id,
837 + NULL,
838 + "workload",
839 + "exchange.workload_active_tasks",
840 + "Workload active tasks.",
841 + "tasks",
842 + PLUGIN_WINDOWS_NAME,
843 + "PerflibExchange",
844 + PRIO_EXCHANGE_WORKlOAD_ACTIVE_TASKS,
845 + update_every,
846 + RRDSET_TYPE_LINE);
847 +
848 + ew->rd_exchange_workload_active_tasks =
849 + rrddim_add(ew->st_exchange_workload_active_tasks, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
850 +
851 + rrdlabels_add(ew->st_exchange_workload_active_tasks->rrdlabels, "workload", workload, RRDLABEL_SRC_AUTO);
852 + }
853 +
854 + rrddim_set_by_pointer(
855 + ew->st_exchange_workload_active_tasks,
856 + ew->rd_exchange_workload_active_tasks,
857 + (collected_number)ew->exchangeWorkloadActiveTasks.current.Data);
858 + rrdset_done(ew->st_exchange_workload_active_tasks);
859 +}
860 +
861 +static void netdata_exchange_workload_completed_tasks(struct exchange_workload *ew, char *workload, int update_every)
862 +{
863 + if (unlikely(!ew->st_exchange_workload_complete_tasks)) {
864 + char id[RRD_ID_LENGTH_MAX + 1];
865 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_workload_%s_completed_tasks", workload);
866 +
867 + ew->st_exchange_workload_complete_tasks = rrdset_create_localhost(
868 + "exchange",
869 + id,
870 + NULL,
871 + "workload",
872 + "exchange.workload_completed_tasks",
873 + "Workload completed tasks.",
874 + "tasks/s",
875 + PLUGIN_WINDOWS_NAME,
876 + "PerflibExchange",
877 + PRIO_EXCHANGE_WORKlOAD_COMPLETE_TASKS,
878 + update_every,
879 + RRDSET_TYPE_LINE);
880 +
881 + ew->rd_exchange_workload_complete_tasks =
882 + rrddim_add(ew->st_exchange_workload_complete_tasks, "completed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
883 +
884 + rrdlabels_add(ew->st_exchange_workload_complete_tasks->rrdlabels, "completed", workload, RRDLABEL_SRC_AUTO);
885 + }
886 +
887 + rrddim_set_by_pointer(
888 + ew->st_exchange_workload_complete_tasks,
889 + ew->rd_exchange_workload_complete_tasks,
890 + (collected_number)ew->exchangeWorkloadCompleteTasks.current.Data);
891 + rrdset_done(ew->st_exchange_workload_complete_tasks);
892 +}
893 +
894 +static void netdata_exchange_workload_queued_tasks(struct exchange_workload *ew, char *workload, int update_every)
895 +{
896 + if (unlikely(!ew->st_exchange_workload_queued_tasks)) {
897 + char id[RRD_ID_LENGTH_MAX + 1];
898 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_workload_%s_queued_tasks", workload);
899 +
900 + ew->st_exchange_workload_queued_tasks = rrdset_create_localhost(
901 + "exchange",
902 + id,
903 + NULL,
904 + "workload",
905 + "exchange.workload_queued_tasks",
906 + "Workload queued tasks.",
907 + "tasks/s",
908 + PLUGIN_WINDOWS_NAME,
909 + "PerflibExchange",
910 + PRIO_EXCHANGE_WORKlOAD_QUEUE_TASKS,
911 + update_every,
912 + RRDSET_TYPE_LINE);
913 +
914 + ew->rd_exchange_workload_queued_tasks =
915 + rrddim_add(ew->st_exchange_workload_queued_tasks, "queued", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
916 +
917 + rrdlabels_add(ew->st_exchange_workload_queued_tasks->rrdlabels, "workload", workload, RRDLABEL_SRC_AUTO);
918 + }
919 +
920 + rrddim_set_by_pointer(
921 + ew->st_exchange_workload_queued_tasks,
922 + ew->rd_exchange_workload_queued_tasks,
923 + (collected_number)ew->exchangeWorkloadQueueTasks.current.Data);
924 + rrdset_done(ew->st_exchange_workload_queued_tasks);
925 +}
926 +
927 +static void netdata_exchange_workload_yielded_tasks(struct exchange_workload *ew, char *workload, int update_every)
928 +{
929 + if (unlikely(!ew->st_exchange_workload_yielded_tasks)) {
930 + char id[RRD_ID_LENGTH_MAX + 1];
931 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_workload_%s_yielded_tasks", workload);
932 +
933 + ew->st_exchange_workload_yielded_tasks = rrdset_create_localhost(
934 + "exchange",
935 + id,
936 + NULL,
937 + "workload",
938 + "exchange.workload_yielded_tasks",
939 + "Workload yielded tasks.",
940 + "tasks/s",
941 + PLUGIN_WINDOWS_NAME,
942 + "PerflibExchange",
943 + PRIO_EXCHANGE_WORKlOAD_YIELDED_TASKS,
944 + update_every,
945 + RRDSET_TYPE_LINE);
946 +
947 + ew->rd_exchange_workload_yielded_tasks =
948 + rrddim_add(ew->st_exchange_workload_yielded_tasks, "yielded", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
949 +
950 + rrdlabels_add(ew->st_exchange_workload_yielded_tasks->rrdlabels, "workload", workload, RRDLABEL_SRC_AUTO);
951 + }
952 +
953 + rrddim_set_by_pointer(
954 + ew->st_exchange_workload_yielded_tasks,
955 + ew->rd_exchange_workload_yielded_tasks,
956 + (collected_number)ew->exchangeWorkloadYieldedTasks.current.Data);
957 + rrdset_done(ew->st_exchange_workload_yielded_tasks);
958 +}
959 +
960 +static void netdata_exchange_workload_activity_status(struct exchange_workload *ew, char *workload, int update_every)
961 +{
962 + if (unlikely(!ew->st_exchange_workload_activity_status)) {
963 + char id[RRD_ID_LENGTH_MAX + 1];
964 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_workload_%s_activity_status", workload);
965 +
966 + ew->st_exchange_workload_activity_status = rrdset_create_localhost(
967 + "exchange",
968 + id,
969 + NULL,
970 + "workload",
971 + "exchange.workload_activity_status",
972 + "Workload activity status.",
973 + "status",
974 + PLUGIN_WINDOWS_NAME,
975 + "PerflibExchange",
976 + PRIO_EXCHANGE_WORKlOAD_ACTIVITY,
977 + update_every,
978 + RRDSET_TYPE_LINE);
979 +
980 + ew->rd_exchange_workload_activity_active_status =
981 + rrddim_add(ew->st_exchange_workload_activity_status, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
982 +
983 + ew->rd_exchange_workload_activity_paused_status =
984 + rrddim_add(ew->st_exchange_workload_activity_status, "paused", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
985 +
986 + rrdlabels_add(ew->st_exchange_workload_activity_status->rrdlabels, "workload", workload, RRDLABEL_SRC_AUTO);
987 + }
988 +
989 + bool value = (bool)ew->exchangeWorkloadActivityStatus.current.Data;
990 + rrddim_set_by_pointer(
991 + ew->st_exchange_workload_activity_status,
992 + ew->rd_exchange_workload_activity_active_status,
993 + (collected_number)value);
994 + rrdset_done(ew->st_exchange_workload_activity_status);
995 +
996 + value = !value;
997 + rrddim_set_by_pointer(
998 + ew->st_exchange_workload_activity_status,
999 + ew->rd_exchange_workload_activity_paused_status,
1000 + (collected_number)value);
1001 + rrdset_done(ew->st_exchange_workload_activity_status);
1002 +}
1003 +
1004 +static void netdata_exchange_workload(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
1005 +{
1006 + PERF_INSTANCE_DEFINITION *pi = NULL;
1007 + for (LONG i = 0; i < pObjectType->NumInstances; i++) {
1008 + pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
1009 + if (!pi)
1010 + break;
1011 +
1012 + if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
1013 + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
1014 +
1015 + if (strcasecmp(windows_shared_buffer, "_Total") == 0)
1016 + continue;
1017 +
1018 + struct exchange_workload *ew = dictionary_set(exchange_workloads, windows_shared_buffer, NULL, sizeof(*ew));
1019 + if (!ew)
1020 + continue;
1021 +
1022 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ew->exchangeWorkloadActiveTasks))
1023 + netdata_exchange_workload_active_tasks(ew, windows_shared_buffer, update_every);
1024 +
1025 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ew->exchangeWorkloadCompleteTasks))
1026 + netdata_exchange_workload_completed_tasks(ew, windows_shared_buffer, update_every);
1027 +
1028 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ew->exchangeWorkloadQueueTasks))
1029 + netdata_exchange_workload_queued_tasks(ew, windows_shared_buffer, update_every);
1030 +
1031 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ew->exchangeWorkloadYieldedTasks))
1032 + netdata_exchange_workload_yielded_tasks(ew, windows_shared_buffer, update_every);
1033 +
1034 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &ew->exchangeWorkloadActivityStatus))
1035 + netdata_exchange_workload_activity_status(ew, windows_shared_buffer, update_every);
1036 + }
1037 +}
1038 +
1039 +static void netdata_exchange_queue_active_mailbox(struct exchange_queue *eq, char *mailbox, int update_every)
1040 +{
1041 + if (unlikely(!eq->st_exchange_queue_active_mailbox)) {
1042 + char id[RRD_ID_LENGTH_MAX + 1];
1043 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_transport_queues_%s_active_mailbox_delivery", mailbox);
1044 +
1045 + eq->st_exchange_queue_active_mailbox = rrdset_create_localhost(
1046 + "exchange",
1047 + id,
1048 + NULL,
1049 + "queue",
1050 + "exchange.transport_queues_active_mail_box_delivery",
1051 + "Active Mailbox Delivery Queue length.",
1052 + "messages",
1053 + PLUGIN_WINDOWS_NAME,
1054 + "PerflibExchange",
1055 + PRIO_EXCHANGE_QUEUE_ACTIVE_MAILBOX_DELIVERY,
1056 + update_every,
1057 + RRDSET_TYPE_LINE);
1058 +
1059 + eq->rd_exchange_queue_active_mailbox =
1060 + rrddim_add(eq->st_exchange_queue_active_mailbox, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1061 +
1062 + rrdlabels_add(eq->st_exchange_queue_active_mailbox->rrdlabels, "mailbox", mailbox, RRDLABEL_SRC_AUTO);
1063 + }
1064 +
1065 + rrddim_set_by_pointer(
1066 + eq->st_exchange_queue_active_mailbox,
1067 + eq->rd_exchange_queue_active_mailbox,
1068 + (collected_number)eq->exchangeTransportQueuesActiveMailboxDelivery.current.Data);
1069 + rrdset_done(eq->st_exchange_queue_active_mailbox);
1070 +}
1071 +
1072 +static void netdata_exchange_queue_external_active_remote_delivery(struct exchange_queue *eq, char *mailbox, int update_every)
1073 +{
1074 + if (unlikely(!eq->st_exchange_queue_external_active_remote_delivery)) {
1075 + char id[RRD_ID_LENGTH_MAX + 1];
1076 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_transport_queues_%s_external_active_remote_delivery", mailbox);
1077 +
1078 + eq->st_exchange_queue_external_active_remote_delivery = rrdset_create_localhost(
1079 + "exchange",
1080 + id,
1081 + NULL,
1082 + "queue",
1083 + "exchange.transport_queues_external_active_remote_delivery",
1084 + "External Active Remote Delivery Queue length.",
1085 + "messages",
1086 + PLUGIN_WINDOWS_NAME,
1087 + "PerflibExchange",
1088 + PRIO_EXCHANGE_QUEUE_EXTERNAL_ACTIVE_REMOTE_DELIVERY,
1089 + update_every,
1090 + RRDSET_TYPE_LINE);
1091 +
1092 + eq->rd_exchange_queue_external_active_remote_delivery =
1093 + rrddim_add(eq->st_exchange_queue_external_active_remote_delivery, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1094 +
1095 + rrdlabels_add(eq->st_exchange_queue_external_active_remote_delivery->rrdlabels, "mailbox", mailbox, RRDLABEL_SRC_AUTO);
1096 + }
1097 +
1098 + rrddim_set_by_pointer(
1099 + eq->st_exchange_queue_external_active_remote_delivery,
1100 + eq->rd_exchange_queue_external_active_remote_delivery,
1101 + (collected_number)eq->exchangeTransportQueuesExternalActiveRemoteDelivery.current.Data);
1102 + rrdset_done(eq->st_exchange_queue_external_active_remote_delivery);
1103 +}
1104 +
1105 +static void netdata_exchange_queue_internal_active_remote_delivery(struct exchange_queue *eq, char *mailbox, int update_every)
1106 +{
1107 + if (unlikely(!eq->st_exchange_queue_internal_active_remote_delivery)) {
1108 + char id[RRD_ID_LENGTH_MAX + 1];
1109 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_transport_queues_%s_internal_active_remote_delivery", mailbox);
1110 +
1111 + eq->st_exchange_queue_internal_active_remote_delivery = rrdset_create_localhost(
1112 + "exchange",
1113 + id,
1114 + NULL,
1115 + "queue",
1116 + "exchange.transport_queues_internal_active_remote_delivery",
1117 + "Internal Active Remote Delivery Queue length.",
1118 + "messages",
1119 + PLUGIN_WINDOWS_NAME,
1120 + "PerflibExchange",
1121 + PRIO_EXCHANGE_QUEUE_INTERNAL_ACTIVE_REMOTE_DELIVERY,
1122 + update_every,
1123 + RRDSET_TYPE_LINE);
1124 +
1125 + eq->rd_exchange_queue_internal_active_remote_delivery =
1126 + rrddim_add(eq->st_exchange_queue_internal_active_remote_delivery, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1127 +
1128 + rrdlabels_add(eq->st_exchange_queue_internal_active_remote_delivery->rrdlabels, "mailbox", mailbox, RRDLABEL_SRC_AUTO);
1129 + }
1130 +
1131 + rrddim_set_by_pointer(
1132 + eq->st_exchange_queue_internal_active_remote_delivery,
1133 + eq->rd_exchange_queue_internal_active_remote_delivery,
1134 + (collected_number)eq->exchangeTransportQueuesInternalActiveRemoteDeliery.current.Data);
1135 + rrdset_done(eq->st_exchange_queue_internal_active_remote_delivery);
1136 +}
1137 +
1138 +static void netdata_exchange_queue_unreachable(struct exchange_queue *eq, char *mailbox, int update_every)
1139 +{
1140 + if (unlikely(!eq->st_exchange_queue_unreachable)) {
1141 + char id[RRD_ID_LENGTH_MAX + 1];
1142 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_transport_queues_%s_unreachable", mailbox);
1143 +
1144 + eq->st_exchange_queue_unreachable = rrdset_create_localhost(
1145 + "exchange",
1146 + id,
1147 + NULL,
1148 + "queue",
1149 + "exchange.transport_queues_unreachable",
1150 + "Unreachable Queue length.",
1151 + "messages",
1152 + PLUGIN_WINDOWS_NAME,
1153 + "PerflibExchange",
1154 + PRIO_EXCHANGE_QUEUE_UNREACHABLE,
1155 + update_every,
1156 + RRDSET_TYPE_LINE);
1157 +
1158 + eq->rd_exchange_queue_unreachable =
1159 + rrddim_add(eq->st_exchange_queue_unreachable, "unreachable", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1160 +
1161 + rrdlabels_add(eq->st_exchange_queue_unreachable->rrdlabels, "mailbox", mailbox, RRDLABEL_SRC_AUTO);
1162 + }
1163 +
1164 + rrddim_set_by_pointer(
1165 + eq->st_exchange_queue_unreachable,
1166 + eq->rd_exchange_queue_unreachable,
1167 + (collected_number)eq->exchangeTransportQueuesUnreachable.current.Data);
1168 + rrdset_done(eq->st_exchange_queue_unreachable);
1169 +}
1170 +
1171 +static void netdata_exchange_queue_poison(struct exchange_queue *eq, char *mailbox, int update_every)
1172 +{
1173 + if (unlikely(!eq->st_exchange_queue_poison)) {
1174 + char id[RRD_ID_LENGTH_MAX + 1];
1175 + snprintfz(id, RRD_ID_LENGTH_MAX, "exchange_transport_queues_%s_poison", mailbox);
1176 +
1177 + eq->st_exchange_queue_poison = rrdset_create_localhost(
1178 + "exchange",
1179 + id,
1180 + NULL,
1181 + "queue",
1182 + "exchange.transport_queues_poison",
1183 + "Poison Queue Length.",
1184 + "messages",
1185 + PLUGIN_WINDOWS_NAME,
1186 + "PerflibExchange",
1187 + PRIO_EXCHANGE_QUEUE_POISON,
1188 + update_every,
1189 + RRDSET_TYPE_LINE);
1190 +
1191 + eq->rd_exchange_queue_poison =
1192 + rrddim_add(eq->st_exchange_queue_poison, "poison", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1193 +
1194 + rrdlabels_add(eq->st_exchange_queue_poison->rrdlabels, "mailbox", mailbox, RRDLABEL_SRC_AUTO);
1195 + }
1196 +
1197 + rrddim_set_by_pointer(
1198 + eq->st_exchange_queue_poison,
1199 + eq->rd_exchange_queue_poison,
1200 + (collected_number)eq->exchangeTransportQueuesPoison.current.Data);
1201 + rrdset_done(eq->st_exchange_queue_poison);
1202 +}
1203 +
1204 +static void netdata_exchange_queues(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
1205 +{
1206 + PERF_INSTANCE_DEFINITION *pi = NULL;
1207 + for (LONG i = 0; i < pObjectType->NumInstances; i++) {
1208 + pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
1209 + if (!pi)
1210 + break;
1211 +
1212 + if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
1213 + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
1214 +
1215 + // Remove 'queue' from instance name
1216 + char *ptr = strchr(windows_shared_buffer, ' ');
1217 + if (ptr)
1218 + *ptr = '\0';
1219 +
1220 + if (strcasecmp(windows_shared_buffer, "_Total") == 0 || strcasecmp(windows_shared_buffer, "total") == 0)
1221 + continue;
1222 +
1223 + struct exchange_queue *eq = dictionary_set(exchange_queues, windows_shared_buffer, NULL, sizeof(*eq));
1224 + if (!eq)
1225 + continue;
1226 +
1227 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &eq->exchangeTransportQueuesActiveMailboxDelivery))
1228 + netdata_exchange_queue_active_mailbox(eq, windows_shared_buffer, update_every);
1229 +
1230 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &eq->exchangeTransportQueuesExternalActiveRemoteDelivery))
1231 + netdata_exchange_queue_external_active_remote_delivery(eq, windows_shared_buffer, update_every);
1232 +
1233 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &eq->exchangeTransportQueuesInternalActiveRemoteDeliery))
1234 + netdata_exchange_queue_internal_active_remote_delivery(eq, windows_shared_buffer, update_every);
1235 +
1236 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &eq->exchangeTransportQueuesUnreachable))
1237 + netdata_exchange_queue_unreachable(eq, windows_shared_buffer, update_every);
1238 +
1239 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &eq->exchangeTransportQueuesPoison))
1240 + netdata_exchange_queue_poison(eq, windows_shared_buffer, update_every);
1241 + }
1242 +}
1243 +
1244 +struct netdata_exchange_objects {
1245 + void (*fnct)(PERF_DATA_BLOCK *, PERF_OBJECT_TYPE *, int);
1246 + char *object;
1247 +} exchange_obj[] = {
1248 + {.fnct = netdata_exchange_owa, .object = "MSExchange OWA"},
1249 + {.fnct = netdata_exchange_active_sync, .object = "MSExchange ActiveSync"},
1250 + {.fnct = netdata_exchange_auto_discover, .object = "MSExchangeAutodiscover"},
1251 + {.fnct = netdata_exchange_availability_service, .object = "MSExchange Availability Service"},
1252 + {.fnct = netdata_exchange_rpc, .object = "MSExchange RpcClientAccess"},
1253 + {.fnct = netdata_exchange_proxy, .object = "MSExchange HttpProxy"},
1254 + {.fnct = netdata_exchange_workload, .object = "MSExchange WorkloadManagement Workloads"},
1255 + {.fnct = netdata_exchange_queues, .object = "MSExchangeTransport Queues"},
1256 +
1257 + // This is the end of the loop
1258 + {.fnct = NULL, .object = NULL}};
1259 +
1260 +int do_PerflibExchange(int update_every, usec_t dt __maybe_unused)
1261 +{
1262 + static bool initialized = false;
1263 +
1264 + if (unlikely(!initialized)) {
1265 + initialize();
1266 + initialized = true;
1267 + }
1268 +
1269 + for (int i = 0; exchange_obj[i].fnct; i++) {
1270 + DWORD id = RegistryFindIDByName(exchange_obj[i].object);
1271 + if (id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
1272 + continue;
1273 +
1274 + PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
1275 + if (!pDataBlock)
1276 + continue;
1277 +
1278 + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, exchange_obj[i].object);
1279 + if (!pObjectType)
1280 + continue;
1281 +
1282 + exchange_obj[i].fnct(pDataBlock, pObjectType, update_every);
1283 + }
1284 +
1285 + return 0;
1286 +}
src/collectors/windows.plugin/windows_plugin.c
+5
@@ -107,6 +107,11 @@ static struct proc_module {
107 .update_every = 30 * UPDATE_EVERY_MIN,
108 .func = do_PerflibServices},
109
110 + {.name = "PerflibExchange",
111 + .dim = "PerflibADFS",
112 + .enabled = CONFIG_BOOLEAN_YES,
113 + .update_every = UPDATE_EVERY_MIN,
114 + .func = do_PerflibExchange},
115 // the terminator of this array
116 {.name = NULL, .dim = NULL, .func = NULL}};
117
src/collectors/windows.plugin/windows_plugin.h
+35 -1
@@ -33,6 +33,7 @@ int do_PerflibADCS(int update_every, usec_t dt);
33 int do_PerflibADFS(int update_every, usec_t dt);
34 int do_PerflibHyperV(int update_every, usec_t dt);
35 int do_PerflibServices(int update_every, usec_t dt);
36 +int do_PerflibExchange(int update_every, usec_t dt __maybe_unused);
37
38 enum PERFLIB_PRIO {
39 PRIO_WEBSITE_IIS_REQUESTS_RATE = 21000, // PRIO selected, because APPS is using 20YYY
@@ -220,7 +221,40 @@ enum PERFLIB_PRIO {
221 PRIO_ADFS_SSO_AUTH,
222 PRIO_ADFS_TRUST_TOKEN_SUCCESS,
223 PRIO_ADFS_USER_PASS_AUTH,
223 - PRIO_ADFS_WSFED_TOKEN_REQUESTS
224 + PRIO_ADFS_WSFED_TOKEN_REQUESTS,
225 +
226 + PRIO_EXCHANGE_QUEUE_ACTIVE_MAILBOX_DELIVERY,
227 + PRIO_EXCHANGE_QUEUE_EXTERNAL_ACTIVE_REMOTE_DELIVERY,
228 + PRIO_EXCHANGE_QUEUE_EXTERNAL_LARGEST_DELIVERY,
229 + PRIO_EXCHANGE_QUEUE_INTERNAL_ACTIVE_REMOTE_DELIVERY,
230 + PRIO_EXCHANGE_QUEUE_INTERNAL_LARGEST_DELIVERY,
231 + PRIO_EXCHANGE_QUEUE_RETRY_MAILBOX_DELIVERY,
232 + PRIO_EXCHANGE_QUEUE_UNREACHABLE,
233 + PRIO_EXCHANGE_QUEUE_POISON,
234 + PRIO_EXCHANGE_ACTIVE_SYNC_PING_CMDS_PENDING,
235 + PRIO_EXCHANGE_ACTIVE_SYNC_REQUESTS,
236 + PRIO_EXCHANGE_ACTIVE_SYNC_CMDS,
237 + PRIO_EXCHANGE_RPC_ACTIVE_USERS_COUNT,
238 + PRIO_EXCHANGE_RPC_AVG_LATENCY,
239 + PRIO_EXCHANGE_RPC_CONNECTION_COUNT,
240 + PRIO_EXCHANGE_RPC_OPERATIONS_TOTAL,
241 + PRIO_EXCHANGE_RPC_REQUESTS,
242 + PRIO_EXCHANGE_RPC_USER_COUNT,
243 + PRIO_EXCHANGE_OWA_REQUESTS_TOTAL,
244 + PRIO_EXCHANGE_OWA_UNIQUE_USERS,
245 + PRIO_EXCHANGE_WORKlOAD_ACTIVE_TASKS,
246 + PRIO_EXCHANGE_WORKlOAD_COMPLETE_TASKS,
247 + PRIO_EXCHANGE_WORKlOAD_QUEUE_TASKS,
248 + PRIO_EXCHANGE_WORKlOAD_YIELDED_TASKS,
249 + PRIO_EXCHANGE_WORKlOAD_ACTIVITY,
250 + PRIO_EXCHANGE_PROXY_AVG_AUTH_LATENCY,
251 + PRIO_EXCHANGE_PROXY_AVG_CAS_PROCESSING_LATENCY,
252 + PRIO_EXCHANGE_PROXY_MAILBOX_PROXY_FAILURE,
253 + PRIO_EXCHANGE_PROXY_SERVER_LOCATIOR_AVG_LATENCY,
254 + PRIO_EXCHANGE_PROXY_OUTSTANDING_PROXY_REQUESTS,
255 + PRIO_EXCHANGE_PROXY_PROXY_REQUESTS_TOTAL,
256 + PRIO_EXCHANGE_AUTO_DISCOVER_REQUESTS,
257 + PRIO_EXCHANGE_AUTO_AVAILABILITY_SERVICES
258 };
259
260 #endif //NETDATA_WINDOWS_PLUGIN_H