summaryrefslogtreecommitdiffstats
path: root/collectors
diff options
context:
space:
mode:
authorthiagoftsm <thiagoftsm@gmail.com>2020-05-13 15:14:04 +0000
committerGitHub <noreply@github.com>2020-05-13 15:14:04 +0000
commit8d5db453b71bb7d3440d909f7e2f3c01718f5ae1 (patch)
tree7c7ef3a007142f84339033e2b059e53b582e7690 /collectors
parent349209f89ab659e42eee13dee24cc761bd60619c (diff)
Ebpf options (#8879)
ebpf options: We are adding command line options to eBPF collector.
Diffstat (limited to 'collectors')
-rw-r--r--collectors/ebpf_process.plugin/ebpf_process.c220
-rw-r--r--collectors/ebpf_process.plugin/ebpf_process.h6
2 files changed, 209 insertions, 17 deletions
diff --git a/collectors/ebpf_process.plugin/ebpf_process.c b/collectors/ebpf_process.plugin/ebpf_process.c
index 8691b71e16..267b1da3ea 100644
--- a/collectors/ebpf_process.plugin/ebpf_process.c
+++ b/collectors/ebpf_process.plugin/ebpf_process.c
@@ -66,7 +66,7 @@ netdata_publish_syscall_t *publish_aggregated = NULL;
static int update_every = 1;
static int thread_finished = 0;
static int close_plugin = 0;
-static int mode = 2;
+static netdata_run_mode_t mode = MODE_ENTRY;
static int debug_log = 0;
static int use_stdout = 0;
struct config collector_config;
@@ -77,6 +77,20 @@ netdata_idx_t *hash_values;
pthread_mutex_t lock;
+static struct ebpf_module {
+ const char *thread_name;
+ int enabled;
+ void (*start_routine) (void *);
+ int update_time;
+ int global_charts;
+ int apps_charts;
+ netdata_run_mode_t mode;
+} ebpf_modules[] = {
+ { .thread_name = "process", .enabled = 0, .start_routine = NULL, .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY },
+ { .thread_name = "network_viewer", .enabled = 0, .start_routine = NULL, .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY },
+ { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_time = 1, .global_charts = 0, .apps_charts = 1, .mode = MODE_ENTRY },
+};
+
static char *dimension_names[NETDATA_MAX_MONITOR_VECTOR] = { "open", "close", "delete", "read", "write", "process", "task", "process", "thread" };
static char *id_names[NETDATA_MAX_MONITOR_VECTOR] = { "do_sys_open", "__close_fd", "vfs_unlink", "vfs_read", "vfs_write", "do_exit", "release_task", "_do_fork", "sys_clone" };
static char *status[] = { "process", "zombie" };
@@ -139,7 +153,7 @@ static void int_exit(int sig)
publish_aggregated = NULL;
}
- if(mode == 1 && debug_log) {
+ if(mode == MODE_DEVMODE && debug_log) {
unmap_memory();
}
@@ -279,7 +293,7 @@ static void netdata_global_charts_create() {
, publish_aggregated
, 2);
- if(mode < 2) {
+ if(mode < MODE_ENTRY) {
netdata_create_chart(NETDATA_EBPF_FAMILY
, NETDATA_FILE_OPEN_ERR_COUNT
, "Calls"
@@ -308,7 +322,7 @@ static void netdata_global_charts_create() {
, &publish_aggregated[NETDATA_IN_START_BYTE]
, 2);
- if(mode < 2) {
+ if(mode < MODE_ENTRY) {
netdata_create_io_chart(NETDATA_EBPF_FAMILY
, NETDATA_VFS_IO_FILE_BYTES
, "bytes/s"
@@ -350,7 +364,7 @@ static void netdata_global_charts_create() {
, NETDATA_PROCESS_GROUP
, 978);
- if(mode < 2) {
+ if(mode < MODE_ENTRY) {
netdata_create_chart(NETDATA_EBPF_FAMILY
, NETDATA_PROCESS_ERROR_NAME
, "Calls"
@@ -479,7 +493,7 @@ static void netdata_publish_data() {
write_global_count_chart(NETDATA_PROCESS_SYSCALL, NETDATA_EBPF_FAMILY, &publish_aggregated[NETDATA_PROCESS_START], 2);
write_status_chart(NETDATA_EBPF_FAMILY, &pvc);
- if(mode < 2) {
+ if(mode < MODE_ENTRY) {
write_global_err_chart(NETDATA_FILE_OPEN_ERR_COUNT, NETDATA_EBPF_FAMILY, publish_aggregated, 2);
write_global_err_chart(NETDATA_VFS_FILE_ERR_COUNT, NETDATA_EBPF_FAMILY, &publish_aggregated[2], NETDATA_VFS_ERRORS);
write_global_err_chart(NETDATA_PROCESS_ERROR_NAME, NETDATA_EBPF_FAMILY, &publish_aggregated[NETDATA_PROCESS_START], 2);
@@ -597,7 +611,7 @@ void *process_log(void *ptr)
{
(void) ptr;
- if (mode == 1 && debug_log) {
+ if (mode == MODE_DEVMODE && debug_log) {
netdata_perf_loop_multi(pmu_fd, headers, nprocs, &close_plugin, netdata_store_bpf, page_cnt);
}
@@ -695,7 +709,7 @@ static int ebpf_load_libraries()
return -1;
}
- if(mode == 1) {
+ if(mode == MODE_DEVMODE) {
set_bpf_perf_event = dlsym(libnetdata, "set_bpf_perf_event");
if ((err = dlerror()) != NULL) {
error("[EBPF_PROCESS] Cannot find set_bpf_perf_event: %s", err);
@@ -728,7 +742,7 @@ static int ebpf_load_libraries()
char *select_file() {
if(!mode)
return "rnetdata_ebpf_process.o";
- if(mode == 1)
+ if(mode == MODE_DEVMODE)
return "dnetdata_ebpf_process.o";
return "pnetdata_ebpf_process.o";
@@ -798,7 +812,7 @@ static void change_syscalls() {
static inline void what_to_load(char *ptr) {
if (!strcasecmp(ptr, "return"))
- mode = 0;
+ mode = MODE_RETURN;
/*
else if (!strcasecmp(ptr, "dev"))
mode = 1;
@@ -853,10 +867,186 @@ static int load_collector_file(char *path) {
return 0;
}
+static inline void ebpf_disable_apps() {
+ int i ;
+ for (i = 0 ;ebpf_modules[i].thread_name ; i++ ) {
+ ebpf_modules[i].apps_charts = 0;
+ }
+}
+
+static inline void ebpf_enable_specific_chart(struct ebpf_module *em, int disable_apps) {
+ em->enabled = 1;
+ if (!disable_apps) {
+ em->apps_charts = 1;
+ }
+ em->global_charts = 1;
+}
+
+static inline void ebpf_enable_all_charts(int apps) {
+ int i ;
+ for (i = 0 ; ebpf_modules[i].thread_name ; i++ ) {
+ ebpf_enable_specific_chart(&ebpf_modules[i], apps);
+ }
+}
+
+static inline void ebpf_enable_chart(int enable, int disable_apps) {
+ int i ;
+ for (i = 0 ; ebpf_modules[i].thread_name ; i++ ) {
+ if (i == enable) {
+ ebpf_enable_specific_chart(&ebpf_modules[i], disable_apps);
+ break;
+ }
+ }
+}
+
+static inline void ebpf_set_thread_mode(netdata_run_mode_t lmode) {
+ int i ;
+ for (i = 0 ; ebpf_modules[i].thread_name ; i++ ) {
+ ebpf_modules[i].mode = lmode;
+ }
+}
+
+void ebpf_print_help() {
+ const time_t t = time(NULL);
+ struct tm ct;
+ struct tm *test = localtime_r(&t, &ct);
+ int year;
+ if (test)
+ year = ct.tm_year;
+ else
+ year = 0;
+
+ fprintf(stderr,
+ "\n"
+ " Netdata ebpf.plugin %s\n"
+ " Copyright (C) 2016-%d Costa Tsaousis <costa@tsaousis.gr>\n"
+ " Released under GNU General Public License v3 or later.\n"
+ " All rights reserved.\n"
+ "\n"
+ " This program is a data collector plugin for netdata.\n"
+ "\n"
+ " Available command line options:\n"
+ "\n"
+ " SECONDS set the data collection frequency.\n"
+ "\n"
+ " --help or -h show this help.\n"
+ "\n"
+ " --version or -v show software version.\n"
+ "\n"
+ " --global or -g disable charts per application.\n"
+ "\n"
+ " --all or -a Enable all chart groups (global and apps), unless -g is also given.\n"
+ "\n"
+ " --net or -n Enable network viewer charts.\n"
+ "\n"
+ " --process or -p Enable charts related to process run time.\n"
+ "\n"
+ " --return or -r Run the collector in return mode.\n"
+ "\n"
+ , VERSION
+ , (year >= 116)?year + 1900: 2020
+ );
+}
+
+static void parse_args(int argc, char **argv)
+{
+ int enabled = 0;
+ int disable_apps = 0;
+ int freq = 0;
+ int c;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"help", no_argument, 0, 'h' },
+ {"version", no_argument, 0, 'v' },
+ {"global", no_argument, 0, 'g' },
+ {"all", no_argument, 0, 'a' },
+ {"net", no_argument, 0, 'n' },
+ {"process", no_argument, 0, 'p' },
+ {"return", no_argument, 0, 'r' },
+ {0, 0, 0, 0}
+ };
+
+ if (argc > 1) {
+ int n = (int)str2l(argv[1]);
+ if(n > 0) {
+ freq = n;
+ }
+ }
+
+ while (1) {
+ c = getopt_long(argc, argv, "hvganpr",long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h': {
+ ebpf_print_help();
+ exit(0);
+ }
+ case 'v': {
+ printf("ebpf.plugin %s\n", VERSION);
+ exit(0);
+ }
+ case 'g': {
+ disable_apps = 1;
+ ebpf_disable_apps();
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF running with global chart group, because it was started with the option \"--global\" or \"-g\".");
+#endif
+ break;
+ }
+ case 'a': {
+ ebpf_enable_all_charts(disable_apps);
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF running with all chart groups, because it was started with the option \"--all\" or \"-a\".");
+#endif
+ break;
+ }
+ case 'n': {
+ enabled = 1;
+ ebpf_enable_chart(1, disable_apps);
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF enabling \"NET\" charts, because it was started with the option \"--net\" or \"-n\".");
+#endif
+ break;
+ }
+ case 'p': {
+ enabled = 1;
+ ebpf_enable_chart(0, disable_apps);
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF enabling \"PROCESS\" charts, because it was started with the option \"--process\" or \"-p\".");
+#endif
+ break;
+ }
+ case 'r': {
+ mode = MODE_RETURN;
+ ebpf_set_thread_mode(mode);
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF running in \"return\" mode, because it was started with the option \"--return\" or \"-r\".");
+#endif
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+
+ if (freq > 0) {
+ update_every = freq;
+ }
+
+ if (!enabled) {
+ ebpf_enable_all_charts(disable_apps);
+#ifdef NETDATA_INTERNAL_CHECKS
+ info("EBPF running with all charts, because neither \"-n\" or \"-p\" was given.");
+#endif
+ }
+}
+
int main(int argc, char **argv)
{
- (void)argc;
- (void)argv;
+ parse_args(argc, argv);
mykernel = get_kernel_version();
if(!has_condition_to_run(mykernel)) {
@@ -874,10 +1064,6 @@ int main(int argc, char **argv)
error_log_errors_per_period = 100;
error_log_throttle_period = 3600;
- if (argc > 1) {
- update_every = (int)strtol(argv[1], NULL, 10);
- }
-
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
if (setrlimit(RLIMIT_MEMLOCK, &r)) {
error("[EBPF PROCESS] setrlimit(RLIMIT_MEMLOCK)");
@@ -913,7 +1099,7 @@ int main(int argc, char **argv)
int_exit(5);
}
- if(mode == 1 && debug_log) {
+ if(mode == MODE_DEVMODE && debug_log) {
if(map_memory()) {
thread_finished++;
error("[EBPF_PROCESS] Cannot map memory used with perf events.");
diff --git a/collectors/ebpf_process.plugin/ebpf_process.h b/collectors/ebpf_process.plugin/ebpf_process.h
index 9813c88576..5f05389e02 100644
--- a/collectors/ebpf_process.plugin/ebpf_process.h
+++ b/collectors/ebpf_process.plugin/ebpf_process.h
@@ -41,6 +41,12 @@
# include "../../libnetdata/config/appconfig.h"
# include "../../libnetdata/ebpf/ebpf.h"
+typedef enum {
+ MODE_RETURN = 0, //This attaches kprobe when the function returns
+ MODE_DEVMODE, //This stores log given description about the errors raised
+ MODE_ENTRY //This attaches kprobe when the function is called
+} netdata_run_mode_t;
+
typedef struct netdata_syscall_stat {
unsigned long bytes; //total number of bytes
uint64_t call; //total number of calls