@cryptotaxi247 / netdata-1 / commits / 8d5db453b

Ebpf options (#8879)

ebpf options: We are adding command line options to eBPF collector.

thiagoftsm committed May 13, 2020 at 15:14 UTC 8d5db453b71bb7d3440d909f7e2f3c01718f5ae1
2 files changed +209 -17
collectors/ebpf_process.plugin/ebpf_process.c
+203 -17
@@ -66,7 +66,7 @@ netdata_publish_syscall_t *publish_aggregated = NULL;
66 static int update_every = 1;
67 static int thread_finished = 0;
68 static int close_plugin = 0;
69 -static int mode = 2;
69 +static netdata_run_mode_t mode = MODE_ENTRY;
70 static int debug_log = 0;
71 static int use_stdout = 0;
72 struct config collector_config;
@@ -77,6 +77,20 @@ netdata_idx_t *hash_values;
77
78 pthread_mutex_t lock;
79
80 +static struct ebpf_module {
81 + const char *thread_name;
82 + int enabled;
83 + void (*start_routine) (void *);
84 + int update_time;
85 + int global_charts;
86 + int apps_charts;
87 + netdata_run_mode_t mode;
88 +} ebpf_modules[] = {
89 + { .thread_name = "process", .enabled = 0, .start_routine = NULL, .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY },
90 + { .thread_name = "network_viewer", .enabled = 0, .start_routine = NULL, .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY },
91 + { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_time = 1, .global_charts = 0, .apps_charts = 1, .mode = MODE_ENTRY },
92 +};
93 +
94 static char *dimension_names[NETDATA_MAX_MONITOR_VECTOR] = { "open", "close", "delete", "read", "write", "process", "task", "process", "thread" };
95 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" };
96 static char *status[] = { "process", "zombie" };
@@ -139,7 +153,7 @@ static void int_exit(int sig)
153 publish_aggregated = NULL;
154 }
155
142 - if(mode == 1 && debug_log) {
156 + if(mode == MODE_DEVMODE && debug_log) {
157 unmap_memory();
158 }
159
@@ -279,7 +293,7 @@ static void netdata_global_charts_create() {
293 , publish_aggregated
294 , 2);
295
282 - if(mode < 2) {
296 + if(mode < MODE_ENTRY) {
297 netdata_create_chart(NETDATA_EBPF_FAMILY
298 , NETDATA_FILE_OPEN_ERR_COUNT
299 , "Calls"
@@ -308,7 +322,7 @@ static void netdata_global_charts_create() {
322 , &publish_aggregated[NETDATA_IN_START_BYTE]
323 , 2);
324
311 - if(mode < 2) {
325 + if(mode < MODE_ENTRY) {
326 netdata_create_io_chart(NETDATA_EBPF_FAMILY
327 , NETDATA_VFS_IO_FILE_BYTES
328 , "bytes/s"
@@ -350,7 +364,7 @@ static void netdata_global_charts_create() {
364 , NETDATA_PROCESS_GROUP
365 , 978);
366
353 - if(mode < 2) {
367 + if(mode < MODE_ENTRY) {
368 netdata_create_chart(NETDATA_EBPF_FAMILY
369 , NETDATA_PROCESS_ERROR_NAME
370 , "Calls"
@@ -479,7 +493,7 @@ static void netdata_publish_data() {
493 write_global_count_chart(NETDATA_PROCESS_SYSCALL, NETDATA_EBPF_FAMILY, &publish_aggregated[NETDATA_PROCESS_START], 2);
494
495 write_status_chart(NETDATA_EBPF_FAMILY, &pvc);
482 - if(mode < 2) {
496 + if(mode < MODE_ENTRY) {
497 write_global_err_chart(NETDATA_FILE_OPEN_ERR_COUNT, NETDATA_EBPF_FAMILY, publish_aggregated, 2);
498 write_global_err_chart(NETDATA_VFS_FILE_ERR_COUNT, NETDATA_EBPF_FAMILY, &publish_aggregated[2], NETDATA_VFS_ERRORS);
499 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)
611 {
612 (void) ptr;
613
600 - if (mode == 1 && debug_log) {
614 + if (mode == MODE_DEVMODE && debug_log) {
615 netdata_perf_loop_multi(pmu_fd, headers, nprocs, &close_plugin, netdata_store_bpf, page_cnt);
616 }
617
@@ -695,7 +709,7 @@ static int ebpf_load_libraries()
709 return -1;
710 }
711
698 - if(mode == 1) {
712 + if(mode == MODE_DEVMODE) {
713 set_bpf_perf_event = dlsym(libnetdata, "set_bpf_perf_event");
714 if ((err = dlerror()) != NULL) {
715 error("[EBPF_PROCESS] Cannot find set_bpf_perf_event: %s", err);
@@ -728,7 +742,7 @@ static int ebpf_load_libraries()
742 char *select_file() {
743 if(!mode)
744 return "rnetdata_ebpf_process.o";
731 - if(mode == 1)
745 + if(mode == MODE_DEVMODE)
746 return "dnetdata_ebpf_process.o";
747
748 return "pnetdata_ebpf_process.o";
@@ -798,7 +812,7 @@ static void change_syscalls() {
812
813 static inline void what_to_load(char *ptr) {
814 if (!strcasecmp(ptr, "return"))
801 - mode = 0;
815 + mode = MODE_RETURN;
816 /*
817 else if (!strcasecmp(ptr, "dev"))
818 mode = 1;
@@ -853,10 +867,186 @@ static int load_collector_file(char *path) {
867 return 0;
868 }
869
870 +static inline void ebpf_disable_apps() {
871 + int i ;
872 + for (i = 0 ;ebpf_modules[i].thread_name ; i++ ) {
873 + ebpf_modules[i].apps_charts = 0;
874 + }
875 +}
876 +
877 +static inline void ebpf_enable_specific_chart(struct ebpf_module *em, int disable_apps) {
878 + em->enabled = 1;
879 + if (!disable_apps) {
880 + em->apps_charts = 1;
881 + }
882 + em->global_charts = 1;
883 +}
884 +
885 +static inline void ebpf_enable_all_charts(int apps) {
886 + int i ;
887 + for (i = 0 ; ebpf_modules[i].thread_name ; i++ ) {
888 + ebpf_enable_specific_chart(&ebpf_modules[i], apps);
889 + }
890 +}
891 +
892 +static inline void ebpf_enable_chart(int enable, int disable_apps) {
893 + int i ;
894 + for (i = 0 ; ebpf_modules[i].thread_name ; i++ ) {
895 + if (i == enable) {
896 + ebpf_enable_specific_chart(&ebpf_modules[i], disable_apps);
897 + break;
898 + }
899 + }
900 +}
901 +
902 +static inline void ebpf_set_thread_mode(netdata_run_mode_t lmode) {
903 + int i ;
904 + for (i = 0 ; ebpf_modules[i].thread_name ; i++ ) {
905 + ebpf_modules[i].mode = lmode;
906 + }
907 +}
908 +
909 +void ebpf_print_help() {
910 + const time_t t = time(NULL);
911 + struct tm ct;
912 + struct tm *test = localtime_r(&t, &ct);
913 + int year;
914 + if (test)
915 + year = ct.tm_year;
916 + else
917 + year = 0;
918 +
919 + fprintf(stderr,
920 + "\n"
921 + " Netdata ebpf.plugin %s\n"
922 + " Copyright (C) 2016-%d Costa Tsaousis <costa@tsaousis.gr>\n"
923 + " Released under GNU General Public License v3 or later.\n"
924 + " All rights reserved.\n"
925 + "\n"
926 + " This program is a data collector plugin for netdata.\n"
927 + "\n"
928 + " Available command line options:\n"
929 + "\n"
930 + " SECONDS set the data collection frequency.\n"
931 + "\n"
932 + " --help or -h show this help.\n"
933 + "\n"
934 + " --version or -v show software version.\n"
935 + "\n"
936 + " --global or -g disable charts per application.\n"
937 + "\n"
938 + " --all or -a Enable all chart groups (global and apps), unless -g is also given.\n"
939 + "\n"
940 + " --net or -n Enable network viewer charts.\n"
941 + "\n"
942 + " --process or -p Enable charts related to process run time.\n"
943 + "\n"
944 + " --return or -r Run the collector in return mode.\n"
945 + "\n"
946 + , VERSION
947 + , (year >= 116)?year + 1900: 2020
948 + );
949 +}
950 +
951 +static void parse_args(int argc, char **argv)
952 +{
953 + int enabled = 0;
954 + int disable_apps = 0;
955 + int freq = 0;
956 + int c;
957 + int option_index = 0;
958 + static struct option long_options[] = {
959 + {"help", no_argument, 0, 'h' },
960 + {"version", no_argument, 0, 'v' },
961 + {"global", no_argument, 0, 'g' },
962 + {"all", no_argument, 0, 'a' },
963 + {"net", no_argument, 0, 'n' },
964 + {"process", no_argument, 0, 'p' },
965 + {"return", no_argument, 0, 'r' },
966 + {0, 0, 0, 0}
967 + };
968 +
969 + if (argc > 1) {
970 + int n = (int)str2l(argv[1]);
971 + if(n > 0) {
972 + freq = n;
973 + }
974 + }
975 +
976 + while (1) {
977 + c = getopt_long(argc, argv, "hvganpr",long_options, &option_index);
978 + if (c == -1)
979 + break;
980 +
981 + switch (c) {
982 + case 'h': {
983 + ebpf_print_help();
984 + exit(0);
985 + }
986 + case 'v': {
987 + printf("ebpf.plugin %s\n", VERSION);
988 + exit(0);
989 + }
990 + case 'g': {
991 + disable_apps = 1;
992 + ebpf_disable_apps();
993 +#ifdef NETDATA_INTERNAL_CHECKS
994 + info("EBPF running with global chart group, because it was started with the option \"--global\" or \"-g\".");
995 +#endif
996 + break;
997 + }
998 + case 'a': {
999 + ebpf_enable_all_charts(disable_apps);
1000 +#ifdef NETDATA_INTERNAL_CHECKS
1001 + info("EBPF running with all chart groups, because it was started with the option \"--all\" or \"-a\".");
1002 +#endif
1003 + break;
1004 + }
1005 + case 'n': {
1006 + enabled = 1;
1007 + ebpf_enable_chart(1, disable_apps);
1008 +#ifdef NETDATA_INTERNAL_CHECKS
1009 + info("EBPF enabling \"NET\" charts, because it was started with the option \"--net\" or \"-n\".");
1010 +#endif
1011 + break;
1012 + }
1013 + case 'p': {
1014 + enabled = 1;
1015 + ebpf_enable_chart(0, disable_apps);
1016 +#ifdef NETDATA_INTERNAL_CHECKS
1017 + info("EBPF enabling \"PROCESS\" charts, because it was started with the option \"--process\" or \"-p\".");
1018 +#endif
1019 + break;
1020 + }
1021 + case 'r': {
1022 + mode = MODE_RETURN;
1023 + ebpf_set_thread_mode(mode);
1024 +#ifdef NETDATA_INTERNAL_CHECKS
1025 + info("EBPF running in \"return\" mode, because it was started with the option \"--return\" or \"-r\".");
1026 +#endif
1027 + break;
1028 + }
1029 + default: {
1030 + break;
1031 + }
1032 + }
1033 + }
1034 +
1035 + if (freq > 0) {
1036 + update_every = freq;
1037 + }
1038 +
1039 + if (!enabled) {
1040 + ebpf_enable_all_charts(disable_apps);
1041 +#ifdef NETDATA_INTERNAL_CHECKS
1042 + info("EBPF running with all charts, because neither \"-n\" or \"-p\" was given.");
1043 +#endif
1044 + }
1045 +}
1046 +
1047 int main(int argc, char **argv)
1048 {
858 - (void)argc;
859 - (void)argv;
1049 + parse_args(argc, argv);
1050
1051 mykernel = get_kernel_version();
1052 if(!has_condition_to_run(mykernel)) {
@@ -874,10 +1064,6 @@ int main(int argc, char **argv)
1064 error_log_errors_per_period = 100;
1065 error_log_throttle_period = 3600;
1066
877 - if (argc > 1) {
878 - update_every = (int)strtol(argv[1], NULL, 10);
879 - }
880 -
1067 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
1068 if (setrlimit(RLIMIT_MEMLOCK, &r)) {
1069 error("[EBPF PROCESS] setrlimit(RLIMIT_MEMLOCK)");
@@ -913,7 +1099,7 @@ int main(int argc, char **argv)
1099 int_exit(5);
1100 }
1101
916 - if(mode == 1 && debug_log) {
1102 + if(mode == MODE_DEVMODE && debug_log) {
1103 if(map_memory()) {
1104 thread_finished++;
1105 error("[EBPF_PROCESS] Cannot map memory used with perf events.");
collectors/ebpf_process.plugin/ebpf_process.h
+6
@@ -41,6 +41,12 @@
41 # include "../../libnetdata/config/appconfig.h"
42 # include "../../libnetdata/ebpf/ebpf.h"
43
44 +typedef enum {
45 + MODE_RETURN = 0, //This attaches kprobe when the function returns
46 + MODE_DEVMODE, //This stores log given description about the errors raised
47 + MODE_ENTRY //This attaches kprobe when the function is called
48 +} netdata_run_mode_t;
49 +
50 typedef struct netdata_syscall_stat {
51 unsigned long bytes; //total number of bytes
52 uint64_t call; //total number of calls