@arcblock/pm2.io

中文文档
6.1.2发布于 2025/07/22Apache-2TypeScriptESM + CJS近 30 天下载 2890

PM2.io 节点JS APM

中文使用文档
文档目录20 节
  1. V8 运行时计量
  2. 自定义计量
  3. 创建自定义衡量标准
  4. 度量衡:可变博览
  5. 计数器: 分解计数器
  6. 计量:频率
  7. 直方图:统计
  8. 曝光远程动作: 远程触发函数
  9. 简单动作
  10. 报告用户错误
  11. 分布式追踪
  12. 追踪到什么
  13. 自定义追踪 API
  14. 配置
  15. 全局配置对象
  16. 移徙指南
  17. 2.x至3.x (中文(简体) )
  18. 3.x至4.x (中文(简体) )
  19. 发展
  20. 页:1

这个 @pm2/io (英语) 模块与 PM2. PM2图书馆负责收集衡量标准,报告例外,曝光远程行动以及与您的应用程序的每一个互动.

如果您想要将您的节点进程连接到PM2 Entertainment,但无需与PM2启动应用程序,也可以将其作为独立的代理.

目录

安装

以 npm 为单位 :

npm install @pm2/io --save

用纱线:

yarn add @pm2/io

V8 运行时计量

默认获取 V8 运行时度量符, 如 :

安装 :

npm install @pm2/node-runtime-stats

然后重新启动应用程序 .

自定义计量

@pm2/io 允许您从您的代码中收集度量衡, 在 PM2 Plus/ Enterprise 仪表板中报告 .

创建自定义衡量标准

您可以用这种方法创建新的自定义度量标准 metric() 联 合 国 @pm2/io。 。 。 .

const io = require('@pm2/io');

const users = io.metric({
  name: 'Realtime user',
});
users.set(10)

这些论点有:

  • 名称: 公尺名( 需要; 字符串)
  • 编号: 度量衡类型(默认为"度量",字符串)
  • 单位: 计量单位( 默认 “; 字符串 )
  • 历史: 将历史保留在 PM2 Plus (默认: 真; 布尔)

衡量标准有4个不同类型:

  • 测量: 显示变量值
  • 计数器: 手动触发一个离散计数器,以计数若干起事件
  • 计数器: 为测量频率,每单位时间重复事件的次数
  • 直方图: 测量过去5分钟里的统计、度量衡

度量衡:可变博览

第一类衡量标准,称为 metric,允许披露变量值。 该变量可以被动地被曝光,其功能每秒都会被调用,或者主动地被调用一个方法来更新值.

活动模式

在活动模式下,您需要创建一个探测器并调用该方法 set() 以更新值.

const myMetric = io.metric({
  name: 'Realtime Value'
});

myMetric.set(23);

被动模式

在被动模式下, 您需要返回要监视的变量 :

const myMetric = io.metric({
  name: 'Realtime Value',
  value: () => {
    return variable_to_monitor
  }
});

计数器: 分解计数器

第二类衡量标准,称为 counter,是帮助您计算特定事件的发生次数的离散计数器。 计数器从0开始,可以递增或递减.

const io = require('@pm2/io');

const currentReq = io.counter({
  name: 'Current req processed',
  type: 'counter',
});

http.createServer((req, res) => {
  // Increment the counter, counter will eq 1
  currentReq.inc();
  req.on('end', () => {
    // Decrement the counter, counter will eq 0
    currentReq.dec();
  });
});

计量:频率

第三类衡量标准,称为 meter,计算一个事件的频率。 每当事件发生,你需要呼叫 mark() 方法。 默认情况下,频率是最后一分钟每秒事件的次数.

const io = require('@pm2/io');

const reqsec = io.meter({
  name: 'req/sec',
  type: 'meter',
});

http.createServer((req, res) => {
  reqsec.mark();
  res.end({ success: true });
});

其他选项 :

  • 样本: (可选) (默认:1) 比率单位。 默认为 1个 秒数.
  • 时限: (可选) (默认: 60) 分析事件的时间范围 。 默认为 页:1 秒数.

直方图:统计

收集价值并提供统计工具,以探索其过去5分钟的分布情况.

const io = require('@pm2/io');

