master
c 196 lines 6.57 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "apps_plugin.h"
4
5 #if (INCREMENTAL_DATA_COLLECTION == 1)
6 bool managed_log(struct pid_stat *p, PID_LOG log, bool status) {
7 if(unlikely(!status)) {
8 // netdata_log_error("command failed log %u, errno %d", log, errno);
9
10 if(unlikely(debug_enabled || errno != ENOENT)) {
11 if(unlikely(debug_enabled || !(p->log_thrown & log))) {
12 p->log_thrown |= log;
13 switch(log) {
14 case PID_LOG_IO:
15 #if !defined(OS_LINUX)
16 netdata_log_error("Cannot fetch process %d I/O info (command '%s')", p->pid, pid_stat_comm(p));
17 #else
18 netdata_log_error("Cannot process %s/proc/%d/io (command '%s')", netdata_configured_host_prefix, p->pid, pid_stat_comm(p));
19 #endif
20 break;
21
22 case PID_LOG_STATUS:
23 #if !defined(OS_LINUX)
24 netdata_log_error("Cannot fetch process %d status info (command '%s')", p->pid, pid_stat_comm(p));
25 #else
26 netdata_log_error("Cannot process %s/proc/%d/status (command '%s')", netdata_configured_host_prefix, p->pid, pid_stat_comm(p));
27 #endif
28 break;
29
30 case PID_LOG_CMDLINE:
31 #if !defined(OS_LINUX)
32 netdata_log_error("Cannot fetch process %d command line (command '%s')", p->pid, pid_stat_comm(p));
33 #else
34 netdata_log_error("Cannot process %s/proc/%d/cmdline (command '%s')", netdata_configured_host_prefix, p->pid, pid_stat_comm(p));
35 #endif
36 break;
37
38 case PID_LOG_FDS:
39 #if !defined(OS_LINUX)
40 netdata_log_error("Cannot fetch process %d files (command '%s')", p->pid, pid_stat_comm(p));
41 #else
42 netdata_log_error("Cannot process entries in %s/proc/%d/fd (command '%s')", netdata_configured_host_prefix, p->pid, pid_stat_comm(p));
43 #endif
44 break;
45
46 case PID_LOG_LIMITS:
47 #if !defined(OS_LINUX)
48 ;
49 #else
50 netdata_log_error("Cannot process %s/proc/%d/limits (command '%s')", netdata_configured_host_prefix, p->pid, pid_stat_comm(p));
51 #endif
52
53 case PID_LOG_LIMITS_DETAIL:
54 break;
55
56 #if (PROCESSES_HAVE_SMAPS_ROLLUP == 1)
57 case PID_LOG_SMAPS:
58 netdata_log_error("Cannot process %s/proc/%d/smaps_rollup (command '%s')", netdata_configured_host_prefix, p->pid, pid_stat_comm(p));
59 break;
60 #endif
61
62 case PID_LOG_STAT:
63 break;
64
65 default:
66 netdata_log_error("unhandled error for pid %d, command '%s'", p->pid, pid_stat_comm(p));
67 break;
68 }
69 }
70 }
71 errno_clear();
72 }
73 else if(unlikely(p->log_thrown & log)) {
74 // netdata_log_error("unsetting log %u on pid %d", log, p->pid);
75 p->log_thrown &= ~log;
76 }
77
78 return status;
79 }
80
81 static inline bool incrementally_read_pid_stat(struct pid_stat *p, void *ptr) {
82 p->last_stat_collected_usec = p->stat_collected_usec;
83 p->stat_collected_usec = now_monotonic_usec();
84 calls_counter++;
85
86 if(!OS_FUNCTION(apps_os_read_pid_stat)(p, ptr))
87 return 0;
88
89 return 1;
90 }
91
92 static inline int incrementally_read_pid_io(struct pid_stat *p, void *ptr) {
93 p->last_io_collected_usec = p->io_collected_usec;
94 p->io_collected_usec = now_monotonic_usec();
95 calls_counter++;
96
97 bool ret = OS_FUNCTION(apps_os_read_pid_io)(p, ptr);
98
99 return ret ? 1 : 0;
100 }
101
102 // --------------------------------------------------------------------------------------------------------------------
103
104 int incrementally_collect_data_for_pid_stat(struct pid_stat *p, void *ptr) {
105 if(unlikely(p->read)) return 0;
106
107 pid_collection_started(p);
108
109 // --------------------------------------------------------------------
110 // /proc/<pid>/stat
111
112 if(unlikely(!managed_log(p, PID_LOG_STAT, incrementally_read_pid_stat(p, ptr)))) {
113 // there is no reason to proceed if we cannot get its status
114 pid_collection_failed(p);
115 return 0;
116 }
117
118 // check its parent pid
119 if(unlikely(p->ppid < INIT_PID))
120 p->ppid = 0;
121
122 // --------------------------------------------------------------------
123 // /proc/<pid>/io
124
125 managed_log(p, PID_LOG_IO, incrementally_read_pid_io(p, ptr));
126
127 // --------------------------------------------------------------------
128 // /proc/<pid>/status
129
130 if(unlikely(!managed_log(p, PID_LOG_STATUS, OS_FUNCTION(apps_os_read_pid_status)(p, ptr)))) {
131 // there is no reason to proceed if we cannot get its status
132 pid_collection_failed(p);
133 return 0;
134 }
135
136 // --------------------------------------------------------------------
137 // /proc/<pid>/fd
138
139 #if (PROCESSES_HAVE_FDS == 1)
140 if(enable_file_charts) {
141 managed_log(p, PID_LOG_FDS, read_pid_file_descriptors(p, ptr));
142 #if (PROCESSES_HAVE_PID_LIMITS == 1)
143 managed_log(p, PID_LOG_LIMITS, OS_FUNCTION(apps_os_read_pid_limits)(p, ptr));
144 #endif
145 }
146 #endif
147
148 // --------------------------------------------------------------------
149 // done!
150
151 #if defined(NETDATA_INTERNAL_CHECKS) && (ALL_PIDS_ARE_READ_INSTANTLY == 0)
152 struct pid_stat *pp = p->parent;
153 if(unlikely(include_exited_childs && pp && !pp->read))
154 nd_log(NDLS_COLLECTORS, NDLP_WARNING,
155 "Read process %d (%s) sortlisted %"PRIu32", but its parent %d (%s) sortlisted %"PRIu32", is not read",
156 p->pid, pid_stat_comm(p), p->sortlist, pp->pid, pid_stat_comm(pp), pp->sortlist);
157 #endif
158
159 pid_collection_completed(p);
160
161 return 1;
162 }
163
164 int incrementally_collect_data_for_pid(pid_t pid, void *ptr) {
165 if(unlikely(pid < INIT_PID)) {
166 netdata_log_error("Invalid pid %d read (expected >= %d). Ignoring process.", pid, INIT_PID);
167 return 0;
168 }
169
170 struct pid_stat *p = get_or_allocate_pid_entry(pid);
171 if(unlikely(!p)) return 0;
172
173 return incrementally_collect_data_for_pid_stat(p, ptr);
174 }
175 #endif
176
177 // --------------------------------------------------------------------------------------------------------------------
178
179 #if (PROCESSES_HAVE_CMDLINE == 1)
180 int read_proc_pid_cmdline(struct pid_stat *p) {
181 static char cmdline[MAX_CMDLINE];
182
183 if(unlikely(!OS_FUNCTION(apps_os_get_pid_cmdline)(p, cmdline, sizeof(cmdline))))
184 goto cleanup;
185
186 update_pid_cmdline(p, cmdline);
187
188 return 1;
189
190 cleanup:
191 // copy the command to the command line
192 string_freez(p->cmdline);
193 p->cmdline = NULL;
194 return 0;
195 }
196 #endif