Ov dZddlZddlmZmZmZdZeddhZdZ de dee d e fd Z dd e d ee e ffd Z dd e deee d ee e ffdZedfde deee d ee e ffdZdS)uS Telemetry collector for LVE Traffic Accounting (CLOS-4341). Parses /proc/lve/list and produces a small set of metrics that let us answer: - does this kernel expose net accounting at all (NETO/NETI columns present)? - how many user LVEs exist and how many actually accumulated traffic? - what's the cumulative NETO/NETI volume across user LVEs on this host? /proc/lve/list contains two non-user LVE rows we exclude from all aggregates: - *default* (user_id = UINT_MAX) — kernel catch-all for processes not attached to any specific LVE (sshd, systemd, dnf, ...). Has non-zero traffic on essentially every running CL host. - *root* (user_id = 0) — LVE container for root (uid 0). Not a hosting user. After exclusion the metrics describe user hosting activity, and lves_total matches the count seen by `lvectl list` and the panel's user list. N)DictIterableOptionalz/proc/lve/listlnet_acct_kernel_supportednet_acct_lves_totalnet_acct_lves_with_trafficnet_acct_total_neto_bytesnet_acct_total_neti_bytes lve_id_fieldexcludedreturnc|ddd} t||vS#t$rYdSwxYw)zTrue if the LVE row's user_id is in the excluded set. LVE ids in /proc/lve/list use the form "," (e.g. "0,1002") or just "" on older kernels. Malformed rows are excluded. ,T)rsplitint ValueError)r r user_ids py/clsummary/net_acct.py_user_id_excludedr+sV !!#q))"-G7||x'' tts / == supportedc|dddddS)Nrr)rs r _empty_resultr8s %. &'%&%&   content skip_user_idsc|stS|}|stS|d}d|vr|ddd}|d} |d}|d}n#t$rtcYSwxYwt t }|r||d}d} d} d} |ddD]} | s| d} t| t||krNt| d|re t| |}t| |}n#t$rYwxYw|dz }|dks|dkr| dz } | |z } | |z } d|| | | dS) uParse /proc/lve/list text and return the 5 net_acct metrics. Format of /proc/lve/list: :LVE...NETONETI # header ... # one row per LVE The leading ":" prefix is optional/version-dependent; we tolerate its presence and absence. NETO/NETI are cumulative byte counters; their lowercase counterparts lNETO/lNETI are limit columns and ignored here. skip_user_ids — additional user-id slots to exclude beyond the standard root/default. Used by cloudlinux-summary to skip its own transient self-LVE (created via _run_self_in_lve) which would otherwise inflate counts by 1 on every collection run. On any structural problem (no header, missing NETO/NETI columns, malformed rows) we treat the kernel as not supporting net accounting and return a zeroed result. r:r NETONETINr) r splitlinessplitindexrsetNON_USER_LVE_IDSupdatestriplenmaxrr)rrlinesheadercolumnsneto_idxneti_idx excluded_idstotal with_trafficsum_netosum_netirawfieldsnetonetis rparse_proc_lve_listr<Bs.     E  1XF f}}c1%%a(ll4  G==((==(( '((L+M*** ELHHQRRyyy{{  4 v;;#h11 1 1  VAY 5 5   vh'((Dvh'((DD    H    !88taxx A LDD&'$&2%-%-   s$3*BB98B9*F  FFpathc<tj|stS t |ddd5}|}dddn #1swxYwYn#t $rtcYSwxYwt||S)zRead /proc/lve/list and return parsed metrics. Missing file (older kernels, non-CL kernels, Ubuntu without lve) yields kernel_supported=0 and zeros for the rest. rzutf-8replace)encodingerrorsN)r)osr=existsropenreadOSErrorr<)r=rfhrs rcollect_net_acct_metricsrIs 7>>$   $gi @ @ @ BggiiG                wm D D DDs5A/A# A/#A''A/*A'+A//B  B )r)N)__doc__rCtypingrrr PROC_LVE_LIST frozensetr) METRIC_NAMESstrrboolrrr<rIrrrrQsh$ ++++++++++ 9a_--  C 8C= T    Sc3h.2MM MHSM*M #s(^MMMMb-1EE EHSM*E #s(^EEEEEEr