const latency = io.histogram({
  name: 'latency',
  measurement: 'mean'
});

var latencyValue = 0;

setInterval(() => {
  latencyValue = Math.round(Math.random() * 100);
  latency.update(latencyValue);
}, 100);

选项是:

  • 计量 : 默认:指;分;分;最大;和;计;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相;相.

曝光远程动作: 远程触发函数

从 PM2 Plus 或 Entertainment 远程触发函数.

简单动作

该函数作为参数(cb)取出一个函数,任务完成后需要调用.

示例

const io = require('@pm2/io');

io.action('db:clean', (cb) => {
  clean.db(() => {
    // cb must be called at the end of the action
    return cb({ success: true });
  });
});

报告用户错误

默认情况下, 在“ 问题” 标签中, 您只被提醒未发现的例外 。 任何你抓到的例外都不报告 你可以手动报告 notifyError() 方法.

const io = require('@pm2/io');

io.notifyError(new Error('This is an error'), {
  // you can some http context that will be reported in the UI
  http: {
    url: req.url
  },
  // or anything that you can like an user id
  custom: {
    user: req.user.id
  }
});

快速错误报告

如果您想要配置您的快递中间软件, 可以用快递的错误中间软件自动发送错误 :

const io = require('@pm2/io')
const express = require('express')
const app = express()

// add the routes that you want
app.use('/toto', () => {
  throw new Error('ajdoijerr')
})

// always add the middleware as the last one
app.use(io.expressErrorHandler())

Koa 错误报告

也暴露出一个自定义的koa中间软件

const io = require('@pm2/io')
const Koa = require('koa')
const app = new Koa()

// the order isn't important with koa
app.use(pmx.koaErrorHandler())

// add the routes that you want
app.use(async ctx => {
  ctx.throw(new Error('toto'))
})

分布式追踪

分布式追踪允许通过您的系统捕捉并传播分布式的痕迹,使您可以直观地看到客户请求如何在服务间流动,迅速进行深层根源分析,并更好地分析在高度分布的一组服务之间的耐久性. 如果您想要启用, 请在此设置简单的选项以启用 :

const io = require('@pm2/io').init({
  tracing: {
    enabled: true,
    // will add the actual queries made to database, false by default
    detailedDatabasesCalls: true,
    // if you want you can ignore some endpoint based on their path
    ignoreIncomingPaths: [
      // can be a regex
      /misc/,
      // or a exact string
      '/api/bucket'
      // or a function with the request
      (url, request) => {
        return true
      }
    ],
    // same as above but used to match entire URLs
    ignoreOutgoingUrls: [],
    /**
     * Determines the probability of a request to be traced. Ranges from 0.0 to 1.0
     * default is 0.5
     */
    samplingRate: 0.5
  }
})

默认情况下, 我们忽略特定收到的请求( 您可以通过设置来覆盖此请求 ) ignoreIncomingPaths: []:

  • 与选择方案或头方法一起提出请求
  • 请求获取静态源代码( N)*.js, (中文(简体) ), *.css, (中文(简体) ), *.ico, (中文(简体) ), *.svg, (中文(简体) ), .png 或者说 *webpack*(中文(简体) )

追踪到什么

您的申请何时会收到申请 http, (中文(简体) ), https 或者说 http2 它会开始追踪 之后,我们将追踪以下模块:

  • http 发出请求
  • https 发出请求
  • http2 发出请求
  • mongodb-core 第1至3版,第1至3页
  • redis 版本 > 2.6
  • ioredis 版本 > 2.6
  • mysql 第1至3版,第1至3页
  • mysql2 第1至3版,第1至3页
  • pg 版本 > 6
  • vue-server-renderer 版本 2

自定义追踪 API

自定义跟踪 API 可用于创建自定义跟踪跨度. 跨度是追踪中的特定工作单位,如RPC请求. 斯班斯可能被筑巢;最外侧的跨度被称作"根地",即使没有筑巢的子地. 根间距一般与收到的请求相对应,而子间距一般与外出请求相对应,或因接来的请求而触发的其他活. 这意味着根间距不应该在已经存在根间距的上下文中创建;在这里,孩子间距更合适. 相反地,应当建立根跨来跟踪在请求生命周期之外完全发生的工作,例如定期排定的工作。 举例说明:

