Skip to content

Commit 8d6b700

Browse files
Nikratiorwmjones
authored andcommitted
Make length of block size histogram configurable.
1 parent 2e6fb64 commit 8d6b700

File tree

2 files changed

+83
-56
lines changed

2 files changed

+83
-56
lines changed

filters/stats/nbdkit-stats-filter.pod

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ nbdkit-stats-filter - display statistics about operations
44

55
=head1 SYNOPSIS
66

7-
nbdkit --filter=stats PLUGIN statsfile=FILE [statsappend=true]
7+
nbdkit --filter=stats PLUGIN statsfile=FILE
8+
[statsappend=true] [statsthreshold=PERCENTILE]
89

910
=head1 DESCRIPTION
1011

@@ -15,53 +16,47 @@ are written to a file once when nbdkit exits.
1516
=head1 EXAMPLE OUTPUT
1617

1718
# nbdkit --filter=exitfirst --filter=stats memory 25G statsfile=example.txt
18-
# nbd-client localhost /dev/nbd1 && mkfs.ext4 /dev/nbd1 && nbd-client -d /dev/nbd1
19+
# nbd-client localhost /dev/nbd1 && mkfs.ext4 /dev/nbd1 &&
20+
nbd-client -d /dev/nbd1
1921
[....]
2022
# cat example.txt
2123
total: 1207 ops, 24.756059 s, 25.13 GiB, 1.02 GiB/s
2224
read: 101 ops, 0.000322 s, 1.64 MiB, 4.99 GiB/s op, 68.02 KiB/s total
2325
write: 1088 ops, 0.067040 s, 132.38 MiB, 1.93 GiB/s op, 5.35 MiB/s total
2426
trim: 14 ops, 0.002605 s, 25.00 GiB, 9596.93 GiB/s op, 1.01 GiB/s total
2527
flush: 4 ops, 0.000001 s, 0 bytes, 0 bytes/s op, 0 bytes/s total
26-
27-
READ Request sizes (top 28):
28+
29+
READ Request sizes:
2830
blocksize request count
29-
4096 67 (66.34%)
30-
16384 7 (6.93%)
31-
8192 3 (2.97%)
32-
24576 3 (2.97%)
33-
61440 3 (2.97%)
34-
20480 2 (1.98%)
35-
28672 2 (1.98%)
36-
36864 2 (1.98%)
37-
40960 2 (1.98%)
38-
57344 2 (1.98%)
39-
65536 2 (1.98%)
40-
69632 2 (1.98%)
41-
32768 1 (0.99%)
42-
122880 1 (0.99%)
43-
126976 1 (0.99%)
44-
131072 1 (0.99%)
45-
46-
WRITE Request sizes (top 28):
31+
4096 93 (68.38%)
32+
61440 5 (3.68%)
33+
24576 5 (3.68%)
34+
8192 5 (3.68%)
35+
16384 5 (3.68%)
36+
126976 3 (2.21%)
37+
258048 3 (2.21%)
38+
57344 2 (1.47%)
39+
262144 2 (1.47%)
40+
20480 2 (1.47%)
41+
86016 2 (1.47%)
42+
40960 2 (1.47%)
43+
(others) 7 (5.15%)
44+
45+
WRITE Request sizes:
4746
blocksize request count
48-
131072 1056 (97.06%)
49-
4096 18 (1.65%)
50-
20480 10 (0.92%)
51-
24576 2 (0.18%)
52-
8192 1 (0.09%)
53-
65536 1 (0.09%)
54-
55-
TRIM Request sizes (top 28):
47+
524288 264 (89.19%)
48+
4096 18 (6.08%)
49+
(others) 14 (4.73%)
50+
51+
TRIM Request sizes:
5652
blocksize request count
5753
2147483648 12 (85.71%)
58-
16777216 1 (7.14%)
5954
1056964608 1 (7.14%)
60-
61-
ZERO Request sizes (top 28):
55+
(others) 1 (7.14%)
56+
57+
ZERO Request sizes:
6258
blocksize request count
6359

64-
6560
=head1 PARAMETERS
6661

6762
=over 4
@@ -76,6 +71,12 @@ This parameter is required.
7671

7772
If set then we append to the file instead of replacing it.
7873

74+
=item B<statsthreshold=>PERCENTILE
75+
76+
Percentile of requests for which block size histogram should be printed.
77+
Set to zero to disable collection of block size statistics. Set to 100
78+
to get a list of every block size encountered. Default: 95.
79+
7980
=back
8081

8182
=head1 FILES
@@ -104,6 +105,8 @@ L<nbdkit-log-filter(1)>.
104105

105106
Richard W.M. Jones
106107

108+
Nikolaus Rath
109+
107110
=head1 COPYRIGHT
108111

109-
Copyright (C) 2019 Red Hat Inc.
112+
Copyright (C) 2019-2022 Red Hat Inc.

