Last active
May 17, 2024 08:08
-
-
Save vtta/7684bbf150684b77cd645844644f5285 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Output looks like this: | |
# Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 1,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2,Node 2 | |
# MemTotal,MemFree,MemUsed,SwapCached,Active,Inactive,Active(anon),Inactive(anon),Active(file),Inactive(file),Unevictable,Mlocked,Dirty,Writeback,FilePages,Mapped,AnonPages,Shmem,KernelStack,PageTables,SecPageTables,NFS_Unstable,Bounce,WritebackTmp,KReclaimable,Slab,SReclaimable,SUnreclaim,AnonHugePages,ShmemHugePages,ShmemPmdMapped,FileHugePages,FilePmdMapped,Unaccepted,HugePages_Total,HugePages_Free,HugePages_Surp,MemTotal,MemFree,MemUsed,SwapCached,Active,Inactive,Active(anon),Inactive(anon),Active(file),Inactive(file),Unevictable,Mlocked,Dirty,Writeback,FilePages,Mapped,AnonPages,Shmem,KernelStack,PageTables,SecPageTables,NFS_Unstable,Bounce,WritebackTmp,KReclaimable,Slab,SReclaimable,SUnreclaim,AnonHugePages,ShmemHugePages,ShmemPmdMapped,FileHugePages,FilePmdMapped,Unaccepted,HugePages_Total,HugePages_Free,HugePages_Surp | |
# 129366064,63343124,66022940,0,9543140,48625776,684,26279856,9542456,22345920,4,0,56,0,31936192,232932,25303716,47812,28528,61316,0,0,0,0,1733292,2227608,1733292,494316,15962112,0,0,0,0,0,0,0,0,266338304,234928788,31409516,0,11534512,17090340,7204,3807400,11527308,13282940,16,16,104,0,24816780,180816,3786656,6532,10160,52652,0,0,0,0,2382112,2620996,2382112,238884,1972224,0,0,0,0,0,0,0,0 | |
# 129366064,63343124,66022940,0,9543140,48626264,684,26280344,9542456,22345920,4,0,56,0,31936192,233048,25303740,47812,28512,61368,0,0,0,0,1733292,2227616,1733292,494324,15962112,0,0,0,0,0,0,0,0,266338304,234928636,31409668,0,11534516,17090336,7204,3807400,11527312,13282936,16,16,104,0,24816780,180640,3786656,6532,10160,52652,0,0,0,0,2382160,2621036,2382160,238876,1972224,0,0,0,0,0,0,0,0 | |
# 129366064,63343376,66022688,0,9543148,48626444,692,26280528,9542456,22345916,4,0,60,0,31936192,233324,25303916,47812,28496,61336,0,0,0,0,1733292,2227616,1733292,494324,15962112,0,0,0,0,0,0,0,0,266338304,234928028,31410276,0,11534520,17090332,7204,3807400,11527316,13282932,16,16,112,0,24816780,180640,3786656,6532,10144,52652,0,0,0,0,2382160,2621484,2382160,239324,1972224,0,0,0,0,0,0,0,0 | |
# ... | |
# Can be read by pandas via: | |
# df = pd.read_csv("numa-meminfo.log", header=[0,1]) | |
# Source file and its format: | |
# $ cat /sys/devices/system/node/node1/meminfo | |
# Node 1 MemTotal: 129366064 kB | |
# Node 1 MemFree: 63741984 kB | |
# Node 1 MemUsed: 65624080 kB | |
# Node 1 SwapCached: 0 kB | |
# Node 1 Active: 9498176 kB | |
# Node 1 Inactive: 48305840 kB | |
# Node 1 Active(anon): 660 kB | |
# Node 1 Inactive(anon): 26065500 kB | |
# Node 1 Active(file): 9497516 kB | |
# Node 1 Inactive(file): 22240340 kB | |
# Node 1 Unevictable: 4 kB | |
# Node 1 Mlocked: 0 kB | |
# Node 1 Dirty: 64 kB | |
# Node 1 Writeback: 0 kB | |
# Node 1 FilePages: 31785672 kB | |
# Node 1 Mapped: 228456 kB | |
# Node 1 AnonPages: 25090548 kB | |
# Node 1 Shmem: 47812 kB | |
# Node 1 KernelStack: 28432 kB | |
# Node 1 PageTables: 58128 kB | |
# Node 1 SecPageTables: 0 kB | |
# Node 1 NFS_Unstable: 0 kB | |
# Node 1 Bounce: 0 kB | |
# Node 1 WritebackTmp: 0 kB | |
# Node 1 KReclaimable: 1706736 kB | |
# Node 1 Slab: 2201460 kB | |
# Node 1 SReclaimable: 1706736 kB | |
# Node 1 SUnreclaim: 494724 kB | |
# Node 1 AnonHugePages: 15962112 kB | |
# Node 1 ShmemHugePages: 0 kB | |
# Node 1 ShmemPmdMapped: 0 kB | |
# Node 1 FileHugePages: 0 kB | |
# Node 1 FilePmdMapped: 0 kB | |
# Node 1 Unaccepted: 0 kB | |
# Node 1 HugePages_Total: 0 | |
# Node 1 HugePages_Free: 0 | |
# Node 1 HugePages_Surp: 0 | |
import re | |
import time | |
from pathlib import Path | |
from typing import List, Optional | |
import fire | |
# from rich import print | |
# meminfo is represented as a dict of dicts | |
# { | |
# 0: { | |
# 'MemTotal': '0', | |
# 'MemFree': '0', | |
# ... | |
# }, | |
# 1: { | |
# 'MemTotal': '129366064', | |
# ... | |
# }, | |
# ... | |
# } | |
class MemInfo: | |
nodes = dict() | |
record_re = re.compile(r"^Node\s+(?P<nid>\d+)\s+(?P<key>[\w+\(\)]+):\s+(?P<value>\d+)(\s+kB)?$", re.M) | |
@property | |
def node_glob(self): | |
return Path("/sys/devices/system/node").glob("node*/meminfo") | |
def __init__(self, nodes: Optional[List[int]] = None): | |
if isinstance(nodes, int): | |
nodes = [nodes] | |
for f in sorted(self.node_glob): | |
nid = int(f.parent.stem[4:]) | |
if nodes and nid not in nodes: | |
continue | |
self.nodes[nid] = dict([ | |
(match.group("key"), match.group("value")) for match in self.record_re.finditer(f.read_text()) | |
]) | |
def csv_header(self): | |
line0 = ",".join([",".join([f"Node {nid}"] * len(node)) for nid, node in self.nodes.items()]) | |
line1 = ",".join([",".join(node.keys()) for node in self.nodes.values()]) | |
return line0 + "\n" + line1 | |
def csv_row(self): | |
return ",".join([",".join(node.values()) for node in self.nodes.values()]) | |
def main(delay: int = 1, nodes: List[int] = []): | |
show_header = True | |
try: | |
while True: | |
meminfo = MemInfo(nodes) | |
if show_header: | |
show_header = False | |
print(meminfo.csv_header()) | |
# flush to avoid broken pipe error | |
print(meminfo.csv_row(), flush=True) | |
time.sleep(delay) | |
except KeyboardInterrupt: | |
pass | |
if __name__ == "__main__": | |
fire.Fire(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment