Giter Site home page Giter Site logo

tencent / tsw Goto Github PK

View Code? Open in Web Editor NEW
1.8K 89.0 184.0 7.86 MB

Tencent Server Web

Home Page: https://tswjs.org/

License: Other

JavaScript 3.90% TypeScript 95.59% Makefile 0.25% Shell 0.25%
nodejs javascript web tsw js server monitor log capture observability

tsw's Introduction

license Build Status tested with jest codecov

What is it

Tencent Server Web(TSW) 是一套面向 WEB 前端开发者,以提升问题定位效率为初衷,提供 染色抓包全息日志 的 Node.js 基础设施。TSW 关注业务的运维监控能力,适用于 http、https 协议的业务场景,可无缝与现有应用(Koa、Express)进行整合。

TSW 2.0 在 1.0 的基础上抽丝剥茧,辅以现代化的设计模式,去除了 1.0 中的大量糟粕,同时对容器化、云原生更加友好。做到了无侵入、低成本接入。

Highlights

🚀

0 侵入

📒

全息日志

🛠

请求抓包

通过 Hack NodeJS 底层代码实现功能。对原有业务代码 0 侵入。 按照请求聚类的显微镜级别的全息日志,给开发者完美的现场还原。 可抓取 Server 端向外部发送的所有请求的完整包体内容,与后台沟通再无障碍。

特别提醒

TSW 1.0 迁移到 2.0 需要注意的地方

  • TSW 1.0 服务包含进程管理,日志管理等多项内置模块,在进行往 2.0 迁移的时候,请选择其他组件完成替代,如引入 PM2 管理 Node 进程,使用 winston 进行日志管理
  • 另外 2.0 没有包含日志清理工具,建议选择 winston-rotating-file 类似工具来完成清理,避免日志存放过多,导致磁盘空间不足

Quick Start

1. 安装

npm install --save @tswjs/tsw
// yarn add @tswjs/tsw

2. 添加配置文件

配置文件是 TSW 启动时加载进运行时的配置文件,主要声明需要使用的 插件 列表。默认会加载项目根目录下的 tswconfig.js 文件,也可以通过启动参数 -c 或者 --config 来手动指定配置文件路径。

注意事项: 2.0 中没有集成开放平台相关逻辑,而是封装成了一个插件让用户按需使用,详情见插件章节。

配置文件示例:

module.exports = {
  plugins: [
    new MyPlugin({})
  ]
}

参数列表:

Name Type default Optional Description
plugins Array<Plugin> - yes 插件列表
cleanLog boolean false yes 是否关闭默认打印
logLevel DEBUG/INFO/WARN/ERROR DEBUG yes 设置 log level
winstonTransports Array<TransportStream> - yes Winston日志通道

3. 启动

npx @tswjs/tsw ./index.js

注意事项:原先 node --inspect ./index.js 中的 CLI 参数如 --inspect 需要转化为环境变量 NODE_OPTIONS 来执行,如 NODE_OPTIONS="--inspect" npx @tswjs/tsw ./index.js

使用 ts: 在保证项目有 ts-node 依赖包的情况下,按照如下方式执行即可直接加载 ts 文件。

NODE_OPTIONS="--require=ts-node/register" npx @tswjs/tsw ./index.ts

CLI (Command Line Interface)

使用 npx @tswjs/tsw --help 来获取 CLI 选项。

Examples

我们提供了一些示例项目以让大家尽快了解该项目。

  1. cd ~
  2. git clone https://github.com/Tencent/TSW.git
  3. cd TSW

Koa

  1. cd examples/koa
  2. yarn
  3. yarn serve 或者 npm run serve
  4. curl -v localhost:4443/path/to/foo -X POST -d "hello, server"

Plugins

插件是什么?

TSW 核心的实现方式是 Hack NodeJS 自身的 http.request 以及 http.createServer, 以此来实现抓包机制。在服务器处理请求的前后,在服务器向其他服务器发包的前后,等等,都会有相应的事件抛出,以供用户来进行自定义处理。为了让用户更加方便地复用、传播这样一组组自定义处理,我们将他们抽象出来,形成了插件机制。

一个最简单的插件

export.modules = class MyPlugin() {
  constructor() {
    this.name = "MyPlugin"
  }

  async init(eventBus, config) {
    eventBus.on("RESPONSE_CLOSE", (payload) => {
      console.log(payload);
    })
  }
}

init 方法是必须的,这个方法在插件加载开始时会被调用,可以是同步也可以是异步。

eventBus

eventBus 是通过 new EventEmitter() 得到的。TSW 核心会在各个关键时机触发上面的事件。