const io = require('@pm2/io').init({ tracing: true })
const tracer = io.getTracer()
// ...

app.get('/:token', function (req, res) {
  const token = req.params.token
  // the '2' correspond to the type of operation you want to trace
  // can be 0 (UNKNOWN), 1 (SERVER) or 2 (CLIENT)
  // 'verifyToken' here will be the name of the operation
  const customSpan = tracer.startChildSpan('verifyToken', 2)
  // note that customSpan can be null if you are not inside a request
  req.Token.verifyToken(token, (err, result) => {
    if (err) {
      // you can add tags to the span to attach more details to the span
      customSpan.addAttribute('error', err.message)
      customSpan.end()
      return res.status(500).send('error')
    }
    customSpan.addAttribute('result', result)
    // be sure to always .end() the spans
    customSpan.end()
    // redirect the user if the token is valid
    res.send('/user/me')
  })
})

// For any significant work done _outside_ of the request lifecycle, use
// startRootSpan.
const traceOptions = {
    name: 'my custom trace',
    // the '1' correspond to the type of operation you want to trace
    // can be 0 (UNKNOWN), 1 (SERVER) or 2 (CLIENT)
    kind: '1'
  }
plugin.tracer.startRootSpan(traceOptions, rootSpan => {
  // ...
  // Be sure to call rootSpan.end().
  rootSpan.end()
});

配置

全局配置对象

export class IOConfig {
  /**
   * Automatically catch unhandled errors
   */
  catchExceptions?: boolean = true
  /**
   * Configure the metrics to add automatically to your process
   */
  metrics?: {
    eventLoop: boolean = true,
    network: boolean = false,
    http: boolean = true,
    gc: boolean = true,
    v8: boolean = true
  }
  /**
   * Configure the default actions that you can run
   */
  actions?: {
    eventLoopDump?: boolean = true
  }
  /**
   * Configure availables profilers that will be exposed
   */
  profiling?: {
    /**
     * Toggle the CPU profiling actions
     */
    cpuJS: boolean = true
    /**
     * Toggle the heap snapshot actions
     */
    heapSnapshot: boolean = true
    /**
     * Toggle the heap sampling actions
     */
    heapSampling: boolean = true
    /**
     * Force a specific implementation of profiler
     *
     * available:
     *  - 'addon' (using the v8-profiler-node8 addon)
     *  - 'inspector' (using the "inspector" api from node core)
     *  - 'none' (disable the profilers)
     *  - 'both' (will try to use inspector and fallback on addon if available)
     */
    implementation: string = 'both'
  }
  /**
   * Configure the transaction tracing options
   */
  tracing?: {
    /**
     * Enabled the distributed tracing feature.
     */
    enabled: boolean
    /**
     * If you want to report a specific service name
     * the default is the same as in apmOptions
     */
    serviceName?: string
    /**
     * Generate trace for outgoing request that aren't connected to a incoming one
     * default is false
     */
    outbound?: boolean
    /**
     * Determines the probability of a request to be traced. Ranges from 0.0 to 1.0
     * default is 0.5
     */
    samplingRate?: number,
    /**
     * Add details about databases calls (redis, mongodb etc)
     */
    detailedDatabasesCalls?: boolean,
    /**
     * Ignore specific incoming request depending on their path
     */
    ignoreIncomingPaths?: Array<IgnoreMatcher<httpModule.IncomingMessage>>
    /**
     * Ignore specific outgoing request depending on their url
     */
    ignoreOutgoingUrls?: Array<IgnoreMatcher<httpModule.ClientRequest>>
    /**
     * Set to true when wanting to create span for raw TCP connection
     * instead of new http request
     */
    createSpanWithNet: boolean
  }
  /**
   * If you want to connect to PM2 Enterprise without using PM2, you should enable
   * the standalone mode
   *
   * default is false
   */
  standalone?: boolean = false
  /**
   * Define custom options for the standalone mode
   */
  apmOptions?: {
    /**
     * public key of the bucket to which the agent need to connect
     */
    publicKey: string
    /**
     * Secret key of the bucket to which the agent need to connect
     */
    secretKey: string
    /**
     * The name of the application/service that will be reported to PM2 Enterprise
     */
    appName: string
    /**
     * The name of the server as reported in PM2 Enterprise
     *
     * default is os.hostname()
     */
    serverName?: string
    /**
     * Broadcast all the logs from your application to our backend
     */
    sendLogs?: Boolean
    /**
     * Avoid to broadcast any logs from your application to our backend
     * Even if the sendLogs option set to false, you can still see some logs
     * when going to the log interface (it automatically trigger broacasting log)
     */
    disableLogs?: Boolean
    /**
     * Since logs can be forwared to our backend you may want to ignore specific
     * logs (containing sensitive data for example)
     */
    logFilter?: string | RegExp
    /**
     * Proxy URI to use when reaching internet
     * Supporting socks5,http,https,pac,socks4
     * see https://github.com/TooTallNate/node-proxy-agent
     *
     * example: socks5://username:[email protected]:9050
     */
    proxy?: string
  }
}

