晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
| DIR:/proc/thread-self/root/opt/cloudlinux/venv/lib64/python3.11/site-packages/clsummary/ |
| Current File : //proc/thread-self/root/opt/cloudlinux/venv/lib64/python3.11/site-packages/clsummary/net_acct.py |
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2026 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
"""
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.
"""
import os
from typing import Dict, Iterable, Optional
PROC_LVE_LIST = "/proc/lve/list"
# user-id slots that don't represent hosting customers and are excluded from
# all per-LVE aggregates: default catch-all bucket and root.
NON_USER_LVE_IDS = frozenset({0, 0xFFFFFFFF}) # 0 = root, UINT_MAX = default
METRIC_NAMES = (
"net_acct_kernel_supported",
"net_acct_lves_total",
"net_acct_lves_with_traffic",
"net_acct_total_neto_bytes",
"net_acct_total_neti_bytes",
)
def _user_id_excluded(lve_id_field: str, excluded: Iterable[int]) -> bool:
"""True if the LVE row's user_id is in the excluded set.
LVE ids in /proc/lve/list use the form "<lvp_id>,<user_id>" (e.g. "0,1002")
or just "<user_id>" on older kernels. Malformed rows are excluded.
"""
user_id = lve_id_field.rsplit(",", 1)[-1]
try:
return int(user_id) in excluded
except ValueError:
return True
def _empty_result(supported: int = 0) -> Dict[str, int]:
return {
"net_acct_kernel_supported": supported,
"net_acct_lves_total": 0,
"net_acct_lves_with_traffic": 0,
"net_acct_total_neto_bytes": 0,
"net_acct_total_neti_bytes": 0,
}
def parse_proc_lve_list(
content: str,
skip_user_ids: Optional[Iterable[int]] = None,
) -> Dict[str, int]:
"""Parse /proc/lve/list text and return the 5 net_acct metrics.
Format of /proc/lve/list:
<version>:<TAB>LVE<TAB>...<TAB>NETO<TAB>NETI # header
<lve_id><TAB>...<TAB><neto><TAB><neti> # one row per LVE
The leading "<version>:" 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.
"""
if not content:
return _empty_result()
lines = content.splitlines()
if not lines:
return _empty_result()
header = lines[0]
# Drop optional "<version>:" prefix that lvectl-format headers carry.
if ":" in header:
header = header.split(":", 1)[1]
columns = header.split("\t")
try:
neto_idx = columns.index("NETO")
neti_idx = columns.index("NETI")
except ValueError:
return _empty_result()
excluded_ids = set(NON_USER_LVE_IDS)
if skip_user_ids:
excluded_ids.update(skip_user_ids)
total = 0
with_traffic = 0
sum_neto = 0
sum_neti = 0
for raw in lines[1:]:
if not raw.strip():
continue
fields = raw.split("\t")
if len(fields) <= max(neto_idx, neti_idx):
continue
if _user_id_excluded(fields[0], excluded_ids):
continue
try:
neto = int(fields[neto_idx])
neti = int(fields[neti_idx])
except ValueError:
continue
total += 1
if neto > 0 or neti > 0:
with_traffic += 1
sum_neto += neto
sum_neti += neti
return {
"net_acct_kernel_supported": 1,
"net_acct_lves_total": total,
"net_acct_lves_with_traffic": with_traffic,
"net_acct_total_neto_bytes": sum_neto,
"net_acct_total_neti_bytes": sum_neti,
}
def collect_net_acct_metrics(
path: str = PROC_LVE_LIST,
skip_user_ids: Optional[Iterable[int]] = None,
) -> Dict[str, int]:
"""Read /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.
"""
if not os.path.exists(path):
return _empty_result()
try:
with open(path, "r", encoding="utf-8", errors="replace") as fh:
content = fh.read()
except OSError:
return _empty_result()
return parse_proc_lve_list(content, skip_user_ids=skip_user_ids)
|