key 含义(触发时机) payload
DNS_LOOKUP_SUCCESS 在每次 DNS 查询成功之后触发 string | dns.LookupAddress[]
DNS_LOOKUP_ERROR 在每次 DNS 查询失败之后触发 NodeJS.ErrorException
RESPONSE_START 在每次服务器开始返回响应(执行 writeHead)时触发 ResponseEventPayload
RESPONSE_FINISH 在响应结束时(res.on("finish"))触发 ResponseEventPayload
RESPONSE_CLOSE 在底层链接关闭时 (res.on("close"))触发 ResponseEventPayload
REQUEST_START 在每次服务器接受到新的请求时触发 RequestEventPayload

Open Platform

在默认的情况下,TSW 只是会把所有的日志和抓包内容抓取到并且送到事件总线上,以供 插件 消费。所以将日志和抓包内容落地查看一般需要用户自己编写插件以及提供存储,使用成本过于高昂。
因此,TSW 官方提供了公共的服务平台 https://tswjs.org,让用户低成本、更快、更方便地使用 TSW 的特性,详情见 开放平台使用指引

Cluster

TSW 2.0 是面对容器化和云原生设计的,所以没有内置 Cluster 相关功能,推荐直接使用容器的健康检查来完成服务的无损重启和故障重启机制。对于没有使用容器化方案的场景来说,我们推荐使用 pm2 类似工具来实现多进程模式。

pm2

使用 Ecosystem File

// ecosystem.config.json

{
  "apps": [
    {
      "name": "app-name",
      "script": "built/index.js",
      "interpreter": "node",
      "interpreter_args": "./node_modules/@tswjs/tsw/dist/cli.js",
      // other options
    }
  ]
}
// package.json

{
  ...
  "scripts": {
    "start": "pm2 start ecosystem.config.json"
  },
  ...
}

Winston

winston 是什么?

winston 是一个通用且轻量的日志包。winston 支持多个日志通道,并且可以分别定义日志优先级。除了内置的三个日志传输通道ConsoleFileHTTP,在 Winston 项目外部还会维护一些传输模块。查看 winston 官方文档

TSW 2.0 支持使用 winston 传输通道记录日志信息,用户在配置文件中可以添加 winston.transports 实例,日志会落到对应配置中。

一个简单的示例

使用 winston 记录 error 级别 以及 debug 级别以下的日志信息到对应文件中,当前 config 文件配置如下:

module.exports = {
  winstonTransports: [
    new winston.transports.File({ filename: 'error.log', level: 'error'}),
    new winston.transports.File({ filename: 'debug.log', level: 'debug'})
  ]
}

日志记录

log

Users

tsw    tsw    tsw     
 
tsw    tsw    tsw      
 
tsw    tsw    tsw      
 
tsw    tsw    tsw      
 
tsw    tsw    tsw      
 
tsw    tsw    tsw      
 
tsw    tsw    tsw      
 
tsw    tsw    tsw      
 
tsw    tsw    tsw

License

Tencent Server Web 的开源协议为 MIT, 详情参见 LICENSE

tsw's People

Contributors

bindeliu avatar caijw avatar chwyh avatar dependabot[bot] avatar gaoyuan123 avatar huangyoukun avatar iscowei avatar jrainlau avatar kajweb avatar loviselu avatar mapleeit avatar mc-zone avatar miantang avatar plusice avatar realyuyanan avatar robinzzh avatar sunxen avatar sunyanxl avatar tarotlwei avatar timcui avatar undefinal avatar wikibady avatar xqin avatar xuqingkuang avatar yes1am avatar yippee701 avatar yuukinan avatar zack921 avatar zhaoda avatar zkd8907 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tsw's Issues

关于node_modules目录的建议

我是在知乎上看到然后过来的。如果这个项目的node_modules目录中包含有修改过的第三方库,我建议可以创建一个vendor目录,然后把修改过的代码挪过去,这样更符合业界的标准做法。

而对于鹅厂内部的库,如果不想push到npm,简单的做法是可以放在顶层的lib目录,更高级一点的做法是可以使用lerna来管理。

请教关于 TSW 文档中的黑话

今天看到 TSW 开源的公告,里面有些黑话没看懂,特意前来请教一下。染色、全息日志这两个词是什么意思?文档中没有给出明确的定义,无法理解。

TSW 可以支持POST请求转发到测试环境吗?

需求背景:有些接口要开放给第三方平台调用,并且处于安全考虑只能用post请求。当接口相关的逻辑变更时,让调用方更改难度太大,又无法转发到测试环境验证,只能外网验证。

