@cryptotaxi247 / netdata-1 / commits / 090475854

Split apps charts (#16095)

Co-authored-by: ilyam8 <ilya@netdata.cloud>

thiagoftsm committed Oct 4, 2023 at 14:51 UTC 0904758540fe93fd92829960497e66d4a0a82a4d
2 files changed +511 -927
collectors/apps.plugin/apps_plugin.c
+207 -512
@@ -265,7 +265,7 @@ struct target {
265 uint32_t idhash;
266
267 char name[MAX_NAME + 1];
268 -
268 + char clean_name[MAX_NAME + 1]; // sanitized name used in chart id (need to replace at least dots)
269 uid_t uid;
270 gid_t gid;
271
@@ -782,7 +782,8 @@ static struct target *get_users_target(uid_t uid) {
782 snprintfz(w->name, MAX_NAME, "%s", pw->pw_name);
783 }
784
785 - netdata_fix_chart_name(w->name);
785 + strncpyz(w->clean_name, w->name, MAX_NAME);
786 + netdata_fix_chart_name(w->clean_name);
787
788 w->uid = uid;
789
@@ -830,7 +831,8 @@ struct target *get_groups_target(gid_t gid)
831 snprintfz(w->name, MAX_NAME, "%s", gr->gr_name);
832 }
833
833 - netdata_fix_chart_name(w->name);
834 + strncpyz(w->clean_name, w->name, MAX_NAME);
835 + netdata_fix_chart_name(w->clean_name);
836
837 w->gid = gid;
838
@@ -899,6 +901,14 @@ static struct target *get_apps_groups_target(const char *id, struct target *targ
901 else
902 // copy the id
903 strncpyz(w->name, nid, MAX_NAME);
904 +
905 + // dots are used to distinguish chart type and id in streaming, so we should replace them
906 + strncpyz(w->clean_name, w->name, MAX_NAME);
907 + netdata_fix_chart_name(w->clean_name);
908 + for (char *d = w->clean_name; *d; d++) {
909 + if (*d == '.')
910 + *d = '_';
911 + }
912
913 strncpyz(w->compare, nid, MAX_COMPARE_NAME);
914 size_t len = strlen(w->compare);
@@ -3431,8 +3441,8 @@ static void calculate_netdata_statistics(void) {
3441 // ----------------------------------------------------------------------------
3442 // update chart dimensions
3443
3434 -static inline void send_BEGIN(const char *type, const char *id, usec_t usec) {
3435 - fprintf(stdout, "BEGIN %s.%s %"PRIu64"\n", type, id, usec);
3444 +static inline void send_BEGIN(const char *type, const char *name,const char *metric, usec_t usec) {
3445 + fprintf(stdout, "BEGIN %s.%s_%s %" PRIu64 "\n", type, name, metric, usec);
3446 }
3447
3448 static inline void send_SET(const char *name, kernel_uint_t value) {
@@ -3440,7 +3450,7 @@ static inline void send_SET(const char *name, kernel_uint_t value) {
3450 }
3451
3452 static inline void send_END(void) {
3443 - fprintf(stdout, "END\n");
3453 + fprintf(stdout, "END\n\n");
3454 }
3455
3456 void send_resource_usage_to_netdata(usec_t dt) {
@@ -3736,249 +3746,103 @@ static void normalize_utilization(struct target *root) {
3746 static void send_collected_data_to_netdata(struct target *root, const char *type, usec_t dt) {
3747 struct target *w;
3748
3739 - send_BEGIN(type, "cpu", dt);
3740 - for (w = root; w ; w = w->next) {
3741 - if(unlikely(w->exposed && w->processes))
3742 - send_SET(w->name, (kernel_uint_t)(w->utime * utime_fix_ratio) + (kernel_uint_t)(w->stime * stime_fix_ratio) + (kernel_uint_t)(w->gtime * gtime_fix_ratio) + (include_exited_childs?((kernel_uint_t)(w->cutime * cutime_fix_ratio) + (kernel_uint_t)(w->cstime * cstime_fix_ratio) + (kernel_uint_t)(w->cgtime * cgtime_fix_ratio)):0ULL));
3743 - }
3744 - send_END();
3745 -
3746 - send_BEGIN(type, "cpu_user", dt);
3749 for (w = root; w ; w = w->next) {
3748 - if(unlikely(w->exposed && w->processes))
3749 - send_SET(w->name, (kernel_uint_t)(w->utime * utime_fix_ratio) + (include_exited_childs?((kernel_uint_t)(w->cutime * cutime_fix_ratio)):0ULL));
3750 - }
3751 - send_END();
3752 -
3753 - send_BEGIN(type, "cpu_system", dt);
3754 - for (w = root; w ; w = w->next) {
3755 - if(unlikely(w->exposed && w->processes))
3756 - send_SET(w->name, (kernel_uint_t)(w->stime * stime_fix_ratio) + (include_exited_childs?((kernel_uint_t)(w->cstime * cstime_fix_ratio)):0ULL));
3757 - }
3758 - send_END();
3750 + if(unlikely(!w->exposed))
3751 + continue;
3752
3760 - if(show_guest_time) {
3761 - send_BEGIN(type, "cpu_guest", dt);
3762 - for (w = root; w ; w = w->next) {
3763 - if(unlikely(w->exposed && w->processes))
3764 - send_SET(w->name, (kernel_uint_t)(w->gtime * gtime_fix_ratio) + (include_exited_childs?((kernel_uint_t)(w->cgtime * cgtime_fix_ratio)):0ULL));
3765 - }
3753 + send_BEGIN(type, w->clean_name, "processes", dt);
3754 + send_SET("processes", w->processes);
3755 send_END();
3767 - }
3756
3769 -#ifndef __FreeBSD__
3770 - send_BEGIN(type, "voluntary_ctxt_switches", dt);
3771 - for (w = root; w ; w = w->next) {
3772 - if(unlikely(w->exposed && w->processes))
3773 - send_SET(w->name, w->status_voluntary_ctxt_switches);
3774 - }
3775 - send_END();
3776 -
3777 - send_BEGIN(type, "involuntary_ctxt_switches", dt);
3778 - for (w = root; w ; w = w->next) {
3779 - if(unlikely(w->exposed && w->processes))
3780 - send_SET(w->name, w->status_nonvoluntary_ctxt_switches);
3781 - }
3782 - send_END();
3783 -#endif
3784 -
3785 - send_BEGIN(type, "threads", dt);
3786 - for (w = root; w ; w = w->next) {
3787 - if(unlikely(w->exposed))
3788 - send_SET(w->name, w->num_threads);
3789 - }
3790 - send_END();
3791 -
3792 - send_BEGIN(type, "processes", dt);
3793 - for (w = root; w ; w = w->next) {
3794 - if(unlikely(w->exposed))
3795 - send_SET(w->name, w->processes);
3796 - }
3797 - send_END();
3798 -
3799 -#ifndef __FreeBSD__
3800 - send_BEGIN(type, "uptime", dt);
3801 - for (w = root; w ; w = w->next) {
3802 - if(unlikely(w->exposed && w->processes))
3803 - send_SET(w->name, (global_uptime > w->starttime)?(global_uptime - w->starttime):0);
3804 - }
3805 - send_END();
3806 -
3807 - if (enable_detailed_uptime_charts) {
3808 - send_BEGIN(type, "uptime_min", dt);
3809 - for (w = root; w ; w = w->next) {
3810 - if(unlikely(w->exposed && w->processes))
3811 - send_SET(w->name, w->uptime_min);
3812 - }
3757 + send_BEGIN(type, w->clean_name, "threads", dt);
3758 + send_SET("threads", w->num_threads);
3759 send_END();
3760
3815 - send_BEGIN(type, "uptime_avg", dt);
3816 - for (w = root; w ; w = w->next) {
3817 - if(unlikely(w->exposed && w->processes))
3818 - send_SET(w->name, w->uptime_sum / w->processes);
3819 - }
3820 - send_END();
3761 + if(unlikely(!w->processes))
3762 + continue;
3763
3822 - send_BEGIN(type, "uptime_max", dt);
3823 - for (w = root; w ; w = w->next) {
3824 - if(unlikely(w->exposed && w->processes))
3825 - send_SET(w->name, w->uptime_max);
3826 - }
3764 + send_BEGIN(type, w->clean_name, "cpu_utilization", dt);
3765 + send_SET("user", (kernel_uint_t)(w->utime * utime_fix_ratio) + (include_exited_childs ? ((kernel_uint_t)(w->cutime * cutime_fix_ratio)) : 0ULL));
3766 + send_SET("system", (kernel_uint_t)(w->stime * stime_fix_ratio) + (include_exited_childs ? ((kernel_uint_t)(w->cstime * cstime_fix_ratio)) : 0ULL));
3767 send_END();
3828 - }
3829 -#endif
3830 -
3831 - send_BEGIN(type, "mem", dt);
3832 - for (w = root; w ; w = w->next) {
3833 - if(unlikely(w->exposed && w->processes))
3834 - send_SET(w->name, (w->status_vmrss > w->status_vmshared)?(w->status_vmrss - w->status_vmshared):0ULL);
3835 - }
3836 - send_END();
3837 -
3838 - send_BEGIN(type, "rss", dt);
3839 - for (w = root; w ; w = w->next) {
3840 - if(unlikely(w->exposed && w->processes))
3841 - send_SET(w->name, w->status_vmrss);
3842 - }
3843 - send_END();
3844 -
3845 - send_BEGIN(type, "vmem", dt);
3846 - for (w = root; w ; w = w->next) {
3847 - if(unlikely(w->exposed && w->processes))
3848 - send_SET(w->name, w->status_vmsize);
3849 - }
3850 - send_END();
3768
3769 #ifndef __FreeBSD__
3853 - send_BEGIN(type, "swap", dt);
3854 - for (w = root; w ; w = w->next) {
3855 - if(unlikely(w->exposed && w->processes))
3856 - send_SET(w->name, w->status_vmswap);
3857 - }
3858 - send_END();
3859 -#endif
3860 -
3861 - send_BEGIN(type, "minor_faults", dt);
3862 - for (w = root; w ; w = w->next) {
3863 - if(unlikely(w->exposed && w->processes))
3864 - send_SET(w->name, (kernel_uint_t)(w->minflt * minflt_fix_ratio) + (include_exited_childs?((kernel_uint_t)(w->cminflt * cminflt_fix_ratio)):0ULL));
3865 - }
3866 - send_END();
3867 -
3868 - send_BEGIN(type, "major_faults", dt);
3869 - for (w = root; w ; w = w->next) {
3870 - if(unlikely(w->exposed && w->processes))
3871 - send_SET(w->name, (kernel_uint_t)(w->majflt * majflt_fix_ratio) + (include_exited_childs?((kernel_uint_t)(w->cmajflt * cmajflt_fix_ratio)):0ULL));
3872 - }
3873 - send_END();
3874 -
3875 -#ifndef __FreeBSD__
3876 - send_BEGIN(type, "lreads", dt);
3877 - for (w = root; w ; w = w->next) {
3878 - if(unlikely(w->exposed && w->processes))
3879 - send_SET(w->name, w->io_logical_bytes_read);
3880 - }
3881 - send_END();
3882 -
3883 - send_BEGIN(type, "lwrites", dt);
3884 - for (w = root; w ; w = w->next) {
3885 - if(unlikely(w->exposed && w->processes))
3886 - send_SET(w->name, w->io_logical_bytes_written);
3887 - }
3888 - send_END();
3889 -#endif
3890 -
3891 - send_BEGIN(type, "preads", dt);
3892 - for (w = root; w ; w = w->next) {
3893 - if(unlikely(w->exposed && w->processes))
3894 - send_SET(w->name, w->io_storage_bytes_read);
3895 - }
3896 - send_END();
3897 -
3898 - send_BEGIN(type, "pwrites", dt);
3899 - for (w = root; w ; w = w->next) {
3900 - if(unlikely(w->exposed && w->processes))
3901 - send_SET(w->name, w->io_storage_bytes_written);
3902 - }
3903 - send_END();
3904 -
3905 - if(enable_file_charts) {
3906 - send_BEGIN(type, "fds_open_limit", dt);
3907 - for (w = root; w; w = w->next) {
3908 - if (unlikely(w->exposed && w->processes))
3909 - send_SET(w->name, w->max_open_files_percent * 100.0);
3770 + if (enable_guest_charts) {
3771 + send_BEGIN(type, w->clean_name, "cpu_guest_utilization", dt);
3772 + send_SET("guest", (kernel_uint_t)(w->gtime * gtime_fix_ratio) + (include_exited_childs ? ((kernel_uint_t)(w->cgtime * cgtime_fix_ratio)) : 0ULL));
3773 + send_END();
3774 }
3911 - send_END();
3775
3913 - send_BEGIN(type, "fds_open", dt);
3914 - for (w = root; w; w = w->next) {
3915 - if (unlikely(w->exposed && w->processes))
3916 - send_SET(w->name, pid_openfds_sum(w));
3917 - }
3776 + send_BEGIN(type, w->clean_name, "cpu_context_switches", dt);
3777 + send_SET("voluntary", w->status_voluntary_ctxt_switches);
3778 + send_SET("involuntary", w->status_nonvoluntary_ctxt_switches);
3779 send_END();
3919 -
3920 - send_BEGIN(type, "fds_files", dt);
3921 - for (w = root; w; w = w->next) {
3922 - if (unlikely(w->exposed && w->processes))
3923 - send_SET(w->name, w->openfds.files);
3924 - }
3780 +#endif
3781 + send_BEGIN(type, w->clean_name, "mem_usage", dt);
3782 + send_SET("rss", w->status_vmrss);
3783 send_END();
3784
3927 - send_BEGIN(type, "fds_sockets", dt);
3928 - for (w = root; w; w = w->next) {
3929 - if (unlikely(w->exposed && w->processes))
3930 - send_SET(w->name, w->openfds.sockets);
3931 - }
3785 + send_BEGIN(type, w->clean_name, "mem_private_usage", dt);
3786 + send_SET("mem", (w->status_vmrss > w->status_vmshared)?(w->status_vmrss - w->status_vmshared) : 0ULL);
3787 send_END();
3788
3934 - send_BEGIN(type, "fds_pipes", dt);
3935 - for (w = root; w; w = w->next) {
3936 - if (unlikely(w->exposed && w->processes))
3937 - send_SET(w->name, w->openfds.pipes);
3938 - }
3789 + send_BEGIN(type, w->clean_name, "vmem_usage", dt);
3790 + send_SET("vmem", w->status_vmsize);
3791 send_END();
3792
3941 - send_BEGIN(type, "fds_inotifies", dt);
3942 - for (w = root; w; w = w->next) {
3943 - if (unlikely(w->exposed && w->processes))
3944 - send_SET(w->name, w->openfds.inotifies);
3945 - }
3793 + send_BEGIN(type, w->clean_name, "mem_page_faults", dt);
3794 + send_SET("minor", (kernel_uint_t)(w->minflt * minflt_fix_ratio) + (include_exited_childs ? ((kernel_uint_t)(w->cminflt * cminflt_fix_ratio)) : 0ULL));
3795 + send_SET("major", (kernel_uint_t)(w->majflt * majflt_fix_ratio) + (include_exited_childs ? ((kernel_uint_t)(w->cmajflt * cmajflt_fix_ratio)) : 0ULL));
3796 send_END();
3797
3948 - send_BEGIN(type, "fds_eventfds", dt);
3949 - for (w = root; w; w = w->next) {
3950 - if (unlikely(w->exposed && w->processes))
3951 - send_SET(w->name, w->openfds.eventfds);
3952 - }
3798 +#ifndef __FreeBSD__
3799 + send_BEGIN(type, w->clean_name, "swap_usage", dt);
3800 + send_SET("swap", w->status_vmswap);
3801 send_END();
3802 +#endif
3803
3955 - send_BEGIN(type, "fds_timerfds", dt);
3956 - for (w = root; w; w = w->next) {
3957 - if (unlikely(w->exposed && w->processes))
3958 - send_SET(w->name, w->openfds.timerfds);
3959 - }
3804 +#ifndef __FreeBSD__
3805 + send_BEGIN(type, w->clean_name, "uptime", dt);
3806 + send_SET("uptime", (global_uptime > w->starttime) ? (global_uptime - w->starttime) : 0);
3807 send_END();
3808
3962 - send_BEGIN(type, "fds_signalfds", dt);
3963 - for (w = root; w; w = w->next) {
3964 - if (unlikely(w->exposed && w->processes))
3965 - send_SET(w->name, w->openfds.signalfds);
3809 + if (enable_detailed_uptime_charts) {
3810 + send_BEGIN(type, w->clean_name, "uptime_summary", dt);
3811 + send_SET("min", w->uptime_min);
3812 + send_SET("avg", w->uptime_sum / w->processes);
3813 + send_SET("max", w->uptime_max);
3814 + send_END();
3815 }
3967 - send_END();
3816 +#endif
3817
3969 - send_BEGIN(type, "fds_eventpolls", dt);
3970 - for (w = root; w; w = w->next) {
3971 - if (unlikely(w->exposed && w->processes))
3972 - send_SET(w->name, w->openfds.eventpolls);
3973 - }
3818 + send_BEGIN(type, w->clean_name, "disk_physical_io", dt);
3819 + send_SET("reads", w->io_storage_bytes_read);
3820 + send_SET("writes", w->io_storage_bytes_written);
3821 send_END();
3822
3976 - send_BEGIN(type, "fds_other", dt);
3977 - for (w = root; w; w = w->next) {
3978 - if (unlikely(w->exposed && w->processes))
3979 - send_SET(w->name, w->openfds.other);
3980 - }
3823 +#ifndef __FreeBSD__
3824 + send_BEGIN(type, w->clean_name, "disk_logical_io", dt);
3825 + send_SET("reads", w->io_logical_bytes_read);
3826 + send_SET("writes", w->io_logical_bytes_written);
3827 send_END();
3828 +#endif
3829 + if (enable_file_charts) {
3830 + send_BEGIN(type, w->clean_name, "fds_open_limit", dt);
3831 + send_SET("limit", w->max_open_files_percent * 100.0);
3832 + send_END();
3833 +
3834 + send_BEGIN(type, w->clean_name, "fds_open", dt);
3835 + send_SET("files", w->openfds.files);
3836 + send_SET("sockets", w->openfds.sockets);
3837 + send_SET("pipes", w->openfds.sockets);
3838 + send_SET("inotifies", w->openfds.inotifies);
3839 + send_SET("event", w->openfds.eventfds);
3840 + send_SET("timer", w->openfds.timerfds);
3841 + send_SET("signal", w->openfds.signalfds);
3842 + send_SET("eventpolls", w->openfds.eventpolls);
3843 + send_SET("other", w->openfds.other);
3844 + send_END();
3845 + }
3846 }
3847 }
3848
@@ -3986,312 +3850,146 @@ static void send_collected_data_to_netdata(struct target *root, const char *type
3850 // ----------------------------------------------------------------------------
3851 // generate the charts
3852
3989 -static void send_charts_updates_to_netdata(struct target *root, const char *type, const char *title)
3853 +static void send_charts_updates_to_netdata(struct target *root, const char *type, const char *lbl_name, const char *title)
3854 {
3855 struct target *w;
3992 - int newly_added = 0;
3993 -
3994 - for(w = root ; w ; w = w->next) {
3995 - if (w->target) continue;
3856
3997 - if(unlikely(w->processes && (debug_enabled || w->debug_enabled))) {
3998 - struct pid_on_target *pid_on_target;
3999 -
4000 - fprintf(stderr, "apps.plugin: target '%s' has aggregated %u process%s:", w->name, w->processes, (w->processes == 1)?"":"es");
4001 -
4002 - for(pid_on_target = w->root_pid; pid_on_target; pid_on_target = pid_on_target->next) {
4003 - fprintf(stderr, " %d", pid_on_target->pid);
3857 + if (debug_enabled) {
3858 + for (w = root; w; w = w->next) {
3859 + if (unlikely(w->debug_enabled && !w->target && w->processes)) {
3860 + struct pid_on_target *pid_on_target;
3861 + fprintf(stderr, "apps.plugin: target '%s' has aggregated %u process(es):", w->name, w->processes);
3862 + for (pid_on_target = w->root_pid; pid_on_target; pid_on_target = pid_on_target->next) {
3863 + fprintf(stderr, " %d", pid_on_target->pid);
3864 + }
3865 + fputc('\n', stderr);
3866 }
4005 -
4006 - fputc('\n', stderr);
4007 - }
4008 -
4009 - if (!w->exposed && w->processes) {
4010 - newly_added++;
4011 - w->exposed = 1;
4012 - if (debug_enabled || w->debug_enabled)
4013 - debug_log_int("%s just added - regenerating charts.", w->name);
3867 }
3868 }
3869
4017 - // nothing more to show
4018 - if(!newly_added && show_guest_time == show_guest_time_old) return;
4019 -
4020 - // we have something new to show
4021 - // update the charts
4022 - fprintf(stdout, "CHART %s.cpu '' '%s CPU Time (100%% = 1 core)' 'percentage' cpu %s.cpu stacked 20001 %d\n", type, title, type, update_every);
4023 - for (w = root; w ; w = w->next) {
4024 - if(unlikely(w->exposed))
4025 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu %s\n", w->name, time_factor * RATES_DETAIL / 100, w->hidden ? "hidden" : "");
4026 - }
4027 - APPS_PLUGIN_FUNCTIONS();
4028 -
4029 - fprintf(stdout, "CHART %s.mem '' '%s Real Memory (w/o shared)' 'MiB' mem %s.mem stacked 20003 %d\n", type, title, type, update_every);
4030 - for (w = root; w ; w = w->next) {
4031 - if(unlikely(w->exposed))
4032 - fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, 1L, 1024L);
4033 - }
4034 - APPS_PLUGIN_FUNCTIONS();
4035 -
4036 - fprintf(stdout, "CHART %s.rss '' '%s Resident Set Size (w/shared)' 'MiB' mem %s.rss stacked 20004 %d\n", type, title, type, update_every);
4037 - for (w = root; w ; w = w->next) {
4038 - if(unlikely(w->exposed))
4039 - fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, 1L, 1024L);
4040 - }
4041 - APPS_PLUGIN_FUNCTIONS();
4042 -
4043 - fprintf(stdout, "CHART %s.vmem '' '%s Virtual Memory Size' 'MiB' mem %s.vmem stacked 20005 %d\n", type, title, type, update_every);
4044 - for (w = root; w ; w = w->next) {
4045 - if(unlikely(w->exposed))
4046 - fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, 1L, 1024L);
4047 - }
4048 - APPS_PLUGIN_FUNCTIONS();
3870 + for (w = root; w; w = w->next) {
3871 + if (likely(w->exposed || !w->processes))
3872 + continue;
3873
4050 - fprintf(stdout, "CHART %s.threads '' '%s Threads' 'threads' processes %s.threads stacked 20006 %d\n", type, title, type, update_every);
4051 - for (w = root; w ; w = w->next) {
4052 - if(unlikely(w->exposed))
4053 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4054 - }
4055 - APPS_PLUGIN_FUNCTIONS();
3874 + w->exposed = 1;
3875
4057 - fprintf(stdout, "CHART %s.processes '' '%s Processes' 'processes' processes %s.processes stacked 20007 %d\n", type, title, type, update_every);
4058 - for (w = root; w ; w = w->next) {
4059 - if(unlikely(w->exposed))
4060 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4061 - }
4062 - APPS_PLUGIN_FUNCTIONS();
3876 + fprintf(stdout, "CHART %s.%s_cpu_utilization '' '%s CPU utilization (100%% = 1 core)' 'percentage' cpu %s.cpu_utilization stacked 20001 %d\n", type, w->clean_name, title, type, update_every);
3877 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3878 + fprintf(stdout, "CLABEL_COMMIT\n");
3879 + fprintf(stdout, "DIMENSION user '' absolute 1 %llu\n", time_factor * RATES_DETAIL / 100LLU);
3880 + fprintf(stdout, "DIMENSION system '' absolute 1 %llu\n", time_factor * RATES_DETAIL / 100LLU);
3881
3882 #ifndef __FreeBSD__
4065 - fprintf(stdout, "CHART %s.uptime '' '%s Carried Over Uptime' 'seconds' processes %s.uptime line 20008 %d\n", type, title, type, update_every);
4066 - for (w = root; w ; w = w->next) {
4067 - if(unlikely(w->exposed))
4068 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4069 - }
4070 - APPS_PLUGIN_FUNCTIONS();
4071 -
4072 - if (enable_detailed_uptime_charts) {
4073 - fprintf(stdout, "CHART %s.uptime_min '' '%s Minimum Uptime' 'seconds' processes %s.uptime_min line 20009 %d\n", type, title, type, update_every);
4074 - for (w = root; w ; w = w->next) {
4075 - if(unlikely(w->exposed))
4076 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4077 - }
4078 - APPS_PLUGIN_FUNCTIONS();
4079 -
4080 - fprintf(stdout, "CHART %s.uptime_avg '' '%s Average Uptime' 'seconds' processes %s.uptime_avg line 20010 %d\n", type, title, type, update_every);
4081 - for (w = root; w ; w = w->next) {
4082 - if(unlikely(w->exposed))
4083 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4084 - }
4085 - APPS_PLUGIN_FUNCTIONS();
4086 -
4087 - fprintf(stdout, "CHART %s.uptime_max '' '%s Maximum Uptime' 'seconds' processes %s.uptime_max line 20011 %d\n", type, title, type, update_every);
4088 - for (w = root; w ; w = w->next) {
4089 - if(unlikely(w->exposed))
4090 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4091 - }
4092 - APPS_PLUGIN_FUNCTIONS();
4093 - }
3883 + if (enable_guest_charts) {
3884 + fprintf(stdout, "CHART %s.%s_cpu_guest_utilization '' '%s CPU guest utlization (100%% = 1 core)' 'percentage' cpu %s.cpu_guest_utilization line 20005 %d\n", type, w->clean_name, title, type, update_every);
3885 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3886 + fprintf(stdout, "CLABEL_COMMIT\n");
3887 + fprintf(stdout, "DIMENSION guest '' absolute 1 %llu\n", time_factor * RATES_DETAIL / 100LLU);
3888 + }
3889 +
3890 + fprintf(stdout, "CHART %s.%s_cpu_context_switches '' '%s CPU context switches' 'switches/s' cpu %s.cpu_context_switches stacked 20010 %d\n", type, w->clean_name, title, type, update_every);
3891 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3892 + fprintf(stdout, "CLABEL_COMMIT\n");
3893 + fprintf(stdout, "DIMENSION voluntary '' absolute 1 %llu\n", RATES_DETAIL);
3894 + fprintf(stdout, "DIMENSION involuntary '' absolute 1 %llu\n", RATES_DETAIL);
3895 #endif
3896
4096 - fprintf(stdout, "CHART %s.cpu_user '' '%s CPU User Time (100%% = 1 core)' 'percentage' cpu %s.cpu_user stacked 20020 %d\n", type, title, type, update_every);
4097 - for (w = root; w ; w = w->next) {
4098 - if(unlikely(w->exposed))
4099 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, time_factor * RATES_DETAIL / 100LLU);
4100 - }
4101 - APPS_PLUGIN_FUNCTIONS();
3897 + fprintf(stdout, "CHART %s.%s_mem_usage '' '%s memory RSS usage' 'MiB' mem %s.mem_usage area 20050 %d\n", type, w->clean_name, title, type, update_every);
3898 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3899 + fprintf(stdout, "CLABEL_COMMIT\n");
3900 + fprintf(stdout, "DIMENSION rss '' absolute %ld %ld\n", 1L, 1024L);
3901
4103 - fprintf(stdout, "CHART %s.cpu_system '' '%s CPU System Time (100%% = 1 core)' 'percentage' cpu %s.cpu_system stacked 20021 %d\n", type, title, type, update_every);
4104 - for (w = root; w ; w = w->next) {
4105 - if(unlikely(w->exposed))
4106 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, time_factor * RATES_DETAIL / 100LLU);
4107 - }
4108 - APPS_PLUGIN_FUNCTIONS();
3902 + fprintf(stdout, "CHART %s.%s_mem_private_usage '' '%s memory usage without shared' 'MiB' mem %s.mem_private_usage area 20055 %d\n", type, w->clean_name, title, type, update_every);
3903 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3904 + fprintf(stdout, "CLABEL_COMMIT\n");
3905 + fprintf(stdout, "DIMENSION mem '' absolute %ld %ld\n", 1L, 1024L);
3906
4110 - if(show_guest_time) {
4111 - fprintf(stdout, "CHART %s.cpu_guest '' '%s CPU Guest Time (100%% = 1 core)' 'percentage' cpu %s.cpu_guest stacked 20022 %d\n", type, title, type, update_every);
4112 - for (w = root; w; w = w->next) {
4113 - if(unlikely(w->exposed))
4114 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, time_factor * RATES_DETAIL / 100LLU);
4115 - }
4116 - APPS_PLUGIN_FUNCTIONS();
4117 - }
3907 + fprintf(stdout, "CHART %s.%s_mem_page_faults '' '%s memory page faults' 'pgfaults/s' mem %s.mem_page_faults stacked 20060 %d\n", type, w->clean_name, title, type, update_every);
3908 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3909 + fprintf(stdout, "CLABEL_COMMIT\n");
3910 + fprintf(stdout, "DIMENSION major '' absolute 1 %llu\n", RATES_DETAIL);
3911 + fprintf(stdout, "DIMENSION minor '' absolute 1 %llu\n", RATES_DETAIL);
3912
4119 -#ifndef __FreeBSD__
4120 - fprintf(stdout, "CHART %s.voluntary_ctxt_switches '' '%s Voluntary Context Switches' 'switches/s' cpu %s.voluntary_ctxt_switches stacked 20023 %d\n", type, title, type, update_every);
4121 - for (w = root; w ; w = w->next) {
4122 - if(unlikely(w->exposed))
4123 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
4124 - }
4125 - APPS_PLUGIN_FUNCTIONS();
4126 -
4127 - fprintf(stdout, "CHART %s.involuntary_ctxt_switches '' '%s Involuntary Context Switches' 'switches/s' cpu %s.involuntary_ctxt_switches stacked 20024 %d\n", type, title, type, update_every);
4128 - for (w = root; w ; w = w->next) {
4129 - if(unlikely(w->exposed))
4130 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
4131 - }
4132 - APPS_PLUGIN_FUNCTIONS();
4133 -#endif
3913 + fprintf(stdout, "CHART %s.%s_vmem_usage '' '%s virtual memory size' 'MiB' mem %s.vmem_usage line 20065 %d\n", type, w->clean_name, title, type, update_every);
3914 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3915 + fprintf(stdout, "CLABEL_COMMIT\n");
3916 + fprintf(stdout, "DIMENSION vmem '' absolute %ld %ld\n", 1L, 1024L);
3917
3918 #ifndef __FreeBSD__
4136 - fprintf(stdout, "CHART %s.swap '' '%s Swap Memory' 'MiB' swap %s.swap stacked 20011 %d\n", type, title, type, update_every);
4137 - for (w = root; w ; w = w->next) {
4138 - if(unlikely(w->exposed))
4139 - fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, 1L, 1024L);
4140 - }
4141 - APPS_PLUGIN_FUNCTIONS();
3919 + fprintf(stdout, "CHART %s.%s_swap_usage '' '%s swap usage' 'MiB' mem %s.swap_usage area 20065 %d\n", type, w->clean_name, title, type, update_every);
3920 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3921 + fprintf(stdout, "CLABEL_COMMIT\n");
3922 + fprintf(stdout, "DIMENSION swap '' absolute %ld %ld\n", 1L, 1024L);
3923 #endif
3924
4144 - fprintf(stdout, "CHART %s.major_faults '' '%s Major Page Faults (swap read)' 'page faults/s' swap %s.major_faults stacked 20012 %d\n", type, title, type, update_every);
4145 - for (w = root; w ; w = w->next) {
4146 - if(unlikely(w->exposed))
4147 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
4148 - }
4149 - APPS_PLUGIN_FUNCTIONS();
4150 -
4151 - fprintf(stdout, "CHART %s.minor_faults '' '%s Minor Page Faults' 'page faults/s' mem %s.minor_faults stacked 20011 %d\n", type, title, type, update_every);
4152 - for (w = root; w ; w = w->next) {
4153 - if(unlikely(w->exposed))
4154 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
4155 - }
4156 - APPS_PLUGIN_FUNCTIONS();
4157 -
4158 -#ifdef __FreeBSD__
4159 - // FIXME: same metric name as in Linux but different units.
4160 - fprintf(stdout, "CHART %s.preads '' '%s Disk Reads' 'blocks/s' disk %s.preads stacked 20002 %d\n", type, title, type, update_every);
4161 - for (w = root; w ; w = w->next) {
4162 - if(unlikely(w->exposed))
4163 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
4164 - }
4165 - APPS_PLUGIN_FUNCTIONS();
4166 -
4167 - fprintf(stdout, "CHART %s.pwrites '' '%s Disk Writes' 'blocks/s' disk %s.pwrites stacked 20002 %d\n", type, title, type, update_every);
4168 - for (w = root; w ; w = w->next) {
4169 - if(unlikely(w->exposed))
4170 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
4171 - }
4172 - APPS_PLUGIN_FUNCTIONS();
3925 +#ifndef __FreeBSD__
3926 + fprintf(stdout, "CHART %s.%s_disk_physical_io '' '%s disk physical IO' 'KiB/s' disk %s.disk_physical_io area 20100 %d\n", type, w->clean_name, title, type, update_every);
3927 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3928 + fprintf(stdout, "CLABEL_COMMIT\n");
3929 + fprintf(stdout, "DIMENSION reads '' absolute 1 %llu\n", 1024LLU * RATES_DETAIL);
3930 + fprintf(stdout, "DIMENSION writes '' absolute 1 %llu\n", 1024LLU * RATES_DETAIL);
3931 +
3932 + fprintf(stdout, "CHART %s.%s_disk_logical_io '' '%s disk logical IO' 'KiB/s' disk %s.disk_logical_io area 20105 %d\n", type, w->clean_name, title, type, update_every);
3933 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3934 + fprintf(stdout, "CLABEL_COMMIT\n");
3935 + fprintf(stdout, "DIMENSION reads '' absolute 1 %llu\n", 1024LLU * RATES_DETAIL);
3936 + fprintf(stdout, "DIMENSION writes '' absolute 1 %llu\n", 1024LLU * RATES_DETAIL);
3937 #else
4174 - fprintf(stdout, "CHART %s.preads '' '%s Disk Reads' 'KiB/s' disk %s.preads stacked 20002 %d\n", type, title, type, update_every);
4175 - for (w = root; w ; w = w->next) {
4176 - if(unlikely(w->exposed))
4177 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
4178 - }
4179 - APPS_PLUGIN_FUNCTIONS();
4180 -
4181 - fprintf(stdout, "CHART %s.pwrites '' '%s Disk Writes' 'KiB/s' disk %s.pwrites stacked 20002 %d\n", type, title, type, update_every);
4182 - for (w = root; w ; w = w->next) {
4183 - if(unlikely(w->exposed))
4184 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
4185 - }
4186 - APPS_PLUGIN_FUNCTIONS();
4187 -
4188 - fprintf(stdout, "CHART %s.lreads '' '%s Disk Logical Reads' 'KiB/s' disk %s.lreads stacked 20042 %d\n", type, title, type, update_every);
4189 - for (w = root; w ; w = w->next) {
4190 - if(unlikely(w->exposed))
4191 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
4192 - }
4193 - APPS_PLUGIN_FUNCTIONS();
4194 -
4195 - fprintf(stdout, "CHART %s.lwrites '' '%s I/O Logical Writes' 'KiB/s' disk %s.lwrites stacked 20042 %d\n", type, title, type, update_every);
4196 - for (w = root; w ; w = w->next) {
4197 - if(unlikely(w->exposed))
4198 - fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
4199 - }
4200 - APPS_PLUGIN_FUNCTIONS();
3938 + fprintf(stdout, "CHART %s.%s_disk_physical_io '' '%s disk physical IO' 'blocks/s' disk %s.disk_physical_block_io area 20100 %d\n", type, w->clean_name, title, type, update_every);
3939 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3940 + fprintf(stdout, "CLABEL_COMMIT\n");
3941 + fprintf(stdout, "DIMENSION reads '' absolute 1 %llu\n", RATES_DETAIL);
3942 + fprintf(stdout, "DIMENSION writes '' absolute 1 %llu\n", RATES_DETAIL);
3943 #endif
3944
4203 - if(enable_file_charts) {
4204 - fprintf(stdout, "CHART %s.fds_open_limit '' '%s Open File Descriptors Limit' '%%' fds %s.fds_open_limit line 20050 %d\n", type,
4205 - title, type, update_every);
4206 - for (w = root; w; w = w->next) {
4207 - if (unlikely(w->exposed))
4208 - fprintf(stdout, "DIMENSION %s '' absolute 1 100\n", w->name);
4209 - }
4210 - APPS_PLUGIN_FUNCTIONS();
4211 -
4212 - fprintf(stdout, "CHART %s.fds_open '' '%s Open File Descriptors' 'fds' fds %s.fds_open stacked 20051 %d\n", type,
4213 - title, type, update_every);
4214 - for (w = root; w; w = w->next) {
4215 - if (unlikely(w->exposed))
4216 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4217 - }
4218 - APPS_PLUGIN_FUNCTIONS();
4219 -
4220 - fprintf(stdout, "CHART %s.fds_files '' '%s Open Files' 'fds' fds %s.fds_files stacked 20052 %d\n", type,
4221 - title, type, update_every);
4222 - for (w = root; w; w = w->next) {
4223 - if (unlikely(w->exposed))
4224 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4225 - }
4226 - APPS_PLUGIN_FUNCTIONS();
4227 -
4228 - fprintf(stdout, "CHART %s.fds_sockets '' '%s Open Sockets' 'fds' fds %s.fds_sockets stacked 20053 %d\n",
4229 - type, title, type, update_every);
4230 - for (w = root; w; w = w->next) {
4231 - if (unlikely(w->exposed))
4232 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4233 - }
4234 - APPS_PLUGIN_FUNCTIONS();
4235 -
4236 - fprintf(stdout, "CHART %s.fds_pipes '' '%s Pipes' 'fds' fds %s.fds_pipes stacked 20054 %d\n", type,
4237 - title, type, update_every);
4238 - for (w = root; w; w = w->next) {
4239 - if (unlikely(w->exposed))
4240 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4241 - }
4242 - APPS_PLUGIN_FUNCTIONS();
4243 -
4244 - fprintf(stdout, "CHART %s.fds_inotifies '' '%s iNotify File Descriptors' 'fds' fds %s.fds_inotifies stacked 20055 %d\n", type,
4245 - title, type, update_every);
4246 - for (w = root; w; w = w->next) {
4247 - if (unlikely(w->exposed))
4248 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4249 - }
4250 - APPS_PLUGIN_FUNCTIONS();
3945 + fprintf(stdout, "CHART %s.%s_processes '' '%s processes' 'processes' processes %s.processes line 20150 %d\n", type, w->clean_name, title, type, update_every);
3946 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3947 + fprintf(stdout, "CLABEL_COMMIT\n");
3948 + fprintf(stdout, "DIMENSION processes '' absolute 1 1\n");
3949 +
3950 + fprintf(stdout, "CHART %s.%s_threads '' '%s threads' 'threads' processes %s.threads line 20155 %d\n", type, w->clean_name, title, type, update_every);
3951 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3952 + fprintf(stdout, "CLABEL_COMMIT\n");
3953 + fprintf(stdout, "DIMENSION threads '' absolute 1 1\n");
3954 +
3955 + if (enable_file_charts) {
3956 + fprintf(stdout, "CHART %s.%s_fds_open_limit '' '%s open file descriptors limit' '%%' fds %s.fds_open_limit line 20200 %d\n", type, w->clean_name, title, type, update_every);
3957 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3958 + fprintf(stdout, "CLABEL_COMMIT\n");
3959 + fprintf(stdout, "DIMENSION limit '' absolute 1 100\n");
3960 +
3961 + fprintf(stdout, "CHART %s.%s_fds_open '' '%s open files descriptors' 'fds' fds %s.fds_open stacked 20210 %d\n", type, w->clean_name, title, type, update_every);
3962 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3963 + fprintf(stdout, "CLABEL_COMMIT\n");
3964 + fprintf(stdout, "DIMENSION files '' absolute 1 1\n");
3965 + fprintf(stdout, "DIMENSION sockets '' absolute 1 1\n");
3966 + fprintf(stdout, "DIMENSION pipes '' absolute 1 1\n");
3967 + fprintf(stdout, "DIMENSION inotifies '' absolute 1 1\n");
3968 + fprintf(stdout, "DIMENSION event '' absolute 1 1\n");
3969 + fprintf(stdout, "DIMENSION timer '' absolute 1 1\n");
3970 + fprintf(stdout, "DIMENSION signal '' absolute 1 1\n");
3971 + fprintf(stdout, "DIMENSION eventpolls '' absolute 1 1\n");
3972 + fprintf(stdout, "DIMENSION other '' absolute 1 1\n");
3973 + }
3974
4252 - fprintf(stdout, "CHART %s.fds_eventfds '' '%s Event File Descriptors' 'fds' fds %s.fds_eventfds stacked 20056 %d\n", type,
4253 - title, type, update_every);
4254 - for (w = root; w; w = w->next) {
4255 - if (unlikely(w->exposed))
4256 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4257 - }
4258 - APPS_PLUGIN_FUNCTIONS();
4259 -
4260 - fprintf(stdout, "CHART %s.fds_timerfds '' '%s Timer File Descriptors' 'fds' fds %s.fds_timerfds stacked 20057 %d\n", type,
4261 - title, type, update_every);
4262 - for (w = root; w; w = w->next) {
4263 - if (unlikely(w->exposed))
4264 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4265 - }
4266 - APPS_PLUGIN_FUNCTIONS();
4267 -
4268 - fprintf(stdout, "CHART %s.fds_signalfds '' '%s Signal File Descriptors' 'fds' fds %s.fds_signalfds stacked 20058 %d\n", type,
4269 - title, type, update_every);
4270 - for (w = root; w; w = w->next) {
4271 - if (unlikely(w->exposed))
4272 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4273 - }
4274 - APPS_PLUGIN_FUNCTIONS();
4275 -
4276 - fprintf(stdout, "CHART %s.fds_eventpolls '' '%s Event Poll File Descriptors' 'fds' fds %s.fds_eventpolls stacked 20059 %d\n", type,
4277 - title, type, update_every);
4278 - for (w = root; w; w = w->next) {
4279 - if (unlikely(w->exposed))
4280 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4281 - }
4282 - APPS_PLUGIN_FUNCTIONS();
4283 -
4284 - fprintf(stdout, "CHART %s.fds_other '' '%s Other File Descriptors' 'fds' fds %s.fds_other stacked 20060 %d\n", type,
4285 - title, type, update_every);
4286 - for (w = root; w; w = w->next) {
4287 - if (unlikely(w->exposed))
4288 - fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
4289 - }
4290 - APPS_PLUGIN_FUNCTIONS();
3975 +#ifndef __FreeBSD__
3976 + fprintf(stdout, "CHART %s.%s_uptime '' '%s uptime' 'seconds' uptime %s.uptime line 20250 %d\n", type, w->clean_name, title, type, update_every);
3977 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3978 + fprintf(stdout, "CLABEL_COMMIT\n");
3979 + fprintf(stdout, "DIMENSION uptime '' absolute 1 1\n");
3980 +
3981 + if (enable_detailed_uptime_charts) {
3982 + fprintf(stdout, "CHART %s.%s_uptime_summary '' '%s uptime summary' 'seconds' uptime %s.uptime_summary area 20255 %d\n", type, w->clean_name, title, type, update_every);
3983 + fprintf(stdout, "CLABEL '%s' '%s' 0\n", lbl_name, w->name);
3984 + fprintf(stdout, "CLABEL_COMMIT\n");
3985 + fprintf(stdout, "DIMENSION min '' absolute 1 1\n");
3986 + fprintf(stdout, "DIMENSION avg '' absolute 1 1\n");
3987 + fprintf(stdout, "DIMENSION max '' absolute 1 1\n");
3988 + }
3989 +#endif
3990 }
3991 }
3992
4294 -
3993 #ifndef __FreeBSD__
3994 static void send_proc_states_count(usec_t dt)
3995 {
@@ -4310,7 +4008,7 @@ static void send_proc_states_count(usec_t dt)
4008 }
4009
4010 // send process state count
4313 - send_BEGIN("system", "processes_state", dt);
4011 + fprintf(stdout, "BEGIN system.processes_state %" PRIu64 "\n", dt);
4012 for (proc_state i = PROC_STATUS_RUNNING; i < PROC_STATUS_END; i++) {
4013 send_SET(proc_states[i], proc_state_count[i]);
4014 }
@@ -5697,21 +5395,18 @@ int main(int argc, char **argv) {
5395 send_proc_states_count(dt);
5396 #endif
5397
5700 - // this is smart enough to show only newly added apps, when needed
5701 - send_charts_updates_to_netdata(apps_groups_root_target, "apps", "Apps");
5702 - if(likely(enable_users_charts))
5703 - send_charts_updates_to_netdata(users_root_target, "users", "Users");
5704 -
5705 - if(likely(enable_groups_charts))
5706 - send_charts_updates_to_netdata(groups_root_target, "groups", "User Groups");
5398 + send_charts_updates_to_netdata(apps_groups_root_target, "app", "app_group", "Apps");
5399 + send_collected_data_to_netdata(apps_groups_root_target, "app", dt);
5400
5708 - send_collected_data_to_netdata(apps_groups_root_target, "apps", dt);
5709 -
5710 - if(likely(enable_users_charts))
5711 - send_collected_data_to_netdata(users_root_target, "users", dt);
5401 + if (enable_users_charts) {
5402 + send_charts_updates_to_netdata(users_root_target, "user", "user", "Users");
5403 + send_collected_data_to_netdata(users_root_target, "user", dt);
5404 + }
5405
5713 - if(likely(enable_groups_charts))
5714 - send_collected_data_to_netdata(groups_root_target, "groups", dt);
5406 + if (enable_groups_charts) {
5407 + send_charts_updates_to_netdata(groups_root_target, "user_group", "user_group", "User Groups");
5408 + send_collected_data_to_netdata(groups_root_target, "user_group", dt);
5409 + }
5410
5411 fflush(stdout);
5412
collectors/apps.plugin/metadata.yaml
+304 -415
@@ -67,160 +67,123 @@ modules:
67 description: ""
68 availability: []
69 scopes:
70 - - name: global
71 - description: ""
72 - labels: []
70 + - name: applications group
71 + description: These metrics refer to the application group.
72 + labels:
73 + - name: app_group
74 + description: The name of the group defined in the configuration.
75 metrics:
74 - - name: apps.cpu
75 - description: Apps CPU Time (100% = 1 core)
76 - unit: "percentage"
77 - chart_type: stacked
78 - dimensions:
79 - - name: a dimension per app group
80 - - name: apps.cpu_user
81 - description: Apps CPU User Time (100% = 1 core)
82 - unit: "percentage"
83 - chart_type: stacked
84 - dimensions:
85 - - name: a dimension per app group
86 - - name: apps.cpu_system
87 - description: Apps CPU System Time (100% = 1 core)
88 - unit: "percentage"
89 - chart_type: stacked
90 - dimensions:
91 - - name: a dimension per app group
92 - - name: apps.cpu_guest
93 - description: Apps CPU Guest Time (100% = 1 core)
94 - unit: "percentage"
95 - chart_type: stacked
96 - dimensions:
97 - - name: a dimension per app group
98 - - name: apps.mem
99 - description: Apps Real Memory (w/o shared)
100 - unit: "MiB"
101 - chart_type: stacked
102 - dimensions:
103 - - name: a dimension per app group
104 - - name: apps.rss
105 - description: Apps Resident Set Size (w/shared)
106 - unit: "MiB"
107 - chart_type: stacked
108 - dimensions:
109 - - name: a dimension per app group
110 - - name: apps.vmem
111 - description: Apps Virtual Memory Size
112 - unit: "MiB"
113 - chart_type: stacked
114 - dimensions:
115 - - name: a dimension per app group
116 - - name: apps.swap
117 - description: Apps Swap Memory
118 - unit: "MiB"
76 + - name: app_group.cpu_utilization
77 + description: Apps CPU utilization (100% = 1 core)
78 + unit: percentage
79 chart_type: stacked
80 dimensions:
121 - - name: a dimension per app group
122 - - name: apps.major_faults
123 - description: Apps Major Page Faults (swap read)
124 - unit: "page faults/s"
125 - chart_type: stacked
126 - dimensions:
127 - - name: a dimension per app group
128 - - name: apps.minor_faults
129 - description: Apps Minor Page Faults (swap read)
130 - unit: "page faults/s"
131 - chart_type: stacked
132 - dimensions:
133 - - name: a dimension per app group
134 - - name: apps.preads
135 - description: Apps Disk Reads
136 - unit: "KiB/s"
137 - chart_type: stacked
138 - dimensions:
139 - - name: a dimension per app group
140 - - name: apps.pwrites
141 - description: Apps Disk Writes
142 - unit: "KiB/s"
143 - chart_type: stacked
144 - dimensions:
145 - - name: a dimension per app group
146 - - name: apps.lreads
147 - description: Apps Disk Logical Reads
148 - unit: "KiB/s"
149 - chart_type: stacked
150 - dimensions:
151 - - name: a dimension per app group
152 - - name: apps.lwrites
153 - description: Apps I/O Logical Writes
154 - unit: "KiB/s"
155 - chart_type: stacked
156 - dimensions:
157 - - name: a dimension per app group
158 - - name: apps.threads
159 - description: Apps Threads
160 - unit: "threads"
161 - chart_type: stacked
81 + - name: user
82 + - name: system
83 + - name: app_group.cpu_guest_utilization
84 + description: Apps CPU guest utilization (100% = 1 core)
85 + unit: percentage
86 + chart_type: line
87 dimensions:
163 - - name: a dimension per app group
164 - - name: apps.processes
165 - description: Apps Processes
166 - unit: "processes"
88 + - name: guest
89 + - name: app_group.cpu_context_switches
90 + description: Apps CPU context switches
91 + unit: switches/s
92 chart_type: stacked
93 dimensions:
169 - - name: a dimension per app group
170 - - name: apps.voluntary_ctxt_switches
171 - description: Apps Voluntary Context Switches
172 - unit: "processes"
173 - chart_type: stacked
94 + - name: voluntary
95 + - name: involuntary
96 + - name: app_group.mem_usage
97 + description: Apps memory RSS usage
98 + unit: MiB
99 + chart_type: line
100 dimensions:
175 - - name: a dimension per app group
176 - - name: apps.involuntary_ctxt_switches
177 - description: Apps Involuntary Context Switches
178 - unit: "processes"
101 + - name: rss
102 + - name: app_group.mem_private_usage
103 + description: Apps memory usage without shared
104 + unit: MiB
105 chart_type: stacked
106 dimensions:
181 - - name: a dimension per app group
182 - - name: apps.uptime
183 - description: Apps Carried Over Uptime
184 - unit: "seconds"
107 + - name: mem
108 + - name: app_group.vmem_usage
109 + description: Apps virtual memory size
110 + unit: MiB
111 chart_type: line
112 dimensions:
187 - - name: a dimension per app group
188 - - name: apps.uptime_min
189 - description: Apps Minimum Uptime
190 - unit: "seconds"
113 + - name: vmem
114 + - name: app_group.mem_page_faults
115 + description: Apps memory page faults
116 + unit: pgfaults/s
117 + chart_type: stacked
118 + dimensions:
119 + - name: minor
120 + - name: major
121 + - name: app_group.swap_usage
122 + description: Apps swap usage
123 + unit: MiB
124 + chart_type: area
125 + dimensions:
126 + - name: swap
127 + - name: app_group.disk_physical_io
128 + description: Apps disk physical IO
129 + unit: KiB/s
130 + chart_type: area
131 + dimensions:
132 + - name: reads
133 + - name: writes
134 + - name: app_group.disk_logical_io
135 + description: Apps disk logical IO
136 + unit: KiB/s
137 + chart_type: area
138 + dimensions:
139 + - name: reads
140 + - name: writes
141 + - name: app_group.processes
142 + description: Apps processes
143 + unit: processes
144 chart_type: line
145 dimensions:
193 - - name: a dimension per app group
194 - - name: apps.uptime_avg
195 - description: Apps Average Uptime
196 - unit: "seconds"
146 + - name: processes
147 + - name: app_group.threads
148 + description: Apps threads
149 + unit: threads
150 chart_type: line
151 dimensions:
199 - - name: a dimension per app group
200 - - name: apps.uptime_max
201 - description: Apps Maximum Uptime
202 - unit: "seconds"
152 + - name: threads
153 + - name: app_group.fds_open_limit
154 + description: Apps open file descriptors limit
155 + unit: percentage
156 chart_type: line
157 dimensions:
205 - - name: a dimension per app group
206 - - name: apps.files
207 - description: Apps Open Files
208 - unit: "open files"
209 - chart_type: stacked
210 - dimensions:
211 - - name: a dimension per app group
212 - - name: apps.sockets
213 - description: Apps Open Sockets
214 - unit: "open sockets"
215 - chart_type: stacked
158 + - name: limit
159 + - name: app_group.fds_open
160 + description: Apps open file descriptors
161 + unit: fds
162 + chart_type: stacked
163 + dimensions:
164 + - name: files
165 + - name: sockets
166 + - name: pipes
167 + - name: inotifies
168 + - name: event
169 + - name: timer
170 + - name: signal
171 + - name: eventpolls
172 + - name: other
173 + - name: app_group.uptime
174 + description: Apps uptime
175 + unit: seconds
176 + chart_type: line
177 dimensions:
217 - - name: a dimension per app group
218 - - name: apps.pipes
219 - description: Apps Open Pipes
220 - unit: "open pipes"
221 - chart_type: stacked
178 + - name: uptime
179 + - name: app_group.uptime_summary
180 + description: Apps uptime summary
181 + unit: seconds
182 + chart_type: area
183 dimensions:
223 - - name: a dimension per app group
184 + - name: min
185 + - name: avg
186 + - name: max
187 - meta:
188 plugin_name: apps.plugin
189 module_name: groups
@@ -289,160 +252,123 @@ modules:
252 description: ""
253 availability: []
254 scopes:
292 - - name: global
293 - description: ""
294 - labels: []
255 + - name: user group
256 + description: These metrics refer to the user group.
257 + labels:
258 + - name: user_group
259 + description: The name of the user group.
260 metrics:
296 - - name: groups.cpu
297 - description: User Groups CPU Time (100% = 1 core)
298 - unit: "percentage"
299 - chart_type: stacked
300 - dimensions:
301 - - name: a dimension per user group
302 - - name: groups.cpu_user
303 - description: User Groups CPU User Time (100% = 1 core)
304 - unit: "percentage"
305 - chart_type: stacked
306 - dimensions:
307 - - name: a dimension per user group
308 - - name: groups.cpu_system
309 - description: User Groups CPU System Time (100% = 1 core)
310 - unit: "percentage"
311 - chart_type: stacked
312 - dimensions:
313 - - name: a dimension per user group
314 - - name: groups.cpu_guest
315 - description: User Groups CPU Guest Time (100% = 1 core)
316 - unit: "percentage"
317 - chart_type: stacked
318 - dimensions:
319 - - name: a dimension per user group
320 - - name: groups.mem
321 - description: User Groups Real Memory (w/o shared)
322 - unit: "MiB"
323 - chart_type: stacked
324 - dimensions:
325 - - name: a dimension per user group
326 - - name: groups.rss
327 - description: User Groups Resident Set Size (w/shared)
328 - unit: "MiB"
329 - chart_type: stacked
330 - dimensions:
331 - - name: a dimension per user group
332 - - name: groups.vmem
333 - description: User Groups Virtual Memory Size
334 - unit: "MiB"
335 - chart_type: stacked
336 - dimensions:
337 - - name: a dimension per user group
338 - - name: groups.swap
339 - description: User Groups Swap Memory
340 - unit: "MiB"
341 - chart_type: stacked
342 - dimensions:
343 - - name: a dimension per user group
344 - - name: groups.major_faults
345 - description: User Groups Major Page Faults (swap read)
346 - unit: "page faults/s"
347 - chart_type: stacked
348 - dimensions:
349 - - name: a dimension per user group
350 - - name: groups.minor_faults
351 - description: User Groups Page Faults (swap read)
352 - unit: "page faults/s"
353 - chart_type: stacked
354 - dimensions:
355 - - name: a dimension per user group
356 - - name: groups.preads
357 - description: User Groups Disk Reads
358 - unit: "KiB/s"
359 - chart_type: stacked
360 - dimensions:
361 - - name: a dimension per user group
362 - - name: groups.pwrites
363 - description: User Groups Disk Writes
364 - unit: "KiB/s"
365 - chart_type: stacked
366 - dimensions:
367 - - name: a dimension per user group
368 - - name: groups.lreads
369 - description: User Groups Disk Logical Reads
370 - unit: "KiB/s"
371 - chart_type: stacked
372 - dimensions:
373 - - name: a dimension per user group
374 - - name: groups.lwrites
375 - description: User Groups I/O Logical Writes
376 - unit: "KiB/s"
377 - chart_type: stacked
378 - dimensions:
379 - - name: a dimension per user group
380 - - name: groups.threads
381 - description: User Groups Threads
382 - unit: "threads"
261 + - name: user_group.cpu_utilization
262 + description: User Groups CPU utilization (100% = 1 core)
263 + unit: percentage
264 chart_type: stacked
265 dimensions:
385 - - name: a dimension per user group
386 - - name: groups.processes
387 - description: User Groups Processes
388 - unit: "processes"
389 - chart_type: stacked
390 - dimensions:
391 - - name: a dimension per user group
392 - - name: groups.voluntary_ctxt_switches
393 - description: User Groups Voluntary Context Switches
394 - unit: "processes"
395 - chart_type: stacked
396 - dimensions:
397 - - name: a dimension per app group
398 - - name: groups.involuntary_ctxt_switches
399 - description: User Groups Involuntary Context Switches
400 - unit: "processes"
401 - chart_type: stacked
402 - dimensions:
403 - - name: a dimension per app group
404 - - name: groups.uptime
405 - description: User Groups Carried Over Uptime
406 - unit: "seconds"
266 + - name: user
267 + - name: system
268 + - name: user_group.cpu_guest_utilization
269 + description: User Groups CPU guest utilization (100% = 1 core)
270 + unit: percentage
271 chart_type: line
272 dimensions:
409 - - name: a dimension per user group
410 - - name: groups.uptime_min
411 - description: User Groups Minimum Uptime
412 - unit: "seconds"
273 + - name: guest
274 + - name: user_group.cpu_context_switches
275 + description: User Groups CPU context switches
276 + unit: switches/s
277 + chart_type: stacked
278 + dimensions:
279 + - name: voluntary
280 + - name: involuntary
281 + - name: user_group.mem_usage
282 + description: User Groups memory RSS usage
283 + unit: MiB
284 + chart_type: area
285 + dimensions:
286 + - name: rss
287 + - name: user_group.mem_private_usage
288 + description: User Groups memory usage without shared
289 + unit: MiB
290 + chart_type: area
291 + dimensions:
292 + - name: mem
293 + - name: user_group.vmem_usage
294 + description: User Groups virtual memory size
295 + unit: MiB
296 chart_type: line
297 dimensions:
415 - - name: a dimension per user group
416 - - name: groups.uptime_avg
417 - description: User Groups Average Uptime
418 - unit: "seconds"
298 + - name: vmem
299 + - name: user_group.mem_page_faults
300 + description: User Groups memory page faults
301 + unit: pgfaults/s
302 + chart_type: stacked
303 + dimensions:
304 + - name: minor
305 + - name: major
306 + - name: user_group.swap_usage
307 + description: User Groups swap usage
308 + unit: MiB
309 + chart_type: area
310 + dimensions:
311 + - name: swap
312 + - name: user_group.disk_physical_io
313 + description: User Groups disk physical IO
314 + unit: KiB/s
315 + chart_type: area
316 + dimensions:
317 + - name: reads
318 + - name: writes
319 + - name: user_group.disk_logical_io
320 + description: User Groups disk logical IO
321 + unit: KiB/s
322 + chart_type: area
323 + dimensions:
324 + - name: reads
325 + - name: writes
326 + - name: user_group.processes
327 + description: User Groups processes
328 + unit: processes
329 chart_type: line
330 dimensions:
421 - - name: a dimension per user group
422 - - name: groups.uptime_max
423 - description: User Groups Maximum Uptime
424 - unit: "seconds"
331 + - name: processes
332 + - name: user_group.threads
333 + description: User Groups threads
334 + unit: threads
335 chart_type: line
336 dimensions:
427 - - name: a dimension per user group
428 - - name: groups.files
429 - description: User Groups Open Files
430 - unit: "open files"
431 - chart_type: stacked
337 + - name: threads
338 + - name: user_group.fds_open_limit
339 + description: User Groups open file descriptors limit
340 + unit: percentage
341 + chart_type: line
342 dimensions:
433 - - name: a dimension per user group
434 - - name: groups.sockets
435 - description: User Groups Open Sockets
436 - unit: "open sockets"
437 - chart_type: stacked
343 + - name: limit
344 + - name: user_group.fds_open
345 + description: User Groups open file descriptors
346 + unit: fds
347 + chart_type: stacked
348 + dimensions:
349 + - name: files
350 + - name: sockets
351 + - name: pipes
352 + - name: inotifies
353 + - name: event
354 + - name: timer
355 + - name: signal
356 + - name: eventpolls
357 + - name: other
358 + - name: user_group.uptime
359 + description: User Groups uptime
360 + unit: seconds
361 + chart_type: line
362 dimensions:
439 - - name: a dimension per user group
440 - - name: groups.pipes
441 - description: User Groups Open Pipes
442 - unit: "open pipes"
443 - chart_type: stacked
363 + - name: uptime
364 + - name: user_group.uptime_summary
365 + description: User Groups uptime summary
366 + unit: seconds
367 + chart_type: area
368 dimensions:
445 - - name: a dimension per user group
369 + - name: min
370 + - name: avg
371 + - name: max
372 - meta:
373 plugin_name: apps.plugin
374 module_name: users
@@ -509,157 +435,120 @@ modules:
435 description: ""
436 availability: []
437 scopes:
512 - - name: global
513 - description: ""
514 - labels: []
438 + - name: user
439 + description: These metrics refer to the user.
440 + labels:
441 + - name: user
442 + description: The name of the user.
443 metrics:
516 - - name: users.cpu
517 - description: Users CPU Time (100% = 1 core)
518 - unit: "percentage"
519 - chart_type: stacked
520 - dimensions:
521 - - name: a dimension per user
522 - - name: users.cpu_user
523 - description: Users CPU User Time (100% = 1 core)
524 - unit: "percentage"
525 - chart_type: stacked
526 - dimensions:
527 - - name: a dimension per user
528 - - name: users.cpu_system
529 - description: Users CPU System Time (100% = 1 core)
530 - unit: "percentage"
531 - chart_type: stacked
532 - dimensions:
533 - - name: a dimension per user
534 - - name: users.cpu_guest
535 - description: Users CPU Guest Time (100% = 1 core)
536 - unit: "percentage"
537 - chart_type: stacked
538 - dimensions:
539 - - name: a dimension per user
540 - - name: users.mem
541 - description: Users Real Memory (w/o shared)
542 - unit: "MiB"
543 - chart_type: stacked
544 - dimensions:
545 - - name: a dimension per user
546 - - name: users.rss
547 - description: Users Resident Set Size (w/shared)
548 - unit: "MiB"
444 + - name: user.cpu_utilization
445 + description: User CPU utilization (100% = 1 core)
446 + unit: percentage
447 chart_type: stacked
448 dimensions:
551 - - name: a dimension per user
552 - - name: users.vmem
553 - description: Users Virtual Memory Size
554 - unit: "MiB"
555 - chart_type: stacked
556 - dimensions:
557 - - name: a dimension per user
558 - - name: users.swap
559 - description: Users Swap Memory
560 - unit: "MiB"
561 - chart_type: stacked
562 - dimensions:
563 - - name: a dimension per user
564 - - name: users.major_faults
565 - description: Users Major Page Faults (swap read)
566 - unit: "page faults/s"
567 - chart_type: stacked
568 - dimensions:
569 - - name: a dimension per user
570 - - name: users.minor_faults
571 - description: Users Page Faults (swap read)
572 - unit: "page faults/s"
573 - chart_type: stacked
574 - dimensions:
575 - - name: a dimension per user
576 - - name: users.preads
577 - description: Users Disk Reads
578 - unit: "KiB/s"
579 - chart_type: stacked
580 - dimensions:
581 - - name: a dimension per user
582 - - name: users.pwrites
583 - description: Users Disk Writes
584 - unit: "KiB/s"
585 - chart_type: stacked
586 - dimensions:
587 - - name: a dimension per user
588 - - name: users.lreads
589 - description: Users Disk Logical Reads
590 - unit: "KiB/s"
591 - chart_type: stacked
592 - dimensions:
593 - - name: a dimension per user
594 - - name: users.lwrites
595 - description: Users I/O Logical Writes
596 - unit: "KiB/s"
597 - chart_type: stacked
598 - dimensions:
599 - - name: a dimension per user
600 - - name: users.threads
601 - description: Users Threads
602 - unit: "threads"
603 - chart_type: stacked
604 - dimensions:
605 - - name: a dimension per user
606 - - name: users.processes
607 - description: Users Processes
608 - unit: "processes"
609 - chart_type: stacked
610 - dimensions:
611 - - name: a dimension per user
612 - - name: users.voluntary_ctxt_switches
613 - description: Users Voluntary Context Switches
614 - unit: "processes"
615 - chart_type: stacked
616 - dimensions:
617 - - name: a dimension per app group
618 - - name: users.involuntary_ctxt_switches
619 - description: Users Involuntary Context Switches
620 - unit: "processes"
621 - chart_type: stacked
622 - dimensions:
623 - - name: a dimension per app group
624 - - name: users.uptime
625 - description: Users Carried Over Uptime
626 - unit: "seconds"
449 + - name: user
450 + - name: system
451 + - name: user.cpu_guest_utilization
452 + description: User CPU guest utilization (100% = 1 core)
453 + unit: percentage
454 chart_type: line
455 dimensions:
629 - - name: a dimension per user
630 - - name: users.uptime_min
631 - description: Users Minimum Uptime
632 - unit: "seconds"
456 + - name: guest
457 + - name: user.cpu_context_switches
458 + description: User CPU context switches
459 + unit: switches/s
460 + chart_type: stacked
461 + dimensions:
462 + - name: voluntary
463 + - name: involuntary
464 + - name: user.mem_usage
465 + description: User memory RSS usage
466 + unit: MiB
467 + chart_type: area
468 + dimensions:
469 + - name: rss
470 + - name: user.mem_private_usage
471 + description: User memory usage without shared
472 + unit: MiB
473 + chart_type: area
474 + dimensions:
475 + - name: mem
476 + - name: user.vmem_usage
477 + description: User virtual memory size
478 + unit: MiB
479 chart_type: line
480 dimensions:
635 - - name: a dimension per user
636 - - name: users.uptime_avg
637 - description: Users Average Uptime
638 - unit: "seconds"
481 + - name: vmem
482 + - name: user.mem_page_faults
483 + description: User memory page faults
484 + unit: pgfaults/s
485 + chart_type: stacked
486 + dimensions:
487 + - name: minor
488 + - name: major
489 + - name: user.swap_usage
490 + description: User swap usage
491 + unit: MiB
492 + chart_type: area
493 + dimensions:
494 + - name: swap
495 + - name: user.disk_physical_io
496 + description: User disk physical IO
497 + unit: KiB/s
498 + chart_type: area
499 + dimensions:
500 + - name: reads
501 + - name: writes
502 + - name: user.disk_logical_io
503 + description: User disk logical IO
504 + unit: KiB/s
505 + chart_type: area
506 + dimensions:
507 + - name: reads
508 + - name: writes
509 + - name: user.processes
510 + description: User processes
511 + unit: processes
512 chart_type: line
513 dimensions:
641 - - name: a dimension per user
642 - - name: users.uptime_max
643 - description: Users Maximum Uptime
644 - unit: "seconds"
514 + - name: processes
515 + - name: user.threads
516 + description: User threads
517 + unit: threads
518 chart_type: line
519 dimensions:
647 - - name: a dimension per user
648 - - name: users.files
649 - description: Users Open Files
650 - unit: "open files"
651 - chart_type: stacked
520 + - name: threads
521 + - name: user.fds_open_limit
522 + description: User open file descriptors limit
523 + unit: percentage
524 + chart_type: line
525 dimensions:
653 - - name: a dimension per user
654 - - name: users.sockets
655 - description: Users Open Sockets
656 - unit: "open sockets"
657 - chart_type: stacked
526 + - name: limit
527 + - name: user.fds_open
528 + description: User open file descriptors
529 + unit: fds
530 + chart_type: stacked
531 + dimensions:
532 + - name: files
533 + - name: sockets
534 + - name: pipes
535 + - name: inotifies
536 + - name: event
537 + - name: timer
538 + - name: signal
539 + - name: eventpolls
540 + - name: other
541 + - name: user.uptime
542 + description: User uptime
543 + unit: seconds
544 + chart_type: line
545 dimensions:
659 - - name: a dimension per user
660 - - name: users.pipes
661 - description: Users Open Pipes
662 - unit: "open pipes"
663 - chart_type: stacked
546 + - name: uptime
547 + - name: user.uptime_summary
548 + description: User uptime summary
549 + unit: seconds
550 + chart_type: area
551 dimensions:
665 - - name: a dimension per user
552 + - name: min
553 + - name: avg
554 + - name: max