如何解读与处理Pyvmomi获取的VM性能数据SampleInfo信息?
如何解读Pyvmomi返回的SampleInfo并转化为可识别的性能指标?
问题描述
我正在使用面向vSphere的Python库Pyvmomi获取虚拟机(VM)的性能数据,相关实现代码如下:
perfManager = content.perfManager metricId = vim.PerformanceManager.MetricId(counterId=6, instance="*") startTime = datetime.datetime.now() - datetime.timedelta(hours=1) endTime = datetime.datetime.now() query = vim.PerformanceManager.QuerySpec(maxSample=1, entity=host, metricId=[metricId], startTime=startTime, endTime=endTime) object = perfManager.QueryPerf(querySpec=[query]) result = object[0] for child in result.sampleInfo: print(child)
但我不清楚如何解读或处理输出的child(即SampleInfo)信息,请问该如何将这些信息转化为可识别的性能指标集?
解决方案
别担心,我来帮你一步步理清楚怎么处理这些数据:
首先得明确:SampleInfo本身只记录采样的时间戳和间隔,不包含具体的性能数值——数值是存在result.value里的,你需要把两者关联起来,再结合性能计数器的元数据,才能得到可读的指标。
1. 先搞懂你用的性能计数器是什么
你代码里硬编码了counterId=6,但不同vSphere版本的counterId可能略有差异,最好先通过Pyvmomi获取这个计数器的详细信息(比如名称、单位、换算规则):
# 获取所有性能计数器的元数据,构建映射表 counter_info = perfManager.perfCounter counter_map = {} for counter in counter_info: counter_map[counter.key] = { "group": counter.groupInfo.key, "name": counter.nameInfo.key, "unit": counter.unitInfo.key, "scale": counter.unitInfo.scale, # 换算系数,比如-2表示除以100 "rollup_type": counter.rollupType # 汇总类型,比如平均、求和 } # 查看counterId=6的具体信息 print(counter_map[6])
通常counterId=6对应的是cpu.usage(CPU使用率),单位是百分比,scale为-2(原始值需要除以100才是实际百分比)。
2. 关联SampleInfo和性能数值
result.sampleInfo的每个元素对应一个采样点,result.value里的每个PerfMetricSeries对应一个你查询的metricId,它们的索引是一一对应的。比如result.value[0].value[0]就是第一个SampleInfo时间点的该计数器原始数值。
3. 转换为可读的性能指标
结合计数器的scale(换算系数),把原始数值转换成实际的指标值。下面是完整的改进代码:
from pyVim.connect import SmartConnect, Disconnect import datetime import vim # 替换成你的vSphere连接信息 si = SmartConnect( host="你的vCenter/ESXi地址", user="用户名", pwd="密码", port=443, disableSslCertValidation=True ) content = si.RetrieveContent() perfManager = content.perfManager # 获取目标主机(这里以第一个主机为例,你可以按需修改) host_view = content.viewManager.CreateContainerView(content.rootFolder, [vim.HostSystem], True) hosts = host_view.view host = hosts[0] host_view.Destroy() # 构建查询 metricId = vim.PerformanceManager.MetricId(counterId=6, instance="*") start_time = datetime.datetime.now() - datetime.timedelta(hours=1) end_time = datetime.datetime.now() query_spec = vim.PerformanceManager.QuerySpec( maxSample=1, entity=host, metricId=[metricId], startTime=start_time, endTime=end_time ) perf_results = perfManager.QueryPerf(querySpec=[query_spec]) if perf_results: result = perf_results[0] # 获取计数器元数据 counter_info = perfManager.perfCounter counter_map = {c.key: {"group": c.groupInfo.key, "name": c.nameInfo.key, "unit": c.unitInfo.key, "scale": c.unitInfo.scale} for c in counter_info} target_counter = counter_map[6] # 遍历采样点,输出可读指标 for idx, sample in enumerate(result.sampleInfo): raw_value = result.value[0].value[idx] # 根据scale转换原始值:scale为-2即乘以10^-2=0.01 actual_value = raw_value * (10 ** target_counter["scale"]) print(f"📅 采样时间: {sample.timestamp}") print(f"⏱️ 采样间隔: {sample.interval}秒") print(f"📊 指标: {target_counter['group']}.{target_counter['name']} = {actual_value:.2f}{target_counter['unit']}\n") Disconnect(si)
几个关键注意点
- 避免硬编码counterId:不同vSphere版本的counterId可能变化,建议通过计数器的分组和名称来查找对应的key,比如找
cpu.usage的counterId:def get_counter_id(perf_manager, group_name, counter_name, unit_name): for counter in perf_manager.perfCounter: if (counter.groupInfo.key == group_name and counter.nameInfo.key == counter_name and counter.unitInfo.key == unit_name): return counter.key return None # 获取CPU使用率的counterId cpu_usage_id = get_counter_id(perfManager, "cpu", "usage", "%") - instance参数:你用了
"*"表示查询所有实例(比如每个CPU核心、每个磁盘),如果只需要汇总值,可以传空字符串""。 - 采样间隔:
sample.interval是该采样点的时间间隔,vSphere会按不同粒度存储历史数据(5分钟、1小时等),maxSample=1会返回最近的一个采样点。
内容的提问来源于stack exchange,提问作者Rafael
相关产品推荐
相关产品推荐

