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");