From: Volker Lendecke Date: Fri, 17 Nov 2023 14:14:33 +0000 (+0100) Subject: profile: Add time buckets to smbprofile_stats_iobytes X-Git-Tag: tevent-0.17.0~346 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d0eea9d5a5f70fc9aca2655442853c25e26a155d;p=thirdparty%2Fsamba.git profile: Add time buckets to smbprofile_stats_iobytes Enable a histogram of time taken for smb2 requests. This puts all smb2 requests into buckets of <1, <2, <4, ... <256 msecs duration and beyond. Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme Reviewed-by: Guenther Deschner --- diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 91af220051d..4779a33c22a 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -290,6 +290,7 @@ struct smbprofile_stats_bytes_async { struct smbprofile_stats_iobytes { uint64_t count; /* number of events */ uint64_t time; /* microseconds */ + uint64_t buckets[10]; /* 1,2,4,...256,Inf msecs */ uint64_t idle; /* idle time compared to 'time' microseconds */ uint64_t inbytes; /* bytes read */ uint64_t outbytes; /* bytes written */ @@ -457,6 +458,7 @@ struct profile_stats { if ((_async).stats != NULL) { \ (_async).stats->outbytes += (_outbytes); \ _SMBPROFILE_TIMER_ASYNC_END(_async); \ + smbprofile_update_hist((_async).stats, profile_timestamp() - (_async).start); \ (_async) = (struct smbprofile_stats_iobytes_async) {}; \ smbprofile_dump_schedule(); \ } \ @@ -504,6 +506,48 @@ static inline bool smbprofile_active(void) return smbprofile_state.config.do_count; } +static inline void smbprofile_update_hist(struct smbprofile_stats_iobytes *s, + uint64_t microsecs) +{ + s->buckets[9]++; + if (microsecs >= 256000) { + return; + } + s->buckets[8]++; + if (microsecs >= 128000) { + return; + } + s->buckets[7]++; + if (microsecs >= 64000) { + return; + } + s->buckets[6]++; + if (microsecs >= 32000) { + return; + } + s->buckets[5]++; + if (microsecs >= 16000) { + return; + } + s->buckets[4]++; + if (microsecs >= 8000) { + return; + } + s->buckets[3]++; + if (microsecs >= 4000) { + return; + } + s->buckets[2]++; + if (microsecs >= 2000) { + return; + } + s->buckets[1]++; + if (microsecs >= 1000) { + return; + } + s->buckets[0]++; +} + static inline bool smbprofile_dump_pending(void) { if (smbprofile_state.internal.te == NULL) { diff --git a/source3/profile/profile_read.c b/source3/profile/profile_read.c index 45a1980773f..7281ff2e52d 100644 --- a/source3/profile/profile_read.c +++ b/source3/profile/profile_read.c @@ -65,6 +65,26 @@ void smbprofile_stats_accumulate(struct profile_stats *acc, add->values.name##_stats.count; \ acc->values.name##_stats.time += \ add->values.name##_stats.time; \ + acc->values.name##_stats.buckets[0] += \ + add->values.name##_stats.buckets[0]; \ + acc->values.name##_stats.buckets[1] += \ + add->values.name##_stats.buckets[1]; \ + acc->values.name##_stats.buckets[2] += \ + add->values.name##_stats.buckets[2]; \ + acc->values.name##_stats.buckets[3] += \ + add->values.name##_stats.buckets[3]; \ + acc->values.name##_stats.buckets[4] += \ + add->values.name##_stats.buckets[4]; \ + acc->values.name##_stats.buckets[5] += \ + add->values.name##_stats.buckets[5]; \ + acc->values.name##_stats.buckets[6] += \ + add->values.name##_stats.buckets[6]; \ + acc->values.name##_stats.buckets[7] += \ + add->values.name##_stats.buckets[7]; \ + acc->values.name##_stats.buckets[8] += \ + add->values.name##_stats.buckets[8]; \ + acc->values.name##_stats.buckets[9] += \ + add->values.name##_stats.buckets[9]; \ acc->values.name##_stats.idle += \ add->values.name##_stats.idle; \ acc->values.name##_stats.inbytes += \ diff --git a/source3/utils/status_profile.c b/source3/utils/status_profile.c index 6e0916ed7e8..082bc5cb61e 100644 --- a/source3/utils/status_profile.c +++ b/source3/utils/status_profile.c @@ -45,6 +45,37 @@ static void profile_separator(const char * title, d_printf("%s\n", line); } +static void print_buckets(struct traverse_state *state, + const char *name, + const struct smbprofile_stats_iobytes *s) +{ + if (state->json_output) { + return; + } + d_printf("%s_buckets: " + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"," + "%"PRIu64"\n", + name, + s->buckets[0], + s->buckets[1], + s->buckets[2], + s->buckets[3], + s->buckets[4], + s->buckets[5], + s->buckets[6], + s->buckets[7], + s->buckets[8], + s->buckets[9]); +} + /******************************************************************* dump the elements of the profile structure ******************************************************************/ @@ -95,6 +126,7 @@ bool status_profile_dump(bool verbose, #define SMBPROFILE_STATS_IOBYTES(name) do { \ __PRINT_FIELD_LINE(#name, name##_stats, count); \ __PRINT_FIELD_LINE(#name, name##_stats, time); \ + print_buckets(state, #name, &stats.values.name##_stats); \ __PRINT_FIELD_LINE(#name, name##_stats, idle); \ __PRINT_FIELD_LINE(#name, name##_stats, inbytes); \ __PRINT_FIELD_LINE(#name, name##_stats, outbytes); \