├── .eslintignore ├── .eslintrc ├── test ├── fixtures │ └── example │ │ ├── package.json │ │ ├── app │ │ ├── router.js │ │ └── controller │ │ │ └── home.js │ │ └── config │ │ └── config.default.js └── plugin.test.js ├── .gitignore ├── .github └── workflows │ ├── release.yml │ └── nodejs.yml ├── app.js ├── config └── config.default.js ├── CHANGELOG.md ├── package.json ├── LICENSE ├── agent.js └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1" 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | npm-debug.log 3 | node_modules/ 4 | coverage/ 5 | .idea/ 6 | run/ 7 | .DS_Store 8 | *.swp 9 | package-lock.json 10 | yarn-lock.json 11 | .vscode 12 | -------------------------------------------------------------------------------- /test/fixtures/example/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/example/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | 5 | exports.xtransit = { 6 | server: 'ws://127.0.0.1:9090', 7 | appId: '123456', 8 | appSecret: 'abc', 9 | logInterval: 1, 10 | checkThrow: false, 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/example/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | this.ctx.body = 'hi, ' + this.app.plugins.xtransit.name; 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | release: 9 | name: Node.js 10 | uses: X-Profiler/github-actions/.github/workflows/node-release.yml@master 11 | secrets: 12 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 13 | GIT_TOKEN: ${{ secrets.GIT_TOKEN }} 14 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | Job: 11 | name: Node.js 12 | uses: node-modules/github-actions/.github/workflows/node-test.yml@master 13 | with: 14 | os: 'ubuntu-latest, macos-latest, windows-latest' 15 | version: '18, 20, 22' 16 | test: 'npm run ci' 17 | secrets: 18 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 19 | -------------------------------------------------------------------------------- /test/plugin.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mock = require('egg-mock'); 4 | 5 | describe('test/plugin.test.js', () => { 6 | let app; 7 | before(() => { 8 | app = mock.app({ 9 | baseDir: 'example', 10 | }); 11 | return app.ready(); 12 | }); 13 | 14 | after(() => app.close()); 15 | afterEach(mock.restore); 16 | 17 | it('should GET /', () => { 18 | return app.httpRequest() 19 | .get('/') 20 | .expect('hi, xtransit') 21 | .expect(200); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const xprofiler = require('xprofiler'); 4 | const path = require('path'); 5 | 6 | class AppBootHook { 7 | constructor(app) { 8 | this.app = app; 9 | this.config = app.config; 10 | } 11 | 12 | configWillLoad() { 13 | // nodejs will handler absolute/relative 14 | let logDir = this.config.xtransit.logDir; 15 | logDir = path.resolve(this.config.logger.dir, logDir); 16 | this.config.xtransit.logDir = logDir; 17 | } 18 | 19 | configDidLoad() { 20 | xprofiler.start({ 21 | log_dir: this.config.xtransit.logDir, 22 | log_interval: this.config.xtransit.logInterval, 23 | check_throw: this.config.xtransit.checkThrow, 24 | }); 25 | } 26 | } 27 | 28 | module.exports = AppBootHook; 29 | -------------------------------------------------------------------------------- /config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = appInfo => { 6 | const config = {}; 7 | 8 | config.xtransit = { 9 | server: '', 10 | appId: '', 11 | appSecret: '', 12 | 13 | disks: [], 14 | errors: [ 15 | path.join(appInfo.root, `logs/${appInfo.pkg.name}/common-error.log`), 16 | path.join(appInfo.root, 'logs/stderr.log'), 17 | ], 18 | packages: [ 19 | path.join(appInfo.baseDir, 'package.json'), 20 | ], 21 | 22 | logDir: 'xprofiler', 23 | logInterval: undefined, 24 | ipMode: false, 25 | libMode: true, 26 | errexp: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/i, 27 | logger: undefined, 28 | checkThrow: true, 29 | }; 30 | 31 | return config; 32 | }; 33 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [3.0.0](https://github.com/X-Profiler/egg-xtransit/compare/v2.0.0...v3.0.0) (2025-03-10) 4 | 5 | 6 | ### ⚠ BREAKING CHANGES 7 | 8 | * drop Node.js < 18.19.0 support 9 | 10 | closes https://github.com/X-Profiler/egg-xtransit/issues/10 11 | 12 | ### Features 13 | 14 | * use xprofiler@3 ([#11](https://github.com/X-Profiler/egg-xtransit/issues/11)) ([19aba98](https://github.com/X-Profiler/egg-xtransit/commit/19aba98b72e7157c615d3877b4f3e993cf50aa1e)) 15 | 16 | 1.1.0 / 2020-06-11 17 | ================== 18 | 19 | **features** 20 | * [[`6e1a60e`](http://github.com/X-Profiler/egg-xtransit/commit/6e1a60e4c1862ea9cba1e2cd4cdf5b66ee6282be)] - feat: refactor (TZ | 天猪 <>),fatal: No names found, cannot describe anything. 21 | 22 | **others** 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-xtransit", 3 | "version": "3.0.0", 4 | "description": "egg-plugin for xtransit", 5 | "eggPlugin": { 6 | "name": "xtransit" 7 | }, 8 | "keywords": [ 9 | "egg", 10 | "eggPlugin", 11 | "egg-plugin" 12 | ], 13 | "dependencies": { 14 | "xprofiler": "^3.0.0", 15 | "xtransit": "^2.0.1" 16 | }, 17 | "devDependencies": { 18 | "assert-file": "^1.0.0", 19 | "egg": "3", 20 | "egg-bin": "6", 21 | "egg-mock": "^5.15.1", 22 | "eslint": "^7.5.0", 23 | "eslint-config-egg": "^8.0.1", 24 | "urllib": "^4.6.11" 25 | }, 26 | "engines": { 27 | "node": ">=18.19.0" 28 | }, 29 | "scripts": { 30 | "test": "npm run lint -- --fix && npm run test-local", 31 | "test-local": "egg-bin test", 32 | "cov": "egg-bin cov", 33 | "lint": "eslint .", 34 | "ci": "npm run lint && npm run cov" 35 | }, 36 | "files": [ 37 | "config", 38 | "agent.js", 39 | "app.js" 40 | ], 41 | "repository": { 42 | "type": "git", 43 | "url": "git+https://github.com/X-Profiler/egg-xtransit.git" 44 | }, 45 | "bugs": { 46 | "url": "https://github.com/X-Profiler/egg-xtransit/issues" 47 | }, 48 | "homepage": "https://github.com/X-Profiler/egg-xtransit#readme", 49 | "author": "hyj1991", 50 | "license": "MIT" 51 | } 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2020, X-Profiler 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const xtransit = require('xtransit'); 4 | const xprofiler = require('xprofiler'); 5 | const assert = require('assert'); 6 | const path = require('path'); 7 | const fs = require('fs'); 8 | 9 | class AgentBootHook { 10 | constructor(agent) { 11 | this.agent = agent; 12 | this.config = agent.config; 13 | } 14 | 15 | configWillLoad() { 16 | // nodejs will handler absolute/relative 17 | let logDir = this.config.xtransit.logDir; 18 | logDir = path.resolve(this.config.logger.dir, logDir); 19 | this.config.xtransit.logDir = logDir; 20 | 21 | /* istanbul ignore next */ 22 | if (!fs.existsSync(logDir)) { 23 | fs.mkdirSync(logDir, { recursive: true }); 24 | } 25 | } 26 | 27 | configDidLoad() { 28 | xprofiler.start({ 29 | log_dir: this.config.xtransit.logDir, 30 | log_interval: this.config.xtransit.logInterval, 31 | check_throw: this.config.xtransit.checkThrow, 32 | }); 33 | } 34 | 35 | async serverDidReady() { 36 | const { server, appId, appSecret } = this.config.xtransit; 37 | assert(server && appId && appSecret, 'xtransit config error, server, appId, appSecret must be passed in.'); 38 | 39 | // logger 40 | this.logger = {}; 41 | for (const method of [ 'info', 'warn', 'error', 'debug' ]) { 42 | this.logger[method] = (message, ...args) => { 43 | this.agent.logger[method](`[xtransit] ${message}`, ...args); 44 | }; 45 | } 46 | 47 | // start xtransit 48 | xtransit.start({ 49 | logger: this.logger, 50 | ...this.config.xtransit, 51 | }); 52 | this.logger.info('xtransit start.'); 53 | } 54 | } 55 | 56 | module.exports = AgentBootHook; 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # egg-xtransit 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | [![Known Vulnerabilities][snyk-image]][snyk-url] 5 | [![npm download][download-image]][download-url] 6 | [![Codecov branch](https://img.shields.io/codecov/c/github/X-Profiler/egg-xtransit/master)](https://codecov.io/gh/X-Profiler/egg-xtransit/branch/master) 7 | [![Continuous integration](https://github.com/X-Profiler/egg-xtransit/actions/workflows/nodejs.yml/badge.svg?branch=master)](https://github.com/X-Profiler/egg-xtransit/actions/workflows/nodejs.yml?query=branch:master) 8 | 9 | [npm-image]: https://img.shields.io/npm/v/egg-xtransit.svg?style=flat-square 10 | [npm-url]: https://npmjs.org/package/egg-xtransit 11 | [snyk-image]: https://snyk.io/test/npm/egg-xtransit/badge.svg?style=flat-square 12 | [snyk-url]: https://snyk.io/test/npm/egg-xtransit 13 | [download-image]: https://img.shields.io/npm/dm/egg-xtransit.svg?style=flat-square 14 | [download-url]: https://npmjs.org/package/egg-xtransit 15 | 16 | ## Install 17 | 18 | ```bash 19 | npm i --save egg-xtransit 20 | ``` 21 | 22 | ## Usage 23 | 24 | ```js 25 | // {app_root}/config/plugin.js 26 | exports.xtransit = { 27 | enable: true, 28 | package: 'egg-xtransit', 29 | }; 30 | ``` 31 | 32 | ## Configuration 33 | 34 | ```js 35 | // {app_root}/config/config.default.js 36 | exports.xtransit = { 37 | server: '', 38 | appId: '', 39 | appSecret: '' 40 | }; 41 | ``` 42 | 43 | see [config/config.default.js](config/config.default.js) for more detail. 44 | 45 | ## Questions & Suggestions 46 | 47 | Please open an issue [here](https://github.com/X-Profiler/egg-xtransit/issues). 48 | 49 | ## License 50 | 51 | [BSD-2-Clause](LICENSE) 52 | 53 | ## Contributors 54 | 55 | [![Contributors](https://contrib.rocks/image?repo=X-Profiler/egg-xtransit)](https://github.com/X-Profiler/egg-xtransit/graphs/contributors) 56 | 57 | Made with [contributors-img](https://contrib.rocks). 58 | --------------------------------------------------------------------------------