@cryptotaxi247 / netdata-1 / commits / c35a969dc

added cloud status in registry?action=hello (#15530)

Co-authored-by: ilyam8 <ilya@netdata.cloud>

Costa Tsaousis committed Jul 25, 2023 at 23:52 UTC c35a969dc835f08df3737873a366403b0dd30096
4 files changed +143 -154
collectors/apps.plugin/apps_plugin.c
+10
@@ -1411,6 +1411,16 @@ static inline int read_proc_pid_limits(struct pid_stat *p, void *ptr) {
1411 proc_pid_limits_buffer[MAX_PROC_PID_LIMITS - 1] = '\0';
1412
1413 p->limits.max_open_files = get_proc_pid_limits_limit(proc_pid_limits_buffer, PROC_PID_LIMITS_MAX_OPEN_FILES_KEY, sizeof(PROC_PID_LIMITS_MAX_OPEN_FILES_KEY) - 1, 0);
1414 + if(p->limits.max_open_files == 1) {
1415 + // it seems a bug in the kernel or something similar
1416 + // it sets max open files to 1 but the number of files
1417 + // the process has open are more than 1...
1418 + // https://github.com/netdata/netdata/issues/15443
1419 + p->limits.max_open_files = 0;
1420 + ret = 1;
1421 + goto cleanup;
1422 + }
1423 +
1424 p->last_limits_collected_usec = p->io_collected_usec;
1425 read_limits = true;
1426
collectors/debugfs.plugin/sys_devices_virtual_powercap.c
+126 -150
@@ -2,64 +2,37 @@
2
3 #include "debugfs_plugin.h"
4
5 -#define METRIC_ID "system.power_consumption"
6 -
7 -struct measurement_t {
8 - unsigned long long energy_uj;
9 - usec_t time_us;
10 -};
11 -
5 struct zone_t {
13 - char name[FILENAME_MAX + 1];
14 - char path[FILENAME_MAX + 1];
6 + char *zone_chart_id;
7 + char *subzone_chart_id;
8 + char *name;
9 + char *path;
10 +
11 unsigned long long max_energy_range_uj;
16 - struct measurement_t measurement;
17 -};
12 + unsigned long long energy_uj;
13
19 -static int g_zones_count = 0;
20 -static struct zone_t *g_zones = NULL;
14 + struct zone_t *subzones;
15
22 -static int get_measurement(const char *path, struct measurement_t *measurement)
23 -{
24 - int result;
25 - if (likely((result = read_single_number_file(path, &measurement->energy_uj)) == 0)) {
26 - measurement->time_us = now_monotonic_high_precision_usec();
27 - }
28 - return result;
29 -}
16 + struct zone_t *prev, *next;
17 +};
18
31 -static double
32 -calculate_watts(unsigned long long max_energy_range_uj, struct measurement_t *before, struct measurement_t *after)
33 -{
34 - unsigned long long energy_uj = 0;
35 - usec_t delta_us = after->time_us - before->time_us;
36 - if (unlikely(delta_us == 0)) {
37 - return 0;
38 - }
19 +static struct zone_t *rapl_zones = NULL;
20
40 - if (likely(after->energy_uj >= before->energy_uj)) {
41 - energy_uj = after->energy_uj - before->energy_uj;
42 - } else {
43 - energy_uj = after->energy_uj + (max_energy_range_uj - before->energy_uj);
44 - }
45 - return (double)energy_uj / delta_us;
21 +static bool get_measurement(const char *path, unsigned long long *energy_uj) {
22 + return read_single_number_file(path, energy_uj) == 0;
23 }
24
48 -static struct zone_t *
49 -get_zone(const char *control_type, struct zone_t *parent, const char *dirname, struct zone_t **zones, size_t *count)
50 -{
25 +static struct zone_t *get_rapl_zone(const char *control_type __maybe_unused, struct zone_t *parent __maybe_unused, const char *dirname) {
26 char temp[FILENAME_MAX + 1];
27 snprintfz(temp, FILENAME_MAX, "%s/%s", dirname, "name");
28
29 char name[FILENAME_MAX + 1] = "";
55 - if (read_file(temp, name, sizeof(name) - 1) != 0) {
30 + if (read_file(temp, name, sizeof(name) - 1) != 0)
31 return NULL;
57 - }
32
33 char *trimmed = trim(name);
60 - if (unlikely(trimmed == NULL || trimmed[0] == 0)) {
34 + if (unlikely(trimmed == NULL || trimmed[0] == 0))
35 return NULL;
62 - }
36
37 snprintfz(temp, FILENAME_MAX, "%s/%s", dirname, "max_energy_range_uj");
38 unsigned long long max_energy_range_uj = 0;
@@ -69,173 +42,176 @@ get_zone(const char *control_type, struct zone_t *parent, const char *dirname, s
42 }
43
44 snprintfz(temp, FILENAME_MAX, "%s/%s", dirname, "energy_uj");
72 - struct measurement_t measurement;
73 - if (unlikely(get_measurement(temp, &measurement) != 0)) {
74 - collector_error("%s: Cannot read %s", trimmed, temp);
45 + unsigned long long energy_uj;
46 + if (unlikely(!get_measurement(temp, &energy_uj))) {
47 + collector_info("%s: Cannot read %s", trimmed, temp);
48 return NULL;
49 }
50
78 - int parent_idx = -1;
79 - if (parent != NULL) {
80 - parent_idx = parent - *zones;
81 - }
51 + struct zone_t *zone = callocz(1, sizeof(*zone));
52
83 - *zones = (struct zone_t *)reallocz(*zones, sizeof(struct zone_t) * (*count + 1));
53 + zone->name = strdupz(trimmed);
54 + zone->path = strdupz(temp);
55
85 - struct zone_t *zone = &(*zones)[*count];
86 - strcpy(zone->path, temp);
87 - if (parent_idx >= 0) {
88 - snprintfz(zone->name, FILENAME_MAX, "%s/%s", (*zones)[parent_idx].name, trimmed);
89 - } else {
90 - snprintfz(zone->name, FILENAME_MAX, "%s/%s", control_type, trimmed);
91 - }
56 zone->max_energy_range_uj = max_energy_range_uj;
93 - zone->measurement = measurement;
57 + zone->energy_uj = energy_uj;
58
59 collector_info("Found zone: \"%s\"", zone->name);
60
97 - ++(*count);
98 -
61 return zone;
62 }
63
102 -static void
103 -look_for_zones(const char *control_type, struct zone_t *parent, const char *path, struct zone_t **zones, size_t *count)
104 -{
64 +static struct zone_t *look_for_rapl_zones(const char *control_type, struct zone_t *parent, const char *path, int depth) {
65 + if(depth > 2)
66 + return NULL;
67 +
68 + struct zone_t *base = NULL;
69 +
70 DIR *dir = opendir(path);
106 - if (unlikely(dir == NULL)) {
107 - return;
108 - }
71 + if (unlikely(dir == NULL))
72 + return NULL;
73
74 struct dirent *de = NULL;
75 while ((de = readdir(dir))) {
112 - if (de->d_type != DT_DIR || de->d_name[0] == '.') {
76 + if (de->d_type != DT_DIR || de->d_name[0] == '.')
77 + continue;
78 +
79 + if(strncmp(de->d_name, "intel-rapl:", 11) != 0)
80 continue;
114 - }
81
82 char zone_path[FILENAME_MAX + 1];
83 snprintfz(zone_path, FILENAME_MAX, "%s/%s", path, de->d_name);
84
119 - collector_info("Looking for zone in \"%s\"", zone_path);
85 + struct zone_t *zone = get_rapl_zone(control_type, parent, zone_path);
86 + if(zone) {
87 + DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(base, zone, prev, next);
88
121 - struct zone_t *zone = get_zone(control_type, parent, zone_path, zones, count);
122 - if (zone != NULL) {
123 - look_for_zones(control_type, zone, zone_path, zones, count);
89 + if(!parent)
90 + zone->subzones = look_for_rapl_zones(control_type, zone, zone_path, depth + 1);
91 }
92 }
93
94 closedir(dir);
95 + return base;
96 }
97
130 -static int get_rapl_zones(struct zone_t **zones)
131 -{
132 - *zones = NULL;
98 +static struct zone_t *get_main_rapl_zones(void) {
99 + struct zone_t *base = NULL;
100
101 char dirname[FILENAME_MAX + 1];
102 snprintfz(dirname, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/virtual/powercap");
103
104 DIR *dir = opendir(dirname);
138 - if (unlikely(dir == NULL)) {
105 + if (unlikely(dir == NULL))
106 return 0;
140 - }
141 -
142 - size_t count = 0;
107
108 struct dirent *de = NULL;
109 while ((de = readdir(dir))) {
146 - if (de->d_type != DT_DIR || de->d_name[0] == '.') {
110 + if (de->d_type != DT_DIR || de->d_name[0] == '.')
111 + continue;
112 +
113 + if(strncmp(de->d_name, "intel-rapl", 10) != 0)
114 continue;
148 - }
115
116 char control_type_path[FILENAME_MAX + 1];
117 snprintfz(control_type_path, FILENAME_MAX, "%s/%s", dirname, de->d_name);
118
119 collector_info("Looking at control type \"%s\"", de->d_name);
154 - look_for_zones(de->d_name, NULL, control_type_path, zones, &count);
120 + struct zone_t *zone = look_for_rapl_zones(de->d_name, NULL, control_type_path, 0);
121 + if(zone)
122 + DOUBLE_LINKED_LIST_APPEND_LIST_UNSAFE(base, zone, prev, next);
123 }
124 closedir(dir);
125
158 - return count;
159 -}
160 -
161 -static void send_chart(int update_every, const char *name)
162 -{
163 - fprintf(
164 - stdout,
165 - "CHART %s '' 'Power Consumption' 'Watts' 'power consumption' '' '%s' %d %d '%s' 'debugfs.plugin' ''\n",
166 - METRIC_ID,
167 - debugfs_rrdset_type_name(RRDSET_TYPE_LINE),
168 - NETDATA_CHART_PRIO_POWERCAP,
169 - update_every,
170 - name);
171 -}
172 -
173 -static void send_dimension(const char *zone_name)
174 -{
175 - fprintf(
176 - stdout,
177 - "DIMENSION '%s' '%s' %s 1 %d ''\n",
178 - zone_name,
179 - zone_name,
180 - debugfs_rrd_algorithm_name(RRD_ALGORITHM_ABSOLUTE),
181 - 1000);
182 -}
183 -
184 -static void send_begin()
185 -{
186 - fprintf(stdout, "BEGIN %s\n", METRIC_ID);
187 -}
188 -
189 -static void send_set(const char *zone_name, collected_number value)
190 -{
191 - fprintf(stdout, "SET %s = %lld\n", zone_name, value);
126 + return base;
127 }
128
194 -static void send_end_and_flush()
195 -{
196 - fprintf(stdout, "END\n");
197 - fflush(stdout);
198 -}
129 +int do_sys_devices_virtual_powercap(int update_every, const char *name __maybe_unused) {
130
200 -int do_sys_devices_virtual_powercap(int update_every, const char *name)
201 -{
202 - if (unlikely(g_zones_count <= 0)) {
203 - g_zones_count = get_rapl_zones(&g_zones);
204 - if (unlikely(g_zones_count < 0)) {
205 - collector_error("Failed to find powercap zones.");
206 - return 1;
207 - } else if (unlikely(g_zones_count == 0)) {
208 - collector_info("No powercap zones found.");
131 + if (unlikely(!rapl_zones)) {
132 + rapl_zones = get_main_rapl_zones();
133 + if (unlikely(!rapl_zones)) {
134 + collector_info("Failed to find powercap zones.");
135 return 1;
136 }
211 -
212 - send_chart(update_every, name);
213 -
214 - for (int ii = 0; ii < g_zones_count; ++ii) {
215 - send_dimension(g_zones[ii].name);
216 - }
217 -
218 - // This measurement is a derivative so start reporting on the next call
219 - return 0;
137 }
138
222 - send_begin();
139 + for(struct zone_t *zone = rapl_zones; zone ; zone = zone->next) {
140 + if(!zone->zone_chart_id) {
141 + char id[1000 + 1];
142 + snprintf(id, 1000, "cpu.powercap_intel_rapl_zone_%s", zone->name);
143 + zone->zone_chart_id = strdupz(id);
144 +
145 + fprintf(stdout,
146 + "CHART '%s' '' 'Intel RAPL Zone Power Consumption' 'Watts' 'powercap' '%s' '%s' %d %d '' 'debugfs.plugin' 'intel_rapl'\n",
147 + zone->zone_chart_id,
148 + "cpu.powercap_intel_rapl_zone",
149 + debugfs_rrdset_type_name(RRDSET_TYPE_LINE),
150 + NETDATA_CHART_PRIO_POWERCAP,
151 + update_every);
152 +
153 + fprintf(stdout,
154 + "CLABEL 'zone' '%s' 0\n"
155 + "CLABEL_COMMIT\n",
156 + zone->name);
157 +
158 + fprintf(stdout,
159 + "DIMENSION 'power' '' %s 1 1000000 ''\n",
160 + debugfs_rrd_algorithm_name(RRD_ALGORITHM_INCREMENTAL));
161 +
162 + // for the sub-zones
163 + snprintf(id, 1000, "cpu.powercap_intel_rapl_subzones_%s", zone->name);
164 + zone->subzone_chart_id = strdupz(id);
165 + fprintf(stdout,
166 + "CHART '%s' '' 'Intel RAPL Subzones Power Consumption' 'Watts' 'powercap' '%s' '%s' %d %d '' 'debugfs.plugin' 'intel_rapl'\n",
167 + zone->subzone_chart_id,
168 + "cpu.powercap_intel_rapl_subzones",
169 + debugfs_rrdset_type_name(RRDSET_TYPE_LINE),
170 + NETDATA_CHART_PRIO_POWERCAP + 1,
171 + update_every);
172 +
173 + fprintf(stdout,
174 + "CLABEL 'zone' '%s' 0\n"
175 + "CLABEL_COMMIT\n",
176 + zone->name);
177 +
178 + for(struct zone_t *subzone = zone->subzones; subzone ; subzone = subzone->next) {
179 + fprintf(stdout,
180 + "DIMENSION '%s' '' %s 1 1000000 ''\n",
181 + subzone->name,
182 + debugfs_rrd_algorithm_name(RRD_ALGORITHM_INCREMENTAL));
183 + }
184 + }
185
224 - for (int ii = 0; ii < g_zones_count; ++ii) {
225 - struct measurement_t measurement;
226 - struct zone_t *zone = &g_zones[ii];
186 + if(get_measurement(zone->path, &zone->energy_uj)) {
187 + fprintf(stdout,
188 + "BEGIN '%s'\n"
189 + "SET power = %lld\n"
190 + "END\n"
191 + , zone->zone_chart_id
192 + , zone->energy_uj);
193 + }
194
228 - if (unlikely(get_measurement(zone->path, &measurement) != 0)) {
229 - collector_error("%s: Cannot read %s", zone->name, zone->path);
230 - continue;
195 + if(zone->subzones) {
196 + fprintf(stdout,
197 + "BEGIN '%s'\n",
198 + zone->subzone_chart_id);
199 +
200 + for (struct zone_t *subzone = zone->subzones; subzone; subzone = subzone->next) {
201 + if(get_measurement(subzone->path, &subzone->energy_uj)) {
202 + fprintf(stdout,
203 + "SET '%s' = %lld\n",
204 + subzone->name,
205 + subzone->energy_uj);
206 + }
207 + }
208 +
209 + fprintf(stdout, "END\n");
210 }
232 - double watts = calculate_watts(zone->max_energy_range_uj, &zone->measurement, &measurement);
233 - zone->measurement = measurement;
211
235 - send_set(zone->name, (collected_number)(watts * 1000));
212 }
213
238 - send_end_and_flush();
214 + fflush(stdout);
215
216 return 0;
217 }
health/health.d/file_descriptors.conf
+2 -2
@@ -20,12 +20,12 @@
20 type: System
21 component: Process
22 os: linux
23 - module: !* *
23 + module: *
24 hosts: *
25 lookup: max -1m unaligned foreach *
26 units: %
27 every: 1m
28 warn: $this > (($status >= $WARNING) ? (85) : (90))
29 - delay: down 15m multiplier 1.5 max 1h
29 + delay: up 5m down 15m multiplier 1.5 max 1h
30 info: maximum utilization of open files among all application group PIDs
31 to: sysadmin
registry/registry.c
+5 -2
@@ -58,7 +58,7 @@ static inline void registry_set_person_cookie(struct web_client *w, REGISTRY_PER
58 static inline void registry_json_header(RRDHOST *host, struct web_client *w, const char *action, const char *status) {
59 buffer_flush(w->response.data);
60 w->response.data->content_type = CT_APPLICATION_JSON;
61 - buffer_json_initialize(w->response.data, "\"", "\"", 0, true, true);
61 + buffer_json_initialize(w->response.data, "\"", "\"", 0, true, false);
62 buffer_json_member_add_string(w->response.data, "action", action);
63 buffer_json_member_add_string(w->response.data, "status", status);
64 buffer_json_member_add_string(w->response.data, "hostname", rrdhost_registry_hostname(host));
@@ -186,8 +186,11 @@ int registry_request_hello_json(RRDHOST *host, struct web_client *w) {
186 }
187 buffer_json_object_close(w->response.data);
188
189 - buffer_json_member_add_string(w->response.data, "registry", registry.registry_to_announce);
189 + CLOUD_STATUS status = cloud_status();
190 + buffer_json_member_add_string(w->response.data, "cloud_status", cloud_status_to_string(status));
191 buffer_json_member_add_string(w->response.data, "cloud_base_url", registry.cloud_base_url);
192 +
193 + buffer_json_member_add_string(w->response.data, "registry", registry.registry_to_announce);
194 buffer_json_member_add_boolean(w->response.data, "anonymous_statistics", netdata_anonymous_statistics_enabled);
195
196 buffer_json_member_add_array(w->response.data, "nodes");