summaryrefslogtreecommitdiffstats
path: root/collectors
diff options
context:
space:
mode:
authorthiagoftsm <thiagoftsm@gmail.com>2021-03-17 10:22:11 +0000
committerGitHub <noreply@github.com>2021-03-17 10:22:11 +0000
commit65f4f12e8606a14d2c133569890e294275c2e056 (patch)
tree351d185fc6e08864e83498f55caed18e37503aa2 /collectors
parent757e418090e1038b183d3776aa8a3c55260369ca (diff)
New thread for ebpf.plugin
Add monitoring to `sync` syscall
Diffstat (limited to 'collectors')
-rw-r--r--collectors/ebpf.plugin/README.md1
-rw-r--r--collectors/ebpf.plugin/ebpf.c45
-rw-r--r--collectors/ebpf.plugin/ebpf.conf2
-rw-r--r--collectors/ebpf.plugin/ebpf.h5
-rw-r--r--collectors/ebpf.plugin/ebpf_apps.h1
-rw-r--r--collectors/ebpf.plugin/ebpf_cachestat.c39
-rw-r--r--collectors/ebpf.plugin/ebpf_cachestat.h2
-rw-r--r--collectors/ebpf.plugin/ebpf_kernel_reject_list.txt2
-rw-r--r--collectors/ebpf.plugin/ebpf_sync.c211
-rw-r--r--collectors/ebpf.plugin/ebpf_sync.h25
10 files changed, 300 insertions, 33 deletions
diff --git a/collectors/ebpf.plugin/README.md b/collectors/ebpf.plugin/README.md
index 5ea3b49514..bfe3f07442 100644
--- a/collectors/ebpf.plugin/README.md
+++ b/collectors/ebpf.plugin/README.md
@@ -194,6 +194,7 @@ The eBPF collector enables and runs the following eBPF programs by default:
When in `return` mode, it also creates charts showing errors when these operations are executed.
- `network viewer`: This eBPF program creates charts with information about `TCP` and `UDP` functions, including the
bandwidth consumed by each.
+- `sync`: Montitor calls for syscall sync(2).
### `[network connections]`
diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c
index 9959279cef..99a426786b 100644
--- a/collectors/ebpf.plugin/ebpf.c
+++ b/collectors/ebpf.plugin/ebpf.c
@@ -86,6 +86,9 @@ ebpf_module_t ebpf_modules[] = {
{ .thread_name = "cachestat", .config_name = "cachestat", .enabled = 0, .start_routine = ebpf_cachestat_thread,
.update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY,
.optional = 0, .apps_routine = ebpf_cachestat_create_apps_charts },
+ { .thread_name = "sync", .config_name = "sync", .enabled = 0, .start_routine = ebpf_sync_thread,
+ .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY,
+ .optional = 0, .apps_routine = NULL },
{ .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_time = 1,
.global_charts = 0, .apps_charts = 1, .mode = MODE_ENTRY,
.optional = 0, .apps_routine = NULL },
@@ -322,6 +325,25 @@ void write_err_chart(char *name, char *family, netdata_publish_syscall_t *move,
}
/**
+ * Write charts
+ *
+ * Write the current information to publish the charts.
+ *
+ * @param family chart family
+ * @param chart chart id
+ * @param dim dimension name
+ * @param v1 value.
+ */
+void ebpf_one_dimension_write_charts(char *family, char *chart, char *dim, long long v1)
+{
+ write_begin_chart(family, chart);
+
+ write_chart_dimension(dim, v1);
+
+ write_end_chart();
+}
+
+/**
* Call the necessary functions to create a chart.
*
* @param chart the chart name
@@ -606,6 +628,8 @@ void ebpf_print_help()
"\n"
" --return or -r Run the collector in return mode.\n"
"\n",
+ " --sync or -s Enable chart related to sync run time.\n"
+ "\n"
VERSION,
(year >= 116) ? year + 1900 : 2020);
}
@@ -1701,6 +1725,14 @@ static void read_collector_values(int *disable_apps)
started++;
}
+ enabled = appconfig_get_boolean(&collector_config, EBPF_PROGRAMS_SECTION, "sync",
+ CONFIG_BOOLEAN_YES);
+
+ if (enabled) {
+ ebpf_enable_chart(EBPF_MODULE_SYNC_IDX, *disable_apps);
+ started++;
+ }
+
if (!started){
ebpf_enable_all_charts(*disable_apps);
// Read network viewer section
@@ -1783,6 +1815,7 @@ static void parse_args(int argc, char **argv)
{"net", no_argument, 0, 'n' },
{"process", no_argument, 0, 'p' },
{"return", no_argument, 0, 'r' },
+ {"sync", no_argument, 0, 's' },
{0, 0, 0, 0}
};
@@ -1797,7 +1830,7 @@ static void parse_args(int argc, char **argv)
}
while (1) {
- int c = getopt_long(argc, argv, "hvgcanpr", long_options, &option_index);
+ int c = getopt_long(argc, argv, "hvgcanprs", long_options, &option_index);
if (c == -1)
break;
@@ -1859,6 +1892,14 @@ static void parse_args(int argc, char **argv)
#endif
break;
}
+ case 's': {
+ enabled = 1;
+ ebpf_enable_chart(EBPF_MODULE_SYNC_IDX, disable_apps);
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF enabling \"sync\" chart, because it was started with the option \"--sync\" or \"-s\".");
+#endif
+ break;
+ }
default: {
break;
}
@@ -1983,6 +2024,8 @@ int main(int argc, char **argv)
NULL, NULL, ebpf_modules[EBPF_MODULE_SOCKET_IDX].start_routine},
{"EBPF CACHESTAT" , NULL, NULL, 1,
NULL, NULL, ebpf_modules[EBPF_MODULE_CACHESTAT_IDX].start_routine},
+ {"EBPF SYNC" , NULL, NULL, 1,
+ NULL, NULL, ebpf_modules[EBPF_MODULE_SYNC_IDX].start_routine},
{NULL , NULL, NULL, 0,
NULL, NULL, NULL}
};
diff --git a/collectors/ebpf.plugin/ebpf.conf b/collectors/ebpf.plugin/ebpf.conf
index f31b5fca4e..a61ba2d2be 100644
--- a/collectors/ebpf.plugin/ebpf.conf
+++ b/collectors/ebpf.plugin/ebpf.conf
@@ -24,10 +24,12 @@
# files removed.
# `socket` : This eBPF program creates charts with information about `TCP` and `UDP` functions, including the
# bandwidth consumed by each.
+# `sync` : Montitor calls for syscall sync(2).
[ebpf programs]
cachestat = no
process = yes
socket = yes
+ sync = yes
network connections = no
#
diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h
index 21665738cd..4f7c371c4c 100644
--- a/collectors/ebpf.plugin/ebpf.h
+++ b/collectors/ebpf.plugin/ebpf.h
@@ -73,7 +73,8 @@ extern ebpf_module_t ebpf_modules[];
enum ebpf_module_indexes {
EBPF_MODULE_PROCESS_IDX,
EBPF_MODULE_SOCKET_IDX,
- EBPF_MODULE_CACHESTAT_IDX
+ EBPF_MODULE_CACHESTAT_IDX,
+ EBPF_MODULE_SYNC_IDX
};
// Copied from musl header
@@ -87,6 +88,7 @@ enum ebpf_module_indexes {
// Chart defintions
#define NETDATA_EBPF_FAMILY "ebpf"
+#define NETDATA_EBPF_MEMORY_GROUP "mem"
// Log file
#define NETDATA_DEVELOPER_LOG_FILE "developer.log"
@@ -203,6 +205,7 @@ extern char *ebpf_algorithms[];
extern void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr);
extern void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr);
extern void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *root);
+extern void ebpf_one_dimension_write_charts(char *family, char *chart, char *dim, long long v1);
extern collected_number get_value_from_structure(char *basis, size_t offset);
extern struct pid_stat *root_of_pids;
extern ebpf_process_stat_t *global_process_stat;
diff --git a/collectors/ebpf.plugin/ebpf_apps.h b/collectors/ebpf.plugin/ebpf_apps.h
index cace52d7bc..b03d0f0c74 100644
--- a/collectors/ebpf.plugin/ebpf_apps.h
+++ b/collectors/ebpf.plugin/ebpf_apps.h
@@ -19,6 +19,7 @@
#include "ebpf_process.h"
#include "ebpf_cachestat.h"
+#include "ebpf_sync.h"
#define MAX_COMPARE_NAME 100
#define MAX_NAME 100
diff --git a/collectors/ebpf.plugin/ebpf_cachestat.c b/collectors/ebpf.plugin/ebpf_cachestat.c
index 93be8e6e93..25254032d7 100644
--- a/collectors/ebpf.plugin/ebpf_cachestat.c
+++ b/collectors/ebpf.plugin/ebpf_cachestat.c
@@ -91,25 +91,6 @@ static void ebpf_cachestat_cleanup(void *ptr)
*****************************************************************/
/**
- * Write charts
- *
- * Write the current information to publish the charts.
- *
- * @param family chart family
- * @param chart chart id
- * @param dim dimension name
- * @param v1 value.
- */
-static inline void cachestat_write_charts(char *family, char *chart, char *dim, long long v1)
-{
- write_begin_chart(family, chart);
-
- write_chart_dimension(dim, v1);
-
- write_end_chart();
-}
-
-/**
* Update publish
*
* Update publish values before to write dimension.
@@ -398,19 +379,21 @@ static void cachestat_send_global(netdata_publish_cachestat_t *publish)
netdata_publish_syscall_t *ptr = cachestat_counter_publish_aggregated;
// The algorithm sets this value to zero sometimes, we are not written them to have a smooth chart
if (publish->ratio) {
- cachestat_write_charts(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_RATIO_CHART,
- ptr[NETDATA_CACHESTAT_IDX_RATIO].dimension, publish->ratio);
+ ebpf_one_dimension_write_charts(
+ NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_RATIO_CHART, ptr[NETDATA_CACHESTAT_IDX_RATIO].dimension,
+ publish->ratio);
}
- cachestat_write_charts(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_DIRTY_CHART,
- ptr[NETDATA_CACHESTAT_IDX_DIRTY].dimension,
- cachestat_hash_values[NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY]);
+ ebpf_one_dimension_write_charts(
+ NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_DIRTY_CHART, ptr[NETDATA_CACHESTAT_IDX_DIRTY].dimension,
+ cachestat_hash_values[NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY]);
- cachestat_write_charts(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_CHART,
- ptr[NETDATA_CACHESTAT_IDX_HIT].dimension, publish->hit);
+ ebpf_one_dimension_write_charts(
+ NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_CHART, ptr[NETDATA_CACHESTAT_IDX_HIT].dimension, publish->hit);
- cachestat_write_charts(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_MISSES_CHART,
- ptr[NETDATA_CACHESTAT_IDX_MISS].dimension, publish->miss);
+ ebpf_one_dimension_write_charts(
+ NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_MISSES_CHART, ptr[NETDATA_CACHESTAT_IDX_MISS].dimension,
+ publish->miss);
}
/**
diff --git a/collectors/ebpf.plugin/ebpf_cachestat.h b/collectors/ebpf.plugin/ebpf_cachestat.h
index b1100b9432..c6fdb79a4b 100644
--- a/collectors/ebpf.plugin/ebpf_cachestat.h
+++ b/collectors/ebpf.plugin/ebpf_cachestat.h
@@ -3,8 +3,6 @@
#ifndef NETDATA_EBPF_CACHESTAT_H
#define NETDATA_EBPF_CACHESTAT_H 1
-#define NETDATA_EBPF_MEMORY_GROUP "mem"
-
// charts
#define NETDATA_CACHESTAT_HIT_RATIO_CHART "cachestat_ratio"
#define NETDATA_CACHESTAT_DIRTY_CHART "cachestat_dirties"
diff --git a/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt b/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt
index d56b216a9c..539bf357f6 100644
--- a/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt
+++ b/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt
@@ -1 +1 @@
-Ubuntu 4.18.0-13.
+Ubuntu 4.18.0
diff --git a/collectors/ebpf.plugin/ebpf_sync.c b/collectors/ebpf.plugin/ebpf_sync.c
new file mode 100644
index 0000000000..ea9f042d5d
--- /dev/null
+++ b/collectors/ebpf.plugin/ebpf_sync.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "ebpf.h"
+#include "ebpf_sync.h"
+
+static ebpf_data_t sync_data;
+
+static struct bpf_link **probe_links = NULL;
+static struct bpf_object *objects = NULL;
+
+static char *sync_counter_dimension_name[NETDATA_SYNC_END] = { "sync" };
+static netdata_syscall_stat_t sync_counter_aggregated_data;
+static netdata_publish_syscall_t sync_counter_publish_aggregated;
+
+static int read_thread_closed = 1;
+
+static int *map_fd = NULL;
+static netdata_idx_t sync_hash_values = 0;
+
+struct netdata_static_thread sync_threads = {"SYNC KERNEL", NULL, NULL, 1,
+ NULL, NULL, NULL};
+
+/*****************************************************************
+ *
+ * DATA THREAD
+ *
+ *****************************************************************/
+
+/**
+ * Read global table
+ *
+ * Read the table with number of calls for all functions
+ */
+static void read_global_table()
+{
+ uint32_t idx = NETDATA_SYNC_CALL;
+ netdata_idx_t stored;
+ int fd = map_fd[NETDATA_SYNC_GLOBLAL_TABLE];
+
+ if (!bpf_map_lookup_elem(fd, &idx, &stored)) {
+ sync_hash_values = stored;
+ }
+}
+
+/**
+ * Sync read hash
+ *
+ * This is the thread callback.
+ *
+ * @param ptr It is a NULL value for this thread.
+ *
+ * @return It always returns NULL.
+ */
+void *ebpf_sync_read_hash(void *ptr)
+{
+ UNUSED(ptr);
+ read_thread_closed = 0;
+
+ heartbeat_t hb;
+ heartbeat_init(&hb);
+ usec_t step = NETDATA_EBPF_SYNC_SLEEP_MS;
+
+ while (!close_ebpf_plugin) {
+ usec_t dt = heartbeat_next(&hb, step);
+ (void)dt;
+
+ read_global_table();
+ }
+ read_thread_closed = 1;
+
+ return NULL;
+}
+
+/**
+ * Send global
+ *
+ * Send global charts to Netdata
+ */
+static void sync_send_global()
+{
+ ebpf_one_dimension_write_charts(NETDATA_EBPF_MEMORY_GROUP, NETDATA_EBPF_SYNC_CHART,
+ sync_counter_publish_aggregated.dimension, sync_hash_values);
+}
+
+/**
+* Main loop for this collector.
+*/
+static void sync_collector(ebpf_module_t *em)
+{
+ sync_threads.thread = mallocz(sizeof(netdata_thread_t));
+ sync_threads.start_routine = ebpf_sync_read_hash;
+
+ map_fd = sync_data.map_fd;
+
+ netdata_thread_create(sync_threads.thread, sync_threads.name, NETDATA_THREAD_OPTION_JOINABLE,
+ ebpf_sync_read_hash, em);
+
+ while (!close_ebpf_plugin) {
+ pthread_mutex_lock(&collect_data_mutex);
+ pthread_cond_wait(&collect_data_cond_var, &collect_data_mutex);
+
+ pthread_mutex_lock(&lock);
+
+ sync_send_global();
+
+ pthread_mutex_unlock(&lock);
+ pthread_mutex_unlock(&collect_data_mutex);
+ }
+}
+
+
+/*****************************************************************
+ *
+ * CLEANUP THREAD
+ *
+ *****************************************************************/
+
+/**
+ * Clean up the main thread.
+ *
+ * @param ptr thread data.
+ */
+static void ebpf_sync_cleanup(void *ptr)
+{
+ ebpf_module_t *em = (ebpf_module_t *)ptr;
+ if (!em->enabled)
+ return;
+
+ heartbeat_t hb;
+ heartbeat_init(&hb);
+ uint32_t tick = 2*USEC_PER_MS;
+ while (!read_thread_closed) {
+ usec_t dt = heartbeat_next(&hb, tick);
+ UNUSED(dt);
+ }
+
+ freez(sync_threads.thread);
+
+ struct bpf_program *prog;
+ size_t i = 0 ;
+ bpf_object__for_each_program(prog, objects) {
+ bpf_link__destroy(probe_links[i]);
+ i++;
+ }
+ bpf_object__close(objects);
+}
+
+/*****************************************************************
+ *
+ * MAIN THREAD
+ *
+ *****************************************************************/
+
+/**
+ * Create global charts
+ *
+ * Call ebpf_create_chart to create the charts for the collector.
+ */
+static void ebpf_create_sync_charts()
+{
+ ebpf_create_chart(NETDATA_EBPF_MEMORY_GROUP, NETDATA_EBPF_SYNC_CHART,
+ "Monitor calls for <a href=\"https://linux.die.net/man/2/sync\">sync(2)</a> syscall.",
+ EBPF_COMMON_DIMENSION_CALL, NETDATA_EBPF_SYNC_SUBMENU, NULL, 21300,
+ ebpf_create_global_dimension, &sync_counter_publish_aggregated, 1);
+}
+
+/**
+ * Sync thread
+ *
+ * Thread used to make sync thread
+ *
+ * @param ptr a pointer to `struct ebpf_module`
+ *
+ * @return It always return NULL
+ */
+void *ebpf_sync_thread(void *ptr)
+{
+ netdata_thread_cleanup_push(ebpf_sync_cleanup, ptr);
+
+ ebpf_module_t *em = (ebpf_module_t *)ptr;
+ fill_ebpf_data(&sync_data);
+
+ if (!em->enabled)
+ goto endsync;
+
+ if (ebpf_update_kernel(&sync_data)) {
+ pthread_mutex_unlock(&lock);
+ goto endsync;
+ }
+
+ probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects, sync_data.map_fd);
+ if (!probe_links) {
+ pthread_mutex_unlock(&lock);
+ goto endsync;
+ }
+
+ int algorithm = NETDATA_EBPF_INCREMENTAL_IDX;
+ ebpf_global_labels(&sync_counter_aggregated_data, &sync_counter_publish_aggregated,
+ sync_counter_dimension_name, sync_counter_dimension_name,
+ &algorithm, NETDATA_SYNC_END);
+
+ pthread_mutex_lock(&lock);
+ ebpf_create_sync_charts();
+ pthread_mutex_unlock(&lock);
+
+ sync_collector(em);
+
+endsync:
+ netdata_thread_cleanup_pop(1);
+ return NULL;
+}
diff --git a/collectors/ebpf.plugin/ebpf_sync.h b/collectors/ebpf.plugin/ebpf_sync.h
new file mode 100644
index 0000000000..ee9c5c8363
--- /dev/null
+++ b/collectors/ebpf.plugin/ebpf_sync.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef NETDATA_EBPF_SYNC_H
+#define NETDATA_EBPF_SYNC_H 1
+
+// charts
+#define NETDATA_EBPF_SYNC_CHART "sync"
+#define NETDATA_EBPF_SYNC_SUBMENU "synchronization"
+
+#define NETDATA_EBPF_SYNC_SLEEP_MS 800000ULL
+
+enum netdata_sync_charts {
+ NETDATA_SYNC_CALL,
+
+ // Keep this as last and don't skip numbers as it is used as element counter
+ NETDATA_SYNC_END
+};
+
+enum netdata_sync_table {
+ NETDATA_SYNC_GLOBLAL_TABLE
+};
+
+extern void *ebpf_sync_thread(void *ptr);
+
+#endif /* NETDATA_EBPF_SYNC_H */