import sqlite3,sys,collections,datetime,statistics def pct(a,p): if not a: return 0 a=sorted(a); k=(len(a)-1)*p/100; f=int(k); c=min(f+1,len(a)-1); return a[f]+(a[c]-a[f])*(k-f) for box in sys.argv[1:]: db=sqlite3.connect(f'file:{box}/metrics.db?mode=ro',uri=True) lo,hi,n=db.execute('select min(ts),max(ts),count(*) from container_metrics').fetchone() print(f'\n=== {box.rsplit("/",1)[1]}: {datetime.datetime.utcfromtimestamp(lo):%Y-%m-%d %H:%M} -> {datetime.datetime.utcfromtimestamp(hi):%Y-%m-%d %H:%M} UTC ({(hi-lo)/86400:.1f} d), {n} rows') rows=collections.defaultdict(list) for ts,name,cpu,tx in db.execute('select ts,container_name,cpu_percent,net_tx_bytes from container_metrics order by ts'): rows[name].append((ts,cpu,tx)) hour=collections.defaultdict(float) out=[] for name,r in rows.items(): rates=[];resets=0;zero=all((x[2] or 0)==0 for x in r) for (t0,_,a),(t1,_,b) in zip(r,r[1:]): if a is None or b is None or t1-t0<=0 or t1-t0>180: continue d=b-a if d<0: resets+=1; continue mbps=d*8/(t1-t0)/1e6; rates.append(mbps) hour[datetime.datetime.utcfromtimestamp(t1).hour]+=d cpus=[x[1] for x in r] out.append((pct(rates,95),name,len(r),pct(rates,50),pct(rates,95),max(rates or [0]),pct(cpus,50),pct(cpus,95),max(cpus),zero,resets)) print(f'{"container":32} {"n":>6} {"tx p50":>8} {"p95":>8} {"max":>8} Mbit/s | {"cpu p50":>7} {"p95":>7} {"max":>7} %core | notes') for o in sorted(out,reverse=True): _,name,nn,a,b,c,d,e,f,zero,res=o note=('tx counter always 0 (host network?)' if zero else '')+(f' resets={res}' if res else '') print(f'{name[:32]:32} {nn:6} {a:8.3f} {b:8.3f} {c:8.2f} | {d:7.1f} {e:7.1f} {f:7.1f} | {note}') tot=sum(hour.values()) or 1 print('busiest UTC hours by bytes sent:',', '.join(f'{h:02d}h {100*v/tot:.0f}%' for h,v in sorted(hour.items(),key=lambda x:-x[1])[:4]))