]>
Commit | Line | Data |
---|---|---|
38e2e9ce | 1 | #!/usr/bin/env @PYTHON_SHEBANG@ |
7634cd54 CS |
2 | # |
3 | # Print out ZFS ARC Statistics exported via kstat(1) | |
b29e31d8 | 4 | # For a definition of fields, or usage, use arcstat -v |
7634cd54 | 5 | # |
b29e31d8 AJ |
6 | # This script was originally a fork of the original arcstat.pl (0.1) |
7 | # by Neelakanth Nadgir, originally published on his Sun blog on | |
7634cd54 CS |
8 | # 09/18/2007 |
9 | # http://blogs.sun.com/realneel/entry/zfs_arc_statistics | |
10 | # | |
b29e31d8 AJ |
11 | # A new version aimed to improve upon the original by adding features |
12 | # and fixing bugs as needed. This version was maintained by Mike | |
13 | # Harsch and was hosted in a public open source repository: | |
7634cd54 CS |
14 | # http://github.com/mharsch/arcstat |
15 | # | |
b29e31d8 AJ |
16 | # but has since moved to the illumos-gate repository. |
17 | # | |
18 | # This Python port was written by John Hixson for FreeNAS, introduced | |
19 | # in commit e2c29f: | |
20 | # https://github.com/freenas/freenas | |
21 | # | |
22 | # and has been improved by many people since. | |
7634cd54 CS |
23 | # |
24 | # CDDL HEADER START | |
25 | # | |
26 | # The contents of this file are subject to the terms of the | |
27 | # Common Development and Distribution License, Version 1.0 only | |
28 | # (the "License"). You may not use this file except in compliance | |
29 | # with the License. | |
30 | # | |
31 | # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
32 | # or http://www.opensolaris.org/os/licensing. | |
33 | # See the License for the specific language governing permissions | |
34 | # and limitations under the License. | |
35 | # | |
36 | # When distributing Covered Code, include this CDDL HEADER in each | |
37 | # file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
38 | # If applicable, add the following below this CDDL HEADER, with the | |
39 | # fields enclosed by brackets "[]" replaced with your own identifying | |
40 | # information: Portions Copyright [yyyy] [name of copyright owner] | |
41 | # | |
42 | # CDDL HEADER END | |
43 | # | |
44 | # | |
45 | # Fields have a fixed width. Every interval, we fill the "v" | |
46 | # hash with its corresponding value (v[field]=value) using calculate(). | |
47 | # @hdr is the array of fields that needs to be printed, so we | |
48 | # just iterate over this array and print the values using our pretty printer. | |
49 | # | |
8a7c4efd | 50 | # This script must remain compatible with Python 3.6+. |
6e72a5b9 | 51 | # |
7634cd54 CS |
52 | |
53 | import sys | |
54 | import time | |
55 | import getopt | |
56 | import re | |
57 | import copy | |
58 | ||
a82db4e1 | 59 | from signal import signal, SIGINT, SIGWINCH, SIG_DFL |
7634cd54 | 60 | |
2f1ca8a3 | 61 | |
7634cd54 CS |
62 | cols = { |
63 | # HDR: [Size, Scale, Description] | |
64 | "time": [8, -1, "Time"], | |
65 | "hits": [4, 1000, "ARC reads per second"], | |
66 | "miss": [4, 1000, "ARC misses per second"], | |
67 | "read": [4, 1000, "Total ARC accesses per second"], | |
2b21da4f | 68 | "hit%": [4, 100, "ARC hit percentage"], |
7634cd54 | 69 | "miss%": [5, 100, "ARC miss percentage"], |
1c49ac57 IH |
70 | "dhit": [4, 1000, "Demand hits per second"], |
71 | "dmis": [4, 1000, "Demand misses per second"], | |
72 | "dh%": [3, 100, "Demand hit percentage"], | |
73 | "dm%": [3, 100, "Demand miss percentage"], | |
7634cd54 CS |
74 | "phit": [4, 1000, "Prefetch hits per second"], |
75 | "pmis": [4, 1000, "Prefetch misses per second"], | |
76 | "ph%": [3, 100, "Prefetch hits percentage"], | |
77 | "pm%": [3, 100, "Prefetch miss percentage"], | |
78 | "mhit": [4, 1000, "Metadata hits per second"], | |
79 | "mmis": [4, 1000, "Metadata misses per second"], | |
63a77ae3 | 80 | "mread": [5, 1000, "Metadata accesses per second"], |
7634cd54 CS |
81 | "mh%": [3, 100, "Metadata hit percentage"], |
82 | "mm%": [3, 100, "Metadata miss percentage"], | |
2b21da4f | 83 | "arcsz": [5, 1024, "ARC size"], |
7b232e93 | 84 | "size": [4, 1024, "ARC size"], |
2b21da4f AJ |
85 | "c": [4, 1024, "ARC target size"], |
86 | "mfu": [4, 1000, "MFU list hits per second"], | |
87 | "mru": [4, 1000, "MRU list hits per second"], | |
88 | "mfug": [4, 1000, "MFU ghost list hits per second"], | |
89 | "mrug": [4, 1000, "MRU ghost list hits per second"], | |
7634cd54 | 90 | "eskip": [5, 1000, "evict_skip per second"], |
08532162 GA |
91 | "el2skip": [7, 1000, "evict skip, due to l2 writes, per second"], |
92 | "el2cach": [7, 1024, "Size of L2 cached evictions per second"], | |
93 | "el2el": [5, 1024, "Size of L2 eligible evictions per second"], | |
94 | "el2mfu": [6, 1024, "Size of L2 eligible MFU evictions per second"], | |
95 | "el2mru": [6, 1024, "Size of L2 eligible MRU evictions per second"], | |
96 | "el2inel": [7, 1024, "Size of L2 ineligible evictions per second"], | |
7634cd54 | 97 | "mtxmis": [6, 1000, "mutex_miss per second"], |
1c49ac57 | 98 | "dread": [5, 1000, "Demand accesses per second"], |
7634cd54 CS |
99 | "pread": [5, 1000, "Prefetch accesses per second"], |
100 | "l2hits": [6, 1000, "L2ARC hits per second"], | |
101 | "l2miss": [6, 1000, "L2ARC misses per second"], | |
102 | "l2read": [6, 1000, "Total L2ARC accesses per second"], | |
103 | "l2hit%": [6, 100, "L2ARC access hit percentage"], | |
104 | "l2miss%": [7, 100, "L2ARC access miss percentage"], | |
08532162 GA |
105 | "l2pref": [6, 1024, "L2ARC prefetch allocated size"], |
106 | "l2mfu": [5, 1024, "L2ARC MFU allocated size"], | |
107 | "l2mru": [5, 1024, "L2ARC MRU allocated size"], | |
108 | "l2data": [6, 1024, "L2ARC data allocated size"], | |
109 | "l2meta": [6, 1024, "L2ARC metadata allocated size"], | |
110 | "l2pref%": [7, 100, "L2ARC prefetch percentage"], | |
111 | "l2mfu%": [6, 100, "L2ARC MFU percentage"], | |
112 | "l2mru%": [6, 100, "L2ARC MRU percentage"], | |
113 | "l2data%": [7, 100, "L2ARC data percentage"], | |
114 | "l2meta%": [7, 100, "L2ARC metadata percentage"], | |
e78b6da3 | 115 | "l2asize": [7, 1024, "Actual (compressed) size of the L2ARC"], |
7634cd54 | 116 | "l2size": [6, 1024, "Size of the L2ARC"], |
2b21da4f AJ |
117 | "l2bytes": [7, 1024, "Bytes read per second from the L2ARC"], |
118 | "grow": [4, 1000, "ARC grow disabled"], | |
119 | "need": [4, 1024, "ARC reclaim need"], | |
120 | "free": [4, 1024, "ARC free memory"], | |
7b232e93 | 121 | "avail": [5, 1024, "ARC available memory"], |
85ec5cba | 122 | "waste": [5, 1024, "Wasted memory due to round up to pagesize"], |
7634cd54 CS |
123 | } |
124 | ||
125 | v = {} | |
126 | hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis", | |
7b232e93 | 127 | "mm%", "size", "c", "avail"] |
f4092679 | 128 | xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "dread", |
129 | "pread", "read"] | |
7634cd54 CS |
130 | sint = 1 # Default interval is 1 second |
131 | count = 1 # Default count is 1 | |
132 | hdr_intr = 20 # Print header every 20 lines of output | |
133 | opfile = None | |
134 | sep = " " # Default separator is 2 spaces | |
135 | version = "0.4" | |
136 | l2exist = False | |
2aaab887 | 137 | cmd = ("Usage: arcstat [-havxp] [-f fields] [-o file] [-s string] [interval " |
23bc1f91 | 138 | "[count]]\n") |
7634cd54 CS |
139 | cur = {} |
140 | d = {} | |
141 | out = None | |
142 | kstat = None | |
2aaab887 | 143 | pretty_print = True |
7634cd54 CS |
144 | |
145 | ||
101f9b17 | 146 | if sys.platform.startswith('freebsd'): |
513c1962 | 147 | # Requires py-sysctl on FreeBSD |
101f9b17 RM |
148 | import sysctl |
149 | ||
150 | def kstat_update(): | |
151 | global kstat | |
152 | ||
513c1962 RM |
153 | k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats') |
154 | if ctl.type != sysctl.CTLTYPE_NODE] | |
101f9b17 RM |
155 | |
156 | if not k: | |
157 | sys.exit(1) | |
158 | ||
159 | kstat = {} | |
160 | ||
161 | for s in k: | |
162 | if not s: | |
163 | continue | |
164 | ||
165 | name, value = s.name, s.value | |
166 | # Trims 'kstat.zfs.misc.arcstats' from the name | |
4df8b2c3 | 167 | kstat[name[24:]] = int(value) |
101f9b17 RM |
168 | |
169 | elif sys.platform.startswith('linux'): | |
2f1ca8a3 RM |
170 | def kstat_update(): |
171 | global kstat | |
172 | ||
173 | k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] | |
174 | ||
175 | if not k: | |
176 | sys.exit(1) | |
177 | ||
178 | del k[0:2] | |
179 | kstat = {} | |
180 | ||
181 | for s in k: | |
182 | if not s: | |
183 | continue | |
184 | ||
185 | name, unused, value = s.split() | |
4df8b2c3 | 186 | kstat[name] = int(value) |
2f1ca8a3 RM |
187 | |
188 | ||
7634cd54 CS |
189 | def detailed_usage(): |
190 | sys.stderr.write("%s\n" % cmd) | |
191 | sys.stderr.write("Field definitions are as follows:\n") | |
192 | for key in cols: | |
193 | sys.stderr.write("%11s : %s\n" % (key, cols[key][2])) | |
194 | sys.stderr.write("\n") | |
195 | ||
e169749f | 196 | sys.exit(0) |
7634cd54 CS |
197 | |
198 | ||
199 | def usage(): | |
200 | sys.stderr.write("%s\n" % cmd) | |
201 | sys.stderr.write("\t -h : Print this help message\n") | |
2aaab887 | 202 | sys.stderr.write("\t -a : Print all possible stats\n") |
7634cd54 | 203 | sys.stderr.write("\t -v : List all possible field headers and definitions" |
23bc1f91 | 204 | "\n") |
7634cd54 CS |
205 | sys.stderr.write("\t -x : Print extended stats\n") |
206 | sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n") | |
207 | sys.stderr.write("\t -o : Redirect output to the specified file\n") | |
208 | sys.stderr.write("\t -s : Override default field separator with custom " | |
23bc1f91 | 209 | "character or string\n") |
2aaab887 | 210 | sys.stderr.write("\t -p : Disable auto-scaling of numerical fields\n") |
7634cd54 | 211 | sys.stderr.write("\nExamples:\n") |
6e72a5b9 BB |
212 | sys.stderr.write("\tarcstat -o /tmp/a.log 2 10\n") |
213 | sys.stderr.write("\tarcstat -s \",\" -o /tmp/a.log 2 10\n") | |
214 | sys.stderr.write("\tarcstat -v\n") | |
215 | sys.stderr.write("\tarcstat -f time,hit%,dh%,ph%,mh% 1\n") | |
7634cd54 CS |
216 | sys.stderr.write("\n") |
217 | ||
218 | sys.exit(1) | |
219 | ||
220 | ||
7634cd54 CS |
221 | def snap_stats(): |
222 | global cur | |
223 | global kstat | |
224 | ||
225 | prev = copy.deepcopy(cur) | |
226 | kstat_update() | |
227 | ||
228 | cur = kstat | |
229 | for key in cur: | |
230 | if re.match(key, "class"): | |
231 | continue | |
232 | if key in prev: | |
233 | d[key] = cur[key] - prev[key] | |
234 | else: | |
235 | d[key] = cur[key] | |
236 | ||
237 | ||
238 | def prettynum(sz, scale, num=0): | |
239 | suffix = [' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z'] | |
240 | index = 0 | |
241 | save = 0 | |
242 | ||
243 | # Special case for date field | |
244 | if scale == -1: | |
245 | return "%s" % num | |
246 | ||
247 | # Rounding error, return 0 | |
09d672d3 | 248 | elif 0 < num < 1: |
7634cd54 CS |
249 | num = 0 |
250 | ||
7b232e93 | 251 | while abs(num) > scale and index < 5: |
7634cd54 CS |
252 | save = num |
253 | num = num / scale | |
254 | index += 1 | |
255 | ||
256 | if index == 0: | |
257 | return "%*d" % (sz, num) | |
258 | ||
7b232e93 | 259 | if abs(save / scale) < 10: |
7634cd54 CS |
260 | return "%*.1f%s" % (sz - 1, num, suffix[index]) |
261 | else: | |
262 | return "%*d%s" % (sz - 1, num, suffix[index]) | |
263 | ||
264 | ||
265 | def print_values(): | |
266 | global hdr | |
267 | global sep | |
268 | global v | |
2aaab887 | 269 | global pretty_print |
7634cd54 | 270 | |
2aaab887 RM |
271 | if pretty_print: |
272 | fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col]) | |
273 | else: | |
274 | fmt = lambda col: v[col] | |
7b232e93 | 275 | |
2aaab887 | 276 | sys.stdout.write(sep.join(fmt(col) for col in hdr)) |
7634cd54 | 277 | sys.stdout.write("\n") |
3ad59c01 | 278 | sys.stdout.flush() |
7634cd54 CS |
279 | |
280 | ||
281 | def print_header(): | |
282 | global hdr | |
283 | global sep | |
2aaab887 | 284 | global pretty_print |
7634cd54 | 285 | |
2aaab887 RM |
286 | if pretty_print: |
287 | fmt = lambda col: "%*s" % (cols[col][0], col) | |
288 | else: | |
289 | fmt = lambda col: col | |
7b232e93 | 290 | |
2aaab887 | 291 | sys.stdout.write(sep.join(fmt(col) for col in hdr)) |
7634cd54 CS |
292 | sys.stdout.write("\n") |
293 | ||
0bde1f7c | 294 | |
4e1c9f9c IH |
295 | def get_terminal_lines(): |
296 | try: | |
0bde1f7c GDN |
297 | import fcntl |
298 | import termios | |
299 | import struct | |
4e1c9f9c IH |
300 | data = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, '1234') |
301 | sz = struct.unpack('hh', data) | |
302 | return sz[0] | |
63e5e960 | 303 | except Exception: |
4e1c9f9c | 304 | pass |
7634cd54 | 305 | |
0bde1f7c | 306 | |
a82db4e1 IH |
307 | def update_hdr_intr(): |
308 | global hdr_intr | |
309 | ||
310 | lines = get_terminal_lines() | |
311 | if lines and lines > 3: | |
312 | hdr_intr = lines - 3 | |
313 | ||
0bde1f7c | 314 | |
a82db4e1 IH |
315 | def resize_handler(signum, frame): |
316 | update_hdr_intr() | |
317 | ||
318 | ||
7634cd54 CS |
319 | def init(): |
320 | global sint | |
321 | global count | |
322 | global hdr | |
323 | global xhdr | |
324 | global opfile | |
325 | global sep | |
326 | global out | |
327 | global l2exist | |
2aaab887 | 328 | global pretty_print |
7634cd54 CS |
329 | |
330 | desired_cols = None | |
2aaab887 | 331 | aflag = False |
7634cd54 CS |
332 | xflag = False |
333 | hflag = False | |
334 | vflag = False | |
335 | i = 1 | |
336 | ||
337 | try: | |
338 | opts, args = getopt.getopt( | |
339 | sys.argv[1:], | |
2aaab887 | 340 | "axo:hvs:f:p", |
7634cd54 | 341 | [ |
2aaab887 | 342 | "all", |
7634cd54 CS |
343 | "extended", |
344 | "outfile", | |
345 | "help", | |
346 | "verbose", | |
d699aaef | 347 | "separator", |
2aaab887 RM |
348 | "columns", |
349 | "parsable" | |
7634cd54 CS |
350 | ] |
351 | ) | |
09d672d3 | 352 | except getopt.error as msg: |
1f87313a | 353 | sys.stderr.write("Error: %s\n" % str(msg)) |
7634cd54 | 354 | usage() |
09d672d3 | 355 | opts = None |
7634cd54 CS |
356 | |
357 | for opt, arg in opts: | |
2aaab887 RM |
358 | if opt in ('-a', '--all'): |
359 | aflag = True | |
7634cd54 CS |
360 | if opt in ('-x', '--extended'): |
361 | xflag = True | |
362 | if opt in ('-o', '--outfile'): | |
363 | opfile = arg | |
364 | i += 1 | |
365 | if opt in ('-h', '--help'): | |
366 | hflag = True | |
367 | if opt in ('-v', '--verbose'): | |
368 | vflag = True | |
d699aaef | 369 | if opt in ('-s', '--separator'): |
7634cd54 CS |
370 | sep = arg |
371 | i += 1 | |
372 | if opt in ('-f', '--columns'): | |
373 | desired_cols = arg | |
374 | i += 1 | |
2aaab887 RM |
375 | if opt in ('-p', '--parsable'): |
376 | pretty_print = False | |
7634cd54 CS |
377 | i += 1 |
378 | ||
379 | argv = sys.argv[i:] | |
4df8b2c3 A |
380 | sint = int(argv[0]) if argv else sint |
381 | count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1) | |
7634cd54 CS |
382 | |
383 | if hflag or (xflag and desired_cols): | |
384 | usage() | |
385 | ||
386 | if vflag: | |
387 | detailed_usage() | |
388 | ||
389 | if xflag: | |
390 | hdr = xhdr | |
391 | ||
a82db4e1 | 392 | update_hdr_intr() |
4e1c9f9c | 393 | |
7634cd54 CS |
394 | # check if L2ARC exists |
395 | snap_stats() | |
396 | l2_size = cur.get("l2_size") | |
397 | if l2_size: | |
398 | l2exist = True | |
399 | ||
400 | if desired_cols: | |
401 | hdr = desired_cols.split(",") | |
402 | ||
403 | invalid = [] | |
404 | incompat = [] | |
405 | for ele in hdr: | |
406 | if ele not in cols: | |
407 | invalid.append(ele) | |
408 | elif not l2exist and ele.startswith("l2"): | |
409 | sys.stdout.write("No L2ARC Here\n%s\n" % ele) | |
410 | incompat.append(ele) | |
411 | ||
412 | if len(invalid) > 0: | |
413 | sys.stderr.write("Invalid column definition! -- %s\n" % invalid) | |
414 | usage() | |
415 | ||
416 | if len(incompat) > 0: | |
23bc1f91 MT |
417 | sys.stderr.write("Incompatible field specified! -- %s\n" % |
418 | incompat) | |
7634cd54 CS |
419 | usage() |
420 | ||
2aaab887 RM |
421 | if aflag: |
422 | if l2exist: | |
423 | hdr = cols.keys() | |
424 | else: | |
425 | hdr = [col for col in cols.keys() if not col.startswith("l2")] | |
426 | ||
7634cd54 CS |
427 | if opfile: |
428 | try: | |
429 | out = open(opfile, "w") | |
430 | sys.stdout = out | |
431 | ||
09d672d3 | 432 | except IOError: |
7634cd54 CS |
433 | sys.stderr.write("Cannot open %s for writing\n" % opfile) |
434 | sys.exit(1) | |
435 | ||
436 | ||
437 | def calculate(): | |
438 | global d | |
439 | global v | |
440 | global l2exist | |
441 | ||
09d672d3 | 442 | v = dict() |
7634cd54 | 443 | v["time"] = time.strftime("%H:%M:%S", time.localtime()) |
2d02bba2 VA |
444 | v["hits"] = d["hits"] // sint |
445 | v["miss"] = d["misses"] // sint | |
7634cd54 | 446 | v["read"] = v["hits"] + v["miss"] |
2d02bba2 | 447 | v["hit%"] = 100 * v["hits"] // v["read"] if v["read"] > 0 else 0 |
7634cd54 CS |
448 | v["miss%"] = 100 - v["hit%"] if v["read"] > 0 else 0 |
449 | ||
2d02bba2 VA |
450 | v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) // sint |
451 | v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) // sint | |
7634cd54 CS |
452 | |
453 | v["dread"] = v["dhit"] + v["dmis"] | |
2d02bba2 | 454 | v["dh%"] = 100 * v["dhit"] // v["dread"] if v["dread"] > 0 else 0 |
7634cd54 CS |
455 | v["dm%"] = 100 - v["dh%"] if v["dread"] > 0 else 0 |
456 | ||
2d02bba2 | 457 | v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) // sint |
7634cd54 | 458 | v["pmis"] = (d["prefetch_data_misses"] + |
2d02bba2 | 459 | d["prefetch_metadata_misses"]) // sint |
7634cd54 CS |
460 | |
461 | v["pread"] = v["phit"] + v["pmis"] | |
2d02bba2 | 462 | v["ph%"] = 100 * v["phit"] // v["pread"] if v["pread"] > 0 else 0 |
7634cd54 CS |
463 | v["pm%"] = 100 - v["ph%"] if v["pread"] > 0 else 0 |
464 | ||
465 | v["mhit"] = (d["prefetch_metadata_hits"] + | |
2d02bba2 | 466 | d["demand_metadata_hits"]) // sint |
7634cd54 | 467 | v["mmis"] = (d["prefetch_metadata_misses"] + |
2d02bba2 | 468 | d["demand_metadata_misses"]) // sint |
7634cd54 CS |
469 | |
470 | v["mread"] = v["mhit"] + v["mmis"] | |
2d02bba2 | 471 | v["mh%"] = 100 * v["mhit"] // v["mread"] if v["mread"] > 0 else 0 |
7634cd54 CS |
472 | v["mm%"] = 100 - v["mh%"] if v["mread"] > 0 else 0 |
473 | ||
474 | v["arcsz"] = cur["size"] | |
7b232e93 | 475 | v["size"] = cur["size"] |
7634cd54 | 476 | v["c"] = cur["c"] |
2d02bba2 VA |
477 | v["mfu"] = d["mfu_hits"] // sint |
478 | v["mru"] = d["mru_hits"] // sint | |
479 | v["mrug"] = d["mru_ghost_hits"] // sint | |
480 | v["mfug"] = d["mfu_ghost_hits"] // sint | |
481 | v["eskip"] = d["evict_skip"] // sint | |
482 | v["el2skip"] = d["evict_l2_skip"] // sint | |
483 | v["el2cach"] = d["evict_l2_cached"] // sint | |
484 | v["el2el"] = d["evict_l2_eligible"] // sint | |
485 | v["el2mfu"] = d["evict_l2_eligible_mfu"] // sint | |
486 | v["el2mru"] = d["evict_l2_eligible_mru"] // sint | |
487 | v["el2inel"] = d["evict_l2_ineligible"] // sint | |
488 | v["mtxmis"] = d["mutex_miss"] // sint | |
7634cd54 CS |
489 | |
490 | if l2exist: | |
2d02bba2 VA |
491 | v["l2hits"] = d["l2_hits"] // sint |
492 | v["l2miss"] = d["l2_misses"] // sint | |
7634cd54 | 493 | v["l2read"] = v["l2hits"] + v["l2miss"] |
2d02bba2 | 494 | v["l2hit%"] = 100 * v["l2hits"] // v["l2read"] if v["l2read"] > 0 else 0 |
7634cd54 CS |
495 | |
496 | v["l2miss%"] = 100 - v["l2hit%"] if v["l2read"] > 0 else 0 | |
e78b6da3 | 497 | v["l2asize"] = cur["l2_asize"] |
7634cd54 | 498 | v["l2size"] = cur["l2_size"] |
2d02bba2 | 499 | v["l2bytes"] = d["l2_read_bytes"] // sint |
7634cd54 | 500 | |
08532162 GA |
501 | v["l2pref"] = cur["l2_prefetch_asize"] |
502 | v["l2mfu"] = cur["l2_mfu_asize"] | |
503 | v["l2mru"] = cur["l2_mru_asize"] | |
504 | v["l2data"] = cur["l2_bufc_data_asize"] | |
505 | v["l2meta"] = cur["l2_bufc_metadata_asize"] | |
2d02bba2 VA |
506 | v["l2pref%"] = 100 * v["l2pref"] // v["l2asize"] |
507 | v["l2mfu%"] = 100 * v["l2mfu"] // v["l2asize"] | |
508 | v["l2mru%"] = 100 * v["l2mru"] // v["l2asize"] | |
509 | v["l2data%"] = 100 * v["l2data"] // v["l2asize"] | |
510 | v["l2meta%"] = 100 * v["l2meta"] // v["l2asize"] | |
08532162 | 511 | |
63a77ae3 GK |
512 | v["grow"] = 0 if cur["arc_no_grow"] else 1 |
513 | v["need"] = cur["arc_need_free"] | |
7b232e93 MA |
514 | v["free"] = cur["memory_free_bytes"] |
515 | v["avail"] = cur["memory_available_bytes"] | |
85ec5cba | 516 | v["waste"] = cur["abd_chunk_waste_size"] |
63a77ae3 | 517 | |
7634cd54 | 518 | |
7634cd54 CS |
519 | def main(): |
520 | global sint | |
521 | global count | |
522 | global hdr_intr | |
523 | ||
524 | i = 0 | |
525 | count_flag = 0 | |
526 | ||
527 | init() | |
528 | if count > 0: | |
529 | count_flag = 1 | |
530 | ||
312f82ce | 531 | signal(SIGINT, SIG_DFL) |
a82db4e1 | 532 | signal(SIGWINCH, resize_handler) |
7634cd54 CS |
533 | while True: |
534 | if i == 0: | |
535 | print_header() | |
536 | ||
537 | snap_stats() | |
538 | calculate() | |
539 | print_values() | |
540 | ||
541 | if count_flag == 1: | |
542 | if count <= 1: | |
543 | break | |
544 | count -= 1 | |
545 | ||
a82db4e1 | 546 | i = 0 if i >= hdr_intr else i + 1 |
7634cd54 CS |
547 | time.sleep(sint) |
548 | ||
549 | if out: | |
550 | out.close() | |
551 | ||
552 | ||
553 | if __name__ == '__main__': | |
554 | main() |