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 { 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; 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(); } }