diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f64cc8df..7fd7b528 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,27 @@ -# Contributing to TSW -Welcome to [report Issues](https://github.com/Tencent/TSW/issues) or [pull requests](https://github.com/Tencent/TSW/pulls). It's recommended to read the following Contributing Guide first before contributing. +# 为TSW做出贡献 +欢迎您 [提出问题](https://github.com/Tencent/TSW/issues) 或 [pull requests](https://github.com/Tencent/TSW/pulls), 建议您在为TSW做出贡献前先阅读以下TSW贡献指南。 ## Issues -We use Github Issues to track public bugs and feature requests. +我们通过Github Issues来收集问题和功能相关的需求。 -### Search Known Issues First -Please search the existing issues to see if any similar issue or feature request has already been filed. You should make sure your issue isn't redundant. +### 首先查看已知的问题 +在您准备提出问题以前,请先查看现有的Github Issues是否已有其他人提出过相似的功能或问题,以确保您提出的问题是有效的。 -### Reporting New Issues -If you open an issue, the more information the better. Such as detailed description, code blocks of your problem. +### 提交问题 +问题的表述应当尽可能的详细,可以包含相关的代码块。 ## Pull Requests -We strongly welcome your pull request to make TSW better. +我们期待您通过PR(Pull Requests)让TSW变的更加完善。 -### Branch Management -There are two main branches here: +### 分支管理 +仓库一共包含两个分支: -1. `master` branch. - 1. **Don't submit any PR on `master` branch.** -2. `dev` branch. - 1. It is our stable developing branch. After full testing, `dev` will be merged to `master` branch for the next release. - 2. **You are recommended to submit bugfix or feature PR on `dev` branch.** +1. `master` 分支 + 1. **请勿在master分支上提交任何PR。** +2. `dev` 分支 + 1. `dev`分支作为稳定的开发分支,经过测试后会在下一个版本合并到`master`分支。 + 2. **PR应该在`dev`分支上提交。** -Normal bugfix or feature request should be submitted to `dev` branch. After full testing, we will merge them to `master` branch for the next release. ``` master @@ -32,18 +31,17 @@ dev feature/bugfix PR ``` -### Make Pull Requests -The code team will monitor all pull request, we run some code check and test on it. After all tests passed, we will accecpt this PR. But it won't merge to `master` branch at once, which have some delay. +### PR流程 +TSW团队会查看所有的PR,我们会运行一些代码检查和测试,一经测试通过,我们会接受这次PR,但不会立即将代码合并到master分支上,会有一些延迟。 -Before submitting a pull request, please make sure the followings are done: +当您准备PR时,请确保已经完成以下几个步骤: -1. Fork the repo and create your branch from `master`. -2. Update code or documentation if you have changed APIs. -3. Add the copyright notice to the top of any new files you've added. -4. Check your code lints and checkstyles. -5. Test and test again your code. -6. Now, you can submit your pull request on `dev`. +1. 将仓库fork下来并且基于`dev`分支创建您的开发分支。 +2. 如果您更改了APIs请更新代码及文档。 +3. 在您添加的每一个新文件头部加上版权声明。 +4. 检查您的代码语法及格式。 +5. 反复测试。 +6. 现在,您可以开始在`dev`分支上PR了。 -## License -By contributing to TSW, you agree that your contributions will be licensed -under its [MIT LICENSE](https://github.com/Tencent/TSW/blob/master/LICENSE) \ No newline at end of file +## 许可证 +通过为TSW做出贡献,代表您同意将其版权归为TSW所有,TSW的开源协议为[MIT LICENSE](https://github.com/Tencent/TSW/blob/master/LICENSE) \ No newline at end of file diff --git a/CONTRIBUTING_en.md b/CONTRIBUTING_en.md new file mode 100644 index 00000000..19316db0 --- /dev/null +++ b/CONTRIBUTING_en.md @@ -0,0 +1,49 @@ +# Contributing to TSW +Welcome to [report Issues](https://github.com/Tencent/TSW/issues) or [pull requests](https://github.com/Tencent/TSW/pulls). It's recommended to read the following Contributing Guide first before contributing. + +## Issues +We use Github Issues to track public bugs and feature requests. + +### Search Known Issues First +Please search the existing issues to see if any similar issue or feature request has already been filed. You should make sure your issue isn't redundant. + +### Reporting New Issues +If you open an issue, the more information the better. Such as detailed description, code blocks of your problem. + +## Pull Requests +We strongly welcome your pull request to make TSW better. + +### Branch Management +There are two main branches here: + +1. `master` branch. + 1. **Don't submit any PR on `master` branch.** +2. `dev` branch. + 1. It is our stable developing branch. After full testing, `dev` will be merged to `master` branch for the next release. + 2. **You are recommended to submit bugfix or feature PR on `dev` branch.** + +Normal bugfix or feature request should be submitted to `dev` branch. After full testing, we will merge them to `master` branch for the next release. + +``` +master + ↑ +dev + ↑ +feature/bugfix PR +``` + +### Make Pull Requests +The code team will monitor all pull request, we run some code check and test on it. After all tests passed, we will accecpt this PR,But it won't merge to `master` branch at once, which have some delay. + +Before submitting a pull request, please make sure the followings are done: + +1. Fork the repo and create your branch from `dev`. +2. Update code or documentation if you have changed APIs. +3. Add the copyright notice to the top of any new files you've added. +4. Check your code lints and checkstyles. +5. Test and test again your code. +6. Now, you can submit your pull request on `dev`. + +## License +By contributing to TSW, you agree that your contributions will be licensed +under its [MIT LICENSE](https://github.com/Tencent/TSW/blob/master/LICENSE) \ No newline at end of file diff --git a/README_en.md b/README_en.md index d16a75dd..f68aadc0 100644 --- a/README_en.md +++ b/README_en.md @@ -69,7 +69,7 @@ docker run -v configure_dir:/data/release/node_modules -p 8080:80 tsw Find a bug or have a feature request? Please read the [issues](https://github.com/Tencent/TSW/issues) guidelines and search for existing and closed issues. -If your problem or idea is not addressed yet, please read through our [contributing guidelines](./CONTRIBUTING.md) and open a new [issues](https://github.com/Tencent/TSW/issues). +If your problem or idea is not addressed yet, please read through our [contributing guidelines](./CONTRIBUTING_en.md) and open a new [issues](https://github.com/Tencent/TSW/issues). ## License diff --git a/bin/proxy/admin.actions.js b/bin/proxy/admin.actions.js index 6c732483..30b9b093 100644 --- a/bin/proxy/admin.actions.js +++ b/bin/proxy/admin.actions.js @@ -26,6 +26,14 @@ module.exports = { res.end('done!\r\n'); }, + '/heapdump': function (req, res) { + process.emit('sendCmd2workerOnce', { + CMD: 'heapdump', + GET: req.GET + }); + res.writeHead(200, { 'Content-Type': 'text/plain; charset=UTF-8' }); + res.end('done!\r\n'); + }, '/profiler': function (req, res) { process.emit('sendCmd2workerOnce', { diff --git a/bin/proxy/config.js b/bin/proxy/config.js index b498d563..4bac0158 100644 --- a/bin/proxy/config.js +++ b/bin/proxy/config.js @@ -46,7 +46,7 @@ if (isFirstLoad) { if (fs.existsSync('/etc/tsw.config.js')) { - cache.config = require('/usr/local/node_modules/config.js'); + cache.config = require('/etc/tsw.config.js'); } else if (fs.existsSync('/usr/local/node_modules/config.js')) { cache.config = require('/usr/local/node_modules/config.js'); } else if (fs.existsSync('/data/release/node_modules/config.js')) { diff --git a/bin/proxy/dump.heap.sh b/bin/proxy/dump.heap.sh new file mode 100755 index 00000000..0012b1a2 --- /dev/null +++ b/bin/proxy/dump.heap.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +echo "begin heapdump" + +curl 127.0.0.1:12701/heapdump + + diff --git a/bin/proxy/http.proxy.js b/bin/proxy/http.proxy.js index b034a79e..da2c41ca 100644 --- a/bin/proxy/http.proxy.js +++ b/bin/proxy/http.proxy.js @@ -101,6 +101,11 @@ methodMap.reload = function() { process.emit('reload'); }; +// heapdump +methodMap.heapdump = function(message) { + process.emit('heapdump', message.GET); +}; + // profiler methodMap.profiler = function(message) { process.emit('profiler', message.GET); @@ -125,6 +130,24 @@ process.on('top100', function(e) { global.top100 = []; }); + +process.on('heapdump', function(e) { + if (isWin32Like) { + return; + } + + require('heapdump').writeSnapshot(__dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.heapsnapshot', function(err, filename) { + if (err) { + logger.error(`dump heap error ${err.message}`); + return; + } + logger.info('dump written to ${filename}', { + filename: filename + }); + }); +}); + + process.on('profiler', function(data = {}) { logger.info('profiler time: ${time}', data); if (isWin32Like) { @@ -177,10 +200,6 @@ function requestHandler(req, res) { // 发者模式清除缓存 cleanCache(); } - if (req.headers.connection === 'upgrade' && req.headers.upgrade === 'websocket') { - // websocket - return; - } res.flush = res.flush || empty; parseGet(req); // 解析get参数 doRoute(req, res); // HTTP路由 @@ -212,7 +231,7 @@ function cleanCache() { } function listen(cpu) { - const user_00 = config.workerUid || 'user_00'; + const wokerUid = config.workerUid || 'user_00'; serverInfo.cpu = cpu || 0; global.cpuUsed = cpuUtil.getCpuUsed(serverInfo.cpu); @@ -257,14 +276,14 @@ function listen(cpu) { if (!isWin32Like) { try { - process.setuid(user_00); + process.setuid(wokerUid); } catch (err) { - logger.error(`switch to uid: ${user_00} fail!`); + logger.error(`switch to uid: ${wokerUid} fail!`); logger.error(err.stack); } logger.info('switch to uid: ${uid}', { - uid: user_00 + uid: wokerUid }); } @@ -407,6 +426,7 @@ function afterCpu80(cpuUsed) { mail.SendMail(key, 'js', 600, { 'to': config.mailTo, 'cc': config.mailCC, + 'runtimeType': 'CPU', 'msgInfo': `${business.module}[CPU]${serverInfo.intranetIp}单核CPU${serverInfo.cpu}使用率为:${cpuUsed},超过80%`, 'title': `${business.module}[CPU]${serverInfo.intranetIp}单核CPU${serverInfo.cpu}使用率为:${cpuUsed},超过80%`, 'content': content, diff --git a/bin/proxy/http.route.js b/bin/proxy/http.route.js index 767ff8e2..2d75bae9 100644 --- a/bin/proxy/http.route.js +++ b/bin/proxy/http.route.js @@ -82,13 +82,13 @@ module.exports = function(req, res) { d.remove(res); if (d.currentContext) { - d.currentContext.window.request = null; - d.currentContext.window.response = null; - d.currentContext.window.onerror = null; - d.currentContext.window = null; - } + if (d.currentContext.window) { + d.currentContext.window.request = null; + d.currentContext.window.response = null; + d.currentContext.window.onerror = null; + d.currentContext.window = null; + } - if (d.currentContext) { d.currentContext.log = null; d.currentContext = null; } @@ -707,6 +707,7 @@ function onerror(req, res, err) { const errorIgnore = { 'socket hang up': 'ignore', + 'Cannot call write after a stream was destroyed': 'ignore', 'Cannot read property \'asyncReset\' of null': 'ignore', 'Cannot read property \'resume\' of null': 'ignore', 'write ECONNRESET': 'ignore', diff --git a/bin/proxy/index.js b/bin/proxy/index.js index 3e8ea720..3ffffde0 100644 --- a/bin/proxy/index.js +++ b/bin/proxy/index.js @@ -10,6 +10,8 @@ const plug = require('../tsw/plug.js'); +require('./version.js'); + plug('runtime/Console.hack.js'); plug('runtime/fs.hack.js'); plug('runtime/Dns.hack.js'); diff --git a/bin/proxy/master.js b/bin/proxy/master.js index cf4ebfc6..bfbcc09d 100644 --- a/bin/proxy/master.js +++ b/bin/proxy/master.js @@ -14,12 +14,14 @@ const cluster = require('cluster'); const cpuUtil = require('util/cpu.js'); const fs = require('fs'); const serverOS = require('util/isWindows.js'); +const mail = require('util/mail/mail.js'); const { debugOptions } = process.binding('config'); const methodMap = {}; const workerMap = {}; const cpuMap = []; const tnm2 = require('api/tnm2'); const network = require('util/network.js'); +const serverInfo = require('serverInfo.js'); process.on('uncaughtException', function(e) { @@ -262,11 +264,9 @@ function checkWorkerAlive() { // 内存超限进程处理 if (worker.lastMessage) { const currMemory = worker.lastMessage.memoryUsage; - - // logger.debug(currMemory); + const key = `memoryLimit.v1:${serverInfo.intranetIp}`; if (currMemory && currMemory.rss > config.memoryLimit) { - logger.error('worker${cpu} pid=${pid} memoryUsage ${memoryUsage}, hit memoryLimit: ${memoryLimit}, kill it', { memoryUsage: currMemory.rss, memoryLimit: config.memoryLimit, @@ -276,6 +276,15 @@ function checkWorkerAlive() { logger.error(worker.lastMessage); + mail.SendMail(key, 'js', 600, { + 'to': config.mailTo, + 'cc': config.mailCC, + 'runtimeType':'Memory', + 'msgInfo': `${serverInfo.intranetIp} 内存超限,服务已重启。请开发人员关注是否存在内存泄露`, + 'title': `${serverInfo.intranetIp} 内存超限告警`, + 'content': `