希望TSW支持POST请求转发到测试环境

crypto.createCipher废弃接口替换

crypto.createCipher自node10.0开始已被废弃,需更改为createCipheriv

image

发现调用接口文件:/bin/tsw/util/auto-report/post.js

module.exports.encode = function(appid, appkey, data) {
    const input = Buffer.from(JSON.stringify(data), 'UTF-8');
    const buff = zlib.deflateSync(input);
    const des = crypto.createCipher('des', (appid + appkey));

ps: 对接接口crypto.createDecipher也需要替换

npm run test 无效

看了下npm script,这两条命令都没办法执行

"test" : "node test/node_modules/mocha/bin/mocha test/bin/**/*.js",
"coverage": "node test/node_modules/nyc/bin/nyc test/node_modules/mocha/bin/mocha test/bin/**/*.js"

你有freestyle嗎?

這嗰項目①嚸嘟卟符合廠の逼格,苡岌莈冇恁何é$līńτ啝cōdīńɡ $τylé
(这个项目一点都不符合大厂的逼格,以及没有任何eslint和coding style)

可以对接eggjs么

你好,最近在使用eggjs进行开发,想要接入tsw,要怎么接入呢,看官方没有相应例子,能不能提供下现在常用一些框架的接入demo

解决数据加解密耗时过大问题

测试环境以及抓包数据加解密耗时过大,导致请求超时

加解密使用PBKDF2的迭代次数过多(32767)
每次生成key耗时45ms左右

这里需要调整迭代次数,兼顾加密安全与性能

关于文档若干改进

  1. Quick start里面不要加入高手可以跳过之类字眼,技术文档应该严肃。
  2. 公开文档的源代码(这样遇到以上问题可以直接交PR)

testinfo配置没有生效

在官方的examples/framework/config.js里添加testInfo配置,并没有生效。
遵循故障排除也无法解决。

config.js:

// http监听地址
this.httpAddress = '0.0.0.0';

// http监听地址
this.httpPort = 80;

// 路由
this.router = require('./router.js');

// logger
this.logger = {
    logLevel: 'debug'
};

this.wsRouter = require('./wsRouter.js');

this.alphaFile = `${__dirname}/alpha.txt`;

this.appid = 'tsw1331';
this.appkey = '*****';

// https://${appid}.tswjs.org/log/view/xxx

this.isTest = true;
this.testInfo = {
    "name"      : "神秘商店",
    "group"     : "TSW",
    "groupName" : "TSW团队",
    "desc"      : "没有人能知道这里在售卖什么",
    "order"     : 30,
    "owner"     : "TSW"
};

log日志:

^C
WEIJIEZHU-MB1:TSW weijie$ 
WEIJIEZHU-MB1:TSW weijie$ 
WEIJIEZHU-MB1:TSW weijie$ node --inspect index.js
Debugger listening on ws://127.0.0.1:9229/8967afd1-1dbd-4198-9388-843aac8f9d9f
For help, see: https://nodejs.org/en/docs/inspector
2019-09-27 15:17:46.013 [INFO] [43710 cpu 0] [null] [master.js:154] start worker....
2019-09-27 15:17:46.014 [INFO] [43710 cpu 0] [null] [master.js:155] config from: /Users/weijie/dev/test/TSW/bin/proxy/../../conf/config.js
2019-09-27 15:17:46.064 [INFO] [43710 cpuX 0] [null] [http.proxy.js:76] pid:43710 createServer ok
2019-09-27 15:17:46.066 [INFO] [43710 cpuX 0] [null] [master.js:167] inspectorEnabled, start listening
2019-09-27 15:17:46.066 [INFO] [43710 cpuX 0] [null] [http.proxy.js:97] receive message, cmd: listen
2019-09-27 15:17:46.066 [INFO] [43710 cpu0 0] [null] [http.proxy.js:243] cpu: 0, beforeStartup...
2019-09-27 15:17:46.066 [INFO] [43710 cpu0 0] [null] [http.proxy.js:249] cpu: 0, listen...
2019-09-27 15:17:46.073 [INFO] [43710 cpu0 0] [null] [http.proxy.js:257] cpu: 0, listen http ok 0.0.0.0:80
2019-09-27 15:17:46.074 [INFO] [43710 cpu0 0] [null] [http.proxy.js:308] cpu: 0, listen http ok 0.0.0.0:12801
2019-09-27 15:17:46.074 [INFO] [43710 cpu0 0] [null] [http.proxy.js:265] start heartbeat
2019-09-27 15:17:46.075 [INFO] [43710 cpu0 0] [null] [http.proxy.js:284] cpu: 0, afterStartup...
2019-09-27 15:17:51.901 [DBUG] [43710 cpu0 1] [null] [http.route.js:424] GET http://127.0.0.1/
2019-09-27 15:17:51.901 [DBUG] [43710 cpu0 1] [null] [http.route.js:431] idc: sz, server ip: , tcp: 127.0.0.1:62975 > 127.0.0.1:80, client ip: 127.0.0.1, cpuUsed: 0
2019-09-27 15:17:51.901 [DBUG] [43710 cpu0 1] [null] [http.route.js:443] config.isTest is true
2019-09-27 15:17:51.903 [DBUG] [43710 cpu0 1] [null] [alphaMap.js:87] update ok
2019-09-27 15:17:51.905 [DBUG] [43710 cpu0 1] [null] [http.route.js:508] node-v10.16.3, name: null, appid: tsw1331
2019-09-27 15:17:51.906 [DBUG] [43710 cpu0 1] [null] [index.js:145] [get] done: /Users/weijie/dev/test/TSW/log/cache/h5test/test.user.list.cache, size: 54, cost: 1ms
2019-09-27 15:17:51.909 [DBUG] [43710 cpu0 1] [null] [ajax.js:294] [1] host from url: openapi.tswjs.org
2019-09-27 15:17:51.910 [DBUG] [43710 cpu0 1] [null] [ajax.js:513] [1] POST json ~ openapi.tswjs.org:443 https://openapi.tswjs.org/v1/h5test/sync
2019-09-27 15:17:51.924 [DBUG] [43710 cpu0 1] [null] [Dns.hack.js:41] dns lookup for openapi.tswjs.org
2019-09-27 15:17:51.925 [DBUG] [43710 cpu0 1] [null] [capturer.js:62] [1] POST openapi.tswjs.org:443 ~ https://openapi.tswjs.org/v1/h5test/sync
2019-09-27 15:17:51.928 [DBUG] [43710 cpu0 1] [null] [blackIpMap.js:59] config.blackIpFile is: null
2019-09-27 15:17:51.929 [DBUG] [43710 cpu0 1] [null] [logger.js:153] setKey: xxx
2019-09-27 15:17:51.930 [DBUG] [43710 cpu0 1] [null] [http.route.js:474] showLineNumber on
2019-09-27 15:17:51.930 [DBUG] [43710 cpu0 1] [null] [http.js:151] capture ServerResponse body on
2019-09-27 15:17:51.931 [DBUG] [43710 cpu0 1] [null] [http.route.js:481] response 200
2019-09-27 15:17:51.935 [DBUG] [43710 cpu0 1] [null] [http.route.js:54] clear called
2019-09-27 15:17:51.936 [DBUG] [43710 cpu0 1] [null] [http.route.js:324] finish, statusCode: 200,cost: 37ms
2019-09-27 15:17:51.937 [DBUG] [43710 cpu0 1] [null] [logReport.js:641] logType: alpha
2019-09-27 15:17:51.940 [DBUG] [43710 cpu0 1] [null] [logReport.js:671] 
GET / HTTP/1.1
host: 127.0.0.1
connection: keep-alive
cache-control: max-age=0
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
sec-fetch-mode: navigate
sec-fetch-user: ?1
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
sec-fetch-site: none
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7
tsw-trace-steps: 1


response 200 {
  "connection": "keep-alive",
  "keep-alive": "timeout=10",
  "x-powered-by": "TSW/Node.js",
  "server": "TSW/1.4.1",
  "cache-control": "no-cache"
}
2019-09-27 15:17:51.941 [DBUG] [43710 cpu0 1] [null] [logReport.js:204] reportCloud
2019-09-27 15:17:51.942 [DBUG] [43710 cpu0 1] [null] [logReport.js:205] report log type: alpha, key xxx
2019-09-27 15:17:51.948 [DBUG] [43710 cpu0 1] [null] [ajax.js:294] [2] host from url: openapi.tswjs.org
2019-09-27 15:17:51.949 [DBUG] [43710 cpu0 1] [null] [ajax.js:513] [2] POST json ~ openapi.tswjs.org:443 https://openapi.tswjs.org/v1/log/report
2019-09-27 15:17:51.950 [DBUG] [43710 cpu0 1] [null] [Dns.hack.js:41] dns lookup for openapi.tswjs.org
2019-09-27 15:17:51.950 [DBUG] [43710 cpu0 1] [null] [capturer.js:62] [2] POST openapi.tswjs.org:443 ~ https://openapi.tswjs.org/v1/log/report
2019-09-27 15:17:51.951 [DBUG] [43710 cpu0 1] [null] [capturer.js:73] [2] capture body on
2019-09-27 15:17:51.951 [DBUG] [43710 cpu0 1] [null] [http.js:151] capture ServerResponse body on
2019-09-27 15:17:51.954 [DBUG] [43710 cpu0 1] [null] [Dns.hack.js:62] dns lookup 30ms: openapi.tswjs.org --> 14.215.138.19
2019-09-27 15:17:51.967 [DBUG] [43710 cpu0 1] [null] [capturer.js:269] [1] dns lookup openapi.tswjs.org -> 14.215.138.19, cost 41ms
2019-09-27 15:17:51.967 [DBUG] [43710 cpu0 1] [null] [Dns.hack.js:62] dns lookup 17ms: openapi.tswjs.org --> 14.215.138.19
2019-09-27 15:17:51.967 [DBUG] [43710 cpu0 1] [null] [capturer.js:269] [2] dns lookup openapi.tswjs.org -> 14.215.138.19, cost 17ms
2019-09-27 15:17:51.976 [DBUG] [43710 cpu0 1] [null] [capturer.js:262] [1] connect 14.215.138.19:443, cost 51ms
2019-09-27 15:17:51.977 [DBUG] [43710 cpu0 1] [null] [ajax.js:573] [1] connect 14.215.138.19:443
2019-09-27 15:17:51.977 [DBUG] [43710 cpu0 1] [null] [capturer.js:262] [2] connect 14.215.138.19:443, cost 27ms
2019-09-27 15:17:51.977 [DBUG] [43710 cpu0 1] [null] [ajax.js:573] [2] connect 14.215.138.19:443
2019-09-27 15:17:52.006 [DBUG] [43710 cpu0 1] [null] [capturer.js:81] [2] send finish, total size 4041
2019-09-27 15:17:52.179 [DBUG] [43710 cpu0 2] [null] [http.route.js:424] GET http://127.0.0.1/favicon.ico
2019-09-27 15:17:52.180 [DBUG] [43710 cpu0 2] [null] [http.route.js:431] idc: sz, server ip: , tcp: 127.0.0.1:62975 > 127.0.0.1:80, client ip: 127.0.0.1, cpuUsed: 0
2019-09-27 15:17:52.180 [DBUG] [43710 cpu0 2] [null] [http.route.js:443] config.isTest is true
2019-09-27 15:17:52.180 [DBUG] [43710 cpu0 2] [favicon.ico] [http.route.js:508] node-v10.16.3, name: favicon.ico, appid: tsw1331
2019-09-27 15:17:52.180 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:294] [1] host from url: openapi.tswjs.org
2019-09-27 15:17:52.181 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:513] [1] POST json ~ openapi.tswjs.org:443 https://openapi.tswjs.org/v1/h5test/sync
2019-09-27 15:17:52.181 [DBUG] [43710 cpu0 2] [favicon.ico] [Dns.hack.js:41] dns lookup for openapi.tswjs.org
2019-09-27 15:17:52.182 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:62] [1] POST openapi.tswjs.org:443 ~ https://openapi.tswjs.org/v1/h5test/sync
2019-09-27 15:17:52.182 [DBUG] [43710 cpu0 2] [favicon.ico] [logger.js:153] setKey: xxx
2019-09-27 15:17:52.183 [DBUG] [43710 cpu0 2] [favicon.ico] [http.route.js:474] showLineNumber on
2019-09-27 15:17:52.183 [DBUG] [43710 cpu0 2] [favicon.ico] [http.js:151] capture ServerResponse body on
2019-09-27 15:17:52.183 [DBUG] [43710 cpu0 2] [favicon.ico] [http.route.js:481] response 200
2019-09-27 15:17:52.184 [DBUG] [43710 cpu0 2] [favicon.ico] [http.route.js:54] clear called
2019-09-27 15:17:52.184 [DBUG] [43710 cpu0 2] [favicon.ico] [http.route.js:324] finish, statusCode: 200,cost: 5ms
2019-09-27 15:17:52.184 [DBUG] [43710 cpu0 2] [favicon.ico] [logReport.js:641] logType: alpha
2019-09-27 15:17:52.185 [DBUG] [43710 cpu0 2] [favicon.ico] [logReport.js:671] 
GET /favicon.ico HTTP/1.1
host: 127.0.0.1
connection: keep-alive
pragma: no-cache
cache-control: no-cache
sec-fetch-mode: no-cors
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
accept: image/webp,image/apng,image/*,*/*;q=0.8
sec-fetch-site: same-origin
referer: http://127.0.0.1/
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7
tsw-trace-steps: 1