filters/stats/stats.cpp

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static char *filename;
5959
static bool append;
6060
static FILE *fp;
6161
static struct timeval start_t;
62+
static double print_threshold = 0.95;
6263

6364
typedef struct {
6465
const char *name;
@@ -158,7 +159,7 @@ static void
158159
inc_blksize_ctr (blksize_hist_t &hist, size_t blksize)
159160
{
160161
static bool out_of_memory = false;
161-
if (out_of_memory)
162+
if (out_of_memory || print_threshold == 0)
162163
return;
163164

164165
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lock);
@@ -175,7 +176,7 @@ inc_blksize_ctr (blksize_hist_t &hist, size_t blksize)
175176
}
176177

177178
static void
178-
print_histogram (const blksize_hist_t& hist, int count)
179+
print_histogram (const blksize_hist_t &hist)
179180
{
180181
double total = 0;
181182
for (auto el : hist) {
@@ -184,38 +185,48 @@ print_histogram (const blksize_hist_t& hist, int count)
184185

185186
// Sort
186187
auto pairs = std::vector<std::pair<size_t, size_t>> (hist.begin(), hist.end());
187-
std::sort(pairs.begin(), pairs.end(),
188-
[](decltype(pairs[0]) a, decltype(pairs[0]) b) {
189-
return a.second > b.second;
190-
});
191-
192-
int i = 0;
188+
std::sort (pairs.begin(), pairs.end(),
189+
[](decltype(pairs[0]) a, decltype(pairs[0]) b) {
190+
return a.second > b.second;
191+
});
192+
193+
// Print values until we have covered *print_threshold* percent of
194+
// requests.
195+
size_t to_print = static_cast<ssize_t>(print_threshold * total);
196+
size_t printed = 0;
193197
for (auto el : pairs) {
194-
if (++i >= count)
198+
if (printed >= to_print) {
199+
size_t requests = total - printed;
200+
fprintf (fp, " (others) %9zu (%.2f%%)\n",
201+
requests, static_cast<double>(requests) / total * 100);
195202
break;
203+
}
204+
size_t blocksize = el.first;
205+
size_t requests = el.second;
196206
fprintf (fp, "%13zu %9zu (%.2f%%)\n",
197-
el.first, el.second, static_cast<double>(el.second) / total * 100);
207+
blocksize, requests, static_cast<double>(requests) / total * 100);
208+
printed += requests;
198209
}
199210
}
200211

201212
static void
202213
print_blocksize_stats (void)
203214
{
204-
fprintf (fp, "\nREAD Request sizes (top 28):\n");
215+
fprintf (fp, "\nREAD Request sizes:\n");
205216
fprintf (fp, " blocksize request count\n");
206-
print_histogram (blksize_pread_st, 28);
207-
208-
fprintf (fp, "\nWRITE Request sizes (top 28):\n");
217+
print_histogram (blksize_pread_st);
218+
219+
fprintf (fp, "\nWRITE Request sizes:\n");
209220
fprintf (fp, " blocksize request count\n");
210-
print_histogram (blksize_pwrite_st, 28);
221+
print_histogram (blksize_pwrite_st);
211222

212-
fprintf (fp, "\nTRIM Request sizes (top 28):\n");
223+
fprintf (fp, "\nTRIM Request sizes:\n");
213224
fprintf (fp, " blocksize request count\n");
214-
print_histogram (blksize_trim_st, 28);
215-
216-
fprintf (fp, "\nZERO Request sizes (top 28):\n");
225+
print_histogram (blksize_trim_st);
226+
227+
fprintf (fp, "\nZERO Request sizes:\n");
217228
fprintf (fp, " blocksize request count\n");
218-
print_histogram (blksize_zero_st, 28);
229+
print_histogram (blksize_zero_st);
219230
}
220231

221232
static inline void
@@ -229,7 +240,8 @@ print_stats (int64_t usecs)
229240
print_stat (&extents_st, usecs);
230241
print_stat (&cache_st, usecs);
231242
print_stat (&flush_st, usecs);
232-
print_blocksize_stats();
243+
if (print_threshold != 0)
244+
print_blocksize_stats ();
233245
fflush (fp);
234246
}
235247

@@ -271,6 +283,18 @@ stats_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
271283
append = r;
272284
return 0;
273285
}
286+
else if (strcmp (key, "statsthreshold") == 0) {
287+
int ival;
288+
r = nbdkit_parse_int ("printing threshold", value, &ival);
289+
if (r == -1)
290+
return -1;
291+
if (ival > 100 or ival < 0) {
292+
nbdkit_error ("statsthreshold must be between 0 and 100 (percent)");
293+
return -1;
294+
}
295+
print_threshold = static_cast<double>(ival) / 100;
296+
return 0;
297+
}
274298

275299
return next (nxdata, key, value);
276300
}

0 commit comments

Comments
 (0)