- 可观测性
- 后端
- 运维
- 前端
- 云原生
- 微服务
- AI Agent
【免费下载链接】oneuptime
Complete open-source monitoring and observability platform.
本篇技术指南以 OneUptime 的 Custom Code Monitor(自定义代码监控器)为主题,完整讲解如何编写自定义 JavaScript 脚本监控应用、接入加密的 Monitor Secrets(监控密钥)、通过oneuptime.captureMetric()采集自定义指标并接入 Metric Explorer,同时结合仓库源码揭示脚本沙箱的隔离机制、资源限制与安全边界。阅读完本文后,你将能够从零编写、调试并安全地发布一个生产可用的自定义代码监控脚本。
什么是 Custom Code Monitor
OneUptime 内置了大量开箱即用的监控器(HTTP、Ping、SSL、端口、浏览器等),但真实业务中总有一些「现有监控器做不到」的场景。Custom Code Monitor 正是为此设计:它允许你在监控器中直接编写一段自定义 JavaScript 脚本,用任意逻辑探测你的应用。
典型场景包括:
- 多步 API 请求:先登录换取 Token,再携带 Token 访问业务接口(现有单次 HTTP 监控无法表达这种依赖关系);
- 复杂的断言与计算:拉取响应后做数据校验、计算延迟、判断队列深度是否超阈值;
- 调用 Node.js 能力:使用
crypto对请求签名(例如生成 HMAC 鉴权头)、使用内置http/https或axios发起任意 HTTP 请求; - 采集业务指标:把脚本运行时观测到的数值通过
oneuptime.captureMetric()上报为自定义指标。
从源码结构看,Custom Code Monitor 属于探针端(Probe)的「合成运行时」体系:用户脚本并不会直接在探针进程里执行,而是被投递到由 WorkerBootstrap.ts 生成的独立 Web Worker 沙箱中运行。脚本能够访问哪些对象、哪些能力被屏蔽、数据如何回传,全部由这套运行时严格定义。
快速上手:第一个自定义代码监控脚本
一个最简的 Custom Code Monitor 脚本如下(与官方文档示例一致):
// You can use axios module. await axios.get("https://api.example.com/"); // Axios Documentation here: https://axios-http.com/docs/intro return { data: "Hello World", // return any data you like here. };几点说明:
- 脚本以async 函数体执行,因此可以直接
await任何 Promise; axios是运行时预置的全局模块,无需import/require;- 通过
return返回任意数据,该数据会被序列化并作为本次监控执行的结果保存; - 执行完成后,监控器会依据是否抛出异常判定为「正常」或「故障」,超时、未捕获异常都会导致本次探测失败。
脚本沙箱:运行时如何执行你的代码
理解沙箱机制有助于写出更稳、更合规的脚本。在 WorkerBootstrap.ts 中可以看到,用户代码被包装成AsyncFunction执行:
const userFunction = new AsyncFunction( ...parameterNames, '"use strict";\nreturn await (async function () {\n"use strict";\n' + payload.code + '\n}).call(undefined);', );脚本真正能访问的只有以参数形式注入的受限对象,包括page、axios、http、https、crypto、console、oneuptime、screenshots、Buffer以及几个定时器函数。与此同时,运行时通过hardenAmbientCapabilities()显式屏蔽了fetch、XMLHttpRequest、WebSocket、importScripts、Worker等可能逃逸隔离边界的浏览器能力(见 WorkerBootstrap.ts)——所以脚本内不要使用fetch,请统一使用axios或http/https。
沙箱还施加了多项资源约束(可在 WorkerBootstrap.ts 中看到定义):
| 约束项 | 上限 |
|---|---|
单次脚本执行采集指标数(MAX_METRICS) | 100 |
单次请求负载大小(MAX_REQUEST_BYTES) | 1 MB |
执行结果大小(MAX_RESULT_BYTES) | 5 MB |
日志总量(MAX_LOG_BYTES) | 1 MB |
日志条数(MAX_LOG_MESSAGES) | 10,000 条 |
参数/结果序列化深度(MAX_SERIALIZATION_DEPTH) | 30 层 |
序列化节点数(MAX_SERIALIZATION_NODES) | 20,000 个 |
此外,脚本存在2 分钟超时:如果脚本执行超过 2 分钟,运行时会直接将其终止。这一限制在探针端 Limits.ts 中也有对应实现(SYNTHETIC_MONITOR_WORKER_STARTUP_ALLOWANCE_IN_MS = 120_000,即 2 分钟)。因此建议所有对外部服务的请求都显式设置超时,避免脚本被整体掐断。
使用 Monitor Secrets(监控密钥)
当脚本需要访问 API Token、密码等敏感信息时,不要硬编码在脚本里——请使用 OneUptime 的 Monitor Secrets。它专门用于在监控器中安全保存密钥,其核心承诺是:密钥在数据库中加密存储,且只有探针(Probe)在执行监控时能够读取。
创建密钥
创建路径:OneUptime Dashboard -> Monitors -> Settings -> Secrets -> Create Monitor Secret。
创建时你可以选择哪些监控器有权访问该密钥(例如添加一个名为ApiKey的密钥,并勾选需要它的监控器)。一个密钥可以同时授权给多个监控器,未授权的监控器脚本无法读取它。
请注意:密钥是加密后安全存储的。一旦保存,你无法再查看或更新它的值;如果丢失,只能重新创建一个新密钥。
这一点在数据模型中有明确体现:查看 MonitorSecret.ts,secretValue字段标注了encrypted: true;其描述明确写着「This value will be encrypted and only accessible by the probe.」(该值将被加密,且只有探针可访问)。同时密钥与监控器之间通过@ManyToMany关联(monitors字段),实现了细粒度的访问授权(见 MonitorSecret.ts)。
在脚本中使用密钥
在脚本上下文中,通过monitorSecrets对象访问已授权给当前监控器的密钥。注意按类型处理引号:
// 字符串类型的密钥需要包在引号里 let stringSecret = '{{monitorSecrets.StringSecret}}'; // number 或 boolean 类型可以直接使用 let numberSecret = {{monitorSecrets.NumberSecret}}; // boolean 类型同样直接使用 let booleanSecret = {{monitorSecrets.BooleanSecret}}; // 也可以 console.log 出来确认是否获取正确 console.log(stringSecret);要点:monitorSecrets是脚本模板层的占位符机制,运行时会把密钥实际值注入到对应位置。字符串型密钥必须加引号,否则会变成裸标识符导致语法错误。
采集自定义指标:oneuptime.captureMetric()
脚本运行中产生的业务数值(响应延迟、队列深度、库存余量等)可以通过oneuptime.captureMetric()上报为自定义指标,随后在 OneUptime 的Metric Explorer(指标浏览器)中绘图、加入仪表盘图表、配置告警。
函数签名
oneuptime.captureMetric(name, value, attributes);| 参数 | 类型 | 说明 |
|---|---|---|
name | string(必填) | 指标名称,例如"api.response.time"。上报后会自动加上custom.monitor.前缀存储 |
value | number(必填) | 指标的数值 |
attributes | object(可选) | 附加上下文的键值对;string、number、boolean 类型会被记录(number 与 boolean 会以文本形式存储,因为指标属性是维度而非度量),其他类型一律忽略 |
完整示例
const response = await axios.get("https://api.example.com/health"); // 采集一个简单指标 oneuptime.captureMetric("api.response.time", response.data.latency); // 带属性的指标 oneuptime.captureMetric("api.queue.depth", response.data.queueDepth, { region: "us-east-1", environment: "production", }); return { data: response.data, };采集完成后,这些指标会以custom.monitor.api.response.time这样的名字出现在 Metric Explorer 中。你可以把它们加入仪表盘图表、配置告警,并按监控器、探针或你提供的任意自定义属性进行过滤。
限制与保留属性键
采集自定义指标时受以下硬性限制约束(同样可以在 WorkerBootstrap.ts 的captureMetric实现中逐一验证):
- 每次脚本执行最多采集100 个指标;
- 指标名称长度上限200 个字符;
- 值必须是数字(非有限数会被直接丢弃);
- 每个指标最多50 个属性;
- 属性键上限200 个字符,属性值上限1000 个字符。
保留属性键(Reserved attribute keys):以下属性名属于 OneUptime 自身所有,脚本不能写入。如果脚本尝试设置,该属性会被丢弃(指标本身仍会记录),同时一条指明该键名的告警会被写入 OneUptime 服务器日志:
- 监控器身份:
monitorId、projectId、monitorName、probeName、probeId、isCustomMetric; oneuptime.与resource.命名空间下的所有内容——这些承载 OneUptime 在摄取时打上的标识符;- 资源身份属性:
service.name、host.name、k8s.cluster.name、iot.fleet.name、proxmox.cluster.name、vmware.vcenter.name、ceph.cluster.name、docker.swarm.cluster.name。
禁止覆盖这些键的原因在于:它们不只是标签,OneUptime 会把这些键读作「该数据点属于哪个资源」的声明。例如,一个被标记为service.name: payments-api的指标会出现在该服务的 Metrics 标签页上;如果你后续再基于service.name构建指标监控器,它的告警会关联到该服务、分页通知该服务负责人,并且在该服务的维护窗口期间保持静默。因此,如果想把监控器与某个服务或主机关联,请使用监控器自身的标签(labels),而不是在指标属性里伪造资源身份。
脚本中可用的模块
官方文档明确列出了脚本内置的模块能力:
axios:基于 Promise 的 HTTP 客户端,用于发起 HTTP 请求。源码中它在沙箱内通过 RPC 桥接到探针宿主实现(见 WorkerBootstrap.ts),支持get/post/put/patch/delete/head/options以及axios.create()自定义实例;crypto:Node.js 内置加密模块的沙箱化子集,提供哈希、HMAC、签名/验签等能力。注意沙箱实现(createCryptoFacade)仅开放 SHA-256 相关的createHash/createHmac以及randomBytes/randomInt/randomUUID,使用其他算法会抛出错误;console.log:向控制台输出日志,便于调试;oneuptime.captureMetric:采集自定义指标,见上文;http:Node.js 内置 HTTP 客户端模块(沙箱化实现,http.get/http.request);https:Node.js 内置 HTTPS 客户端模块(沙箱化实现,https.get/https.request)。
除上述模块外,脚本是标准的 JavaScript 脚本,你可以使用全部 JavaScript 语言特性(async/await、解构、Map/Set、正则、Buffer等),但必须运行在沙箱授予的能力范围内。
调试与注意事项
- 查看日志:脚本中的
console.log输出会出现在监控器的日志区域(Probes -> View Logs)。遇到脚本报错时,先看这里; - 返回值:使用
return语句返回数据,返回值会作为本次监控执行结果被记录与展示; - 超时:脚本整体超时时间为2 分钟,超时会被终止。对外部 API 的请求请自行设置超时;
- 数据量限制:注意 100 个指标/次、1 MB 请求负载、5 MB 返回结果、1 MB 日志等沙箱配额,避免脚本因数据过大被判定失败;
- 不要使用被屏蔽的能力:
fetch、XMLHttpRequest、WebSocket、importScripts等在沙箱中被显式禁用,一律改用axios/http/https; - 密钥安全:不要在脚本中硬编码密钥,也不要
console.log打印真实密钥到日志,请统一使用monitorSecrets,并注意字符串型密钥的引号包裹。
结语
Custom Code Monitor 把「监控」从固定的单次请求扩展为任意可编程逻辑,配合 Monitor Secrets 的安全密钥注入与oneuptime.captureMetric()的自定义指标上报,能够覆盖多步鉴权 API、复杂业务断言、自定义业务指标等真实场景。编写脚本时牢记沙箱能力边界、2 分钟超时与 100 指标/次的配额,并遵守保留属性键约定,即可稳定地把它纳入你的监控与告警体系。
- 可观测性
- 后端
- 运维
- 前端
- 云原生
- 微服务
- AI Agent
【免费下载链接】oneuptime
Complete open-source monitoring and observability platform.
相关推荐
OneUptime 自定义代码监控器(Custom Code Monitor)完全指南:脚本化监控、Monitor Secrets 与自定义指标
OneUptime 自定义代码监控器(Custom Code Monitor)完全指南:脚本化监控、Monitor Secrets 与自定义指标 自定义代码监控
可观测性后端运维前端云原生微服务AI AgentOneUptime 自定义代码监控器(Custom Code Monitor)完全指南:脚本、密钥与自定义指标实战
OneUptime 自定义代码监控器(Custom Code Monitor)完全指南:脚本、密钥与自定义指标实战 自定义代码监控器(Custom Code M
可观测性后端运维前端云原生微服务AI AgentOneUptime 自定义代码监控器(Custom Code Monitor)实战指南:脚本编写、安全密钥与自定义指标采集
OneUptime 自定义代码监控器(Custom Code Monitor)实战指南:脚本编写、安全密钥与自定义指标采集 自定义代码监控器(Custom Co
可观测性后端运维前端云原生微服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考