response 200 {
  "connection": "keep-alive",
  "keep-alive": "timeout=10",
  "x-powered-by": "TSW/Node.js",
  "server": "TSW/1.4.1",
  "cache-control": "no-cache"
}
2019-09-27 15:17:52.185 [DBUG] [43710 cpu0 2] [favicon.ico] [logReport.js:204] reportCloud
2019-09-27 15:17:52.185 [DBUG] [43710 cpu0 2] [favicon.ico] [logReport.js:205] report log type: alpha, key xxx
2019-09-27 15:17:52.187 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:294] [2] host from url: openapi.tswjs.org
2019-09-27 15:17:52.188 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:513] [2] POST json ~ openapi.tswjs.org:443 https://openapi.tswjs.org/v1/log/report
2019-09-27 15:17:52.188 [DBUG] [43710 cpu0 2] [favicon.ico] [Dns.hack.js:41] dns lookup for openapi.tswjs.org
2019-09-27 15:17:52.188 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:62] [2] POST openapi.tswjs.org:443 ~ https://openapi.tswjs.org/v1/log/report
2019-09-27 15:17:52.189 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:73] [2] capture body on
2019-09-27 15:17:52.189 [DBUG] [43710 cpu0 2] [favicon.ico] [http.js:151] capture ServerResponse body on
2019-09-27 15:17:52.190 [DBUG] [43710 cpu0 2] [favicon.ico] [Dns.hack.js:62] dns lookup 9ms: openapi.tswjs.org --> 14.215.138.19
2019-09-27 15:17:52.190 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:269] [1] dns lookup openapi.tswjs.org -> 14.215.138.19, cost 8ms
2019-09-27 15:17:52.190 [DBUG] [43710 cpu0 2] [favicon.ico] [Dns.hack.js:62] dns lookup 2ms: openapi.tswjs.org --> 14.215.138.19
2019-09-27 15:17:52.190 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:269] [2] dns lookup openapi.tswjs.org -> 14.215.138.19, cost 2ms
2019-09-27 15:17:52.206 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:262] [2] connect 14.215.138.19:443, cost 18ms
2019-09-27 15:17:52.206 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:573] [2] connect 14.215.138.19:443
2019-09-27 15:17:52.206 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:262] [1] connect 14.215.138.19:443, cost 24ms
2019-09-27 15:17:52.207 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:573] [1] connect 14.215.138.19:443
2019-09-27 15:17:52.219 [DBUG] [43710 cpu0 1] [null] [capturer.js:189] [1] 10.68.108.65:62981 > 14.215.138.19:443 response 200 cost:294ms gzip
2019-09-27 15:17:52.220 [DBUG] [43710 cpu0 1] [null] [ajax.js:780] [1] 14.215.138.19:443 response 200 cost:310ms gzip
2019-09-27 15:17:52.222 [DBUG] [43710 cpu0 1] [null] [capturer.js:224] [1] end size:79, receive data cost: 297ms
2019-09-27 15:17:52.223 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:81] [2] send finish, total size 3573
2019-09-27 15:17:52.224 [DBUG] [43710 cpu0 1] [null] [ajax.js:936] [1] end:102,        receive data cost: 4ms
2019-09-27 15:17:52.225 [DBUG] [43710 cpu0 1] [null] [ajax.js:965] [1] done size:102
2019-09-27 15:17:52.225 [DBUG] [43710 cpu0 1] [null] [ajax.js:1016] [1] responseText:
{
  "code": 0,
  "data": {
    "123": "alpha",
    "1111111": "alpha",
    "e453534534": "alpha"
  }
}
2019-09-27 15:17:52.225 [DBUG] [43710 cpu0 1] [null] [ajax.js:419] [1] 返回码:0, isFail:0
2019-09-27 15:17:52.226 [DBUG] [43710 cpu0 1] [null] [index.js:80] [set] filename : /Users/weijie/dev/test/TSW/log/cache/h5test/test.user.list.cache
2019-09-27 15:17:52.226 [DBUG] [43710 cpu0 1] [null] [index.js:81] [set] dirname : /Users/weijie/dev/test/TSW/log/cache/h5test
2019-09-27 15:17:52.226 [DBUG] [43710 cpu0 1] [null] [index.js:82] [set] basename : test.user.list.cache
2019-09-27 15:17:52.227 [DBUG] [43710 cpu0 1] [null] [index.js:83] [set] randomname : test.user.list.cache.tmp.8911482326009084
2019-09-27 15:17:52.227 [DBUG] [43710 cpu0 1] [null] [is-test.js:204] syncFromCloud success.
2019-09-27 15:17:52.228 [DBUG] [43710 cpu0 1] [null] [index.js:95] [write] done: test.user.list.cache.tmp.8911482326009084, size: 54
2019-09-27 15:17:52.229 [DBUG] [43710 cpu0 1] [null] [index.js:109] [rename] done: test.user.list.cache, cost: 3ms
2019-09-27 15:17:52.345 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:189] [1] 10.68.108.65:62983 > 14.215.138.19:443 response 200 cost:163ms gzip
2019-09-27 15:17:52.345 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:780] [1] 14.215.138.19:443 response 200 cost:164ms gzip
2019-09-27 15:17:52.346 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:224] [1] end size:79, receive data cost: 164ms
2019-09-27 15:17:52.347 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:936] [1] end:102, receive data cost: 1ms
2019-09-27 15:17:52.347 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:965] [1] done size:102
2019-09-27 15:17:52.347 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:1016] [1] responseText:
{
  "code": 0,
  "data": {
    "123": "alpha",
    "1111111": "alpha",
    "e453534534": "alpha"
  }
}
2019-09-27 15:17:52.347 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:419] [1] 返回码:0, isFail:0
2019-09-27 15:17:52.348 [DBUG] [43710 cpu0 2] [favicon.ico] [index.js:80] [set] filename : /Users/weijie/dev/test/TSW/log/cache/h5test/test.user.list.cache
2019-09-27 15:17:52.348 [DBUG] [43710 cpu0 2] [favicon.ico] [index.js:81] [set] dirname : /Users/weijie/dev/test/TSW/log/cache/h5test
2019-09-27 15:17:52.348 [DBUG] [43710 cpu0 2] [favicon.ico] [index.js:82] [set] basename : test.user.list.cache
2019-09-27 15:17:52.348 [DBUG] [43710 cpu0 2] [favicon.ico] [index.js:83] [set] randomname : test.user.list.cache.tmp.08120765845520994
2019-09-27 15:17:52.348 [DBUG] [43710 cpu0 2] [favicon.ico] [is-test.js:204] syncFromCloud success.
2019-09-27 15:17:52.349 [DBUG] [43710 cpu0 2] [favicon.ico] [index.js:95] [write] done: test.user.list.cache.tmp.08120765845520994, size: 54
2019-09-27 15:17:52.349 [DBUG] [43710 cpu0 2] [favicon.ico] [index.js:109] [rename] done: test.user.list.cache, cost: 2ms
2019-09-27 15:17:52.710 [DBUG] [43710 cpu0 1] [null] [capturer.js:189] [2] 10.68.108.65:62982 > 14.215.138.19:443 response 200 cost:760ms 
2019-09-27 15:17:52.710 [DBUG] [43710 cpu0 1] [null] [ajax.js:780] [2] 14.215.138.19:443 response 200 cost:762ms 
2019-09-27 15:17:52.711 [DBUG] [43710 cpu0 1] [null] [capturer.js:224] [2] end size:39, receive data cost: 761ms
2019-09-27 15:17:52.712 [DBUG] [43710 cpu0 1] [null] [ajax.js:936] [2] end:39, receive data cost: 2ms
2019-09-27 15:17:52.712 [DBUG] [43710 cpu0 1] [null] [ajax.js:965] [2] done size:39
2019-09-27 15:17:52.712 [DBUG] [43710 cpu0 1] [null] [ajax.js:1016] [2] responseText:
{
  "code": 0,
  "message": "success"
}
2019-09-27 15:17:52.713 [DBUG] [43710 cpu0 1] [null] [ajax.js:419] [2] 返回码:0, isFail:0
2019-09-27 15:17:52.713 [DBUG] [43710 cpu0 1] [null] [logReport.js:238] reportCloud success.
2019-09-27 15:17:52.730 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:189] [2] 10.68.108.65:62984 > 14.215.138.19:443 response 200 cost:542ms 
2019-09-27 15:17:52.730 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:780] [2] 14.215.138.19:443 response 200 cost:543ms 
2019-09-27 15:17:52.730 [DBUG] [43710 cpu0 2] [favicon.ico] [capturer.js:224] [2] end size:39, receive data cost: 542ms
2019-09-27 15:17:52.731 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:936] [2] end:39,  receive data cost: 1ms
2019-09-27 15:17:52.731 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:965] [2] done size:39
2019-09-27 15:17:52.731 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:1016] [2] responseText:
{
  "code": 0,
  "message": "success"
}
2019-09-27 15:17:52.731 [DBUG] [43710 cpu0 2] [favicon.ico] [ajax.js:419] [2] 返回码:0, isFail:0
2019-09-27 15:17:52.731 [DBUG] [43710 cpu0 2] [favicon.ico] [logReport.js:238] reportCloud success.
2019-09-27 15:17:53.957 [DBUG] [43710 cpu0 1] [null] [http.route.js:81] clearing
2019-09-27 15:17:54.189 [DBUG] [43710 cpu0 2] [favicon.ico] [http.route.js:81] clearing

