54 lines
2.7 KiB
TypeScript
54 lines
2.7 KiB
TypeScript
import {performance} from 'node:perf_hooks';
|
|
import type {Bot} from '@wp2508/mineflayer';
|
|
import {instrument_bot, metadata, ResourceInfo} from '../resource_metrics.ts';
|
|
|
|
export interface CpuInfo {
|
|
scope: 'bot_context';
|
|
estimated: true;
|
|
method: 'instrumented_sync_time';
|
|
usage_percent: number | null;
|
|
sampled_time_ms: number;
|
|
interval_ms: number;
|
|
coverage: string;
|
|
}
|
|
|
|
const coverage = '计量 Bot.emit 和初始 _client.emit 监听器的同步执行(包括数据包监听器和 physicsTick),'
|
|
+ '以及函数 run 的同步调用阶段;嵌套调用去重。不包含 emit 前的协议解析、异步等待及后续执行、'
|
|
+ '无关定时器、上述入口之外的插件执行和 BotContext 通知。'
|
|
+ '同步经过时间包含垃圾回收和操作系统调度暂停,因此该指标不是进程 CPU 使用率。';
|
|
|
|
export class init extends ResourceInfo<CpuInfo> {
|
|
readonly name = 'used_cpu';
|
|
readonly i18n = metadata('上下文 CPU 占用估算', coverage, {
|
|
scope: ['归属范围', '指标归属于机器人上下文,固定为 bot_context'],
|
|
estimated: ['是否为估算', '固定为 true,表示该指标始终是估算值'],
|
|
method: ['计量方法', '通过插桩计量同步经过时间,不使用操作系统 CPU 计数器'],
|
|
usage_percent: ['占用比例', '采样同步耗时除以实际经过时间再乘以 100,单位为百分比;首次采样前为 null'],
|
|
sampled_time_ms: ['采样同步耗时', '本次采样间隔内去重后的同步执行耗时,单位为毫秒'],
|
|
interval_ms: ['采样间隔', '通过单调时钟测得的实际经过时间,单位为毫秒'],
|
|
coverage: ['计量覆盖范围', '同步执行计量包含的入口及未覆盖的执行阶段'],
|
|
});
|
|
private readonly meter: ReturnType<typeof instrument_bot>;
|
|
constructor(bot: Bot) {
|
|
super({scope: 'bot_context', estimated: true, method: 'instrumented_sync_time',
|
|
usage_percent: null, sampled_time_ms: 0, interval_ms: 0, coverage});
|
|
this.meter = instrument_bot(bot);
|
|
let time = performance.now();
|
|
let total = this.meter.total();
|
|
this.start(1000, () => {
|
|
const now = performance.now();
|
|
const next = this.meter.total();
|
|
const elapsed = now - time;
|
|
const sampled = Math.max(0, next - total);
|
|
time = now;
|
|
total = next;
|
|
this.publish({...this.info, usage_percent: elapsed > 0 ? sampled / elapsed * 100 : null,
|
|
sampled_time_ms: sampled, interval_ms: elapsed});
|
|
});
|
|
}
|
|
override dispose(): void {
|
|
super.dispose();
|
|
this.meter.dispose();
|
|
}
|
|
}
|