18308: Merge branch 'main' into 18308-enable-collection-versioning
[arvados.git] / services / fuse / arvados_fuse / crunchstat.py
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 from builtins import str
6 from builtins import object
7 import sys
8 import time
9 from collections import namedtuple
10
11 Stat = namedtuple("Stat", ['name', 'get'])
12
13 class StatWriter(object):
14     def __init__(self, prefix, interval, stats):
15         self.prefix = prefix
16         self.interval = interval
17         self.stats = stats
18         self.previous_stats = []
19         self.update_previous_stats()
20
21     def update_previous_stats(self):
22         self.previous_stats = [stat.get() for stat in self.stats]
23
24     def update(self):
25         def append_by_type(string, name, value):
26             if type(value) is float:
27                 string += " %.6f %s" % (value, name)
28             else:
29                 string += " %s %s" % (str(value), name)
30             return string
31
32         out = "crunchstat: %s" % self.prefix
33         delta = "-- interval %.4f seconds" % self.interval
34         for i, stat in enumerate(self.stats):
35             value = stat.get()
36             diff = value - self.previous_stats[i]
37             delta = append_by_type(delta, stat.name, diff)
38             out = append_by_type(out, stat.name, value)
39
40         sys.stderr.write("%s %s\n" % (out, delta))
41         self.update_previous_stats()
42
43 def statlogger(interval, keep, ops):
44     calls = StatWriter("keepcalls", interval, [
45         Stat("put", keep.put_counter.get),
46         Stat("get", keep.get_counter.get)
47     ])
48     net = StatWriter("net:keep0", interval, [
49         Stat("tx", keep.upload_counter.get),
50         Stat("rx", keep.download_counter.get)
51     ])
52     cache = StatWriter("keepcache", interval, [
53         Stat("hit", keep.hits_counter.get),
54         Stat("miss", keep.misses_counter.get)
55     ])
56     fuseops = StatWriter("fuseops", interval, [
57         Stat("write", ops.write_ops_counter.get),
58         Stat("read", ops.read_ops_counter.get)
59     ])
60     fusetimes = []
61     for cur_op in ops.metric_op_names():
62         name = "fuseop:{0}".format(cur_op)
63         fusetimes.append(StatWriter(name, interval, [
64             Stat("count", ops.metric_count_func(cur_op)),
65             Stat("time", ops.metric_sum_func(cur_op))
66         ]))
67     blk = StatWriter("blkio:0:0", interval, [
68         Stat("write", ops.write_counter.get),
69         Stat("read", ops.read_counter.get)
70     ])
71
72     while True:
73         time.sleep(interval)
74         calls.update()
75         net.update()
76         cache.update()
77         blk.update()
78         fuseops.update()
79         for ftime in fusetimes:
80             ftime.update()
81
82