用法含义错误

6

String.replace本意用来替换的,而且也里面函数也没返回值
如果只是用来提取数据应该用更明确的方法

关于npm install的报错

miaoh@DESKTOP-FCLG1GN MINGW64 ~/Desktop/tsw/TSW (master)
$ npm install --no-optional
npm ERR! code Z_BUF_ERROR
npm ERR! errno -5
npm ERR! unexpected end of file

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\miaoh\AppData\Roaming\npm-cache_logs\2018-06-12T14_50_47_817Z-debug.log
这个报错是什么原因呢

现有的TSW源码与业务代码整合问题?

如果我有多个koa的应用项目,彼此没有任何联系。

那么是 一个tsw + 一个koa项目整合在一起,还是一个全局的tsw,通过配置挂载多个koa项目。哪种方式会更好?

tsw+webpack dev middle做本地开发,热更新很慢,希望支持配置解决,谢谢

参考KM文章中:http://km.oa.com/articles/show/358254?kmref=search&from_page=1&no=4
里面也写到“我们node服务用的是tsw作为接入层,由于tsw设置了默认超时。当长时间保持http链接时,会被tsw认为是超时链接,被默认关闭。解决办法也很简单,对于content-type为event-stream不做超时处理”
咨询过作者,是改动了tsw源码去实现的。可否不改动tsw实现呢,希望指点

