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