diff options
author | thiagoftsm <thiagoftsm@gmail.com> | 2021-10-08 13:07:26 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-08 13:07:26 +0000 |
commit | dbc8fefd54ed9381537f2febbf714ce9ff121feb (patch) | |
tree | 303fb8d245b72be65cbd1c839aba4b1aadea9bc8 /collectors | |
parent | d1126fae7d51caf340061aa1e60a8c3c0577d777 (diff) |
eBPF and cgroup (process, file descriptor, VFS, directory cache and OOMkill) (#11611)
Diffstat (limited to 'collectors')
-rw-r--r-- | collectors/ebpf.plugin/ebpf.h | 1 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_apps.h | 5 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_cgroup.c | 5 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_cgroup.h | 11 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_dcstat.c | 355 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_dcstat.h | 11 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_fd.c | 328 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_fd.h | 11 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_oomkill.c | 244 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_oomkill.h | 2 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_process.c | 296 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_process.h | 12 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_swap.c | 70 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_swap.h | 6 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_vfs.c | 670 | ||||
-rw-r--r-- | collectors/ebpf.plugin/ebpf_vfs.h | 18 |
16 files changed, 1964 insertions, 81 deletions
diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h index c09560c72f..7a3fd76242 100644 --- a/collectors/ebpf.plugin/ebpf.h +++ b/collectors/ebpf.plugin/ebpf.h @@ -117,6 +117,7 @@ typedef struct ebpf_tracepoint { #define NETDATA_EBPF_MEMORY_GROUP "mem" #define NETDATA_EBPF_SYSTEM_GROUP "system" #define NETDATA_SYSTEM_SWAP_SUBMENU "swap" +#define NETDATA_SYSTEM_CGROUP_SWAP_SUBMENU "swap (eBPF)" #define NETDATA_SYSTEM_IPC_SHM_SUBMENU "ipc shared memory" // Log file diff --git a/collectors/ebpf.plugin/ebpf_apps.h b/collectors/ebpf.plugin/ebpf_apps.h index 92419625cb..aad28f7528 100644 --- a/collectors/ebpf.plugin/ebpf_apps.h +++ b/collectors/ebpf.plugin/ebpf_apps.h @@ -12,6 +12,7 @@ #define NETDATA_APPS_FAMILY "apps" #define NETDATA_APPS_FILE_GROUP "file_access" +#define NETDATA_APPS_FILE_CGROUP_GROUP "file_access (eBPF)" #define NETDATA_APPS_PROCESS_GROUP "process (eBPF)" #define NETDATA_APPS_NET_GROUP "net" #define NETDATA_APPS_IPC_SHM_GROUP "ipc shared memory" @@ -353,18 +354,14 @@ typedef struct ebpf_process_stat { uint32_t pid; //Counter - uint32_t open_call; uint32_t exit_call; uint32_t release_call; uint32_t fork_call; uint32_t clone_call; - uint32_t close_call; //Counter - uint32_t open_err; uint32_t fork_err; uint32_t clone_err; - uint32_t close_err; uint8_t removeme; } ebpf_process_stat_t; diff --git a/collectors/ebpf.plugin/ebpf_cgroup.c b/collectors/ebpf.plugin/ebpf_cgroup.c index aa34d4047b..9672991ed6 100644 --- a/collectors/ebpf.plugin/ebpf_cgroup.c +++ b/collectors/ebpf.plugin/ebpf_cgroup.c @@ -330,13 +330,14 @@ void ebpf_parse_cgroup_shm_data() * @param charttype chart type * @param order the chart order * @param algorithm the algorithm used by dimension + * @param context add context for chart * @param module chart module name, this is the eBPF thread. */ void ebpf_create_charts_on_systemd(char *id, char *title, char *units, char *family, char *charttype, int order, - char *algorithm, char *module) + char *algorithm, char *context, char *module) { ebpf_cgroup_target_t *w; - ebpf_write_chart_cmd(NETDATA_SERVICE_FAMILY, id, title, units, family, charttype, NULL, order, module); + ebpf_write_chart_cmd(NETDATA_SERVICE_FAMILY, id, title, units, family, charttype, context, order, module); for (w = ebpf_cgroup_pids; w; w = w->next) { if (unlikely(w->systemd) && unlikely(w->updated)) diff --git a/collectors/ebpf.plugin/ebpf_cgroup.h b/collectors/ebpf.plugin/ebpf_cgroup.h index 6d95f66c6a..8ffb0670d6 100644 --- a/collectors/ebpf.plugin/ebpf_cgroup.h +++ b/collectors/ebpf.plugin/ebpf_cgroup.h @@ -16,6 +16,10 @@ struct pid_on_target2 { int updated; netdata_publish_swap_t swap; + netdata_fd_stat_t fd; + netdata_publish_vfs_t vfs; + ebpf_process_stat_t ps; + netdata_dcstat_pid_t dc; struct pid_on_target2 *next; }; @@ -40,6 +44,11 @@ typedef struct ebpf_cgroup_target { uint32_t updated; netdata_publish_swap_t publish_systemd_swap; + netdata_fd_stat_t publish_systemd_fd; + netdata_publish_vfs_t publish_systemd_vfs; + ebpf_process_stat_t publish_systemd_ps; + netdata_publish_dcstat_t publish_dc; + int oomkill; struct pid_on_target2 *pids; struct ebpf_cgroup_target *next; @@ -50,6 +59,6 @@ extern void ebpf_parse_cgroup_shm_data(); extern void ebpf_close_cgroup_shm(); extern void ebpf_clean_cgroup_pids(); extern void ebpf_create_charts_on_systemd(char *id, char *title, char *units, char *family, char *charttype, int order, - char *algorithm, char *module); + char *algorithm, char *context, char *module); #endif /* NETDATA_EBPF_CGROUP_H */ diff --git a/collectors/ebpf.plugin/ebpf_dcstat.c b/collectors/ebpf.plugin/ebpf_dcstat.c index d4f04c8c99..26159c852d 100644 --- a/collectors/ebpf.plugin/ebpf_dcstat.c +++ b/collectors/ebpf.plugin/ebpf_dcstat.c @@ -286,6 +286,43 @@ static void read_apps_table() } /** + * Update cgroup + * + * Update cgroup data based in + */ +static void ebpf_update_dc_cgroup() +{ + netdata_dcstat_pid_t *cv = dcstat_vector; + int fd = dcstat_maps[NETDATA_DCSTAT_PID_STATS].map_fd; + size_t length = sizeof(netdata_dcstat_pid_t)*ebpf_nprocs; + + ebpf_cgroup_target_t *ect; + pthread_mutex_lock(&mutex_cgroup_shm); + for (ect = ebpf_cgroup_pids; ect; ect = ect->next) { + struct pid_on_target2 *pids; + for (pids = ect->pids; pids; pids = pids->next) { + int pid = pids->pid; + netdata_dcstat_pid_t *out = &pids->dc; + if (dcstat_pid[pid]) { + netdata_publish_dcstat_t *in = dcstat_pid[pid]; + + memcpy(out, &in->curr, sizeof(netdata_dcstat_pid_t)); + } else { + memset(cv, 0, length); + if (bpf_map_lookup_elem(fd, &pid, cv)) { + continue; + } + + dcstat_apps_accumulator(cv); + + memcpy(out, cv, sizeof(netdata_dcstat_pid_t)); + } + } + } + pthread_mutex_unlock(&mutex_cgroup_shm); +} + +/** * Read global table * * Read the table with number of calls for all functions @@ -475,6 +512,317 @@ static void dcstat_send_global(netdata_publish_dcstat_t *publish) } /** + * Create specific directory cache charts + * + * Create charts for cgroup/application. + * + * @param type the chart type. + */ +static void ebpf_create_specific_dc_charts(char *type) +{ + ebpf_create_chart(type, NETDATA_DC_HIT_CHART, "Percentage of files listed inside directory cache.", + EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_CGROUP_DC_HIT_RATIO_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5700, + ebpf_create_global_dimension, + dcstat_counter_publish_aggregated, 1, NETDATA_EBPF_MODULE_NAME_DCSTAT); + + ebpf_create_chart(type, NETDATA_DC_REFERENCE_CHART, "Count file access.", + EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_CGROUP_DC_REFERENCE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5701, + ebpf_create_global_dimension, + &dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_REFERENCE], 1, + NETDATA_EBPF_MODULE_NAME_DCSTAT); + + ebpf_create_chart(type, NETDATA_DC_REQUEST_NOT_CACHE_CHART, + "Access to files that were not present inside directory cache.", + EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_CGROUP_DC_NOT_CACHE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5702, + ebpf_create_global_dimension, + &dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_SLOW], 1, + NETDATA_EBPF_MODULE_NAME_DCSTAT); + + ebpf_create_chart(type, NETDATA_DC_REQUEST_NOT_FOUND_CHART, + "Number of requests for files that were not found on filesystem.", + EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_CGROUP_DC_NOT_FOUND_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5703, + ebpf_create_global_dimension, + &dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_MISS], 1, + NETDATA_EBPF_MODULE_NAME_DCSTAT); +} + +/** + * Obsolete specific directory cache charts + * + * Obsolete charts for cgroup/application. + * + * @param type the chart type. + */ +static void ebpf_obsolete_specific_dc_charts(char *type) +{ + ebpf_write_chart_obsolete(type, NETDATA_DC_HIT_CHART, + "Percentage of files listed inside directory cache.", + EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_HIT_RATIO_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5700); + + ebpf_write_chart_obsolete(type, NETDATA_DC_REFERENCE_CHART, + "Count file access.", + EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_REFERENCE_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5701); + + ebpf_write_chart_obsolete(type, NETDATA_DC_REQUEST_NOT_CACHE_CHART, + "Access to files that were not present inside directory cache.", + EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_NOT_CACHE_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5702); + + ebpf_write_chart_obsolete(type, NETDATA_DC_REQUEST_NOT_FOUND_CHART, + "Number of requests for files that were not found on filesystem.", + EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_NOT_FOUND_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5703); +} + +/** + * Cachestat sum PIDs + * + * Sum values for all PIDs associated to a group + * + * @param publish output structure. + * @param root structure with listed IPs + */ +void ebpf_dc_sum_cgroup_pids(netdata_publish_dcstat_t *publish, struct pid_on_target2 *root) +{ + memset(&publish->curr, 0, sizeof(netdata_dcstat_pid_t)); + netdata_dcstat_pid_t *dst = &publish->curr; + while (root) { + int32_t pid = root->pid; + netdata_publish_dcstat_t *w = dcstat_pid[pid]; + if (w) { + netdata_dcstat_pid_t *src = &w->curr; + dst->cache_access += src->cache_access; + dst->file_system += src->file_system; + dst->not_found += src->not_found; + } + + root = root->next; + } +} + +/** + * Calc chart values + * + * Do necessary math to plot charts. + */ +void ebpf_dc_calc_chart_values() +{ + ebpf_cgroup_target_t *ect; + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + ebpf_dc_sum_cgroup_pids(&ect->publish_dc, ect->pids); + uint64_t cache = ect->publish_dc.curr.cache_access; + uint64_t not_found = ect->publish_dc.curr.not_found; + + dcstat_update_publish(&ect->publish_dc, cache, not_found); + + ect->publish_dc.cache_access = (long long)ect->publish_dc.curr.cache_access - + (long long)ect->publish_dc.prev.cache_access; + ect->publish_dc.prev.cache_access = ect->publish_dc.curr.cache_access; + + if (ect->publish_dc.curr.not_found < ect->publish_dc.prev.not_found) { + ect->publish_dc.prev.not_found = 0; + } + } +} + +/** + * Create Systemd directory cache Charts + * + * Create charts when systemd is enabled + **/ +static void ebpf_create_systemd_dc_charts() +{ + ebpf_create_charts_on_systemd(NETDATA_DC_HIT_CHART, + "Percentage of files listed inside directory cache.", + EBPF_COMMON_DIMENSION_PERCENTAGE, + NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, + 21200, + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], + NETDATA_SYSTEMD_DC_HIT_RATIO_CONTEXT, NETDATA_EBPF_MODULE_NAME_DCSTAT); + + ebpf_create_charts_on_systemd(NETDATA_DC_REFERENCE_CHART, + "Count file access.", + EBPF_COMMON_DIMENSION_FILES, + NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, + 21201, + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], + NETDATA_SYSTEMD_DC_REFERENCE_CONTEXT, NETDATA_EBPF_MODULE_NAME_DCSTAT); + + ebpf_create_charts_on_systemd(NETDATA_DC_REQUEST_NOT_CACHE_CHART, + "Access to files that were not present inside directory cache.", + EBPF_COMMON_DIMENSION_FILES, + NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, + 21202, + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], + NETDATA_SYSTEMD_DC_NOT_CACHE_CONTEXT, NETDATA_EBPF_MODULE_NAME_DCSTAT); + + ebpf_create_charts_on_systemd(NETDATA_DC_REQUEST_NOT_FOUND_CHART, + "Number of requests for files that were not found on filesystem.", + EBPF_COMMON_DIMENSION_FILES, + NETDATA_DIRECTORY_CACHE_SUBMENU, + NETDATA_EBPF_CHART_TYPE_LINE, + 21202, + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], + NETDATA_SYSTEMD_DC_NOT_FOUND_CONTEXT, NETDATA_EBPF_MODULE_NAME_DCSTAT); +} + +/** + * Send Directory Cache charts + * + * Send collected data to Netdata. + * + * @return It returns the status for chart creation, if it is necessary to remove a specific dimension, zero is returned + * otherwise function returns 1 to avoid chart recreation + */ +static int ebpf_send_systemd_dc_charts() +{ + int ret = 1; + collected_number value; + ebpf_cgroup_target_t *ect; + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_DC_HIT_CHART); + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (unlikely(ect->systemd) && unlikely(ect->updated)) { + write_chart_dimension(ect->name, (long long) ect->publish_dc.ratio); + } else + ret = 0; + } + write_end_chart(); + + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_DC_REFERENCE_CHART); + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (unlikely(ect->systemd) && unlikely(ect->updated)) { + write_chart_dimension(ect->name, (long long) ect->publish_dc.cache_access); + } + } + write_end_chart(); + + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_DC_REQUEST_NOT_CACHE_CHART); + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (unlikely(ect->systemd) && unlikely(ect->updated)) { + value = (collected_number) (!ect->publish_dc.cache_access) ? 0 : + (long long )ect->publish_dc.curr.file_system - (long long)ect->publish_dc.prev.file_system; + ect->publish_dc.prev.file_system = ect->publish_dc.curr.file_system; + + write_chart_dimension(ect->name, (long long) value); + } + } + write_end_chart(); + + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_DC_REQUEST_NOT_FOUND_CHART); + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (unlikely(ect->systemd) && unlikely(ect->updated)) { + value = (collected_number) (!ect->publish_dc.cache_access) ? 0 : + (long long)ect->publish_dc.curr.not_found - (long long)ect->publish_dc.prev.not_found; + + ect->publish_dc.prev.not_found = ect->publish_dc.curr.not_found; + + write_chart_dimension(ect->name, (long long) value); + } + } + write_end_chart(); + + return ret; +} + +/** + * Send Directory Cache charts + * + * Send collected data to Netdata. + * + */ +static void ebpf_send_specific_dc_data(char *type, netdata_publish_dcstat_t *pdc) +{ + collected_number value; + write_begin_chart(type, NETDATA_DC_HIT_CHART); + write_chart_dimension(dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_RATIO].name, + (long long) pdc->ratio); + write_end_chart(); + + write_begin_chart(type, NETDATA_DC_REFERENCE_CHART); + write_chart_dimension(dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_REFERENCE].name, + (long long) pdc->cache_access); + write_end_chart(); + + value = (collected_number) (!pdc->cache_access) ? 0 : + (long long )pdc->curr.file_system - (long long)pdc->prev.file_system; + pdc->prev.file_system = pdc->curr.file_system; + + write_begin_chart(type, NETDATA_DC_REQUEST_NOT_CACHE_CHART); + write_chart_dimension(dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_SLOW].name, (long long) value); + write_end_chart(); + + value = (collected_number) (!pdc->cache_access) ? 0 : + (long long)pdc->curr.not_found - (long long)pdc->prev.not_found; + pdc->prev.not_found = pdc->curr.not_found; + + write_begin_chart(type, NETDATA_DC_REQUEST_NOT_FOUND_CHART); + write_chart_dimension(dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_MISS].name, (long long) value); + write_end_chart(); +} + +/** + * Send data to Netdata calling auxiliar functions. +*/ +void ebpf_dc_send_cgroup_data() +{ + if (!ebpf_cgroup_pids) + return; + + pthread_mutex_lock(&mutex_cgroup_shm); + ebpf_cgroup_target_t *ect; + ebpf_dc_calc_chart_values(); + + int has_systemd = shm_ebpf_cgroup.header->systemd_enabled; + if (has_systemd) { + static int systemd_charts = 0; + if (!systemd_charts) { + ebpf_create_systemd_dc_charts(); + systemd_charts = 1; + } + + systemd_charts = ebpf_send_systemd_dc_charts(); + } + + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (ect->systemd) + continue; + + if (!(ect->flags & NETDATA_EBPF_CGROUP_HAS_DC_CHART) && ect->updated) { + ebpf_create_specific_dc_charts(ect->name); + ect->flags |= NETDATA_EBPF_CGROUP_HAS_DC_CHART; + } + + if (ect->flags & NETDATA_EBPF_CGROUP_HAS_DC_CHART) { + if (ect->updated) { + ebpf_send_specific_dc_data(ect->name, &ect->publish_dc); + } else { + ebpf_obsolete_specific_dc_charts(ect->name); + ect->flags &= ~NETDATA_EBPF_CGROUP_HAS_DC_CHART; + } + } + } + + pthread_mutex_unlock(&mutex_cgroup_shm); +} + +/** * Main loop for this collector. */ static void dcstat_collector(ebpf_module_t *em) @@ -488,6 +836,7 @@ static void dcstat_collector(ebpf_module_t *em) netdata_publish_dcstat_t publish; memset(&publish, 0, sizeof(publish)); int apps = em->apps_charts; + int cgroups = em->cgroup_charts; while (!close_ebpf_plugin) { pthread_mutex_lock(&collect_data_mutex); pthread_cond_wait(&collect_data_cond_var, &collect_data_mutex); @@ -495,6 +844,9 @@ static void dcstat_collector(ebpf_module_t *em) if (apps) read_apps_table(); + if (cgroups) + ebpf_update_dc_cgroup(); + pthread_mutex_lock(&lock); dcstat_send_global(&publish); @@ -502,6 +854,9 @@ static void dcstat_collector(ebpf_module_t *em) if (apps) ebpf_dcache_send_apps_data(apps_groups_root_target); + if (cgroups) + ebpf_dc_send_cgroup_data(); + pthread_mutex_unlock(&lock); pthread_mutex_unlock(&collect_data_mutex); } diff --git a/collectors/ebpf.plugin/ebpf_dcstat.h b/collectors/ebpf.plugin/ebpf_dcstat.h index 0f5ab784b3..c5e6e2bcf3 100644 --- a/collectors/ebpf.plugin/ebpf_dcstat.h +++ b/collectors/ebpf.plugin/ebpf_dcstat.h @@ -17,6 +17,17 @@ // configuration file #define NETDATA_DIRECTORY_DCSTAT_CONFIG_FILE "dcstat.conf" +// Contexts +#define NETDATA_CGROUP_DC_HIT_RATIO_CONTEXT "cgroup.dc_ratio" +#define NETDATA_CGROUP_DC_REFERENCE_CONTEXT "cgroup.dc_reference" +#define NETDATA_CGROUP_DC_NOT_CACHE_CONTEXT "cgroup.dc_not_cache" +#define NETDATA_CGROUP_DC_NOT_FOUND_CONTEXT "cgroup.dc_not_found" + +#define NETDATA_SYSTEMD_DC_HIT_RATIO_CONTEXT "services.dc_ratio" +#define NETDATA_SYSTEMD_DC_REFERENCE_CONTEXT "services.dc_reference" +#define NETDATA_SYSTEMD_DC_NOT_CACHE_CONTEXT "services.dc_not_cache" +#define NETDATA_SYSTEMD_DC_NOT_FOUND_CONTEXT "services.dc_not_found" + #define NETDATA_LATENCY_DCSTAT_SLEEP_MS 700000ULL enum directory_cache_indexes { diff --git a/collectors/ebpf.plugin/ebpf_fd.c b/collectors/ebpf.plugin/ebpf_fd.c index 507597917a..d5b8e8c64d 100644 --- a/collectors/ebpf.plugin/ebpf_fd.c +++ b/collectors/ebpf.plugin/ebpf_fd.c @@ -250,6 +250,41 @@ static void read_apps_table() } /** + * Update cgroup + * + * Update cgroup data based in + */ +static void ebpf_update_fd_cgroup() +{ + ebpf_cgroup_target_t *ect ; + netdata_fd_stat_t *fv = fd_vector; + int fd = fd_maps[NETDATA_FD_PID_STATS].map_fd; + size_t length = sizeof(netdata_fd_stat_t) * ebpf_nprocs; + + pthread_mutex_lock(&mutex_cgroup_shm); + for (ect = ebpf_cgroup_pids; ect; ect = ect->next) { + struct pid_on_target2 *pids; + for (pids = ect->pids; pids; pids = pids->next) { + int pid = pids->pid; + netdata_fd_stat_t *out = &pids->fd; + if (fd_pid[pid]) { + netdata_fd_stat_t *in = fd_pid[pid]; + + memcpy(out, in, sizeof(netdata_fd_stat_t)); + } else { + memset(fv, 0, length); + if (!bpf_map_lookup_elem(fd, &pid, fv)) { + fd_apps_accumulator(fv); + + memcpy(out, fv, sizeof(netdata_publish_swap_t)); + } + } + } + } + pthread_mutex_unlock(&mutex_cgroup_shm); +} + +/** * Sum PIDs * * Sum values for all targets. @@ -337,6 +372,292 @@ void ebpf_fd_send_apps_data(ebpf_module_t *em, struct target *root) } /** + * Sum PIDs + * + * Sum values for all targets. + * + * @param fd structure used to store data + * @param pids input data + */ +static void ebpf_fd_sum_cgroup_pids(netdata_fd_stat_t *fd, struct pid_on_target2 *pids) +{ + netdata_fd_stat_t accumulator; + memset(&accumulator, 0, sizeof(accumulator)); + + while (pids) { + netdata_fd_stat_t *w = &pids->fd; + + accumulator.open_err += w->open_err; + accumulator.open_call += w->open_call; + accumulator.close_call += w->close_call; + accumulator.close_err += w->close_err; + + pids = pids->next; + } + + fd->open_call = (accumulator.open_call >= fd->open_call) ? accumulator.open_call : fd->open_call; + fd->open_err = (accumulator.open_err >= fd->open_err) ? accumulator.open_err : fd->open_err; + fd->close_call = (accumulator.close_call >= fd->close_call) ? accumulator.close_call : fd->close_call; + fd->close_err = (accumulator.close_err >= fd->close_err) ? accumulator.close_err : fd->close_err; +} + +/** + * Create specific file descriptor charts + * + * Create charts for cgroup/application. + * + * @param type the chart type. + * @param em the main thread structure. + */ +static void ebpf_create_specific_fd_charts(char *type, ebpf_module_t *em) +{ + ebpf_create_chart(type, NETDATA_SYSCALL_APPS_FILE_OPEN, "Number of open files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_CGROUP_FD_OPEN_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5400, + ebpf_create_global_dimension, + &fd_publish_aggregated[NETDATA_FD_SYSCALL_OPEN], + 1, NETDATA_EBPF_MODULE_NAME_SWAP); + + if (em->mode < MODE_ENTRY) { + ebpf_create_chart(type, NETDATA_SYSCALL_APPS_FILE_OPEN_ERROR, "Fails to open files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_CGROUP_FD_OPEN_ERR_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5401, + ebpf_create_global_dimension, + &fd_publish_aggregated[NETDATA_FD_SYSCALL_OPEN], + 1, + NETDATA_EBPF_MODULE_NAME_SWAP); + } + + ebpf_create_chart(type, NETDATA_SYSCALL_APPS_FILE_CLOSED, "Files closed", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_CGROUP_FD_CLOSE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5402, + ebpf_create_global_dimension, + &fd_publish_aggregated[NETDATA_FD_SYSCALL_CLOSE], + 1, NETDATA_EBPF_MODULE_NAME_SWAP); + + if (em->mode < MODE_ENTRY) { + ebpf_create_chart(type, NETDATA_SYSCALL_APPS_FILE_CLOSE_ERROR, "Fails to close files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_CGROUP_FD_CLOSE_ERR_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5403, + ebpf_create_global_dimension, + &fd_publish_aggregated[NETDATA_FD_SYSCALL_CLOSE], + 1, + NETDATA_EBPF_MODULE_NAME_SWAP); + } +} + +/** + * Obsolete specific file descriptor charts + * + * Obsolete charts for cgroup/application. + * + * @param type the chart type. + * @param em the main thread structure. + */ +static void ebpf_obsolete_specific_fd_charts(char *type, ebpf_module_t *em) +{ + ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_FILE_OPEN, "Number of open files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_GROUP, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_FD_OPEN_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5400); + + if (em->mode < MODE_ENTRY) { + ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_FILE_OPEN_ERROR, "Fails to open files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_GROUP, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_FD_OPEN_ERR_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5401); + } + + ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_FILE_CLOSED, "Files closed", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_GROUP, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_FD_CLOSE_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5402); + + if (em->mode < MODE_ENTRY) { + ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_FILE_CLOSE_ERROR, "Fails to close files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_GROUP, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_FD_CLOSE_ERR_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5403); + } +} + +/* + * Send specific file descriptor data + * + * Send data for specific cgroup/apps. + * + * @param type chart type + * @param values structure with values that will be sent to netdata + */ +static void ebpf_send_specific_fd_data(char *type, netdata_fd_stat_t *values, ebpf_module_t *em) +{ + write_begin_chart(type, NETDATA_SYSCALL_APPS_FILE_OPEN); + write_chart_dimension(fd_publish_aggregated[NETDATA_FD_SYSCALL_OPEN].name, (long long)values->open_call); + write_end_chart(); + + if (em->mode < MODE_ENTRY) { + write_begin_chart(type, NETDATA_SYSCALL_APPS_FILE_OPEN_ERROR); + write_chart_dimension(fd_publish_aggregated[NETDATA_FD_SYSCALL_OPEN].name, (long long)values->open_err); + write_end_chart(); + } + + write_begin_chart(type, NETDATA_SYSCALL_APPS_FILE_CLOSED); + write_chart_dimension(fd_publish_aggregated[NETDATA_FD_SYSCALL_CLOSE].name, (long long)values->close_call); + write_end_chart(); + + if (em->mode < MODE_ENTRY) { + write_begin_chart(type, NETDATA_SYSCALL_APPS_FILE_CLOSE_ERROR); + write_chart_dimension(fd_publish_aggregated[NETDATA_FD_SYSCALL_CLOSE].name, (long long)values->close_err); + write_end_chart(); + } +} + +/** + * Create systemd file descriptor charts + * + * Create charts when systemd is enabled + * + * @param em the main collector structure + **/ +static void ebpf_create_systemd_fd_charts(ebpf_module_t *em) +{ + ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_FILE_OPEN, "Number of open files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, 20061, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_FD_OPEN_CONTEXT, + NETDATA_EBPF_MODULE_NAME_PROCESS); + + if (em->mode < MODE_ENTRY) { + ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_FILE_OPEN_ERROR, "Fails to open files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, 20062, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_FD_OPEN_ERR_CONTEXT, + NETDATA_EBPF_MODULE_NAME_PROCESS); + } + + ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_FILE_CLOSED, "Files closed", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, 20063, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_FD_CLOSE_CONTEXT, + NETDATA_EBPF_MODULE_NAME_PROCESS); + + if (em->mode < MODE_ENTRY) { + ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_FILE_CLOSE_ERROR, "Fails to close files", + EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_FILE_CGROUP_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, 20064, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_FD_CLOSE_ERR_CONTEXT, + |