你可以通过任何选择 io.init,它将自动更新其配置.

移徙指南

2.x至3.x (中文(简体) )

在此列出断开更改列表 :

  • 删除 io.scopedAction 由于用户采用率低
  • 删除 io.notify 赞成: io.notifyError (调试器替换)
  • 删除支持 gc-stats 模块
  • 在使用配置器加通时删除了 Heap 剖析支持( 这根本不可能)
  • 移除了深度支持(这个模块可以将关于websocket/mongo的度量衡从盒子中取出),我们正在研究一个更好的解决方案.
  • 删除 io.transpose
  • 删除 io.probe() 输入参数
  • 改变配置结构

如果您使用自定义配置, 可能性很大 io.init,需要修改以反映新的配置. 除此之外,还有 io.notify 移除,它不应该打破你 即时测量的方式. 如果你找到别的东西,请告诉我们技术@ keymeters.io) (中文(简体) ).

3.x至4.x (中文(简体) )

与"4.x"版本的唯一区别在于所设置的新追踪系统,所以唯一一回相關:

  • 放弃了节点 4 的支持 (如果使用节点4, 您仍然可以使用3. x, 但是您无法访问分布式追踪)
  • 更改了追踪配置 (见上文备选方案)

发展

要在文件更改时自动重建 :

$ npm install
$ npm run watch

只测试一个文件 :

$ npm run unit <typescript-file-to-test.ts>

运行转接+测试+覆盖:

$ npm run test

只运行转接 + 测试 :

$ npm run unit <test>

页:1

这个软件包与 amqp 如果你使用 network 度量衡。 在此情况下, 我们建议禁用以下配置的度量衡 :

io.init({
  metrics: {
    network: false
  }
})

版本与发布记录

@arcblock/pm2.io 共发布 6 个版本,首次发布于 2024/06/16;过去 12 个月发布了 0 个版本。

版本发布日期距今
6.1.2latest2025/07/221.3 年前
6.1.2-beta-2025-07-22-21-32-842beta2025/07/221.3 年前
6.1.12025/07/221.3 年前
6.1.1-beta-2025-07-22-14-53-6802025/07/221.3 年前
6.0.12024/06/162 年前
6.0.1-beta-2024-06-16-16-01-4992024/06/162 年前

关于 @arcblock/pm2.io 的常见问题

@arcblock/pm2.io 是什么?

PM2.io 节点JS APM

如何安装 @arcblock/pm2.io?

在项目目录运行 npm install @arcblock/pm2.io,或使用 pnpm add / yarn add / bun add。

@arcblock/pm2.io 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@arcblock/pm2.io 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@arcblock/pm2.io 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=6.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@arcblock/pm2.io 可以商用吗?

@arcblock/pm2.io 使用 Apache-2 许可。声明的许可为 Apache-2,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@arcblock/pm2.io 的下载量有多少?

根据 npm 官方下载统计,@arcblock/pm2.io 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,890 次,日均约 96 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arcblock/pm2.io 还在维护吗?

最新版本 6.1.2 发布于 2025/07/22(1.3 年前);至今共发布 6 个版本,其中过去 12 个月发布了 0 个;首次发布于 2024/06/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。