summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@netdata.cloud>2024-02-02 22:44:20 +0200
committerGitHub <noreply@github.com>2024-02-02 20:44:20 +0000
commitde75ef2f6dccfa1d357d14b86179b8174c3745a5 (patch)
treecb261f2fc0c74e3580123e0d24ee8222a05ae154
parentbb8dfac31270375229e843f3ac143f77830718dc (diff)
add support for the info parameter to all external plugin functions (#16915)
* add support for the info parameter to all functions * add SO_CLOEXEC to inbound connections * network-connections aggregated view for servers with dozens of thousands of connections * optimized /proc/net files parsing; aggregated view of network-connections returns sorted sockets to avoid dancing visualization * local-sockets is now using aral * lower the payload returned by network-connections
-rw-r--r--collectors/apps.plugin/apps_plugin.c22
-rw-r--r--collectors/cgroups.plugin/cgroup-top.c2
-rw-r--r--collectors/diskspace.plugin/plugin_diskspace.c1
-rw-r--r--collectors/ebpf.plugin/ebpf_functions.c16
-rw-r--r--collectors/freeipmi.plugin/freeipmi_plugin.c24
-rw-r--r--collectors/network-viewer.plugin/network-connections-chart.html28
-rw-r--r--collectors/network-viewer.plugin/network-viewer.c864
-rw-r--r--collectors/plugins.d/local_listeners.c2
-rw-r--r--collectors/plugins.d/pluginsd_functions.c5
-rw-r--r--collectors/proc.plugin/proc_diskstats.c1
-rw-r--r--collectors/proc.plugin/proc_net_dev.c1
-rw-r--r--src/database/rrdfunctions-inflight.c1
-rw-r--r--src/database/rrdfunctions-streaming.c1
-rw-r--r--src/libnetdata/aral/aral.c6
-rw-r--r--src/libnetdata/aral/aral.h4
-rw-r--r--src/libnetdata/buffer/buffer.c6
-rw-r--r--src/libnetdata/inlined.h18
-rw-r--r--src/libnetdata/maps/local-sockets.h146
-rw-r--r--src/libnetdata/query_progress/progress.c1
-rw-r--r--src/libnetdata/socket/socket.c2
20 files changed, 760 insertions, 391 deletions
diff --git a/collectors/apps.plugin/apps_plugin.c b/collectors/apps.plugin/apps_plugin.c
index 4144787edc..7e0758f69f 100644
--- a/collectors/apps.plugin/apps_plugin.c
+++ b/collectors/apps.plugin/apps_plugin.c
@@ -4399,10 +4399,11 @@ static void apps_plugin_function_processes_help(const char *transaction) {
buffer_json_add_array_item_double(wb, _tmp); \
} while(0)
-static void function_processes(const char *transaction, char *function __maybe_unused,
+static void function_processes(const char *transaction, char *function,
usec_t *stop_monotonic_ut __maybe_unused, bool *cancelled __maybe_unused,
BUFFER *payload __maybe_unused, HTTP_ACCESS access,
const char *source __maybe_unused, void *data __maybe_unused) {
+ time_t now_s = now_realtime_sec();
struct pid_stat *p;
bool show_cmdline = http_access_user_has_enough_access_level_for_endpoint(
@@ -4418,6 +4419,7 @@ static void function_processes(const char *transaction, char *function __maybe_u
pid_t pid = 0;
uid_t uid = 0;
gid_t gid = 0;
+ bool info = false;
bool filter_pid = false, filter_uid = false, filter_gid = false;
@@ -4468,16 +4470,11 @@ static void function_processes(const char *transaction, char *function __maybe_u
apps_plugin_function_processes_help(transaction);
return;
}
- else {
- char msg[1024];
- snprintfz(msg, sizeof(msg), "Invalid parameter '%s'", keyword);
- pluginsd_function_json_error_to_stdout(transaction, HTTP_RESP_BAD_REQUEST, msg);
- return;
+ else if(strcmp(keyword, "info") == 0) {
+ info = true;
}
}
- time_t expires = now_realtime_sec() + update_every;
-
unsigned int cpu_divisor = time_factor * RATES_DETAIL / 100;
unsigned int memory_divisor = 1024;
unsigned int io_divisor = 1024 * RATES_DETAIL;
@@ -4487,9 +4484,13 @@ static void function_processes(const char *transaction, char *function __maybe_u
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", update_every);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", APPS_PLUGIN_PROCESSES_FUNCTION_DESCRIPTION);
buffer_json_member_add_array(wb, "data");
+ if(info)
+ goto close_and_send;
+
NETDATA_DOUBLE
UserCPU_max = 0.0
, SysCPU_max = 0.0
@@ -5251,10 +5252,11 @@ static void function_processes(const char *transaction, char *function __maybe_u
}
buffer_json_object_close(wb); // group_by
- buffer_json_member_add_time_t(wb, "expires", expires);
+close_and_send:
+ buffer_json_member_add_time_t(wb, "expires", now_s + update_every);
buffer_json_finalize(wb);
- pluginsd_function_result_to_stdout(transaction, HTTP_RESP_OK, "application/json", expires, wb);
+ pluginsd_function_result_to_stdout(transaction, HTTP_RESP_OK, "application/json", now_s + update_every, wb);
buffer_free(wb);
}
diff --git a/collectors/cgroups.plugin/cgroup-top.c b/collectors/cgroups.plugin/cgroup-top.c
index 7593aae3e5..aa413dad11 100644
--- a/collectors/cgroups.plugin/cgroup-top.c
+++ b/collectors/cgroups.plugin/cgroup-top.c
@@ -107,6 +107,7 @@ int cgroup_function_cgroup_top(BUFFER *wb, const char *function __maybe_unused)
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", 1);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", RRDFUNCTIONS_CGTOP_HELP);
buffer_json_member_add_array(wb, "data");
@@ -349,6 +350,7 @@ int cgroup_function_systemd_top(BUFFER *wb, const char *function __maybe_unused)
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", 1);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", RRDFUNCTIONS_CGTOP_HELP);
buffer_json_member_add_array(wb, "data");
diff --git a/collectors/diskspace.plugin/plugin_diskspace.c b/collectors/diskspace.plugin/plugin_diskspace.c
index 38b5ab42de..d93e743ae5 100644
--- a/collectors/diskspace.plugin/plugin_diskspace.c
+++ b/collectors/diskspace.plugin/plugin_diskspace.c
@@ -645,6 +645,7 @@ int diskspace_function_mount_points(BUFFER *wb, const char *function __maybe_unu
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", 1);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", RRDFUNCTIONS_DISKSPACE_HELP);
buffer_json_member_add_array(wb, "data");
diff --git a/collectors/ebpf.plugin/ebpf_functions.c b/collectors/ebpf.plugin/ebpf_functions.c
index feb4caf302..7876c9b945 100644
--- a/collectors/ebpf.plugin/ebpf_functions.c
+++ b/collectors/ebpf.plugin/ebpf_functions.c
@@ -292,6 +292,9 @@ static void ebpf_function_socket_manipulation(const char *transaction,
rw_spinlock_write_lock(&ebpf_judy_pid.index.rw_spinlock);
network_viewer_opt.enabled = CONFIG_BOOLEAN_YES;
uint32_t previous;
+ bool info = false;
+ time_t now_s = now_realtime_sec();
+
static const char *socket_help = {
"ebpf.plugin / socket\n"
"\n"
@@ -413,7 +416,8 @@ for (int i = 1; i < PLUGINSD_MAX_WORDS; i++) {
ebpf_function_help(transaction, socket_help);
rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
return;
- }
+ } else if (strncmp(keyword, "info", 4) == 0)
+ info = true;
}
rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
@@ -443,8 +447,12 @@ for (int i = 1; i < PLUGINSD_MAX_WORDS; i++) {
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", em->update_every);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", EBPF_PLUGIN_SOCKET_FUNCTION_DESCRIPTION);
+ if(info)
+ goto close_and_send;
+
// Collect data
buffer_json_member_add_array(wb, "data");
ebpf_socket_read_open_connections(wb, em);
@@ -652,12 +660,12 @@ for (int i = 1; i < PLUGINSD_MAX_WORDS; i++) {
}
buffer_json_object_close(wb); // group_by
- time_t expires = now_realtime_sec() + em->update_every;
- buffer_json_member_add_time_t(wb, "expires", expires);
+close_and_send:
+ buffer_json_member_add_time_t(wb, "expires", now_s + em->update_every);
buffer_json_finalize(wb);
// Lock necessary to avoid race condition
- pluginsd_function_result_begin_to_stdout(transaction, HTTP_RESP_OK, "application/json", expires);
+ pluginsd_function_result_begin_to_stdout(transaction, HTTP_RESP_OK, "application/json", now_s + em->update_every);
fwrite(buffer_tostring(wb), buffer_strlen(wb), 1, stdout);
diff --git a/collectors/freeipmi.plugin/freeipmi_plugin.c b/collectors/freeipmi.plugin/freeipmi_plugin.c
index b94d365c7b..2ef223c306 100644
--- a/collectors/freeipmi.plugin/freeipmi_plugin.c
+++ b/collectors/freeipmi.plugin/freeipmi_plugin.c
@@ -1475,14 +1475,31 @@ static void freeimi_function_sensors(const char *transaction, char *function __m
usec_t *stop_monotonic_ut __maybe_unused, bool *cancelled __maybe_unused,
BUFFER *payload __maybe_unused, HTTP_ACCESS access __maybe_unused,
const char *source __maybe_unused, void *data __maybe_unused) {
- time_t expires = now_realtime_sec() + update_every;
+ time_t now_s = now_realtime_sec();
BUFFER *wb = buffer_create(4096, NULL);
buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_NEWLINE_ON_ARRAY_ITEMS);
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", update_every);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", "View IPMI sensor readings and its state");
+
+ char function_copy[strlen(function) + 1];
+ memcpy(function_copy, function, sizeof(function_copy));
+ char *words[1024];
+ size_t num_words = quoted_strings_splitter_pluginsd(function_copy, words, 1024);
+ for(size_t i = 1; i < num_words ;i++) {
+ char *param = get_word(words, num_words, i);
+ if(strcmp(param, "info") == 0) {
+ buffer_json_member_add_array(wb, "accepted_params");
+ buffer_json_array_close(wb); // accepted_params
+ buffer_json_member_add_array(wb, "required_params");
+ buffer_json_array_close(wb); // required_params
+ goto close_and_send;
+ }
+ }
+
buffer_json_member_add_array(wb, "data");
struct sensor *sn;
@@ -1608,10 +1625,11 @@ static void freeimi_function_sensors(const char *transaction, char *function __m
}
buffer_json_array_close(wb);
- buffer_json_member_add_time_t(wb, "expires", now_realtime_sec() + 1);
+close_and_send:
+ buffer_json_member_add_time_t(wb, "expires", now_s + update_every);
buffer_json_finalize(wb);
- pluginsd_function_result_to_stdout(transaction, HTTP_RESP_OK, "application/json", expires, wb);
+ pluginsd_function_result_to_stdout(transaction, HTTP_RESP_OK, "application/json", now_s + update_every, wb);
buffer_free(wb);
}
diff --git a/collectors/network-viewer.plugin/network-connections-chart.html b/collectors/network-viewer.plugin/network-connections-chart.html
index 385e715ff6..dd66b9a005 100644
--- a/collectors/network-viewer.plugin/network-connections-chart.html
+++ b/collectors/network-viewer.plugin/network-connections-chart.html
@@ -557,15 +557,39 @@
const app = updateApps(svg, data, w, h, borderPadding, theme);
+ app.transition().duration(5000)
+
simulation = d3.forceSimulation(data)
//.force('center', d3.forceCenter(cw, ch).strength(1))
- .force("x", d3.forceX(d => d.d3.x).strength(0.05))
- .force("y", d3.forceY(d => d.d3.y).strength(0.05))
+ .force("x", d3.forceX(d => d.d3.x).strength(d => {
+ if(d.counts.listen === d.counts.total)
+ return 0.5
+ else
+ return 0.05
+ }))
+ .force("y", d3.forceY(d => d.d3.y).strength(d => {
+ if(d.counts.listen === d.counts.total)
+ return 0.5
+ else
+ return 0.05
+ }))
//.force("charge", d3.forceManyBody().strength(-0.05))
.force("collide", d3.forceCollide(d => d.d3.size * 1.1 + 15).strength(1))
.on('tick', ticked);
function ticked() {
+ data.forEach(d => {
+ if(d.x > w - d.d3.size)
+ d.x = w - d.d3.size;
+ else if(d.x < 0)
+ d.x = 0;
+
+ if(d.y > h - d.d3.size)
+ d.y = h - d.d3.size;
+ else if(d.y < 0)
+ d.y = 0;
+ });
+
app.attr('transform', d => `translate(${d.x}, ${d.y})`);
}
diff --git a/collectors/network-viewer.plugin/network-viewer.c b/collectors/network-viewer.plugin/network-viewer.c
index 130e56d715..8d9a451f34 100644
--- a/collectors/network-viewer.plugin/network-viewer.c
+++ b/collectors/network-viewer.plugin/network-viewer.c
@@ -3,12 +3,23 @@
#include "collectors/all.h"
#include "libnetdata/libnetdata.h"
#include "libnetdata/required_dummies.h"
+
+#define LOCAL_SOCKETS_EXTENDED_MEMBERS struct { \
+ size_t count; \
+ const char *local_address_space; \
+ const char *remote_address_space; \
+ } network_viewer;
+
#include "libnetdata/maps/local-sockets.h"
#include "libnetdata/maps/system-users.h"
#define NETWORK_CONNECTIONS_VIEWER_FUNCTION "network-connections"
#define NETWORK_CONNECTIONS_VIEWER_HELP "Network connections explorer"
+#define SIMPLE_HASHTABLE_VALUE_TYPE LOCAL_SOCKET
+#define SIMPLE_HASHTABLE_NAME _AGGREGATED_SOCKETS
+#include "libnetdata/simple_hashtable.h"
+
netdata_mutex_t stdout_mutex = NETDATA_MUTEX_INITIALIZER;
static bool plugin_should_exit = false;
static USERNAMES_CACHE *uc;
@@ -44,10 +55,7 @@ ENUM_STR_MAP_DEFINE(TCP_STATE) = {
};
ENUM_STR_DEFINE_FUNCTIONS(TCP_STATE, 0, "unknown");
-
-static void local_socket_to_array(struct local_socket_state *ls, struct local_socket *n, void *data) {
- BUFFER *wb = data;
-
+static void local_socket_to_json_array(BUFFER *wb, LOCAL_SOCKET *n, uint64_t proc_self_net_ns_inode, bool aggregated) {
char local_address[INET6_ADDRSTRLEN];
char remote_address[INET6_ADDRSTRLEN];
char *protocol;
@@ -66,7 +74,7 @@ static void local_socket_to_array(struct local_socket_state *ls, struct local_so
return;
const char *type;
- if(n->net_ns_inode == ls->proc_self_net_ns_inode)
+ if(n->net_ns_inode == proc_self_net_ns_inode)
type = "system";
else if(n->net_ns_inode == 0)
type = "[unknown]";
@@ -90,55 +98,141 @@ static void local_socket_to_array(struct local_socket_state *ls, struct local_so
else
buffer_json_add_array_item_string(wb, n->comm);
- buffer_json_add_array_item_string(wb, n->cmdline);
+ // buffer_json_add_array_item_string(wb, string2str(n->cmdline));
if(n->uid == UID_UNSET) {
- buffer_json_add_array_item_uint64(wb, n->uid);
+ // buffer_json_add_array_item_uint64(wb, n->uid);
buffer_json_add_array_item_string(wb, "[unknown]");
}
else {
- buffer_json_add_array_item_uint64(wb, n->uid);
+ // buffer_json_add_array_item_uint64(wb, n->uid);
STRING *u = system_usernames_cache_lookup_uid(uc, n->uid);
buffer_json_add_array_item_string(wb, string2str(u));
string_freez(u);
}
- buffer_json_add_array_item_string(wb, local_address);
- buffer_json_add_array_item_uint64(wb, n->local.port);
- buffer_json_add_array_item_string(wb, local_sockets_address_space(&n->local));
- buffer_json_add_array_item_string(wb, remote_address);
- buffer_json_add_array_item_uint64(wb, n->remote.port);
- buffer_json_add_array_item_string(wb, local_sockets_address_space(&n->remote));
+ if(!aggregated) {
+ buffer_json_add_array_item_string(wb, local_address);
+ buffer_json_add_array_item_uint64(wb, n->local.port);
+ }
+ buffer_json_add_array_item_string(wb, n->network_viewer.local_address_space);
+
+ if(!aggregated) {
+ buffer_json_add_array_item_string(wb, remote_address);
+ buffer_json_add_array_item_uint64(wb, n->remote.port);
+ }
+ buffer_json_add_array_item_string(wb, n->network_viewer.remote_address_space);
uint16_t server_port;
- switch(n->direction) {
+ const char *server_address;
+ const char *client_address_space;
+ const char *server_address_space;
+ switch (n->direction) {
case SOCKET_DIRECTION_LISTEN:
case SOCKET_DIRECTION_INBOUND:
case SOCKET_DIRECTION_LOCAL_INBOUND:
server_port = n->local.port;
+ server_address = local_address;
+ server_address_space = n->network_viewer.local_address_space;
+ client_address_space = n->network_viewer.remote_address_space;
break;
case SOCKET_DIRECTION_OUTBOUND:
case SOCKET_DIRECTION_LOCAL_OUTBOUND:
server_port = n->remote.port;
+ server_address = remote_address;
+ server_address_space = n->network_viewer.remote_address_space;
+ client_address_space = n->network_viewer.local_address_space;
break;
case SOCKET_DIRECTION_NONE:
break;
}
+ if(aggregated)
+ buffer_json_add_array_item_string(wb, server_address);
+
buffer_json_add_array_item_uint64(wb, server_port);
- buffer_json_add_array_item_uint64(wb, n->inode);
- buffer_json_add_array_item_uint64(wb, n->net_ns_inode);
- buffer_json_add_array_item_uint64(wb, 1); // count
+ if(aggregated) {
+ buffer_json_add_array_item_string(wb, client_address_space);
+ buffer_json_add_array_item_string(wb, server_address_space);
+ }
+
+ // buffer_json_add_array_item_uint64(wb, n->inode);
+ // buffer_json_add_array_item_uint64(wb, n->net_ns_inode);
+ buffer_json_add_array_item_uint64(wb, n->network_viewer.count);
}
buffer_json_array_close(wb);
}
+static void local_sockets_cb_to_json(LS_STATE *ls, LOCAL_SOCKET *n, void *data) {
+ n->network_viewer.count = 1;
+ n->network_viewer.local_address_space = local_sockets_address_space(&n->local);
+ n->network_viewer.remote_address_space = local_sockets_address_space(&n->remote);
+ local_socket_to_json_array(data, n, ls->proc_self_net_ns_inode, false);
+}
+
+static void local_sockets_cb_to_aggregation(LS_STATE *ls __maybe_unused, LOCAL_SOCKET *n, void *data) {
+ SIMPLE_HASHTABLE_AGGREGATED_SOCKETS *ht = data;
+ n->network_viewer.count = 1;
+ n->network_viewer.local_address_space = local_sockets_address_space(&n->local);
+ n->network_viewer.remote_address_space = local_sockets_address_space(&n->remote);
+
+ switch(n->direction) {
+ case SOCKET_DIRECTION_INBOUND:
+ case SOCKET_DIRECTION_LOCAL_INBOUND:
+ case SOCKET_DIRECTION_LISTEN:
+ memset(&n->remote.ip, 0, sizeof(n->remote.ip));
+ n->remote.port = 0;
+ break;
+
+ case SOCKET_DIRECTION_OUTBOUND:
+ case SOCKET_DIRECTION_LOCAL_OUTBOUND:
+ memset(&n->local.ip, 0, sizeof(n->remote.ip));
+ n->local.port = 0;
+ break;
+
+ case SOCKET_DIRECTION_NONE:
+ return;
+ }
+
+ n->inode = 0;
+ n->local_ip_hash = 0;
+ n->remote_ip_hash = 0;
+ n->local_port_hash = 0;
+ n->timer = 0;
+ n->retransmits = 0;
+ n->expires = 0;
+ n->rqueue = 0;
+ n->wqueue = 0;
+ memset(&n->local_port_key, 0, sizeof(n->local_port_key));
+
+ XXH64_hash_t hash = XXH3_64bits(n, sizeof(*n));
+ SIMPLE_HASHTABLE_SLOT_AGGREGATED_SOCKETS *sl = simple_hashtable_get_slot_AGGREGATED_SOCKETS(ht, hash, n, true);
+ LOCAL_SOCKET *t = SIMPLE_HASHTABLE_SLOT_DATA(sl);
+ if(t) {
+ t->network_viewer.count++;
+ }
+ else {
+ t = mallocz(sizeof(*t));
+ memcpy(t, n, sizeof(*t));
+ t->cmdline = string_dup(t->cmdline);
+ simple_hashtable_set_slot_AGGREGATED_SOCKETS(ht, sl, hash, t);
+ }
+}
+
+static int local_sockets_compar(const void *a, const void *b) {
+ LOCAL_SOCKET *n1 = *(LOCAL_SOCKET **)a, *n2 = *(LOCAL_SOCKET **)b;
+ return strcmp(n1->comm, n2->comm);
+}
+
void network_viewer_function(const char *transaction, char *function __maybe_unused, usec_t *stop_monotonic_ut __maybe_unused,
bool *cancelled __maybe_unused, BUFFER *payload __maybe_unused, HTTP_ACCESS access __maybe_unused,
const char *source __maybe_unused, void *data __maybe_unused) {
+ time_t now_s = now_realtime_sec();
+ bool aggregated = false;
+
CLEAN_BUFFER *wb = buffer_create(0, NULL);
buffer_flush(wb);
wb->content_type = CT_APPLICATION_JSON;
@@ -147,360 +241,483 @@ void network_viewer_function(const char *transaction, char *function __maybe_unu
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", 5);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", NETWORK_CONNECTIONS_VIEWER_HELP);
- buffer_json_member_add_array(wb, "data");
-
- LS_STATE ls = {
- .config = {
- .listening = true,
- .inbound = true,
- .outbound = true,
- .local = true,
- .tcp4 = true,
- .tcp6 = true,
- .udp4 = true,
- .udp6 = true,
- .pid = true,
- .uid = true,
- .cmdline = true,
- .comm = true,
- .namespaces = true,
-
- .max_errors = 10,
-
- .cb = local_socket_to_array,
- .data = wb,
- },
- .stats = { 0 },
- .sockets_hashtable = { 0 },
- .local_ips_hashtable = { 0 },
- .listening_ports_hashtable = { 0 },
- };
-
- local_sockets_process(&ls);
- buffer_json_array_close(wb);
- buffer_json_member_add_object(wb, "columns");
+#ifdef ENABLE_DETAILED_VIEW
+ buffer_json_member_add_array(wb, "accepted_params");
{
- size_t field_id = 0;
-
- // Direction
- buffer_rrdf_table_add_field(wb, field_id++, "Direction", "Socket Direction",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Protocol
- buffer_rrdf_table_add_field(wb, field_id++, "Protocol", "Socket Protocol",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Type
- buffer_rrdf_table_add_field(wb, field_id++, "Namespace", "Namespace",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // State
- buffer_rrdf_table_add_field(wb, field_id++, "State", "Socket State",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Pid
- buffer_rrdf_table_add_field(wb, field_id++, "PID", "Process ID",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Comm
- buffer_rrdf_table_add_field(wb, field_id++, "Process", "Process Name",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_VISIBLE|RRDF_FIELD_OPTS_FULL_WIDTH,
- NULL);
-
- // Cmdline
- buffer_rrdf_table_add_field(wb, field_id++, "CommandLine", "Command Line",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_NONE|RRDF_FIELD_OPTS_FULL_WIDTH,
- NULL);
-
- // Uid
- buffer_rrdf_table_add_field(wb, field_id++, "UID", "User ID",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_NONE,
- NULL);
-
- // Username
- buffer_rrdf_table_add_field(wb, field_id++, "User", "Username",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Local Address
- buffer_rrdf_table_add_field(wb, field_id++, "LocalIP", "Local IP Address",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_VISIBLE|RRDF_FIELD_OPTS_FULL_WIDTH,
- NULL);
-
- // Local Port
- buffer_rrdf_table_add_field(wb, field_id++, "LocalPort", "Local Port",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Local Address Space
- buffer_rrdf_table_add_field(wb, field_id++, "LocalAddressSpace", "Local IP Address Space",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_NONE,
- NULL);
-
- // Remote Address
- buffer_rrdf_table_add_field(wb, field_id++, "RemoteIP", "Remote IP Address",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_VISIBLE|RRDF_FIELD_OPTS_FULL_WIDTH,
- NULL);
-
- // Remote Port
- buffer_rrdf_table_add_field(wb, field_id++, "RemotePort", "Remote Port",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_VISIBLE,
- NULL);
-
- // Remote Address Space
- buffer_rrdf_table_add_field(wb, field_id++, "RemoteAddressSpace", "Remote IP Address Space",
- RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_NONE,
- NULL);
-
- // Server Port
- buffer_rrdf_table_add_field(wb, field_id++, "ServerPort", "Server Port",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_NONE,
- NULL);
-
- // inode
- buffer_rrdf_table_add_field(wb, field_id++, "Inode", "Socket Inode",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_NONE,
- NULL);
-
- // Namespace inode
- buffer_rrdf_table_add_field(wb, field_id++, "Namespace Inode", "Namespace Inode",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_NONE,
- NULL);
-
- // Count
- buffer_rrdf_table_add_field(wb, field_id++, "Count", "Count",
- RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
- 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
- RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_NONE,
- RRDF_FIELD_OPTS_NONE,
- NULL);
+ buffer_json_add_array_item_string(wb, "sockets");
}
- buffer_json_object_close(wb); // columns
- buffer_json_member_add_string(wb, "default_sort_column", "Direction");
-
- buffer_json_member_add_object(wb, "custom_charts");
+ buffer_json_array_close(wb); // accepted_params
+ buffer_json_member_add_array(wb, "required_params");
{
- buffer_json_member_add_object(wb, "Network Map");
+ buffer_json_add_array_item_object(wb);
{
- buffer_json_member_ad