diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 73f5a3d..817eadd 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -16,7 +16,7 @@ jobs: {os: "macos-latest", arch: "x64"}, {os: "ubuntu-latest", arch: "x64"}, ] - node-version: [ 12, 14, 16, 18, 20, 21, 22 ] + node-version: [ 18, 20, 22 ] steps: - name: Set up Python uses: actions/setup-python@v4 diff --git a/README.md b/README.md index 5bd5580..bc92239 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Easy-Monitor v3.0 Node.js Runtime 插件,输出性能日志,并且可以进行实时的运行时状态采样。 -点击访问 [控制台 Demo](http://www.devtoolx.com/easy-monitor) 进行体验,完整的性能监控部署文档:https://www.yuque.com/hyj1991/easy-monitor +点击访问 [控制台 Demo](http://www.devtoolx.com/easy-monitor) 进行体验,完整的性能监控部署文档: ## 兼容性 @@ -18,24 +18,16 @@ xprofiler 插件支持三大主流操作系统: - Linux (x64 / arm64) - macosX (x64 / arm64) -支持的 node.js runtime 版本: +支持的 Node.js runtime 版本: -- v12.x -- v13.x -- v14.x -- v15.x -- v16.x -- v17.x - v18.x -- v19.x - v20.x -- v21.x - v22.x -更低的版本因为在此项目创建时已经不在官方 LTS 计划中,故正常情况下不再支持。 - -需要在 `node-v12.x` 以下的版本中使用,可以使用 `v1.x-staging` 分支的的最新版本:[1.4.0](https://github.com/X-Profiler/xprofiler/tree/v1.x-staging) +更低的版本已经不在 Node.js 官方 LTS 计划中,故正常情况下不再支持。 +- 需要在 `node-v16.x` 以下的版本中使用,可以使用 `2.x` 分支的的最新版本: +- 需要在 `node-v12.x` 以下的版本中使用,可以使用 `1.x` 分支的的最新版本:[1.4.0](https://github.com/X-Profiler/xprofiler/tree/v1.x-staging) ## 快速开始 @@ -47,10 +39,10 @@ xprofiler 插件支持三大主流操作系统: npm i xprofiler --save --xprofiler_binary_host_mirror=https://npmmirror.com/mirrors/xprofiler ``` -如果 npmmirror 镜像暂时没同步的话,也可以执行阿里云镜像: +如果 npmmirror 镜像暂时没同步的话,也可以从 GitHub Releases 下载: ```bash -npm i xprofiler --save --xprofiler_binary_host_mirror=http://devtoolx.com/xprofiler +npm i xprofiler --save ``` > 这里使用了 `@mapbox/node-pre-gyp` 帮助开发者无需进行本地编译即可使用此插件,默认插件位于 [Github Release](https://github.com/X-Profiler/xprofiler/releases) 页面,国内访问可能较慢,你也可以自行镜像到其它位置加速安装。 @@ -74,45 +66,41 @@ require('xprofiler')(); 本插件提供方以下的可配置参数: -* **log_dir**: 内核输出日志和性能文件的目录,默认为 `os.tmpdir()` -* **log_interval**: 内核对性能日志采样的时间间隔,默认为 `60s` -* **log_level**: 输出日志信息级别,0 info,1 error,2 debug,默认只输出 info 和 error 日志,默认为 `1` -* **log_type**: 日志输出位置,0 文件,1 控制台,默认为 `0` -* **log_format_alinode**: 是否以 Node.js 性能平台(原 AliNode)的格式输出性能分析日志,默认为 `false` -* **patch_http**: 是否对原生 http 模块进行 patch,输出 http 请求相关信息,默认 `true` -* **patch_http_with_diagnostics_channel**: 是否对通过 diagnostics_channel 模块进行 patch,输出 http 请求相关信息,在 esm 下需要开启,默认 `false` -* **patch_http_timeout**: 默认 http 请求超时时间,单位秒,作为 http 请求统计,默认 `30` -* **check_throw**: `xprofiler` 启动时检测错误时是否需要 throw,默认 `true` -* **auto_incr_heap_limit_size**: `enable_auto_incr_heap_limit` 开启后,每次自动增加的堆上限大小,默认为 `256` (MB) -* **enable_log_uv_handles**: 是否要采集 libuv 句柄的详细分类信息,比如 tcp 句柄数量,timers 数量,文件句柄数量等,默认为 `true` -* **enable_fatal_error_hook**: 是否需要在 V8 出现 FatalError 时配置钩子,默认 `true` -* **enable_fatal_error_report**: 是否需要在 V8 出现 FataLError 时导出 Report 文件,默认 `true` -* **enable_fatal_error_coredump**: 是否需要在 V8 出现 FataLError 时 Coredump,默认 `false` -* **enable_http_profiling**: 是否需要 CPU 采样时进行 HTTP Profiling。默认 `false` -* **enable_auto_incr_heap_limit**: 是否需要在 Node.js 进程达到堆上限时自动增加堆上限防止 OOM,默认 `false` - +- **log_dir**: 内核输出日志和性能文件的目录,默认为 `os.tmpdir()` +- **log_interval**: 内核对性能日志采样的时间间隔,默认为 `60s` +- **log_level**: 输出日志信息级别,0 info,1 error,2 debug,默认只输出 info 和 error 日志,默认为 `1` +- **log_type**: 日志输出位置,0 文件,1 控制台,默认为 `0` +- **log_format_alinode**: 是否以 Node.js 性能平台(原 AliNode)的格式输出性能分析日志,默认为 `false` +- **patch_http**: 是否对原生 http 模块进行 patch,输出 http 请求相关信息,默认 `true` +- **patch_http_timeout**: 默认 http 请求超时时间,单位秒,作为 http 请求统计,默认 `30` +- **check_throw**: `xprofiler` 启动时检测错误时是否需要 throw,默认 `true` +- **auto_incr_heap_limit_size**: `enable_auto_incr_heap_limit` 开启后,每次自动增加的堆上限大小,默认为 `256` (MB) +- **enable_log_uv_handles**: 是否要采集 libuv 句柄的详细分类信息,比如 tcp 句柄数量,timers 数量,文件句柄数量等,默认为 `true` +- **enable_fatal_error_hook**: 是否需要在 V8 出现 FatalError 时配置钩子,默认 `true` +- **enable_fatal_error_report**: 是否需要在 V8 出现 FataLError 时导出 Report 文件,默认 `true` +- **enable_fatal_error_coredump**: 是否需要在 V8 出现 FataLError 时 Coredump,默认 `false` +- **enable_http_profiling**: 是否需要 CPU 采样时进行 HTTP Profiling。默认 `false` +- **enable_auto_incr_heap_limit**: 是否需要在 Node.js 进程达到堆上限时自动增加堆上限防止 OOM,默认 `false` 您可以通过环境变量或者在 JavaScript 代码中引入插件时传入配置的方式来使用这些配置,具体如下所示: #### 1. 环境变量配置 -* **XPROFILER_LOG_DIR**: 其值为 String,覆盖 `log_dir` -* **XPROFILER_LOG_INTERVAL**: 其值为 Number,覆盖 `log_interval` -* **XPROFILER_LOG_LEVEL**: 其值为 String,覆盖 `log_level` -* **XPROFILER_LOG_TYPE**: 其值为 String,覆盖 `log_type` -* **XPROFILER_LOG_FORMAT_ALINODE**: 其值为 YES/NO,覆盖 `log_format_alinode` -* **XPROFILER_PATCH_HTTP**: 其值为 YES/NO,覆盖 `patch_http` -* **XPROFILER_PATCH_HTTP_WITH_DIAGNOSTICS_CHANNEL**: 其值为 YES/NO,覆盖 `patch_http_with_diagnostics_channel` -* **XPROFILER_PATCH_HTTP_TIMEOUT**: 其值为 String,覆盖 `patch_http_timeout` -* **XPROFILER_CHECK_THROW**: 其值为 YES/NO 覆盖 `check_throw` -* **XPROFILER_AUTO_INCR_HEAP_LIMIT_SIZE**: 其值为 String 覆盖 `auto_incr_heap_limit_size` -* **XPROFILER_ENABLE_LOG_UV_HANDLES**: 其值为 YES/NO,覆盖 `enable_log_uv_handles` -* **XPROFILER_ENABLE_FATAL_ERROR_HOOK**: 其值为 YES/NO,覆盖 `enable_fatal_error_hook` -* **XPROFILER_ENABLE_FATAL_ERROR_REPORT**: 其值为 YES/NO,覆盖 `enable_fatal_error_report` -* **XPROFILER_ENABLE_FATAL_ERROR_COREDUMP**: 其值为 YES/NO,覆盖 `enable_fatal_error_coredump` -* **XPROFILER_ENABLE_HTTP_PROFILING**: 其值为 YES/NO,覆盖 `enable_http_profiling` -* **XPROFILER_ENABLE_AUTO_INCR_HEAP_LIMIT**: 其值为 YES/NO 覆盖 `enable_auto_incr_heap_limit` - +- **XPROFILER_LOG_DIR**: 其值为 String,覆盖 `log_dir` +- **XPROFILER_LOG_INTERVAL**: 其值为 Number,覆盖 `log_interval` +- **XPROFILER_LOG_LEVEL**: 其值为 String,覆盖 `log_level` +- **XPROFILER_LOG_TYPE**: 其值为 String,覆盖 `log_type` +- **XPROFILER_LOG_FORMAT_ALINODE**: 其值为 YES/NO,覆盖 `log_format_alinode` +- **XPROFILER_PATCH_HTTP**: 其值为 YES/NO,覆盖 `patch_http` +- **XPROFILER_PATCH_HTTP_TIMEOUT**: 其值为 String,覆盖 `patch_http_timeout` +- **XPROFILER_CHECK_THROW**: 其值为 YES/NO 覆盖 `check_throw` +- **XPROFILER_AUTO_INCR_HEAP_LIMIT_SIZE**: 其值为 String 覆盖 `auto_incr_heap_limit_size` +- **XPROFILER_ENABLE_LOG_UV_HANDLES**: 其值为 YES/NO,覆盖 `enable_log_uv_handles` +- **XPROFILER_ENABLE_FATAL_ERROR_HOOK**: 其值为 YES/NO,覆盖 `enable_fatal_error_hook` +- **XPROFILER_ENABLE_FATAL_ERROR_REPORT**: 其值为 YES/NO,覆盖 `enable_fatal_error_report` +- **XPROFILER_ENABLE_FATAL_ERROR_COREDUMP**: 其值为 YES/NO,覆盖 `enable_fatal_error_coredump` +- **XPROFILER_ENABLE_HTTP_PROFILING**: 其值为 YES/NO,覆盖 `enable_http_profiling` +- **XPROFILER_ENABLE_AUTO_INCR_HEAP_LIMIT**: 其值为 YES/NO 覆盖 `enable_auto_incr_heap_limit` #### 2. 引入插件时传入配置 @@ -140,7 +128,6 @@ const defaultConfig = { log_type: 0, log_format_alinode: false, patch_http: true, - patch_http_with_diagnostics_channel: false, patch_http_timeout: 30, // seconds, check_throw: true, auto_incr_heap_limit_size: 128 // MB, @@ -161,14 +148,14 @@ const xprofilerConfig = Object.assign({}, defaultConfig, envConfig, userConfig); 本插件按照固定的格式来输出性能分析日志,但是也目前为了兼容已有的 alinode 运行时日志,提供了对 alinode 的支持,通过 `log_format_alinode: true` 配置或者 `XPROFILER_LOG_FORMAT_ALINODE=YES` 环境变量来启用 alinode 日志。两种日志文件名区别如下: -* 默认 xprofiler 日志文件名称 - * info 日志:xprofiler-${YYYYMMDD}.log - * error 日志:xprofiler-error-${YYYYMMDD}.log - * debug 日志:xprofiler-debug-${YYYYMMDD}.log -* 以 alinode 方式输出日志文件名称 - * info 日志:node-${YYYYMMDD}.log - * error 日志:node-error-${YYYYMMDD}.log - * debug 日志:node-debug-${YYYYMMDD}.log +- 默认 xprofiler 日志文件名称 + - info 日志:xprofiler-${YYYYMMDD}.log + - error 日志:xprofiler-error-${YYYYMMDD}.log + - debug 日志:xprofiler-debug-${YYYYMMDD}.log +- 以 alinode 方式输出日志文件名称 + - info 日志:node-${YYYYMMDD}.log + - error 日志:node-error-${YYYYMMDD}.log + - debug 日志:node-debug-${YYYYMMDD}.log 默认的 xprofiler 和 alinode 两种日志的主要区别在日志前缀上(当然输出的部分内容也不尽相同),其中 xprofiler 日志前缀如下: @@ -231,16 +218,14 @@ xprofctl -p [-w ] [-t profiling_time] copyright 2019 ``` - ## 插件架构和实现原理 参见 [文档 - 整体架构](https://www.yuque.com/hyj1991/easy-monitor/architecture) - ## 稳定性 -xprofiler 每个 commit 都会通过 github actions 进行在 windows/linux/macos 下的编译以及单元测试,如果您在使用中依旧出现意外的 crash,可以反馈到 [Issue 列表](https://github.com/X-Profiler/xprofiler/issues) 进行跟踪处理。 - +xprofiler 每个 commit 都会通过 github actions 进行在 windows/linux/macos 下的编译以及单元测试, +如果您在使用中依旧出现意外的 crash,可以反馈到 [Issue 列表](https://github.com/X-Profiler/xprofiler/issues) 进行跟踪处理。 ## 测试与代码覆盖率 @@ -252,19 +237,17 @@ npm run cov master 分支的代码覆盖率情况可以参见 [codecov badge](https://codecov.io/gh/X-Profiler/xprofiler/branch/master)。 - ## 如何参与贡献 -* fork 本仓库至你自己的 github 仓库列表中 -* clone 你 fork 出来的仓库至本地开发 -* 进行本地开发,添加功能或者修改 bug,并且附上必要的测试 -* 请在 commit 中描述下添加的功能或者修改 bug 的详细信息,并提交至你的远程仓库 -* 在 [PR](https://github.com/X-Profiler/xprofiler/pulls) 页面选择 New Pull Request,继续选择 compare across forks,在列表中选中你的 Fork,然后创建新的 PR -* 查看 pr 下的 travis/appveypr CI 状态,如果执行失败请到对应页面查看失败原因并在你自己的仓库下进行修复,修复 commit 会自动同步到此 pr 下,无需关闭重启发起 +- fork 本仓库至你自己的 github 仓库列表中 +- clone 你 fork 出来的仓库至本地开发 +- 进行本地开发,添加功能或者修改 bug,并且附上必要的测试 +- 请在 commit 中描述下添加的功能或者修改 bug 的详细信息,并提交至你的远程仓库 +- 在 [PR](https://github.com/X-Profiler/xprofiler/pulls) 页面选择 New Pull Request,继续选择 compare across forks,在列表中选中你的 Fork,然后创建新的 PR +- 查看 pr 下的 GitHub Action CI 状态,如果执行失败请到对应页面查看失败原因并在你自己的仓库下进行修复,修复 commit 会自动同步到此 pr 下,无需关闭重启发起 我们将在 review 后选择合并至本仓库内,贡献者也会加入到本项目的协作者列表中。 - ## 贡献者 [![contributors](https://contrib.rocks/image?repo=x-profiler/xprofiler&max=240&columns=26)](https://github.com/x-profiler/xprofiler/graphs/contributors) diff --git a/configuration.js b/configuration.js index 4950749..d73a492 100644 --- a/configuration.js +++ b/configuration.js @@ -42,15 +42,6 @@ module.exports = () => { ...config('patch_http', 'XPROFILER_PATCH_HTTP', 'boolean', true), }, - { - ...xprofctl(false), - ...config('patch_http_with_diagnostics_channel', - 'XPROFILER_PATCH_HTTP_WITH_DIAGNOSTICS_CHANNEL', - 'boolean', - false, - ), - }, - { ...xprofctl(false), ...config('patch_http_timeout', 'XPROFILER_PATCH_HTTP_TIMEOUT', 'number', 30), // seconds diff --git a/index.d.ts b/index.d.ts index 308d26e..48305d7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,7 +8,6 @@ export interface XprofilerConfig { log_format_alinode?: boolean; enable_log_uv_handles?: boolean; patch_http?: boolean; - patch_http_with_diagnostics_channel?: boolean; patch_http_timeout?: number; check_throw?: boolean; auto_incr_heap_limit_size?: number; diff --git a/package.json b/package.json index 0f5e28a..c8f8979 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,9 @@ { "name": "xprofiler", "version": "2.6.1", + "engines": { + "node": ">=18.19.0" + }, "description": "node.js addon to output runtime logs", "bin": { "xprofctl": "bin/xprofctl" diff --git a/patch/http.js b/patch/http.js index fd9c804..af191e4 100644 --- a/patch/http.js +++ b/patch/http.js @@ -1,9 +1,5 @@ 'use strict'; -const shimmer = require('./shimmer'); -const http = require('http'); -const https = require('https'); - const httpConfig = { http_detail_profiling: false, start_time: 0, @@ -16,71 +12,6 @@ function getRequestDetail(req, res, start, sent) { return `${offset},${url},${req.method},${sent},${res.statusCode},${rt}`; } -function requestListenerWrapper(original, methods) { - const { setHttpConfig, addLiveRequest, addCloseRequest, addSentRequest, - addRequestTimeout, addHttpStatusCode, addHttpProfilingDetail, patch_http_timeout } = methods; - - setHttpConfig(httpConfig); - - return function (req, res) { - addLiveRequest(); - - const start = Date.now(); - - const timer = setTimeout(() => { - addRequestTimeout(); - if (httpConfig.http_detail_profiling) { - const detail = getRequestDetail(req, res, start, 0); - addHttpProfilingDetail(detail); - } - }, patch_http_timeout * 1000); - timer.unref(); - - res.on('finish', () => { - addHttpStatusCode(res.statusCode); - addSentRequest(Date.now() - start); - clearTimeout(timer); - if (httpConfig.http_detail_profiling) { - const detail = getRequestDetail(req, res, start, 1); - addHttpProfilingDetail(detail); - } - }); - - res.on('close', () => { - addCloseRequest(); - clearTimeout(timer); - }); - - // call origin function - const returned = original.apply(this, arguments); - return returned; - }; -} - -function serverWrapper(methods, original) { - return function (opts, requestListener) { - const args = Array.from(arguments); - let returned; - - if (typeof opts === 'function') { - args.splice(0, 1, requestListenerWrapper(opts, methods)); - } else if (typeof requestListener === 'function') { - args.splice(1, 1, requestListenerWrapper(requestListener, methods)); - } - - returned = original.apply(this, args); - - return returned; - }; -} - -function patchHttp(methods) { - // patch http server - shimmer.wrap(http, 'createServer', serverWrapper.bind(this, methods)); - // patch https server - shimmer.wrap(https, 'createServer', serverWrapper.bind(this, methods)); -} - let _onHttpServerRequestStart; function subscribeHttpServerRequestStart(options) { const { setHttpConfig, addLiveRequest, addCloseRequest, addSentRequest, @@ -134,4 +65,4 @@ function unsubscribeHttpServerRequestStart() { diagnosticsChannel.unsubscribe('http.server.request.start', _onHttpServerRequestStart); } -module.exports = { patchHttp, subscribeHttpServerRequestStart, unsubscribeHttpServerRequestStart }; +module.exports = { subscribeHttpServerRequestStart, unsubscribeHttpServerRequestStart }; diff --git a/patch/index.js b/patch/index.js index da8f794..0942d2e 100644 --- a/patch/index.js +++ b/patch/index.js @@ -1,15 +1,11 @@ 'use strict'; -const { patchHttp, subscribeHttpServerRequestStart } = require('./http'); +const { subscribeHttpServerRequestStart } = require('./http'); function patch(config, methods) { if (config.patch_http) { const options = { ...methods, patch_http_timeout: config.patch_http_timeout }; - if (config.patch_http_with_diagnostics_channel) { - subscribeHttpServerRequestStart(options); - } else { - patchHttp(options); - } + subscribeHttpServerRequestStart(options); } } diff --git a/test/fixtures/cases/command.js b/test/fixtures/cases/command.js index 8abee37..e0a7534 100644 --- a/test/fixtures/cases/command.js +++ b/test/fixtures/cases/command.js @@ -228,7 +228,6 @@ exports = module.exports = function (logdir) { { key: 'data.log_level', rule: /^2$/ }, { key: 'data.log_type', rule: /^1$/ }, { key: 'data.patch_http', rule: { label: 'true', test: value => value === true } }, - { key: 'data.patch_http_with_diagnostics_channel', rule: { label: 'false', test: value => value === false } }, { key: 'data.patch_http_timeout', rule: /^30$/ }, { key: 'data.check_throw', rule: { label: 'false', test: value => value === false } }, { key: 'data.auto_incr_heap_limit_size', rule: /^256$/ }, @@ -258,8 +257,7 @@ exports = module.exports = function (logdir) { + ' - log_type: 1\n' + ' - m_mmap_threshold: 128\n' + ' - patch_http: true\n' - + ' - patch_http_timeout: 30\n' - + ' - patch_http_with_diagnostics_channel: false') + + ' - patch_http_timeout: 30') ]; } }, diff --git a/test/fixtures/cases/config.js b/test/fixtures/cases/config.js index 2578da8..8ae3124 100644 --- a/test/fixtures/cases/config.js +++ b/test/fixtures/cases/config.js @@ -100,12 +100,6 @@ const configure = { envValue: 'NO', userValue: false }, - patch_http_with_diagnostics_channel: { - defaultValue: false, - envKey: 'XPROFILER_PATCH_HTTP_WITH_DIAGNOSTICS_CHANNEL', - envValue: 'YES', - userValue: true - }, patch_http_timeout: { defaultValue: 30, envKey: 'XPROFILER_PATCH_HTTP_TIMEOUT', diff --git a/test/fixtures/cases/logbypass.js b/test/fixtures/cases/logbypass.js index be8c6b2..a6d71da 100644 --- a/test/fixtures/cases/logbypass.js +++ b/test/fixtures/cases/logbypass.js @@ -135,7 +135,6 @@ function getTestCases(title, logdirBlocking, logdirNonBlocking, envConfig, struc const commonEnvConfig = Object.assign({}, process.env, { XPROFILER_LOG_INTERVAL: 1, XPROFILER_PATCH_HTTP_TIMEOUT: 1, - XPROFILER_PATCH_HTTP_WITH_DIAGNOSTICS_CHANNEL: 0, }); // common case config diff --git a/test/patch/http.test.js b/test/patch/http.test.js index 6808680..3af3be5 100644 --- a/test/patch/http.test.js +++ b/test/patch/http.test.js @@ -1,14 +1,12 @@ 'use strict'; const http = require('http'); -const EventEmitter = require('events').EventEmitter; -const mm = require('mm'); const expect = require('expect.js'); -const { patchHttp } = require('../../patch/http'); +const { subscribeHttpServerRequestStart, unsubscribeHttpServerRequestStart } = require('../../patch/http'); const status = {}; -describe(`patch http.createServer(cb)`, function () { +describe(`monitor http server request with diagnostics_channel`, function () { const requestTimes = 5; let triggerTimes = 0; @@ -41,58 +39,32 @@ describe(`patch http.createServer(cb)`, function () { } } - function mockCreateServer(opts, requestHandle) { - return new Promise(resolve => { - let times = 0; - const interval = setInterval(() => { - if (times < requestTimes) { - const request = new EventEmitter(); - const response = new EventEmitter(); - if (typeof opts === 'function') { - opts(request, response); - } else if (typeof requestHandle === 'function') { - requestHandle(request, response); - } - times++; - } else { - clearInterval(interval); - resolve(); - } - }, 100); - }); - } - before(async function () { - mm(http, 'createServer', mockCreateServer); - patchHttp({ setHttpConfig, addLiveRequest, addCloseRequest, addSentRequest, addHttpStatusCode }); - await http.createServer(function (request, response) { - triggerTimes++; - response.statusCode = 200; - response.emit('finish'); - response.emit('close'); + subscribeHttpServerRequestStart({ + setHttpConfig, + addLiveRequest, + addCloseRequest, + addSentRequest, + addHttpStatusCode, }); - - await http.createServer({}, function (request, response) { + const server = http.createServer(function (request, response) { triggerTimes++; response.statusCode = 200; - response.emit('finish'); - response.emit('close'); - }); - - await http.createServer({}, {}, function (request, response) { - triggerTimes++; - response.statusCode = 200; - response.emit('finish'); - response.emit('close'); + response.end(`hello world ${request.url}`); }); + server.listen(0); + const port = server.address().port; + const url = `http://localhost:${port}`; + for (let i = 0; i < requestTimes; i++) { + await new Promise((resolve) => { + http.get(url, resolve); + }); + } + server.close(); }); after(function () { - mm.restore(); - }); - - it('patch should be ok', function () { - expect(http.createServer).not.to.be(mockCreateServer); + unsubscribeHttpServerRequestStart(); }); it('http config.http_detail_profiling should be false', function () { @@ -103,23 +75,23 @@ describe(`patch http.createServer(cb)`, function () { expect(httpConfig.start_time).to.be(0); }); - it(`request handler should trigger ${requestTimes} * 2 times`, function () { - expect(triggerTimes).to.be(requestTimes * 2); + it(`request handler should trigger ${requestTimes} times`, function () { + expect(triggerTimes).to.be(requestTimes); }); - it(`live request shoule be ${requestTimes} * 2`, function () { - expect(liveRequest).to.be(requestTimes * 2); + it(`live request should be ${requestTimes}`, function () { + expect(liveRequest).to.be(requestTimes); }); - it(`close request shoule be ${requestTimes} * 2`, function () { - expect(closeRequest).to.be(requestTimes * 2); + it(`close request should be ${requestTimes}`, function () { + expect(closeRequest).to.be(requestTimes); }); - it(`sent request shoule be ${requestTimes} * 2`, function () { - expect(sentRequest).to.be(requestTimes * 2); + it(`sent request should be ${requestTimes}`, function () { + expect(sentRequest).to.be(requestTimes); }); - it(`count of http status code 200 should be ${requestTimes} * 2`, function () { - expect(status[200]).to.be(requestTimes * 2); + it(`count of http status code 200 should be ${requestTimes}`, function () { + expect(status[200]).to.be(requestTimes); }); -}); \ No newline at end of file +}); diff --git a/test/patch/http_with_diagnostics_channel.test.js b/test/patch/http_with_diagnostics_channel.test.js deleted file mode 100644 index b24ad19..0000000 --- a/test/patch/http_with_diagnostics_channel.test.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; - -const http = require('http'); -const expect = require('expect.js'); -const { subscribeHttpServerRequestStart, unsubscribeHttpServerRequestStart } = require('../../patch/http'); - -const status = {}; - -describe(`patch with diagnostics_channel`, function () { - const requestTimes = 5; - let triggerTimes = 0; - - let httpConfig = {}; - let liveRequest = 0; - let closeRequest = 0; - let sentRequest = 0; - - function setHttpConfig(config) { - httpConfig = config; - } - - function addLiveRequest() { - liveRequest++; - } - - function addCloseRequest() { - closeRequest++; - } - - function addSentRequest() { - sentRequest++; - } - - function addHttpStatusCode(code) { - if (status[code]) { - status[code]++; - } else { - status[code] = 1; - } - } - - before(async function () { - subscribeHttpServerRequestStart({ - setHttpConfig, - addLiveRequest, - addCloseRequest, - addSentRequest, - addHttpStatusCode, - }); - const server = http.createServer(function (request, response) { - triggerTimes++; - response.statusCode = 200; - response.end(`hello world ${request.url}`); - }); - server.listen(0); - const port = server.address().port; - const url = `http://localhost:${port}`; - for (let i = 0; i < requestTimes; i++) { - await new Promise((resolve) => { - http.get(url, resolve); - }); - } - server.close(); - }); - - after(function () { - unsubscribeHttpServerRequestStart(); - }); - - it('http config.http_detail_profiling should be false', function () { - expect(httpConfig.http_detail_profiling).to.be(false); - }); - - it('http config.start_time should be 0', function () { - expect(httpConfig.start_time).to.be(0); - }); - - it(`request handler should trigger ${requestTimes} times`, function () { - expect(triggerTimes).to.be(requestTimes); - }); - - it(`live request should be ${requestTimes}`, function () { - expect(liveRequest).to.be(requestTimes); - }); - - it(`close request should be ${requestTimes}`, function () { - expect(closeRequest).to.be(requestTimes); - }); - - it(`sent request should be ${requestTimes}`, function () { - expect(sentRequest).to.be(requestTimes); - }); - - it(`count of http status code 200 should be ${requestTimes}`, function () { - expect(status[200]).to.be(requestTimes); - }); -});