tsw如何集成到express 和 koa 脚手架生成的项目

现象

按照官网,跑了一下example中的例子,但是实际用express 和 koa 的项目必然不是像example中那样的一个 xxx.js ,通常nodejs项目大家应该都习惯用脚手架搭好,再开始码业务代码。但是实际使用过程中tsw接入express 和 koa 脚手架生成的项目的时候,一直返回 not found

nbwn8yvtka z n p40fy6sg

重现

  1. 安装 express 和 koa 脚手架 (express-generator and koa-generator)
  2. 生成两个项目
express express-test
koa2 koa-test
  1. 将这两个项目移动到 example 文件夹下(纯属为了方便)
  2. 直接修改 ../examples/framework/config.js 这个文件中的路由map,指向新的两个demo项目
// http://127.0.0.1/express
express: '../examples/express-test/app.js',
// http://127.0.0.1/koa
koa: '../examples/koa2-text/app.js'

2 9bxx 3mmw s 67uzrqah

  1. 之后启动 tsw node --inspect index.js 访问

b 5yq hnaw5 v1e iz3p 6

ykcigll2qw_9 x 9f1yn 8

Test

火速占坑拿下 #1 !!

关于项目的部分小建议

粗略看了下,说几点优化建议(只是个人建议,有更好的方式最好):

  1. 单元测试
    • 尽快完善测试用例吧...
    • 有可能的话加上 mocha+karma+travis+coveralls 类似的一些平台进行集成测试(当然不一定是前面说的几个,可以根据自己的需求来选择),并附加 badge,这样开发者也能知道项目概况;
    • npm script 里面没必要调用 node_modules 路径,install 后直接可以用命令来调用;
  2. 项目结构
    • 项目中文件没有区分度,很多都堆积在 bin 目录下(可能是历史原因,但开源毕竟开源,很多人在看),希望可以从整体架构层面优化一些(不带历史包袱最好,虽然看样子不可能);
    • readme 里面的图片直接仍在最上层文件夹,这让人就受不了了,如果后续里面有很多图那是不是得全放在下面?所以建议有个 static/resource 的概念,统一管理资源类;
  3. changelog
    • 开源按照开源的套路走,用 GitHub release note 不是更专业点么?
  4. 版本概念
    • 现在我看还没有版本的概念(tags 管理),加上对以后维护也有一定好处。
  5. 依赖 && 配置
    • /test, /bin 下面都有 node_module,不知道为什么要这么做?如果是需要改动源码来满足需求的话,建议还是自己开发吧...如果实在开发不了,我看里面部分 module 是 MIT 的,改动下自己发个 npm 包也能解决这个问题;
    • 加入 .gitignore.editorconfig 之类的配置文件统一规范整个项目吧。

其他一些点就不说了,很多人在知乎上都提过,开源是一件非常棒的事,也非常期望能够做好。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.