${serverInfo.intranetIp} 内存超限,服务已重启。请开发人员关注是否存在内存泄露

` + }); + restartWorker(worker); } } @@ -368,6 +377,8 @@ function masterEventHandler() { cpu: cpu }); + tnm2.Attr_API('SUM_TSW_WORKER_FORK', 1); + // 绑定cpu cpuUtil.taskset(cpu, currWorker.process.pid); @@ -430,6 +441,7 @@ function masterEventHandler() { process.on('reload', function(GET) { logger.info('reload'); + tnm2.Attr_API('SUM_TSW_WORKER_RELOAD', 1); for (const key in workerMap) { const worker = workerMap[key]; diff --git a/bin/tsw/util/mail/src/_config.js b/bin/proxy/version.js similarity index 59% rename from bin/tsw/util/mail/src/_config.js rename to bin/proxy/version.js index ee08608b..6dfc6505 100644 --- a/bin/tsw/util/mail/src/_config.js +++ b/bin/proxy/version.js @@ -8,17 +8,15 @@ 'use strict'; -define(function(require, exports, module) { +const arr = process.versions.node.split('.'); - return { - - tmpl: { - create: true - }, - all: { - create: false - } - - }; - -}); +if (arr[0] < 8) { + console.error('The nodejs version you installed is ' + process.versions.node); + console.error('Please update the nodejs version to 8.0.0'); + process.exit(1); +} +if (arr[0] == 10 && (arr[1] >= 0 && arr[1] <= 3)) { + console.error('The nodejs version you installed is ' + process.versions.node); + console.error('Please update to the nodejs version which greater than 10.4.0'); + process.exit(1); +} diff --git a/bin/proxy/webSocketServer.js b/bin/proxy/webSocketServer.js new file mode 100644 index 00000000..273f6084 --- /dev/null +++ b/bin/proxy/webSocketServer.js @@ -0,0 +1,60 @@ +const WebSocket = require('ws'); +const http = require('http'); +const url = require('url'); +const config = require('./config.js'); + +class webSocketServer extends WebSocket.Server { + handleUpgrade(req, socket, head, cb) { + const origin = req['headers']['origin'] || ''; + if (origin) { + const obj = url.parse(origin); + const host = req['headers']['host']; + + if (obj.host !== host) { + const allowWebSocketOriginHost = config.allowWebSocketOriginHost || []; + if (allowWebSocketOriginHost.length === 0) { + super.handleUpgrade(req, socket, head, cb); + return; + } + + let i, + len, + v; + for (i = 0, len = allowWebSocketOriginHost.length; i < len; i++) { + v = allowWebSocketOriginHost[i]; + + if (typeof v === 'string') { + if (v !== obj.host) { + abortConnection(socket, 403); + return; + } + } else if (typeof v === 'object') { + if (!v.test || (v.test && !v.test(obj.host))) { + abortConnection(socket, 403); + return; + } + } + } + } + } + + super.handleUpgrade(req, socket, head, cb); + } +} + +module.exports = webSocketServer; + +function abortConnection(socket, code, message) { + if (socket.writable) { + message = message || http.STATUS_CODES[code]; + socket.write( + `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + + 'Connection: close\r\n' + + 'Content-type: text/html\r\n' + + `Content-Length: ${Buffer.byteLength(message)}\r\n` + + '\r\n' + message + ); + } + + socket.destroy(); +} diff --git a/bin/proxy/websocket.js b/bin/proxy/websocket.js index 0ca02ee2..1edaaecf 100644 --- a/bin/proxy/websocket.js +++ b/bin/proxy/websocket.js @@ -9,7 +9,7 @@ const WebSocket = require('ws'); -const WSServer = WebSocket.Server; +const WSServer = require('./webSocketServer'); const logger = require('logger'); const domain = require('domain'); const Context = require('runtime/Context'); @@ -34,6 +34,7 @@ function wsFiller(ws, req) { ws.logReportTimer = null; ws.__tempSend = ws.send; ws.reportIndex = 1; + ws.messageTriggerCount = 0; ws.send = function(message) { if (ws.readyState == WebSocket.OPEN) { @@ -46,7 +47,12 @@ function wsFiller(ws, req) { } }; - ws.logKey = Math.random(); + ws.logKey = req.headers['sec-websocket-key'] || Math.random(); +} + +function emitReportLog(ws, type) { + ws.upgradeReq.emit(type); + ws.messageTriggerCount = 0; } function reportWebSocketLog(ws, isEnd) { @@ -55,13 +61,15 @@ function reportWebSocketLog(ws, isEnd) { // 每次上报log时,先看下Log多不多,不多的话,延迟上报下 clearTimeout(ws.logReportTimer); if (isEnd) { - ws.upgradeReq.emit('reportLog'); + emitReportLog('reportLog'); } else if (logLength > 30) { // 立即上报 - ws.upgradeReq.emit('reportLogStream'); + emitReportLog('reportLogStream'); + } else if (ws.messageTriggerCount > 9) { + emitReportLog('reportLogStream'); } else { ws.logReportTimer = setTimeout(function() { - ws.upgradeReq.emit('reportLogStream'); + emitReportLog('reportLogStream'); }, 5000); } } @@ -186,6 +194,7 @@ function bind_listen(server) { }; ws.on('message', function(message) { + ws.messageTriggerCount++; logger.debug('server get message : ${message}', { message }); diff --git a/bin/tsw/api/keyman/runtimeType.json b/bin/tsw/api/keyman/runtimeType.json index a5833f14..7186ce1d 100644 --- a/bin/tsw/api/keyman/runtimeType.json +++ b/bin/tsw/api/keyman/runtimeType.json @@ -7,6 +7,8 @@ "Css404" : "内联CSS不存在", "LargeJs" : "内联JS过大", "Js404" : "内联JS不存在", + "CPU" : "CPU告警", + "Memory" : "内存超载", "hello" : "hello" } diff --git a/bin/tsw/api/tnm2/index.js b/bin/tsw/api/tnm2/index.js index 0aff6422..df369312 100644 --- a/bin/tsw/api/tnm2/index.js +++ b/bin/tsw/api/tnm2/index.js @@ -9,7 +9,7 @@ const serverInfo = require('serverInfo.js'); -const mapping = require('./mapping.json'); +const mapping = require('api/tnm2/mapping.json'); const url = require('url'); const Deferred = require('util/Deferred'); const cluster = require('cluster'); diff --git a/bin/tsw/api/tnm2/mapping.json b/bin/tsw/api/tnm2/mapping.json index 3d3261cd..2bddc518 100644 --- a/bin/tsw/api/tnm2/mapping.json +++ b/bin/tsw/api/tnm2/mapping.json @@ -48,6 +48,13 @@ "SUM_TSW_WEBSOCKET_ERROR" : 1253122, "SUM_TSW_WEBSOCKET_CLOSE" : 1253126, + "SUM_TSW_WORKER_RELOAD" : 1285174, + "SUM_TSW_WORKER_FORK" : 1285175, + + "SUM_TSW_CKV_CMD" : 1253127, + "AVG_TSW_CKV_QUEUE_COST" : 1253128, + "AVG_TSW_CKV_CMD_COST" : 1253129, + "AVG_TSW_CPU_LOAD_1" : 1280713, "AVG_TSW_CPU_LOAD_5" : 1280714, "AVG_TSW_CPU_LOAD_15" : 1280716, diff --git a/bin/tsw/pool/cmem.l5.js b/bin/tsw/pool/cmem.l5.js index 41ecf0ad..c2216e45 100644 --- a/bin/tsw/pool/cmem.l5.js +++ b/bin/tsw/pool/cmem.l5.js @@ -11,6 +11,7 @@ const logger = require('logger'); const Queue = require('util/Queue'); const dcapi = require('api/libdcapi/dcapi.js'); +const tnm2 = require('api/tnm2'); const L5 = require('api/L5/L5.api.js'); const { isWin32Like } = require('util/isWindows.js'); let cache = global[__filename]; @@ -23,9 +24,9 @@ if (!cache) { module.exports = function(opt) { /** - * 这里像这样写的目的主要是为了进行测试 - 因为在使用sinon.js时, 如果你exports的是一个function,你就无法进行stub, - */ + * 这里像这样写的目的主要是为了进行测试 + 因为在使用sinon.js时, 如果你exports的是一个function,你就无法进行stub, + */ return module.exports.getCmem(opt); }; @@ -56,14 +57,29 @@ module.exports.getCmem = function(opt) { return null; } + return fromCache(opt); +}; + +const fromCache = (opt) => { const key = [opt.modid, opt.cmd, opt.host].join(':'); if (!cache[key]) { const Memcached = require('memcached'); - cache[key] = queueWrap(new Memcached(opt.host, opt)); + const poolSize = opt.poolSize || 1; + const queueWrapList = []; + const option = Object.assign({}, opt, { + poolSize: 1 + }); + for (let i = 0; i < poolSize; i++) { + queueWrapList.push(queueWrap(new Memcached(opt.host, option))); + } + queueWrapList.curr = 0; + cache[key] = queueWrapList; + } else { + cache[key].curr = (cache[key].curr + 1) % cache[key].length; } - return cache[key]; + return cache[key][cache[key].curr]; }; @@ -83,7 +99,13 @@ function queueWrap(memcached) { const servers = memcached.servers && memcached.servers[0]; const start = Date.now(); + tnm2.Attr_API('SUM_TSW_CKV_CMD', 1); + queue.queue(function() { + const startQueue = Date.now(); + const costQueue = startQueue - start; + + tnm2.Attr_API_Set('AVG_TSW_CKV_QUEUE_COST', costQueue); const fn = (function(queryCompiler) { return function() { @@ -119,6 +141,8 @@ function queueWrap(memcached) { } } + tnm2.Attr_API_Set('AVG_TSW_CKV_CMD_COST', Date.now() - startQueue); + dcapi.report({ key: 'EVENT_TSW_MEMCACHED', toIp: toIp, diff --git a/bin/tsw/runtime/CCFinder.js b/bin/tsw/runtime/CCFinder.js index 4cd88245..48a9144f 100644 --- a/bin/tsw/runtime/CCFinder.js +++ b/bin/tsw/runtime/CCFinder.js @@ -250,7 +250,8 @@ this.check = function (req, res) { 'to': config.mailTo, 'cc': config.mailCC, 'title': title, - 'content': '

服务器IP:' + serverInfo.intranetIp + '

' + 'content': '

IP聚集相关信息,详情请参阅文档: https://tswjs.org/doc/api/ipCCFinder

' + +'

服务器IP:' + serverInfo.intranetIp + '

' + '

恶意IP:' + max.ip + '

' + '

自动拉黑:' + (config.CCIPLimitAutoBlock ? '是' : '否') + '

' + '

IP聚集度:' + cache.ipCacheLast.StdX10 + '%

' diff --git a/bin/tsw/runtime/ContextWrap.js b/bin/tsw/runtime/ContextWrap.js index 95b3e9a9..fa2ec2cb 100644 --- a/bin/tsw/runtime/ContextWrap.js +++ b/bin/tsw/runtime/ContextWrap.js @@ -66,8 +66,23 @@ class ContextWrap extends EventEmitter { } destroy() { - this._domain.remove(this._req); - this._domain.remove(this._rsp); + + const d = this._domain; + + d.remove(this._req); + d.remove(this._rsp); + + if (d.currentContext) { + if (d.currentContext.window) { + d.currentContext.window.request = null; + d.currentContext.window.response = null; + d.currentContext.window.onerror = null; + d.currentContext.window = null; + } + + d.currentContext.log = null; + d.currentContext = null; + } this._domain = null; this._req = null; diff --git a/bin/tsw/runtime/fs.hack.js b/bin/tsw/runtime/fs.hack.js index 1da48087..1ac74443 100644 --- a/bin/tsw/runtime/fs.hack.js +++ b/bin/tsw/runtime/fs.hack.js @@ -36,7 +36,7 @@ if (global[__filename]) { sum = cache.map[key]; if (sum % TIMES_LIMIT === 0 && !config.devMode) { - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}', { + logger.warn('[sync]${name} called ${sum} times on file: ${file} \n${stack}', { name: name, file: file, sum: sum, @@ -56,7 +56,7 @@ if (global[__filename]) { sum = cache.map[key]; if (sum % TIMES_LIMIT === 0 && !config.devMode) { - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}', { + logger.warn('[sync]${name} called ${sum} times on file: ${file} \n${stack}', { name: name, file: file, sum: sum, @@ -75,8 +75,8 @@ if (global[__filename]) { cache.map[key] = ~~cache.map[key] + 1; sum = cache.map[key]; - if (sum > TIMES_LIMIT && !config.devMode) { - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}', { + if (sum % TIMES_LIMIT === 0 && !config.devMode) { + logger.warn('[sync]${name} called ${sum} times on file: ${file} \n${stack}', { name: name, file: file, sum: sum, @@ -96,7 +96,7 @@ if (global[__filename]) { sum = cache.map[key]; if (sum % TIMES_LIMIT === 0 && !config.devMode) { - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}', { + logger.warn('[sync]${name} called ${sum} times on file: ${file} \n${stack}', { name: name, file: file, sum: sum, @@ -115,8 +115,8 @@ if (global[__filename]) { cache.map[key] = ~~cache.map[key] + 1; sum = cache.map[key]; - if (sum > TIMES_LIMIT && !config.devMode) { - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}', { + if (sum % TIMES_LIMIT === 0 && !config.devMode) { + logger.warn('[sync]${name} called ${sum} times on file: ${file} \n${stack}', { name: name, file: file, sum: sum, @@ -136,7 +136,7 @@ if (global[__filename]) { sum = cache.map[key]; if (sum % TIMES_LIMIT === 0 && !config.devMode) { - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}', { + logger.warn('[sync]${name} called ${sum} times on file: ${file} \n${stack}', { name: name, file: file, sum: sum, diff --git a/bin/tsw/util/auto-report/alpha.js b/bin/tsw/util/auto-report/alpha.js index ac0e3fc6..ba36d54e 100644 --- a/bin/tsw/util/auto-report/alpha.js +++ b/bin/tsw/util/auto-report/alpha.js @@ -8,10 +8,7 @@ 'use strict'; -const config = require('config'); -const logger = require('logger'); const { isWin32Like } = require('util/isWindows'); -const TSW = require('api/keyman'); if (!global[__filename]) { global[__filename] = {}; @@ -27,6 +24,10 @@ this.add = function(uin) { this.isAlpha = function(req) { + const TSW = require('api/keyman'); + const logger = require('logger'); + const config = require('config'); + let uin; if (typeof req === 'object') { @@ -63,6 +64,7 @@ this.isAlpha = function(req) { }; this.getUin = function(req) { + const config = require('config'); let uin; const window = context.window || {}; diff --git a/bin/tsw/util/auto-report/logReport.js b/bin/tsw/util/auto-report/logReport.js index 5f434903..5f788d00 100644 --- a/bin/tsw/util/auto-report/logReport.js +++ b/bin/tsw/util/auto-report/logReport.js @@ -291,6 +291,30 @@ module.exports.receiveCloud = function(req, res) { return returnJson('get appkey error'); } + if (!data.logText) { + return returnJson('logText is required'); + } + + if (typeof data.logText !== 'string') { + return returnJson('logText is not a string'); + } + + if (data.logText.length >= 64 * 1024) { + return returnJson('logText is large than 64KB'); + } + + if (!data.logJson) { + return returnJson('logJson is required'); + } + + if (typeof data.logJson !== 'string') { + return returnJson('logJson is not a string'); + } + + if (data.logJson.length >= 1024 * 1024) { + return returnJson('logJson is large than 1MB'); + } + const appid = context.appid; const appkey = context.appkey; const reportKey = [appid, data.key].join('/'); @@ -510,13 +534,13 @@ function reportLog() { const isWebSocket = !!window.websocket; const req = window.request; const res = window.response; + const logJson = logger.getJson(isWebSocket) || {}; let log = logger.getLog(), type = '', typeKey = '', arrtKey = '', code = 0, - logJson = logger.getJson(), key; @@ -676,7 +700,6 @@ function reportLog() { res._body = Buffer.from(format.formatBuffer(res._body)); } - logJson = logJson || logger.getJson() || {}; logJson.curr = { protocol: 'HTTP', host: req.headers.host, diff --git a/bin/tsw/util/auto-report/src/view.tmpl.html b/bin/tsw/util/auto-report/src/view.tmpl.html index 4a8a315a..3ce6dd68 100644 --- a/bin/tsw/util/auto-report/src/view.tmpl.html +++ b/bin/tsw/util/auto-report/src/view.tmpl.html @@ -74,7 +74,6 @@
- 下载全部抓包 Fiddler下载 Whistle下载(mac推荐) @@ -82,6 +81,9 @@ <%if(appid){%> 实时监控 测试环境 + 个人主页 + runtime + 应用详情 <%}else{%> 临时染色 <%}%> diff --git a/bin/tsw/util/auto-report/tmpl.js b/bin/tsw/util/auto-report/tmpl.js index 2629ea02..8c55ccff 100644 --- a/bin/tsw/util/auto-report/tmpl.js +++ b/bin/tsw/util/auto-report/tmpl.js @@ -293,11 +293,9 @@ define(function(require, exports, module) { groupArr = tmp; var XSS = plug('util/xss.js'); - __p.push('\n\n \n TSW云抓包™\n \n \n\n\n
\n 下载全部抓包\n Fiddler下载\n Whistle下载(mac推荐)\n \n '); + __p.push('\n\n \n TSW云抓包™\n \n \n\n\n
\n Fiddler下载\n Whistle下载(mac推荐)\n \n '); if (appid) { - __p.push(' 实时监控\n 测试环境'); + __p.push(' 实时监控\n 测试环境\n 个人主页\n runtime\n 应用详情'); } else { __p.push(' 临时染色'); }__p.push('