master
c 304 lines 9.66 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "windows_plugin.h"
4 #include "windows-internals.h"
5
6 struct smb_share {
7 usec_t last_collected;
8
9 RRDSET *st_current_open_file_count;
10 RRDSET *st_tree_connect_count;
11 RRDSET *st_received_bytes;
12 RRDSET *st_write_requests;
13 RRDSET *st_read_requests;
14 RRDSET *st_metadata_requests;
15 RRDSET *st_sent_bytes;
16 RRDSET *st_files_opened;
17
18 RRDDIM *rd_current_open_file_count;
19 RRDDIM *rd_tree_connect_count;
20 RRDDIM *rd_received_bytes;
21 RRDDIM *rd_write_requests;
22 RRDDIM *rd_read_requests;
23 RRDDIM *rd_metadata_requests;
24 RRDDIM *rd_sent_bytes;
25 RRDDIM *rd_files_opened;
26
27 COUNTER_DATA currentOpenFileCount;
28 COUNTER_DATA treeConnectCount;
29 COUNTER_DATA receivedBytes;
30 COUNTER_DATA writeRequests;
31 COUNTER_DATA readRequests;
32 COUNTER_DATA metadataRequests;
33 COUNTER_DATA sentBytes;
34 COUNTER_DATA filesOpened;
35 };
36
37 static DICTIONARY *smb_shares = NULL;
38
39 static void smb_share_initialize(struct smb_share *share)
40 {
41 share->currentOpenFileCount.key = "Current Open File Count";
42 share->treeConnectCount.key = "Tree Connect Count";
43 share->receivedBytes.key = "Received Bytes/sec";
44 share->writeRequests.key = "Write Requests/sec";
45 share->readRequests.key = "Read Requests/sec";
46 share->metadataRequests.key = "Metadata Requests/sec";
47 share->sentBytes.key = "Sent Bytes/sec";
48 share->filesOpened.key = "Files Opened/sec";
49 }
50
51 static void smb_share_cleanup(struct smb_share *share)
52 {
53 rrdset_is_obsolete___safe_from_collector_thread(share->st_current_open_file_count);
54 rrdset_is_obsolete___safe_from_collector_thread(share->st_tree_connect_count);
55 rrdset_is_obsolete___safe_from_collector_thread(share->st_received_bytes);
56 rrdset_is_obsolete___safe_from_collector_thread(share->st_write_requests);
57 rrdset_is_obsolete___safe_from_collector_thread(share->st_read_requests);
58 rrdset_is_obsolete___safe_from_collector_thread(share->st_metadata_requests);
59 rrdset_is_obsolete___safe_from_collector_thread(share->st_sent_bytes);
60 rrdset_is_obsolete___safe_from_collector_thread(share->st_files_opened);
61 }
62
63 static void dict_smb_share_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
64 {
65 struct smb_share *share = value;
66
67 smb_share_initialize(share);
68 }
69
70 static void dict_smb_share_delete_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
71 {
72 struct smb_share *share = value;
73
74 smb_share_cleanup(share);
75 }
76
77 static void initialize(void)
78 {
79 smb_shares = dictionary_create_advanced(
80 DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct smb_share));
81
82 dictionary_register_insert_callback(smb_shares, dict_smb_share_insert_cb, NULL);
83 dictionary_register_delete_callback(smb_shares, dict_smb_share_delete_cb, NULL);
84 }
85
86 static void smb_share_chart(
87 RRDSET **st,
88 RRDDIM **rd,
89 COUNTER_DATA *counter,
90 int update_every,
91 const char *share,
92 const char *id_suffix,
93 const char *context,
94 const char *title,
95 const char *units,
96 int priority,
97 const char *dimension)
98 {
99 if (!counter->updated)
100 return;
101
102 if (unlikely(!*st)) {
103 char id[RRD_ID_LENGTH_MAX + 1];
104 snprintfz(id, sizeof(id), "smb_share_%s_%s", share, id_suffix);
105 netdata_fix_chart_name(id);
106
107 *st = rrdset_create_localhost(
108 "smb",
109 id,
110 NULL,
111 "shares",
112 context,
113 title,
114 units,
115 PLUGIN_WINDOWS_NAME,
116 "PerflibSMB",
117 priority,
118 update_every,
119 RRDSET_TYPE_LINE);
120
121 *rd = perflib_rrddim_add(*st, dimension, NULL, 1, 1, counter);
122 rrdlabels_add((*st)->rrdlabels, "share", share, RRDLABEL_SRC_AUTO);
123 }
124
125 perflib_rrddim_set_by_pointer(*st, *rd, counter);
126 rrdset_done(*st);
127 }
128
129 static bool do_smb_server_shares(PERF_DATA_BLOCK *pDataBlock, int update_every)
130 {
131 PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "SMB Server Shares");
132 if (!pObjectType)
133 return false;
134
135 usec_t now_ut = now_monotonic_usec();
136
137 PERF_INSTANCE_DEFINITION *pi = NULL;
138 for (LONG i = 0; i < pObjectType->NumInstances; i++) {
139 pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
140 if (!pi)
141 break;
142
143 if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
144 strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
145
146 struct smb_share *share = dictionary_set(smb_shares, windows_shared_buffer, NULL, sizeof(*share));
147 share->last_collected = now_ut;
148
149 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->currentOpenFileCount);
150 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->treeConnectCount);
151 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->receivedBytes);
152 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->writeRequests);
153 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->readRequests);
154 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->metadataRequests);
155 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->sentBytes);
156 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &share->filesOpened);
157
158 smb_share_chart(
159 &share->st_current_open_file_count,
160 &share->rd_current_open_file_count,
161 &share->currentOpenFileCount,
162 update_every,
163 windows_shared_buffer,
164 "current_open_file_count",
165 "smb.server_shares_current_open_file_count",
166 "Current open file count on the SMB share",
167 "files",
168 PRIO_SMB_SERVER_SHARES_CURRENT_OPEN_FILE_COUNT,
169 "open");
170
171 smb_share_chart(
172 &share->st_tree_connect_count,
173 &share->rd_tree_connect_count,
174 &share->treeConnectCount,
175 update_every,
176 windows_shared_buffer,
177 "tree_connect_count",
178 "smb.server_shares_tree_connect_count",
179 "Tree connect count on the SMB share",
180 "connections",
181 PRIO_SMB_SERVER_SHARES_TREE_CONNECT_COUNT,
182 "connections");
183
184 smb_share_chart(
185 &share->st_received_bytes,
186 &share->rd_received_bytes,
187 &share->receivedBytes,
188 update_every,
189 windows_shared_buffer,
190 "received_bytes",
191 "smb.server_shares_received_bytes",
192 "Received bytes on the SMB share",
193 "bytes/s",
194 PRIO_SMB_SERVER_SHARES_RECEIVED_BYTES,
195 "received");
196
197 smb_share_chart(
198 &share->st_write_requests,
199 &share->rd_write_requests,
200 &share->writeRequests,
201 update_every,
202 windows_shared_buffer,
203 "write_requests",
204 "smb.server_shares_write_requests",
205 "Write requests on the SMB share",
206 "requests/s",
207 PRIO_SMB_SERVER_SHARES_WRITE_REQUESTS,
208 "writes");
209
210 smb_share_chart(
211 &share->st_read_requests,
212 &share->rd_read_requests,
213 &share->readRequests,
214 update_every,
215 windows_shared_buffer,
216 "read_requests",
217 "smb.server_shares_read_requests",
218 "Read requests on the SMB share",
219 "requests/s",
220 PRIO_SMB_SERVER_SHARES_READ_REQUESTS,
221 "reads");
222
223 smb_share_chart(
224 &share->st_metadata_requests,
225 &share->rd_metadata_requests,
226 &share->metadataRequests,
227 update_every,
228 windows_shared_buffer,
229 "metadata_requests",
230 "smb.server_shares_metadata_requests",
231 "Metadata requests on the SMB share",
232 "requests/s",
233 PRIO_SMB_SERVER_SHARES_METADATA_REQUESTS,
234 "metadata");
235
236 smb_share_chart(
237 &share->st_sent_bytes,
238 &share->rd_sent_bytes,
239 &share->sentBytes,
240 update_every,
241 windows_shared_buffer,
242 "sent_bytes",
243 "smb.server_shares_sent_bytes",
244 "Sent bytes on the SMB share",
245 "bytes/s",
246 PRIO_SMB_SERVER_SHARES_SENT_BYTES,
247 "sent");
248
249 smb_share_chart(
250 &share->st_files_opened,
251 &share->rd_files_opened,
252 &share->filesOpened,
253 update_every,
254 windows_shared_buffer,
255 "files_opened",
256 "smb.server_shares_files_opened",
257 "Files opened on the SMB share",
258 "files/s",
259 PRIO_SMB_SERVER_SHARES_FILES_OPENED,
260 "opened");
261 }
262
263 // delete entries not seen in this collection cycle
264 {
265 struct smb_share *share;
266 dfe_start_write(smb_shares, share)
267 {
268 if (share->last_collected < now_ut)
269 dictionary_del(smb_shares, share_dfe.name);
270 }
271 dfe_done(share);
272 dictionary_garbage_collect(smb_shares);
273 }
274
275 return true;
276 }
277
278 void do_PerflibSMB_cleanup(void)
279 {
280 dictionary_destroy(smb_shares);
281 smb_shares = NULL;
282 }
283
284 int do_PerflibSMB(int update_every, usec_t dt __maybe_unused)
285 {
286 static bool initialized = false;
287
288 if (unlikely(!initialized)) {
289 initialize();
290 initialized = true;
291 }
292
293 DWORD id = RegistryFindIDByName("SMB Server Shares");
294 if (id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
295 return -1;
296
297 PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
298 if (!pDataBlock)
299 return -1;
300
301 do_smb_server_shares(pDataBlock, update_every);
302
303 return 0;
304 }