master
h 819 lines 27.2 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_APPS_PLUGIN_H
4 #define NETDATA_APPS_PLUGIN_H
5
6 #include "collectors/all.h"
7 #include "libnetdata/libnetdata.h"
8
9 #define OS_FUNC_CONCAT(a, b) a##b
10
11 #if defined(OS_FREEBSD)
12 #include <sys/user.h>
13
14 #define OS_INIT_PID 1
15 #define ALL_PIDS_ARE_READ_INSTANTLY 1
16 #define PROCESSES_HAVE_CPU_GUEST_TIME 0
17 #define PROCESSES_HAVE_CPU_CHILDREN_TIME 1
18 #define PROCESSES_HAVE_VOLCTX 0
19 #define PROCESSES_HAVE_NVOLCTX 0
20 #define PROCESSES_HAVE_PHYSICAL_IO 0
21 #define PROCESSES_HAVE_LOGICAL_IO 1
22 #define PROCESSES_HAVE_IO_CALLS 0
23 #define PROCESSES_HAVE_UID 1
24 #define PROCESSES_HAVE_GID 1
25 #define PROCESSES_HAVE_SID 0
26 #define PROCESSES_HAVE_MAJFLT 1
27 #define PROCESSES_HAVE_CHILDREN_FLTS 1
28 #define PROCESSES_HAVE_VMSWAP 0
29 #define PROCESSES_HAVE_VMSHARED 0
30 #define PROCESSES_HAVE_RSSFILE 0
31 #define PROCESSES_HAVE_RSSSHMEM 0
32 #define PROCESSES_HAVE_FDS 1
33 #define PROCESSES_HAVE_HANDLES 0
34 #define PROCESSES_HAVE_CMDLINE 1
35 #define PROCESSES_HAVE_PID_LIMITS 0
36 #define PROCESSES_HAVE_COMM_AND_NAME 0
37 #define PROCESSES_HAVE_STATE 0
38 #define PPID_SHOULD_BE_RUNNING 1
39 #define INCREMENTAL_DATA_COLLECTION 1
40 #define CPU_TO_NANOSECONDCORES (1)
41 #define OS_FUNCTION(func) OS_FUNC_CONCAT(func, _freebsd)
42
43 #elif defined(OS_MACOS)
44 #include <mach/mach.h>
45 #include <mach/mach_host.h>
46 #include <libproc.h>
47 #include <sys/proc_info.h>
48 #include <sys/sysctl.h>
49 #include <mach/mach_time.h> // For mach_timebase_info_data_t and mach_timebase_info
50 #include <AvailabilityMacros.h>
51
52 struct pid_info {
53 struct kinfo_proc proc;
54 struct proc_taskinfo taskinfo;
55 struct proc_bsdinfo bsdinfo;
56 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
57 struct rusage_info_v4 rusageinfo;
58 #endif
59 };
60
61 #define OS_INIT_PID 1
62 #define ALL_PIDS_ARE_READ_INSTANTLY 1
63 #define PROCESSES_HAVE_CPU_GUEST_TIME 0
64 #define PROCESSES_HAVE_CPU_CHILDREN_TIME 0
65 #define PROCESSES_HAVE_VOLCTX 1
66 #define PROCESSES_HAVE_NVOLCTX 0
67 #define PROCESSES_HAVE_PHYSICAL_IO 0
68 #define PROCESSES_HAVE_LOGICAL_IO 1
69 #define PROCESSES_HAVE_IO_CALLS 0
70 #define PROCESSES_HAVE_UID 1
71 #define PROCESSES_HAVE_GID 1
72 #define PROCESSES_HAVE_SID 0
73 #define PROCESSES_HAVE_MAJFLT 1
74 #define PROCESSES_HAVE_CHILDREN_FLTS 0
75 #define PROCESSES_HAVE_VMSWAP 0
76 #define PROCESSES_HAVE_VMSHARED 0
77 #define PROCESSES_HAVE_RSSFILE 0
78 #define PROCESSES_HAVE_RSSSHMEM 0
79 #define PROCESSES_HAVE_SMAPS_ROLLUP 0
80 #define PROCESSES_HAVE_FDS 1
81 #define PROCESSES_HAVE_HANDLES 0
82 #define PROCESSES_HAVE_CMDLINE 1
83 #define PROCESSES_HAVE_PID_LIMITS 0
84 #define PROCESSES_HAVE_COMM_AND_NAME 0
85 #define PROCESSES_HAVE_STATE 0
86 #define PPID_SHOULD_BE_RUNNING 1
87 #define INCREMENTAL_DATA_COLLECTION 1
88 #define CPU_TO_NANOSECONDCORES (1) // already in nanoseconds
89 #define OS_FUNCTION(func) OS_FUNC_CONCAT(func, _macos)
90
91 #elif defined(OS_WINDOWS)
92 #define OS_INIT_PID 0 // dynamic, is set during data collection
93 #define ALL_PIDS_ARE_READ_INSTANTLY 1
94 #define PROCESSES_HAVE_CPU_GUEST_TIME 0
95 #define PROCESSES_HAVE_CPU_CHILDREN_TIME 0
96 #define PROCESSES_HAVE_VOLCTX 0
97 #define PROCESSES_HAVE_NVOLCTX 0
98 #define PROCESSES_HAVE_PHYSICAL_IO 0
99 #define PROCESSES_HAVE_LOGICAL_IO 1
100 #define PROCESSES_HAVE_IO_CALLS 1
101 #define PROCESSES_HAVE_UID 0
102 #define PROCESSES_HAVE_GID 0
103 #define PROCESSES_HAVE_SID 1
104 #define PROCESSES_HAVE_SERVICE 1
105 #define PROCESSES_HAVE_MAJFLT 0
106 #define PROCESSES_HAVE_CHILDREN_FLTS 0
107 #define PROCESSES_HAVE_VMSWAP 1
108 #define PROCESSES_HAVE_VMSHARED 0
109 #define PROCESSES_HAVE_RSSFILE 0
110 #define PROCESSES_HAVE_RSSSHMEM 0
111 #define PROCESSES_HAVE_SMAPS_ROLLUP 0
112 #define PROCESSES_HAVE_FDS 0
113 #define PROCESSES_HAVE_HANDLES 1
114 #define PROCESSES_HAVE_CMDLINE 0
115 #define PROCESSES_HAVE_PID_LIMITS 0
116 #define PROCESSES_HAVE_COMM_AND_NAME 1
117 #define PROCESSES_HAVE_STATE 0
118 #define PPID_SHOULD_BE_RUNNING 0
119 #define INCREMENTAL_DATA_COLLECTION 0
120 #define CPU_TO_NANOSECONDCORES (100) // convert 100ns to ns
121 #define OS_FUNCTION(func) OS_FUNC_CONCAT(func, _windows)
122
123 #elif defined(OS_LINUX)
124 #define OS_INIT_PID 1
125 #define ALL_PIDS_ARE_READ_INSTANTLY 0
126 #define PROCESSES_HAVE_CPU_GUEST_TIME 1
127 #define PROCESSES_HAVE_CPU_CHILDREN_TIME 1
128 #define PROCESSES_HAVE_VOLCTX 1
129 #define PROCESSES_HAVE_NVOLCTX 1
130 #define PROCESSES_HAVE_PHYSICAL_IO 1
131 #define PROCESSES_HAVE_LOGICAL_IO 1
132 #define PROCESSES_HAVE_IO_CALLS 1
133 #define PROCESSES_HAVE_UID 1
134 #define PROCESSES_HAVE_GID 1
135 #define PROCESSES_HAVE_SID 0
136 #define PROCESSES_HAVE_MAJFLT 1
137 #define PROCESSES_HAVE_CHILDREN_FLTS 1
138 #define PROCESSES_HAVE_VMSWAP 1
139 #define PROCESSES_HAVE_VMSHARED 1
140 #define PROCESSES_HAVE_RSSFILE 1
141 #define PROCESSES_HAVE_RSSSHMEM 1
142 #define PROCESSES_HAVE_SMAPS_ROLLUP 1
143 #define PROCESSES_HAVE_FDS 1
144 #define PROCESSES_HAVE_HANDLES 0
145 #define PROCESSES_HAVE_CMDLINE 1
146 #define PROCESSES_HAVE_PID_LIMITS 1
147 #define PROCESSES_HAVE_COMM_AND_NAME 0
148 #define PROCESSES_HAVE_STATE 1
149 #define PPID_SHOULD_BE_RUNNING 1
150 #define USE_APPS_GROUPS_CONF 1
151 #define INCREMENTAL_DATA_COLLECTION 1
152 #define CPU_TO_NANOSECONDCORES (NSEC_PER_SEC / system_hz)
153 #define OS_FUNCTION(func) OS_FUNC_CONCAT(func, _linux)
154
155 extern int max_fds_cache_seconds;
156
157 #else
158 #error "Unsupported operating system"
159 #endif
160
161 #if (PROCESSES_HAVE_UID == 1) && (PROCESSES_HAVE_SID == 1)
162 #error "Do not enable SID and UID at the same time"
163 #endif
164
165 // --------------------------------------------------------------------------------------------------------------------
166
167 #define MAX_SYSTEM_FD_TO_ALLOW_FILES_PROCESSING 100000
168
169 extern pid_t INIT_PID;
170
171 extern bool debug_enabled;
172
173 extern bool enable_detailed_uptime_charts;
174 extern bool enable_users_charts;
175 extern bool enable_groups_charts;
176 extern bool include_exited_childs;
177 extern bool enable_function_cmdline;
178 extern bool proc_pid_cmdline_is_needed;
179 extern int enable_file_charts;
180 extern bool obsolete_file_charts;
181
182 extern size_t
183 global_iterations_counter,
184 calls_counter,
185 file_counter,
186 filenames_allocated_counter,
187 inodes_changed_counter,
188 links_changed_counter,
189 targets_assignment_counter,
190 apps_groups_targets_count;
191
192 #if (PROCESSES_HAVE_CPU_GUEST_TIME == 1)
193 extern bool enable_guest_charts;
194 extern bool show_guest_time;
195 #endif
196
197 #if (ALL_PIDS_ARE_READ_INSTANTLY == 0)
198 extern kernel_uint_t
199 global_utime,
200 global_stime,
201 global_gtime;
202 #endif
203
204 // the normalization ratios, as calculated by normalize_utilization()
205 extern NETDATA_DOUBLE
206 utime_fix_ratio,
207 stime_fix_ratio,
208 gtime_fix_ratio,
209 minflt_fix_ratio,
210 majflt_fix_ratio,
211 cutime_fix_ratio,
212 cstime_fix_ratio,
213 cgtime_fix_ratio,
214 cminflt_fix_ratio,
215 cmajflt_fix_ratio;
216
217 extern size_t pagesize;
218
219 extern netdata_mutex_t apps_and_stdout_mutex;
220
221 // --------------------------------------------------------------------------------------------------------------------
222 // string lengths
223
224 #define MAX_CMDLINE 65536
225
226 // --------------------------------------------------------------------------------------------------------------------
227 // to avoid reallocating too frequently when we add file descriptors,
228 // we double the allocation at every increase request.
229
230 static inline uint32_t fds_new_size(uint32_t old_size, uint32_t new_fd) {
231 return MAX(old_size * 2, new_fd + 1); // 1 space always
232 }
233
234 // --------------------------------------------------------------------------------------------------------------------
235 // some variables for keeping track of processes count by states
236 #if (PROCESSES_HAVE_STATE == 1)
237 typedef enum {
238 PROC_STATUS_RUNNING = 0,
239 PROC_STATUS_SLEEPING_D, // uninterruptible sleep
240 PROC_STATUS_SLEEPING, // interruptible sleep
241 PROC_STATUS_ZOMBIE,
242 PROC_STATUS_STOPPED,
243 PROC_STATUS_END, //place holder for ending enum fields
244 } proc_state;
245
246 extern proc_state proc_state_count[PROC_STATUS_END];
247 extern const char *proc_states[];
248 #endif
249
250 // --------------------------------------------------------------------------------------------------------------------
251 // the rates we are going to send to netdata will have this detail a value of:
252 // - 1 will send just integer parts to netdata
253 // - 100 will send 2 decimal points
254 // - 1000 will send 3 decimal points
255 // etc.
256 #define RATES_DETAIL 10000ULL
257
258 #if (PROCESSES_HAVE_FDS == 1)
259 struct openfds {
260 kernel_uint_t files;
261 kernel_uint_t pipes;
262 kernel_uint_t sockets;
263 kernel_uint_t inotifies;
264 kernel_uint_t eventfds;
265 kernel_uint_t timerfds;
266 kernel_uint_t signalfds;
267 kernel_uint_t eventpolls;
268 kernel_uint_t other;
269 };
270 #define pid_openfds_sum(p) ((p)->openfds.files + (p)->openfds.pipes + (p)->openfds.sockets + (p)->openfds.inotifies + (p)->openfds.eventfds + (p)->openfds.timerfds + (p)->openfds.signalfds + (p)->openfds.eventpolls + (p)->openfds.other)
271 #endif
272
273 // --------------------------------------------------------------------------------------------------------------------
274 // target
275 //
276 // target is the structure that processes are aggregated to be reported
277 // to netdata.
278 //
279 // - Each entry in /etc/apps_groups.conf creates a target.
280 // - Each user and group used by a process in the system, creates a target.
281
282 struct pid_on_target {
283 int32_t pid;
284 struct pid_on_target *next;
285 };
286
287 typedef enum __attribute__((packed)) {
288 TARGET_TYPE_APP_GROUP = 1,
289 #if (PROCESSES_HAVE_UID == 1)
290 TARGET_TYPE_UID,
291 #endif
292 #if (PROCESSES_HAVE_GID == 1)
293 TARGET_TYPE_GID,
294 #endif
295 #if (PROCESSES_HAVE_SID == 1)
296 TARGET_TYPE_SID,
297 #endif
298 #if (PROCESSES_HAVE_SERVICE == 1)
299 TARGET_TYPE_SERVICE,
300 #endif
301 TARGET_TYPE_TREE,
302 } TARGET_TYPE;
303
304 typedef enum __attribute__((packed)) {
305 // CPU utilization time
306 // The values are expressed in "NANOSECONDCORES".
307 // 1 x "NANOSECONDCORE" = 1 x NSEC_PER_SEC (1 billion).
308 PDF_UTIME, // CPU user time
309 PDF_STIME, // CPU system time
310 #if (PROCESSES_HAVE_CPU_GUEST_TIME == 1)
311 PDF_GTIME, // CPU guest time
312 #endif
313 #if (PROCESSES_HAVE_CPU_CHILDREN_TIME == 1)
314 PDF_CUTIME, // exited children CPU user time
315 PDF_CSTIME, // exited children CPU system time
316 #if (PROCESSES_HAVE_CPU_GUEST_TIME == 1)
317 PDF_CGTIME, // exited children CPU guest time
318 #endif
319 #endif
320
321 PDF_MINFLT, // rate, unit: faults * RATES_DETAIL
322
323 #if (PROCESSES_HAVE_MAJFLT == 1)
324 PDF_MAJFLT, // rate, unit: faults * RATES_DETAIL
325 #endif
326
327 #if (PROCESSES_HAVE_CHILDREN_FLTS == 1)
328 PDF_CMINFLT, // rate, unit: faults * RATES_DETAIL
329 PDF_CMAJFLT, // rate, unit: faults * RATES_DETAIL
330 #endif
331
332 PDF_VMSIZE, // the current virtual memory used by the process, in bytes
333 PDF_VMRSS, // the resident memory used by the process, in bytes
334
335 #if (PROCESSES_HAVE_VMSHARED == 1)
336 PDF_VMSHARED, // the shared memory used by the process, in bytes
337 #endif
338
339 #if (PROCESSES_HAVE_SMAPS_ROLLUP == 1)
340 PDF_MEM_ESTIMATED, // estimated memory usage using smaps ratios, in bytes
341 PDF_PSS, // proportional set size, in bytes
342 #endif
343
344 #if (PROCESSES_HAVE_RSSFILE == 1)
345 PDF_RSSFILE, // unit: bytes
346 #endif
347
348 #if (PROCESSES_HAVE_RSSSHMEM == 1)
349 PDF_RSSSHMEM, // unit: bytes
350 #endif
351
352 #if (PROCESSES_HAVE_VMSWAP == 1)
353 PDF_VMSWAP, // the swap memory used by the process, in bytes
354 #endif
355
356 #if (PROCESSES_HAVE_VOLCTX == 1)
357 PDF_VOLCTX, // rate, unit: switches * RATES_DETAIL
358 #endif
359
360 #if (PROCESSES_HAVE_NVOLCTX == 1)
361 PDF_NVOLCTX, // rate, unit: switches * RATES_DETAIL
362 #endif
363
364 #if (PROCESSES_HAVE_LOGICAL_IO == 1)
365 PDF_LREAD, // rate, logical reads in bytes/sec * RATES_DETAIL
366 PDF_LWRITE, // rate, logical writes in bytes/sec * RATES_DETAIL
367 #endif
368
369 #if (PROCESSES_HAVE_PHYSICAL_IO == 1)
370 PDF_PREAD, // rate, physical reads in bytes/sec * RATES_DETAIL
371 PDF_PWRITE, // rate, physical writes in bytes/sec * RATES_DETAIL
372 #endif
373
374 #if (PROCESSES_HAVE_IO_CALLS == 1)
375 PDF_OREAD, // rate, read ops/sec * RATES_DETAIL
376 PDF_OWRITE, // rate, write ops/sec * RATES_DETAIL
377 #endif
378
379 PDF_UPTIME, // the process uptime in seconds
380 PDF_THREADS, // the number of threads
381 PDF_PROCESSES, // the number of processes
382
383 #if (PROCESSES_HAVE_HANDLES == 1)
384 PDF_HANDLES, // the number of handles the process maintains
385 #endif
386
387 // terminator
388 PDF_MAX
389 } PID_FIELD;
390
391 typedef struct apps_match {
392 bool starts_with:1;
393 bool ends_with:1;
394 STRING *compare;
395 SIMPLE_PATTERN *pattern;
396 } APPS_MATCH;
397
398 struct target {
399 STRING *id;
400 STRING *name;
401 STRING *clean_name;
402
403 TARGET_TYPE type;
404 APPS_MATCH match;
405 #if (PROCESSES_HAVE_UID == 1)
406 uid_t uid;
407 #endif
408 #if (PROCESSES_HAVE_GID == 1)
409 gid_t gid;
410 #endif
411 #if (PROCESSES_HAVE_SID == 1)
412 STRING *sid_name;
413 #endif
414 #if (PROCESSES_HAVE_SERVICE == 1)
415 STRING *service_name;
416 #endif
417
418 kernel_uint_t values[PDF_MAX];
419
420 kernel_uint_t uptime_min;
421 kernel_uint_t uptime_max;
422
423 #if (PROCESSES_HAVE_FDS == 1)
424 struct openfds openfds;
425 NETDATA_DOUBLE max_open_files_percent;
426 int *target_fds;
427 uint32_t target_fds_size;
428 #endif
429
430 bool exposed:1; // if set, we have sent this to netdata
431 bool needs_smaps_update:1;
432
433 struct pid_on_target *root_pid; // list of aggregated pids for target debugging
434
435 struct target *target; // the one that will be reported to netdata
436 struct target *next;
437 };
438
439 // --------------------------------------------------------------------------------------------------------------------
440 // internal flags
441 // handled in code (automatically set)
442
443 // log each problem once per process
444 // log flood protection flags (log_thrown)
445 typedef enum __attribute__((packed)) {
446 PID_LOG_IO = (1 << 0),
447 PID_LOG_STATUS = (1 << 1),
448 PID_LOG_CMDLINE = (1 << 2),
449 PID_LOG_FDS = (1 << 3),
450 PID_LOG_STAT = (1 << 4),
451 PID_LOG_LIMITS = (1 << 5),
452 PID_LOG_LIMITS_DETAIL = (1 << 6),
453 #if (PROCESSES_HAVE_SMAPS_ROLLUP == 1)
454 PID_LOG_SMAPS = (1 << 7),
455 #endif
456 } PID_LOG;
457
458 // --------------------------------------------------------------------------------------------------------------------
459 // pid_stat
460 //
461 // structure to store data for each process running
462 // see: man proc for the description of the fields
463
464 #if (PROCESSES_HAVE_PID_LIMITS == 1)
465 struct pid_limits {
466 // kernel_uint_t max_cpu_time;
467 // kernel_uint_t max_file_size;
468 // kernel_uint_t max_data_size;
469 // kernel_uint_t max_stack_size;
470 // kernel_uint_t max_core_file_size;
471 // kernel_uint_t max_resident_set;
472 // kernel_uint_t max_processes;
473 kernel_uint_t max_open_files;
474 // kernel_uint_t max_locked_memory;
475 // kernel_uint_t max_address_space;
476 // kernel_uint_t max_file_locks;
477 // kernel_uint_t max_pending_signals;
478 // kernel_uint_t max_msgqueue_size;
479 // kernel_uint_t max_nice_priority;
480 // kernel_uint_t max_realtime_priority;
481 // kernel_uint_t max_realtime_timeout;
482 };
483 #endif
484
485 struct pid_fd {
486 int fd;
487
488 #if defined(OS_LINUX)
489 ino_t inode;
490 char *filename;
491 uint32_t link_hash;
492 size_t cache_iterations_counter;
493 size_t cache_iterations_reset;
494 #endif
495 };
496
497 #define pid_stat_comm(p) (string2str((p)->comm))
498 #define pid_stat_cmdline(p) (string2str((p)->cmdline))
499 uint32_t all_files_len_get(void);
500
501 struct pid_stat {
502 int32_t pid;
503 int32_t ppid;
504 // int32_t pgrp;
505 // int32_t session;
506 // int32_t tty_nr;
507 // int32_t tpgid;
508 // uint64_t flags;
509
510 struct pid_stat *parent;
511 struct pid_stat *next;
512 struct pid_stat *prev;
513
514 struct target *target; // app_groups.conf/tree targets
515 struct target *prev_target;
516
517 #if (PROCESSES_HAVE_UID == 1)
518 struct target *uid_target; // uid based targets
519 #endif
520 #if (PROCESSES_HAVE_GID == 1)
521 struct target *gid_target; // gid based targets
522 #endif
523 #if (PROCESSES_HAVE_SID == 1)
524 struct target *sid_target; // sid based targets
525 #endif
526 #if (PROCESSES_HAVE_SERVICE == 1)
527 struct target *service_target; // service based targets
528 #endif
529
530 STRING *comm_orig; // the command, as-collected
531 STRING *comm; // the command, sanitized
532 STRING *name; // the command name, if any, sanitized
533 STRING *cmdline; // the full command line of the program
534
535 #if defined(OS_WINDOWS)
536 COUNTER_DATA perflib[PDF_MAX];
537 #else
538 kernel_uint_t raw[PDF_MAX];
539 #endif
540
541 kernel_uint_t values[PDF_MAX];
542
543 #if (PROCESSES_HAVE_UID == 1)
544 uid_t uid;
545 #endif
546 #if (PROCESSES_HAVE_GID == 1)
547 gid_t gid;
548 #endif
549 #if (PROCESSES_HAVE_SID == 1)
550 STRING *sid_name;
551 #endif
552 #if (PROCESSES_HAVE_SERVICE == 1)
553 STRING *service_name;
554 #endif
555
556 #if (ALL_PIDS_ARE_READ_INSTANTLY == 0)
557 uint32_t sortlist; // higher numbers = top on the process tree
558 // each process gets a unique number (non-sequential though)
559 #endif
560
561 #if (PROCESSES_HAVE_FDS == 1)
562 struct openfds openfds;
563 #if (PROCESSES_HAVE_PID_LIMITS == 1)
564 struct pid_limits limits;
565 NETDATA_DOUBLE openfds_limits_percent;
566 #endif
567 struct pid_fd *fds; // array of fds it uses
568 uint32_t fds_size; // the size of the fds array
569 #endif
570
571 uint32_t children_count; // the number of processes directly referencing this.
572 // used internally for apps_groups.conf inheritance.
573 // don't rely on it for anything else.
574
575 uint32_t keeploops; // increases by 1 every time keep is 1 and updated 0
576
577 PID_LOG log_thrown;
578
579 bool read:1; // true when we have already read this process for this iteration
580 bool updated:1; // true when the process is currently running
581 bool merged:1; // true when it has been merged to its parent
582 bool keep:1; // true when we need to keep this process in memory even after it exited
583 bool is_manager:1; // true when this pid is a process manager
584 bool is_aggregator:1; // true when this pid is a process aggregator
585
586 bool matched_by_config:1;
587
588 #if (PROCESSES_HAVE_STATE == 1)
589 char state;
590 #endif
591
592 #if defined(OS_WINDOWS)
593 bool got_info:1;
594 bool got_service:1;
595 bool initialized:1;
596 #endif
597
598 usec_t stat_collected_usec;
599 usec_t last_stat_collected_usec;
600
601 usec_t io_collected_usec;
602 usec_t last_io_collected_usec;
603 usec_t last_limits_collected_usec;
604
605 #if defined(OS_LINUX)
606 ARL_BASE *status_arl;
607 char *fds_dirname; // the full directory name in /proc/PID/fd
608 char *stat_filename;
609 char *status_filename;
610 char *io_filename;
611 char *cmdline_filename;
612 char *limits_filename;
613 #if (PROCESSES_HAVE_SMAPS_ROLLUP == 1)
614 char *smaps_rollup_filename;
615 ARL_BASE *smaps_rollup_arl;
616 kernel_uint_t vmshared_delta;
617 NETDATA_DOUBLE pss_total_ratio;
618 size_t last_pss_iteration;
619 kernel_uint_t pss_bytes;
620 #endif
621 #endif
622 };
623
624 // --------------------------------------------------------------------------------------------------------------------
625
626 extern int update_every;
627
628 // --------------------------------------------------------------------------------------------------------------------
629 // debugging
630
631 static inline void debug_log_int(const char *fmt, ... ) {
632 va_list args;
633
634 fprintf( stderr, "apps.plugin: ");
635 va_start( args, fmt );
636 vfprintf( stderr, fmt, args );
637 va_end( args );
638
639 fputc('\n', stderr);
640 }
641
642 #ifdef NETDATA_INTERNAL_CHECKS
643
644 #define debug_log(fmt, args...) do { if(unlikely(debug_enabled)) debug_log_int(fmt, ##args); } while(0)
645
646 #else
647
648 static inline void debug_log_dummy(void) {}
649 #define debug_log(fmt, args...) debug_log_dummy()
650
651 #endif
652 bool managed_log(struct pid_stat *p, PID_LOG log, bool status);
653 void sanitize_apps_plugin_chart_meta(char *buf);
654
655 // --------------------------------------------------------------------------------------------------------------------
656 // macro to calculate the incremental rate of a value
657 // each parameter is accessed only ONCE - so it is safe to pass function calls
658 // or other macros as parameters
659
660 #define incremental_rate(rate_variable, last_kernel_variable, new_kernel_value, collected_usec, last_collected_usec, multiplier) do { \
661 kernel_uint_t _new_tmp = new_kernel_value; \
662 (rate_variable) = (_new_tmp - (last_kernel_variable)) * (USEC_PER_SEC * (multiplier)) / ((collected_usec) - (last_collected_usec)); \
663 (last_kernel_variable) = _new_tmp; \
664 } while(0)
665
666 // the same macro for struct pid members
667 #define pid_incremental_rate(type, idx, value) \
668 incremental_rate(p->values[idx], p->raw[idx], value, p->type##_collected_usec, p->last_##type##_collected_usec, RATES_DETAIL)
669
670 #define pid_incremental_cpu(type, idx, value) \
671 incremental_rate(p->values[idx], p->raw[idx], value, p->type##_collected_usec, p->last_##type##_collected_usec, CPU_TO_NANOSECONDCORES)
672
673 void apps_managers_and_aggregators_init(void);
674 void apps_pids_init(void);
675
676 #if (PROCESSES_HAVE_CMDLINE == 1)
677 int read_proc_pid_cmdline(struct pid_stat *p);
678 #endif
679
680 #if (PROCESSES_HAVE_FDS == 1)
681 void clear_pid_fd(struct pid_fd *pfd);
682 void file_descriptor_not_used(int id);
683 void init_pid_fds(struct pid_stat *p, size_t first, size_t size);
684 void aggregate_pid_fds_on_targets(struct pid_stat *p);
685 int read_pid_file_descriptors(struct pid_stat *p, void *ptr);
686 void make_all_pid_fds_negative(struct pid_stat *p);
687 uint32_t file_descriptor_find_or_add(const char *name, uint32_t hash);
688 #endif
689
690 // --------------------------------------------------------------------------------------------------------------------
691 // data collection management
692
693 bool pid_match_check(struct pid_stat *p, APPS_MATCH *match);
694 APPS_MATCH pid_match_create(const char *comm);
695 void pid_match_cleanup(APPS_MATCH *m);
696
697 bool collect_data_for_all_pids(void);
698
699 void pid_collection_started(struct pid_stat *p);
700 void pid_collection_failed(struct pid_stat *p);
701 void pid_collection_completed(struct pid_stat *p);
702
703 #if (INCREMENTAL_DATA_COLLECTION == 1)
704 bool collect_parents_before_children(void);
705 int incrementally_collect_data_for_pid(pid_t pid, void *ptr);
706 int incrementally_collect_data_for_pid_stat(struct pid_stat *p, void *ptr);
707 #endif
708
709 // --------------------------------------------------------------------------------------------------------------------
710 // pid management
711
712 struct pid_stat *root_of_pids(void);
713 size_t all_pids_count(void);
714
715 struct pid_stat *get_or_allocate_pid_entry(pid_t pid);
716 struct pid_stat *find_pid_entry(pid_t pid);
717 void del_pid_entry(pid_t pid);
718 void update_pid_comm(struct pid_stat *p, const char *comm);
719 void update_pid_cmdline(struct pid_stat *p, const char *cmdline);
720
721 bool is_process_a_manager(struct pid_stat *p);
722 bool is_process_an_aggregator(struct pid_stat *p);
723 bool is_process_an_interpreter(struct pid_stat *p);
724
725 // --------------------------------------------------------------------------------------------------------------------
726 // targets management
727
728 struct target *find_target_by_name(struct target *base, const char *name);
729 struct target *get_tree_target(struct pid_stat *p);
730
731 void aggregate_processes_to_targets(void);
732
733 #if (PROCESSES_HAVE_UID == 1)
734 extern struct target *users_root_target;
735 struct target *get_uid_target(uid_t uid);
736 #endif
737
738 #if (PROCESSES_HAVE_GID == 1)
739 extern struct target *groups_root_target;
740 struct target *get_gid_target(gid_t gid);
741 #endif
742
743 #if (PROCESSES_HAVE_SID == 1)
744 extern struct target *sids_root_target;
745 struct target *get_sid_target(STRING *sid_name);
746 #endif
747
748 #if (PROCESSES_HAVE_SERVICE == 1)
749 extern bool enable_services_charts;
750 extern struct target *services_root_target;
751 struct target *get_service_target(STRING *service_name);
752 #endif
753
754 extern struct target *apps_groups_root_target;
755 int read_apps_groups_conf(const char *path, const char *file);
756
757 // --------------------------------------------------------------------------------------------------------------------
758 // output
759
760 void send_charts_updates_to_netdata(struct target *root, const char *type, const char *lbl_name, const char *title);
761 void send_collected_data_to_netdata(struct target *root, const char *type, usec_t dt);
762 void send_resource_usage_to_netdata(usec_t dt);
763
764 #if (PROCESSES_HAVE_STATE == 1)
765 void send_proc_states_count(usec_t dt);
766 #endif
767
768 #define APPS_PLUGIN_PROCESSES_FUNCTION_DESCRIPTION "Provides detailed process information including CPU usage, memory consumption, I/O statistics, file descriptors, page faults, and parent-child relationships (PPID) for all processes including those in containers."
769 void function_processes(const char *transaction, char *function,
770 usec_t *stop_monotonic_ut __maybe_unused, bool *cancelled __maybe_unused,
771 BUFFER *payload __maybe_unused, HTTP_ACCESS access,
772 const char *source __maybe_unused, void *data __maybe_unused);
773
774 // --------------------------------------------------------------------------------------------------------------------
775 // operating system functions
776
777 // one time initialization per operating system
778 void OS_FUNCTION(apps_os_init)(void);
779
780 // collect all the available information for all processes running
781 bool OS_FUNCTION(apps_os_collect_all_pids)(void);
782
783 bool OS_FUNCTION(apps_os_read_pid_status)(struct pid_stat *p, void *ptr);
784 bool OS_FUNCTION(apps_os_read_pid_stat)(struct pid_stat *p, void *ptr);
785 bool OS_FUNCTION(apps_os_read_pid_io)(struct pid_stat *p, void *ptr);
786
787 #if (PROCESSES_HAVE_PID_LIMITS == 1)
788 bool OS_FUNCTION(apps_os_read_pid_limits)(struct pid_stat *p, void *ptr);
789 #endif
790
791 #if (PROCESSES_HAVE_CMDLINE == 1)
792 bool OS_FUNCTION(apps_os_get_pid_cmdline)(struct pid_stat *p, char *cmdline, size_t bytes);
793 #endif
794
795 #if (PROCESSES_HAVE_FDS == 1)
796 bool OS_FUNCTION(apps_os_read_pid_fds)(struct pid_stat *p, void *ptr);
797 #endif
798
799 #if (PROCESSES_HAVE_SMAPS_ROLLUP == 1)
800 bool OS_FUNCTION(apps_os_read_pid_smaps_rollup)(struct pid_stat *p, void *ptr);
801 bool OS_FUNCTION(apps_os_have_smaps_rollup)(void);
802 static inline bool apps_os_have_smaps_rollup(void) {
803 return OS_FUNCTION(apps_os_have_smaps_rollup)();
804 }
805 extern int pss_refresh_period;
806 #else
807 static inline bool OS_FUNCTION(apps_os_read_pid_smaps_rollup)(struct pid_stat *p __maybe_unused, void *ptr __maybe_unused) { return false; }
808 static inline bool OS_FUNCTION(apps_os_have_smaps_rollup)(void) { return false; }
809 static inline bool apps_os_have_smaps_rollup(void) { return false; }
810 #endif
811
812 #if (ALL_PIDS_ARE_READ_INSTANTLY == 0)
813 bool OS_FUNCTION(apps_os_read_global_cpu_utilization)(void);
814 #endif
815
816 // return the total physical memory of the system, in bytes
817 uint64_t OS_FUNCTION(apps_os_get_total_memory)(void);
818
819 #endif //NETDATA_APPS_PLUGIN_H