summaryrefslogtreecommitdiffstats
path: root/collectors
diff options
context:
space:
mode:
authorthiagoftsm <thiagoftsm@gmail.com>2023-12-27 14:28:24 +0000
committerGitHub <noreply@github.com>2023-12-27 14:28:24 +0000
commit28394c9236d740939ae27e23044b8751962ee268 (patch)
tree07a629152abb0ac25637eaa7275989ef3987a47c /collectors
parentcafe5d607a07b53ff94bd940f324e2f6da8cdfae (diff)
eBPF socket (eBPF) (#16669)
Diffstat (limited to 'collectors')
-rw-r--r--collectors/ebpf.plugin/ebpf.c16
-rw-r--r--collectors/ebpf.plugin/ebpf_functions.c529
-rw-r--r--collectors/ebpf.plugin/ebpf_functions.h20
3 files changed, 92 insertions, 473 deletions
diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c
index 381bf5718c..f9fc88db9f 100644
--- a/collectors/ebpf.plugin/ebpf.c
+++ b/collectors/ebpf.plugin/ebpf.c
@@ -3777,11 +3777,6 @@ static void ebpf_create_statistic_charts(int update_every)
NETDATA_EBPF_ORDER_STAT_THREADS,
update_every,
NULL);
- /*
-#ifdef NETDATA_DEV_MODE
- EBPF_PLUGIN_FUNCTIONS(EBPF_FUNCTION_THREAD, EBPF_PLUGIN_THREAD_FUNCTION_DESCRIPTION);
-#endif
- */
ebpf_create_thread_chart(NETDATA_EBPF_LIFE_TIME,
"Time remaining for thread.",
@@ -3789,11 +3784,6 @@ static void ebpf_create_statistic_charts(int update_every)
NETDATA_EBPF_ORDER_STAT_LIFE_TIME,
update_every,
NULL);
- /*
-#ifdef NETDATA_DEV_MODE
- EBPF_PLUGIN_FUNCTIONS(EBPF_FUNCTION_THREAD, EBPF_PLUGIN_THREAD_FUNCTION_DESCRIPTION);
-#endif
- */
int i,j;
char name[256];
@@ -3811,9 +3801,6 @@ static void ebpf_create_statistic_charts(int update_every)
j++,
update_every,
em);
-#ifdef NETDATA_DEV_MODE
- EBPF_PLUGIN_FUNCTIONS(em->functions.fcnt_name, em->functions.fcnt_desc);
-#endif
em->functions.order_thread_lifetime = j;
snprintfz(name, sizeof(name) - 1, "%s_%s", NETDATA_EBPF_LIFE_TIME, em->info.thread_name);
@@ -3824,9 +3811,6 @@ static void ebpf_create_statistic_charts(int update_every)
j++,
update_every,
em);
-#ifdef NETDATA_DEV_MODE
- EBPF_PLUGIN_FUNCTIONS(em->functions.fcnt_name, em->functions.fcnt_desc);
-#endif
}
ebpf_create_statistic_load_chart(update_every);
diff --git a/collectors/ebpf.plugin/ebpf_functions.c b/collectors/ebpf.plugin/ebpf_functions.c
index 8d161c4e71..3129fe5ed7 100644
--- a/collectors/ebpf.plugin/ebpf_functions.c
+++ b/collectors/ebpf.plugin/ebpf_functions.c
@@ -38,66 +38,6 @@ static int ebpf_function_start_thread(ebpf_module_t *em, int period)
}
/*****************************************************************
- * EBPF SELECT MODULE
- *****************************************************************/
-
-/**
- * Select Module
- *
- * @param thread_name name of the thread we are looking for.
- *
- * @return it returns a pointer for the module that has thread_name on success or NULL otherwise.
-ebpf_module_t *ebpf_functions_select_module(const char *thread_name) {
- int i;
- for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
- if (strcmp(ebpf_modules[i].info.thread_name, thread_name) == 0) {
- return &ebpf_modules[i];
- }
- }
-
- return NULL;
-}
- */
-
-/*****************************************************************
- * EBPF HELP FUNCTIONS
- *****************************************************************/
-
-/**
- * Thread Help
- *
- * Shows help with all options accepted by thread function.
- *
- * @param transaction the transaction id that Netdata sent for this function execution
-static void ebpf_function_thread_manipulation_help(const char *transaction) {
- BUFFER *wb = buffer_create(0, NULL);
- buffer_sprintf(wb, "%s",
- "ebpf.plugin / thread\n"
- "\n"
- "Function `thread` allows user to control eBPF threads.\n"
- "\n"
- "The following filters are supported:\n"
- "\n"
- " thread:NAME\n"
- " Shows information for the thread NAME. Names are listed inside `ebpf.d.conf`.\n"
- "\n"
- " enable:NAME:PERIOD\n"
- " Enable a specific thread named `NAME` to run a specific PERIOD in seconds. When PERIOD is not\n"
- " specified plugin will use the default 300 seconds\n"
- "\n"
- " disable:NAME\n"
- " Disable a sp.\n"
- "\n"
- "Filters can be combined. Each filter can be given only one time.\n"
- );
-
- pluginsd_function_result_to_stdout(transaction, HTTP_RESP_OK, "text/plain", now_realtime_sec() + 3600, wb);
-
- buffer_free(wb);
-}
-*/
-
-/*****************************************************************
* EBPF ERROR FUNCTIONS
*****************************************************************/
@@ -110,269 +50,10 @@ static void ebpf_function_thread_manipulation_help(const char *transaction) {
* @param code the error code to show with the message.
* @param msg the error message
*/
-static void ebpf_function_error(const char *transaction, int code, const char *msg) {
+static inline void ebpf_function_error(const char *transaction, int code, const char *msg) {
pluginsd_function_json_error_to_stdout(transaction, code, msg);
}
-/*****************************************************************
- * EBPF THREAD FUNCTION
- *****************************************************************/
-
-/**
- * Function: thread
- *
- * Enable a specific thread.
- *
- * @param transaction the transaction id that Netdata sent for this function execution
- * @param function function name and arguments given to thread.
- * @param line_buffer buffer used to parse args
- * @param line_max Number of arguments given
- * @param timeout The function timeout
- * @param em The structure with thread information
-static void ebpf_function_thread_manipulation(const char *transaction,
- char *function __maybe_unused,
- char *line_buffer __maybe_unused,
- int line_max __maybe_unused,
- int timeout __maybe_unused,
- ebpf_module_t *em)
-{
- char *words[PLUGINSD_MAX_WORDS] = { NULL };
- char message[512];
- uint32_t show_specific_thread = 0;
- size_t num_words = quoted_strings_splitter_pluginsd(function, words, PLUGINSD_MAX_WORDS);
- for(int i = 1; i < PLUGINSD_MAX_WORDS ;i++) {
- const char *keyword = get_word(words, num_words, i);
- if (!keyword)
- break;
-
- ebpf_module_t *lem;
- if(strncmp(keyword, EBPF_THREADS_ENABLE_CATEGORY, sizeof(EBPF_THREADS_ENABLE_CATEGORY) -1) == 0) {
- char thread_name[128];
- int period = -1;
- const char *name = &keyword[sizeof(EBPF_THREADS_ENABLE_CATEGORY) - 1];
- char *separator = strchr(name, ':');
- if (separator) {
- strncpyz(thread_name, name, separator - name);
- period = str2i(++separator);
- } else {
- strncpyz(thread_name, name, strlen(name));
- }
-
- lem = ebpf_functions_select_module(thread_name);
- if (!lem) {
- snprintfz(message, sizeof(message) - 1, "%s%s", EBPF_PLUGIN_THREAD_FUNCTION_ERROR_THREAD_NOT_FOUND, name);
- ebpf_function_error(transaction, HTTP_RESP_NOT_FOUND, message);
- return;
- }
-
- pthread_mutex_lock(&ebpf_exit_cleanup);
- if (lem->enabled > NETDATA_THREAD_EBPF_FUNCTION_RUNNING) {
- // Load configuration again
- ebpf_update_module(lem, default_btf, running_on_kernel, isrh);
-
- if (ebpf_function_start_thread(lem, period)) {
- ebpf_function_error(transaction,
- HTTP_RESP_INTERNAL_SERVER_ERROR,
- "Cannot start thread.");
- return;
- }
- } else {
- lem->running_time = 0;
- if (period > 0) // user is modifying period to run
- lem->lifetime = period;
-#ifdef NETDATA_INTERNAL_CHECKS
- netdata_log_info("Thread %s had lifetime updated for %d", thread_name, period);
-#endif
- }
- pthread_mutex_unlock(&ebpf_exit_cleanup);
- } else if(strncmp(keyword, EBPF_THREADS_DISABLE_CATEGORY, sizeof(EBPF_THREADS_DISABLE_CATEGORY) -1) == 0) {
- const char *name = &keyword[sizeof(EBPF_THREADS_DISABLE_CATEGORY) - 1];
- lem = ebpf_functions_select_module(name);
- if (!lem) {
- snprintfz(message, sizeof(message) - 1, "%s%s", EBPF_PLUGIN_THREAD_FUNCTION_ERROR_THREAD_NOT_FOUND, name);
- ebpf_function_error(transaction, HTTP_RESP_NOT_FOUND, message);
- return;
- }
-
- pthread_mutex_lock(&ebpf_exit_cleanup);
- if (lem->enabled < NETDATA_THREAD_EBPF_STOPPING && lem->thread->thread) {
- lem->lifetime = 0;
- lem->running_time = lem->update_every;
- netdata_thread_cancel(*lem->thread->thread);
- }
- pthread_mutex_unlock(&ebpf_exit_cleanup);
- } else if(strncmp(keyword, EBPF_THREADS_SELECT_THREAD, sizeof(EBPF_THREADS_SELECT_THREAD) -1) == 0) {
- const char *name = &keyword[sizeof(EBPF_THREADS_SELECT_THREAD) - 1];
- lem = ebpf_functions_select_module(name);
- if (!lem) {
- snprintfz(message, sizeof(message) - 1, "%s%s", EBPF_PLUGIN_THREAD_FUNCTION_ERROR_THREAD_NOT_FOUND, name);
- ebpf_function_error(transaction, HTTP_RESP_NOT_FOUND, message);
- return;
- }
-
- show_specific_thread |= 1<<lem->thread_id;
- } else if(strncmp(keyword, "help", 4) == 0) {
- ebpf_function_thread_manipulation_help(transaction);
- return;
- }
- }
-
- time_t expires = now_realtime_sec() + em->update_every;
-
- BUFFER *wb = buffer_create(PLUGINSD_LINE_MAX, 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", em->update_every);
- buffer_json_member_add_string(wb, "help", EBPF_PLUGIN_THREAD_FUNCTION_DESCRIPTION);
-
- // Collect data
- buffer_json_member_add_array(wb, "data");
- int i;
- for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
- if (show_specific_thread && !(show_specific_thread & 1<<i))
- continue;
-
- ebpf_module_t *wem = &ebpf_modules[i];
- buffer_json_add_array_item_array(wb);
-
- // IMPORTANT!
- // THE ORDER SHOULD BE THE SAME WITH THE FIELDS!
-
- // thread name
- buffer_json_add_array_item_string(wb, wem->info.thread_name);
-
- // description
- buffer_json_add_array_item_string(wb, wem->info.thread_description);
- // Either it is not running or received a disabled signal and it is stopping.
- if (wem->enabled > NETDATA_THREAD_EBPF_FUNCTION_RUNNING ||
- (!wem->lifetime && (int)wem->running_time == wem->update_every)) {
- // status
- buffer_json_add_array_item_string(wb, EBPF_THREAD_STATUS_STOPPED);
-
- // Time remaining
- buffer_json_add_array_item_uint64(wb, 0);
-
- // action
- buffer_json_add_array_item_string(wb, "NULL");
- } else {
- // status
- buffer_json_add_array_item_string(wb, EBPF_THREAD_STATUS_RUNNING);
-
- // Time remaining
- buffer_json_add_array_item_uint64(wb, (wem->lifetime) ? (wem->lifetime - wem->running_time) : 0);
-
- // action
- buffer_json_add_array_item_string(wb, "Enabled/Disabled");
- }
-
- buffer_json_array_close(wb);
- }
-
- buffer_json_array_close(wb); // data
-
- buffer_json_member_add_object(wb, "columns");
- {
- int fields_id = 0;
-
- // IMPORTANT!
- // THE ORDER SHOULD BE THE SAME WITH THE VALUES!
- buffer_rrdf_table_add_field(wb, fields_id++, "Thread", "Thread 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_STICKY | RRDF_FIELD_OPTS_UNIQUE_KEY, NULL);
-
- buffer_rrdf_table_add_field(wb, fields_id++, "Description", "Thread Desc", 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_STICKY, NULL);
-
- buffer_rrdf_table_add_field(wb, fields_id++, "Status", "Thread Status", 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_STICKY, NULL);
-
- buffer_rrdf_table_add_field(wb, fields_id++, "Time", "Time Remaining", RRDF_FIELD_TYPE_INTEGER,
- RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL,
- NAN, RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT,
- RRDF_FIELD_FILTER_MULTISELECT,
- RRDF_FIELD_OPTS_NONE, NULL);
-
- buffer_rrdf_table_add_field(wb, fields_id++, "Action", "Thread Action", 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_STICKY, NULL);
- }
- buffer_json_object_close(wb); // columns
-
- buffer_json_member_add_string(wb, "default_sort_column", "Thread");
-
- buffer_json_member_add_object(wb, "charts");
- {
- // Threads
- buffer_json_member_add_object(wb, "eBPFThreads");
- {
- buffer_json_member_add_string(wb, "name", "Threads");
- buffer_json_member_add_string(wb, "type", "line");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "Threads");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
-
- // Life Time
- buffer_json_member_add_object(wb, "eBPFLifeTime");
- {
- buffer_json_member_add_string(wb, "name", "LifeTime");
- buffer_json_member_add_string(wb, "type", "line");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "Threads");
- buffer_json_add_array_item_string(wb, "Time");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
- }
- buffer_json_object_close(wb); // charts
-
- // Do we use only on fields that can be groupped?
- buffer_json_member_add_object(wb, "group_by");
- {
- // group by Status
- buffer_json_member_add_object(wb, "Status");
- {
- buffer_json_member_add_string(wb, "name", "Thread status");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "Status");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
- }
- buffer_json_object_close(wb); // group_by
-
- buffer_json_member_add_time_t(wb, "expires", expires);
- buffer_json_finalize(wb);
-
- // Lock necessary to avoid race condition
- pluginsd_function_result_to_stdout(transaction, HTTP_RESP_OK, "application/json", expires, wb);
-
- buffer_free(wb);
-}
- */
-
-/*****************************************************************
- * EBPF SOCKET FUNCTION
- *****************************************************************/
-
/**
* Thread Help
*
@@ -380,46 +61,18 @@ static void ebpf_function_thread_manipulation(const char *transaction,
*
* @param transaction the transaction id that Netdata sent for this function execution
*/
-static void ebpf_function_socket_help(const char *transaction) {
+static inline void ebpf_function_help(const char *transaction, const char *message) {
pluginsd_function_result_begin_to_stdout(transaction, HTTP_RESP_OK, "text/plain", now_realtime_sec() + 3600);
- fprintf(stdout, "%s",
- "ebpf.plugin / socket\n"
- "\n"
- "Function `socket` display information for all open sockets during ebpf.plugin runtime.\n"
- "During thread runtime the plugin is always collecting data, but when an option is modified, the plugin\n"
- "resets completely the previous table and can show a clean data for the first request before to bring the\n"
- "modified request.\n"
- "\n"
- "The following filters are supported:\n"
- "\n"
- " family:FAMILY\n"
- " Shows information for the FAMILY specified. Option accepts IPV4, IPV6 and all, that is the default.\n"
- "\n"
- " period:PERIOD\n"
- " Enable socket to run a specific PERIOD in seconds. When PERIOD is not\n"
- " specified plugin will use the default 300 seconds\n"
- "\n"
- " resolve:BOOL\n"
- " Resolve service name, default value is YES.\n"
- "\n"
- " range:CIDR\n"
- " Show sockets that have only a specific destination. Default all addresses.\n"
- "\n"
- " port:range\n"
- " Show sockets that have only a specific destination.\n"
- "\n"
- " reset\n"
- " Send a reset to collector. When a collector receives this command, it uses everything defined in configuration file.\n"
- "\n"
- " interfaces\n"
- " When the collector receives this command, it read all available interfaces on host.\n"
- "\n"
- "Filters can be combined. Each filter can be given only one time. Default all ports\n"
- );
+ fprintf(stdout, "%s", message);
pluginsd_function_result_end_to_stdout();
fflush(stdout);
}
+/*****************************************************************
+ * EBPF SOCKET FUNCTION
+ *****************************************************************/
+
+
/**
* Fill Fake socket
*
@@ -651,8 +304,42 @@ 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;
-
- for (int i = 1; i < PLUGINSD_MAX_WORDS; i++) {
+ static const char *socket_help = {
+ "ebpf.plugin / socket\n"
+ "\n"
+ "Function `socket` display information for all open sockets during ebpf.plugin runtime.\n"
+ "During thread runtime the plugin is always collecting data, but when an option is modified, the plugin\n"
+ "resets completely the previous table and can show a clean data for the first request before to bring the\n"
+ "modified request.\n"
+ "\n"
+ "The following filters are supported:\n"
+ "\n"
+ " family:FAMILY\n"
+ " Shows information for the FAMILY specified. Option accepts IPV4, IPV6 and all, that is the default.\n"
+ "\n"
+ " period:PERIOD\n"
+ " Enable socket to run a specific PERIOD in seconds. When PERIOD is not\n"
+ " specified plugin will use the default 300 seconds\n"
+ "\n"
+ " resolve:BOOL\n"
+ " Resolve service name, default value is YES.\n"
+ "\n"
+ " range:CIDR\n"
+ " Show sockets that have only a specific destination. Default all addresses.\n"
+ "\n"
+ " port:range\n"
+ " Show sockets that have only a specific destination.\n"
+ "\n"
+ " reset\n"
+ " Send a reset to collector. When a collector receives this command, it uses everything defined in configuration file.\n"
+ "\n"
+ " interfaces\n"
+ " When the collector receives this command, it read all available interfaces on host.\n"
+ "\n"
+ "Filters can be combined. Each filter can be given only one time. Default all ports\n"
+ };
+
+for (int i = 1; i < PLUGINSD_MAX_WORDS; i++) {
const char *keyword = get_word(words, num_words, i);
if (!keyword)
break;
@@ -735,20 +422,20 @@ static void ebpf_function_socket_manipulation(const char *transaction,
ebpf_read_local_addresses_unsafe();
rw_spinlock_write_unlock(&network_viewer_opt.rw_spinlock);
} else if (strncmp(keyword, "help", 4) == 0) {
- ebpf_function_socket_help(transaction);
+ ebpf_function_help(transaction, socket_help);
rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
return;
}
}
rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
- pthread_mutex_lock(&ebpf_exit_cleanup);
if (em->enabled > NETDATA_THREAD_EBPF_FUNCTION_RUNNING) {
// Cleanup when we already had a thread running
rw_spinlock_write_lock(&ebpf_judy_pid.index.rw_spinlock);
ebpf_socket_clean_judy_array_unsafe();
rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
+ pthread_mutex_lock(&ebpf_exit_cleanup);
if (ebpf_function_start_thread(em, period)) {
ebpf_function_error(transaction,
HTTP_RESP_INTERNAL_SERVER_ERROR,
@@ -757,16 +444,14 @@ static void ebpf_function_socket_manipulation(const char *transaction,
return;
}
} else {
- if (period < 0 && em->lifetime < EBPF_NON_FUNCTION_LIFE_TIME) {
- em->lifetime = EBPF_NON_FUNCTION_LIFE_TIME;
- }
+ pthread_mutex_lock(&ebpf_exit_cleanup);
+ if (period < 0)
+ em->lifetime = (em->enabled != NETDATA_THREAD_EBPF_FUNCTION_RUNNING) ? EBPF_NON_FUNCTION_LIFE_TIME : EBPF_DEFAULT_LIFETIME;
}
pthread_mutex_unlock(&ebpf_exit_cleanup);
- time_t expires = now_realtime_sec() + em->update_every;
-
BUFFER *wb = buffer_create(PLUGINSD_LINE_MAX, NULL);
- buffer_json_initialize(wb, "\"", "\"", 0, true, false);
+ 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", em->update_every);
@@ -790,7 +475,7 @@ static void ebpf_function_socket_manipulation(const char *transaction,
RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_STICKY,
NULL);
- buffer_rrdf_table_add_field(wb, fields_id++, "Process Name", "Process Name", RRDF_FIELD_TYPE_STRING,
+ buffer_rrdf_table_add_field(wb, fields_id++, "PName", "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,
@@ -835,14 +520,14 @@ static void ebpf_function_socket_manipulation(const char *transaction,
RRDF_FIELD_FILTER_MULTISELECT,
RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_STICKY, NULL);
- buffer_rrdf_table_add_field(wb, fields_id++, "Incoming Bandwidth", "Bytes received.", RRDF_FIELD_TYPE_INTEGER,
+ buffer_rrdf_table_add_field(wb, fields_id++, "IncomingBandwidth", "Bytes received.", RRDF_FIELD_TYPE_INTEGER,
RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL, NAN,
RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT,
RRDF_FIELD_FILTER_MULTISELECT,
RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_STICKY,
NULL);
- buffer_rrdf_table_add_field(wb, fields_id++, "Outgoing Bandwidth", "Bytes sent.", RRDF_FIELD_TYPE_INTEGER,
+ buffer_rrdf_table_add_field(wb, fields_id++, "OutgoingBandwidth", "Bytes sent.", RRDF_FIELD_TYPE_INTEGER,
RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL, NAN,
RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT,
RRDF_FIELD_FILTER_MULTISELECT,
@@ -858,97 +543,49 @@ static void ebpf_function_socket_manipulation(const char *transaction,
}
buffer_json_object_close(wb); // columns
+ buffer_json_member_add_string(wb, "default_sort_column", "IncomingBandwidth");
+
buffer_json_member_add_object(wb, "charts");
{
- // OutBound Connections
- buffer_json_member_add_object(wb, "IPInboundConn");
+ buffer_json_member_add_object(wb, "IncomingConnections");
{
buffer_json_member_add_string(wb, "name", "TCP Inbound Connection");
- buffer_json_member_add_string(wb, "type", "line");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "connected_tcp");
- buffer_json_add_array_item_string(wb, "connected_udp");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
-
- // OutBound Connections
- buffer_json_member_add_object(wb, "IPTCPOutboundConn");
- {
- buffer_json_member_add_string(wb, "name", "TCP Outbound Connection");
- buffer_json_member_add_string(wb, "type", "line");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "connected_V4");
- buffer_json_add_array_item_string(wb, "connected_V6");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
-
- // TCP Functions
- buffer_json_member_add_object(wb, "TCPFunctions");
- {
- buffer_json_member_add_string(wb, "name", "TCPFunctions");
- buffer_json_member_add_string(wb, "type", "line");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "received");
- buffer_json_add_array_item_string(wb, "sent");
- buffer_json_add_array_item_string(wb, "close");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
-
- // TCP Bandwidth
- buffer_json_member_add_object(wb, "TCPBandwidth");
- {
- buffer_json_member_add_string(wb, "name", "TCPBandwidth");
- buffer_json_member_add_string(wb, "type", "line");
- buffer_json_member_add_array(wb, "columns");
- {
- buffer_json_add_array_item_string(wb, "received");
- buffer_json_add_array_item_string(wb, "sent");
- }
- buffer_json_array_close(wb);
- }
- buffer_json_object_close(wb);
-
- // UDP Functions
- buffer_json_member_add_object(wb, "UDPFunctions");
- {
- buffer_json_member_add_string(wb, "name", "UDPFunctions");
- buffer_json_member_add_string(wb, "type", "line");
+ buffer_json_member_add_string(wb, "type", "stacked-bar");
buffer_json_member_add_array(wb, "columns");
{
- buffer_json_add_array_item_string(wb, "received");
- buffer_json_add_array_item_string(wb, "sent");
+ buffer_json_add_array_item_string(wb, "IncomingBandwidth");
}
buffer_json_array_close(wb);
}
buffer_json_object_close(wb);
- // UDP Bandwidth
- buffer_json_member_add_object(wb, "UDPBandwidth");
+ buffer_json_member_add_object(wb, "OutgoingConnections");
{
- buffer_json_member_add_string(wb, "name", "UDPBandwidth");
- buffer_json_member_add_string(wb, "type", "line");
+ buffer_json_member_add_string(wb, "name", "TCP Outgoing Connection");
+ buffer_json_member_add_string(wb, "type", "stacked-bar");
buffer_json_member_add_array(wb, "columns");
{
- buffer_json_add_array_item_string(wb, "received");
- buffer_json_add_array_item_string(wb, "sent");
+ buffer_json_add_array_item_string(wb, "OutgoingBandwidth");
}
buffer_json_array_close(wb);
}
buffer_json_object_close(wb);
-
}
buffer_json_object_close(wb); // charts
- buffer_json_member_add_string(wb, "default_sort_column", "PID");
+ buffer_json_member_add_array(wb, "default_charts");
+ {
+ buffer_json_add_array_item_array(wb);
+ buffer_json_add_array_item_string(wb, "IncomingConnections");
+ buffer_json_add_array_item_string(wb, "PName");
+ buffer_json_array_close(wb);
+
+ buffer_json_add_array_item_array(wb);
+ buffer_json_add_array_item_string(wb, "OutgoingConnections");
+ buffer_json_add_array_item_string(wb, "PName");
+ buffer_json_array_close(wb);
+ }
+ buffer_json_array_close(wb);
// Do we use only on fields that can be groupped?
buffer_json_member_add_object(wb, "group_by");
@@ -966,12 +603,12 @@ static void ebpf_function_socket_manipulation(const char *transaction,
buffer_json_object_close(wb);
// group by Process Name
- buffer_json_member_add_object(wb, "Process Name");
+ buffer_json_member_add_object(wb, "PName");
{
buffer_json_member_add_string(wb, "name", "Process Name");
buffer_json_member_add_array(wb, "columns");
{
- buffer_json_add_array_item_string(wb, "Process Name");
+ buffer_json_add_array_item_string(wb, "PName");
}
buffer_json_array_close(wb);
}
@@ -1039,6 +676,7 @@ static void ebpf_function_socket_manipulation(const char *transaction,
}
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);
buffer_json_finalize(wb);
@@ -1078,6 +716,17 @@ void *ebpf_function_thread(void *ptr)
ebpf_function_socket_manipulation,
PLUGINS_FUNCTIONS_TIMEOUT_DEFAULT);
+ pthread_mutex_lock(&lock);
+ int i;
+ for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
+ ebpf_module_t *em = &ebpf_modules[i];
+ if (!em->functions.fnct_routine)
+ continue;
+
+ EBPF_PLUGIN_FUNCTIONS(em->functions.fcnt_name, em->functions.fcnt_desc, em->update_every);
+ }
+ pthread_mutex_unlock(&lock);
+
heartbeat_t hb;
heartbeat_init(&hb);
while(!ebpf_plugin_exit) {
diff --git a/collectors/ebpf.plugin/ebpf_functions.h b/collectors/ebpf.plugin/ebpf_functions.h
index 330c402d87..f437312c86 100644
--- a/collectors/ebpf.plugin/ebpf_functions.h
+++ b/collectors/ebpf.plugin/ebpf_functions.h
@@ -3,33 +3,19 @@
#ifndef NETDATA_EBPF_FUNCTIONS_H
#define NETDATA_EBPF_FUNCTIONS_H 1
-#ifdef NETDATA_DEV_MODE
// Common
-static inline void EBPF_PLUGIN_FUNCTIONS(const char *NAME, const char *DESC) {
- fprintf(stdout, "%s \"%s\" 10 \"%s\" \"top\" \"any\" %d\n",
- PLUGINSD_KEYWORD_FUNCTION, NAME, DESC, RRDFUNCTIONS_PRIORITY_DEFAULT);
+static inline void EBPF_PLUGIN_FUNCTIONS(const char *NAME, const char *DESC, int update_every) {
+ fprintf(stdout, PLUGINSD_KEYWORD_FUNCTION " GLOBAL \"%s\" %d \"%s\" \"top\" \"members\" %d\n",
+ NAME, update_every, DESC, RRDFUNCTIONS_PRIORITY_DEFAULT);
}
-#endif
// configuration file & description
#define NETDATA_DIRECTORY_FUNCTIONS_CONFIG_FILE "functions.conf"
#define NETDATA_EBPF_FUNCTIONS_MODULE_DESC "Show information about current function status."
// function list
-#define EBPF_FUNCTION_THREAD "ebpf_thread"
#define EBPF_FUNCTION_SOCKET "ebpf_socket"
-// thread constants
-#define EBPF_PLUGIN_THREAD_FUNCTION_DESCRIPTION "Detailed information about eBPF threads."
-#define EBPF_PLUGIN_THREAD_FUNCTION_ERROR_THREAD_NOT_FOUND "ebpf.plugin does not have thread named "
-
-#define EBPF_THREADS_SELECT_THREAD "thread:"
-#define EBPF_THREADS_ENABLE_CATEGORY "enable:"
-#define EBPF_THREADS_DISABLE_CATEGORY "disable:"
-
-#define EBPF_THREAD_STATUS_RUNNING "running"
-#define EBPF_THREAD_STATUS_STOPPED "stopped"
-
// socket constants
#define EBPF_PLUGIN_SOCKET_FUNCTION_DESCRIPTION "Detailed information about open sockets."
#define EBPF_FUNCTION_SOCKET_FAMILY "family:"