Add IPC shared memory charts (#5522)
Vladimir Kobal committed
Mar 6, 2019 at 20:19 UTC
9653ee0d6852030e4e89cc9d8cf8d6b96d6b74bc
3 files changed
+145
-22
collectors/all.h
+7
-7
@@ -53,13 +53,13 @@
53
#define NETDATA_CHART_PRIO_SYSTEM_SOFT_INTR 1100 // freebsd only
54
#define NETDATA_CHART_PRIO_SYSTEM_ENTROPY 1000
55
#define NETDATA_CHART_PRIO_SYSTEM_UPTIME 1000
56
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_QUEUES 990 // freebsd only
57
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_MESSAGES 1000
58
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_SIZE 1100
59
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_SEMAPHORES 1000
60
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_SEM_ARRAYS 1000
61
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_SEGS 1000 // freebsd only
62
-#define NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_SIZE 1000 // freebsd only
56
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_QUEUES 1200 // freebsd only
57
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_MESSAGES 1201
58
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_SIZE 1202
59
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_SEMAPHORES 1203
60
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_SEM_ARRAYS 1204
61
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_SEGS 1205
62
+#define NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_SIZE 1206
63
#define NETDATA_CHART_PRIO_SYSTEM_PACKETS 7001 // freebsd only
64
65
collectors/proc.plugin/README.md
+23
-12
@@ -387,12 +387,12 @@ and metrics:
387
388
```
389
[plugin:proc:/sys/class/power_supply]
390
- # battery capacity = yes
391
- # battery charge = no
392
- # battery energy = no
393
- # power supply voltage = no
394
- # keep files open = auto
395
- # directory to monitor = /sys/class/power_supply
390
+ # battery capacity = yes
391
+ # battery charge = no
392
+ # battery energy = no
393
+ # power supply voltage = no
394
+ # keep files open = auto
395
+ # directory to monitor = /sys/class/power_supply
396
```
397
398
#### notes
@@ -413,16 +413,27 @@ This way, alerts which match on these will still work.
413
414
## IPC
415
416
-This module monitors the number of semaphores, semaphore arrays, number of messages in message queues, and amount of memory used by message queues. As far as the message queue charts are dynamic, sane limits are applied for the number of dimensions per chart (the limit is configurable).
416
+### Monitored IPC metrics
417
418
-#### configuration
418
+- **number of messages in message queues**
419
+- **amount of memory used by message queues**
420
+- **number of semaphores**
421
+- **number of semaphore arrays**
422
+- **number of shared memory segments**
423
+- **amount of memory used by shared memory segments**
424
+
425
+As far as the message queue charts are dynamic, sane limits are applied for the number of dimensions per chart (the limit is configurable).
426
+
427
+### configuration
428
429
```
430
[plugin:proc:ipc]
422
- # semaphore totals = yes
423
- # message queues = yes
424
- # msg filename to monitor = /proc/sysvipc/msg
425
- # max dimensions in memory allowed = 50
431
+ # message queues = yes
432
+ # semaphore totals = yes
433
+ # shared memory totals = yes
434
+ # msg filename to monitor = /proc/sysvipc/msg
435
+ # shm filename to monitor = /proc/sysvipc/shm
436
+ # max dimensions in memory allowed = 50
437
```
438
439
[]()
collectors/proc.plugin/ipc.c
+115
-3
@@ -65,6 +65,11 @@ struct message_queue {
65
struct message_queue * next;
66
};
67
68
+struct shm_stats {
69
+ unsigned long long segments;
70
+ unsigned long long bytes;
71
+};
72
+
73
static inline int ipc_sem_get_limits(struct ipc_limits *lim) {
74
static procfile *ff = NULL;
75
static int error_shown = 0;
@@ -179,7 +184,7 @@ int ipc_msq_get_info(char *msg_filename, struct message_queue **message_queue_ro
184
struct message_queue *msq;
185
186
if(unlikely(!ff)) {
182
- ff = procfile_open(config_get("plugin:proc:ipc", "msg filename to monitor", msg_filename), " \t:", PROCFILE_FLAG_DEFAULT);
187
+ ff = procfile_open(msg_filename, " \t:", PROCFILE_FLAG_DEFAULT);
188
if(unlikely(!ff)) return 1;
189
}
190
@@ -230,10 +235,49 @@ int ipc_msq_get_info(char *msg_filename, struct message_queue **message_queue_ro
235
return 0;
236
}
237
238
+int ipc_shm_get_info(char *shm_filename, struct shm_stats *shm) {
239
+ static procfile *ff;
240
+
241
+ if(unlikely(!ff)) {
242
+ ff = procfile_open(shm_filename, " \t:", PROCFILE_FLAG_DEFAULT);
243
+ if(unlikely(!ff)) return 1;
244
+ }
245
+
246
+ ff = procfile_readall(ff);
247
+ if(unlikely(!ff)) return 1;
248
+
249
+ size_t lines = procfile_lines(ff);
250
+ size_t words = 0;
251
+
252
+ if(unlikely(lines < 2)) {
253
+ error("Cannot read %s. Expected 2 or more lines, read %zu.", ff->filename, lines);
254
+ return 1;
255
+ }
256
+
257
+ shm->segments = 0;
258
+ shm->bytes = 0;
259
+
260
+ // loop through all lines except the first and the last ones
261
+ size_t l;
262
+ for(l = 1; l < lines - 1; l++) {
263
+ words = procfile_linewords(ff, l);
264
+ if(unlikely(words < 2)) continue;
265
+ if(unlikely(words < 16)) {
266
+ error("Cannot read %s line. Expected 16 params, read %zu.", ff->filename, words);
267
+ continue;
268
+ }
269
+
270
+ shm->segments++;
271
+ shm->bytes += str2ull(procfile_lineword(ff, l, 3));
272
+ }
273
+
274
+ return 0;
275
+}
276
+
277
int do_ipc(int update_every, usec_t dt) {
278
(void)dt;
279
236
- static int do_sem = -1, do_msg = -1;
280
+ static int do_sem = -1, do_msg = -1, do_shm = -1;
281
static int read_limits_next = -1;
282
static struct ipc_limits limits;
283
static struct ipc_status status;
@@ -243,15 +287,21 @@ int do_ipc(int update_every, usec_t dt) {
287
static char *msg_filename = NULL;
288
static struct message_queue *message_queue_root = NULL;
289
static long long dimensions_limit;
290
+ static char *shm_filename = NULL;
291
292
if(unlikely(do_sem == -1)) {
248
- do_sem = config_get_boolean("plugin:proc:ipc", "semaphore totals", CONFIG_BOOLEAN_YES);
293
do_msg = config_get_boolean("plugin:proc:ipc", "message queues", CONFIG_BOOLEAN_YES);
294
+ do_sem = config_get_boolean("plugin:proc:ipc", "semaphore totals", CONFIG_BOOLEAN_YES);
295
+ do_shm = config_get_boolean("plugin:proc:ipc", "shared memory totals", CONFIG_BOOLEAN_YES);
296
297
char filename[FILENAME_MAX + 1];
298
+
299
snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/sysvipc/msg");
300
msg_filename = config_get("plugin:proc:ipc", "msg filename to monitor", filename);
301
302
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/sysvipc/shm");
303
+ shm_filename = config_get("plugin:proc:ipc", "shm filename to monitor", filename);
304
+
305
dimensions_limit = config_get_number("plugin:proc:ipc", "max dimensions in memory allowed", 50);
306
307
// make sure it works
@@ -460,5 +510,67 @@ int do_ipc(int update_every, usec_t dt) {
510
}
511
}
512
513
+ // --------------------------------------------------------------------
514
+
515
+ if(likely(do_shm != CONFIG_BOOLEAN_NO)) {
516
+ static RRDSET *st_shm_segments = NULL, *st_shm_bytes = NULL;
517
+ static RRDDIM *rd_shm_segments = NULL, *rd_shm_bytes = NULL;
518
+ struct shm_stats shm;
519
+
520
+ if(!ipc_shm_get_info(shm_filename, &shm)) {
521
+ if(unlikely(!st_shm_segments)) {
522
+ st_shm_segments = rrdset_create_localhost(
523
+ "system"
524
+ , "shared_memory_segments"
525
+ , NULL
526
+ , "ipc shared memory"
527
+ , NULL
528
+ , "IPC Shared Memory Number of Segments"
529
+ , "segments"
530
+ , PLUGIN_PROC_NAME
531
+ , "ipc"
532
+ , NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_SEGS
533
+ , update_every
534
+ , RRDSET_TYPE_STACKED
535
+ );
536
+
537
+ rd_shm_segments = rrddim_add(st_shm_segments, "segments", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
538
+ }
539
+ else
540
+ rrdset_next(st_shm_segments);
541
+
542
+ rrddim_set_by_pointer(st_shm_segments, rd_shm_segments, shm.segments);
543
+
544
+ rrdset_done(st_shm_segments);
545
+
546
+ // --------------------------------------------------------------------
547
+
548
+ if(unlikely(!st_shm_bytes)) {
549
+ st_shm_bytes = rrdset_create_localhost(
550
+ "system"
551
+ , "shared_memory_bytes"
552
+ , NULL
553
+ , "ipc shared memory"
554
+ , NULL
555
+ , "IPC Shared Memory Used Bytes"
556
+ , "bytes"
557
+ , PLUGIN_PROC_NAME
558
+ , "ipc"
559
+ , NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_SIZE
560
+ , update_every
561
+ , RRDSET_TYPE_STACKED
562
+ );
563
+
564
+ rd_shm_bytes = rrddim_add(st_shm_bytes, "bytes", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
565
+ }
566
+ else
567
+ rrdset_next(st_shm_bytes);
568
+
569
+ rrddim_set_by_pointer(st_shm_bytes, rd_shm_bytes, shm.bytes);
570
+
571
+ rrdset_done(st_shm_bytes);
572
+ }
573
+ }
574
+
575
return 0;
576
}