perf: 支持日志文件

pull/180/head
xiaojunnuo 2020-11-13 14:36:00 +08:00
parent c8437439ca
commit 83276a328f
26 changed files with 178 additions and 165 deletions

View File

@ -31,6 +31,9 @@ const localApi = {
return { return {
version: pk.version version: pk.version
} }
},
getConfigDir () {
return getDefaultConfigBasePath()
} }
}, },
/** /**
@ -81,6 +84,7 @@ const localApi = {
*/ */
save (newConfig) { save (newConfig) {
// 对比默认config的异同 // 对比默认config的异同
DevSidecar.api.config.set(newConfig)
const defConfig = DevSidecar.api.config.getDefault() const defConfig = DevSidecar.api.config.getDefault()
const saveConfig = doMerge(defConfig, newConfig) const saveConfig = doMerge(defConfig, newConfig)
fs.writeFileSync(_getConfigPath(), JSON5.stringify(saveConfig, null, 2)) fs.writeFileSync(_getConfigPath(), JSON5.stringify(saveConfig, null, 2))

View File

@ -17,6 +17,7 @@ const bindApi = (api, param1) => {
}) })
} }
const apiObj = { const apiObj = {
ipc: {
on (channel, callback) { on (channel, callback) {
ipcRenderer.on(channel, callback) ipcRenderer.on(channel, callback)
}, },
@ -24,6 +25,10 @@ const apiObj = {
send, send,
openExternal (href) { openExternal (href) {
shell.openExternal(href) shell.openExternal(href)
},
openPath (file) {
shell.openPath(file)
}
} }
} }
let inited = false let inited = false

View File

@ -39,13 +39,14 @@ export default {
this.applyLoading = true this.applyLoading = true
await this.applyBefore() await this.applyBefore()
await this.saveConfig() await this.saveConfig()
if (this.applyAfter) {
await this.applyAfter() await this.applyAfter()
}
this.applyLoading = false this.applyLoading = false
}, },
async applyBefore () { async applyBefore () {
},
async applyAfter () {
}, },
resetDefault () { resetDefault () {
const key = this.getKey() const key = this.getKey()

View File

@ -1,12 +1,12 @@
function install (app, api) { function install (app, api) {
api.on('error.core', (event, message) => { api.ipc.on('error.core', (event, message) => {
console.error('view on error', message) console.error('view on error', message)
const key = message.key const key = message.key
if (key === 'server') { if (key === 'server') {
handleServerStartError(message, message.error, app, api) handleServerStartError(message, message.error, app, api)
} }
}) })
api.on('error', (event, message) => { api.ipc.on('error', (event, message) => {
console.error('error', event, message) console.error('error', event, message)
}) })
} }

View File

@ -1,6 +1,6 @@
let updateParams = { } let updateParams = { }
function install (app, api) { function install (app, api) {
api.on('update', (event, message) => { api.ipc.on('update', (event, message) => {
console.log('on message', event, message) console.log('on message', event, message)
handleUpdateMessage(message, app) handleUpdateMessage(message, app)
}) })
@ -8,13 +8,13 @@ function install (app, api) {
api.update = { api.update = {
checkForUpdate (params) { checkForUpdate (params) {
updateParams = params || { fromUser: false, autoDownload: true, progress: 0 } updateParams = params || { fromUser: false, autoDownload: true, progress: 0 }
api.send('update', { key: 'checkForUpdate' }) api.ipc.send('update', { key: 'checkForUpdate' })
}, },
downloadUpdate () { downloadUpdate () {
api.send('update', { key: 'downloadUpdate' }) api.ipc.send('update', { key: 'downloadUpdate' })
}, },
doUpdateNow () { doUpdateNow () {
api.send('update', { key: 'doUpdateNow' }) api.ipc.send('update', { key: 'doUpdateNow' })
} }
} }

View File

@ -233,7 +233,7 @@ export default {
this.$api.update.checkForUpdate(this.update) this.$api.update.checkForUpdate(this.update)
}, },
openExternal (url) { openExternal (url) {
this.$api.openExternal(url) this.$api.ipc.openExternal(url)
} }
} }
} }

View File

@ -25,6 +25,8 @@
<a-tag v-else color="red"> <a-tag v-else color="red">
当前未启动 当前未启动
</a-tag> </a-tag>
<a-button class="md-mr-10" icon="profile" @click="openLog()"></a-button>
</a-form-item> </a-form-item>
<a-form-item label="代理端口" :label-col="labelCol" :wrapper-col="wrapperCol" > <a-form-item label="代理端口" :label-col="labelCol" :wrapper-col="wrapperCol" >
<a-input v-model="config.server.port"/> <a-input v-model="config.server.port"/>
@ -132,6 +134,10 @@ export default {
}, },
addDnsMapping () { addDnsMapping () {
this.dnsMappings.unshift({ key: '', value: 'usa' }) this.dnsMappings.unshift({ key: '', value: 'usa' })
},
async openLog () {
const dir = await this.$api.info.getConfigDir()
this.$api.ipc.openPath(dir + '/logs/server.log')
} }
} }
} }

View File

@ -12,7 +12,7 @@ const status = {
} }
} }
async function install (api) { async function install (api) {
api.on('status', (event, message) => { api.ipc.on('status', (event, message) => {
console.log('view on status', event, message) console.log('view on status', event, message)
const value = message.value const value = message.value
const key = message.key const key = message.key

View File

@ -1,7 +1,7 @@
const mitmproxy = require('./lib/proxy') const mitmproxy = require('./lib/proxy')
const ProxyOptions = require('./options') const ProxyOptions = require('./options')
const config = require('./lib/proxy/common/config') const config = require('./lib/proxy/common/config')
const log = require('./utils/util.log')
function fireError (e) { function fireError (e) {
process.send({ type: 'error', event: e }) process.send({ type: 'error', event: e })
} }
@ -13,28 +13,28 @@ let server
function registerProcessListener () { function registerProcessListener () {
process.on('message', function (msg) { process.on('message', function (msg) {
console.log('child get msg: ' + JSON.stringify(msg)) log.info('child get msg: ' + JSON.stringify(msg))
if (msg.type === 'action') { if (msg.type === 'action') {
api[msg.event.key](msg.event.params) api[msg.event.key](msg.event.params)
} }
}) })
process.on('SIGINT', () => { process.on('SIGINT', () => {
console.log('on sigint : closed ') log.info('on sigint : closed ')
process.exit(0) process.exit(0)
}) })
// 避免异常崩溃 // 避免异常崩溃
process.on('uncaughtException', function (err) { process.on('uncaughtException', function (err) {
if (err.code === 'ECONNABORTED') { if (err.code === 'ECONNABORTED') {
// console.error(err.errno) // log.error(err.errno)
return return
} }
console.error('uncaughtException:', err) log.error('uncaughtException:', err)
}) })
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason) log.info('Unhandled Rejection at: Promise', p, 'reason:', reason)
// application specific logging, throwing an error, or other logic here // application specific logging, throwing an error, or other logic here
}) })
} }
@ -49,17 +49,17 @@ const api = {
} }
const newServer = mitmproxy.createProxy(proxyOptions, () => { const newServer = mitmproxy.createProxy(proxyOptions, () => {
fireStatus(true) fireStatus(true)
console.log('代理服务已启动127.0.0.1:' + proxyOptions.port) log.info('代理服务已启动127.0.0.1:' + proxyOptions.port)
}) })
newServer.on('close', () => { newServer.on('close', () => {
console.log('server will closed ') log.info('server will closed ')
if (server === newServer) { if (server === newServer) {
server = null server = null
fireStatus(false) fireStatus(false)
} }
}) })
newServer.on('error', (e) => { newServer.on('error', (e) => {
console.log('server error', e) log.info('server error', e)
// newServer = null // newServer = null
fireError(e) fireError(e)
}) })
@ -72,20 +72,20 @@ const api = {
if (server) { if (server) {
server.close((err) => { server.close((err) => {
if (err) { if (err) {
console.log('close error', err, ',', err.code, ',', err.message, ',', err.errno) log.info('close error', err, ',', err.code, ',', err.message, ',', err.errno)
if (err.code === 'ERR_SERVER_NOT_RUNNING') { if (err.code === 'ERR_SERVER_NOT_RUNNING') {
console.log('代理服务关闭成功') log.info('代理服务关闭成功')
resolve() resolve()
return return
} }
reject(err) reject(err)
} else { } else {
console.log('代理服务关闭成功') log.info('代理服务关闭成功')
resolve() resolve()
} }
}) })
} else { } else {
console.log('server is null') log.info('server is null')
fireStatus(false) fireStatus(false)
resolve() resolve()
} }

View File

@ -1,8 +1,6 @@
const LRU = require('lru-cache') const LRU = require('lru-cache')
// const { isIP } = require('validator') // const { isIP } = require('validator')
const getLogger = require('../utils/logger') const log = require('../../utils/util.log')
const logger = getLogger('dns')
const cacheSize = 1024 const cacheSize = 1024
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
// function _isIP (v) { // function _isIP (v) {
@ -104,11 +102,11 @@ module.exports = class BaseDNS {
ipCache.setIpList(ipList) ipCache.setIpList(ipList)
logger.debug(`[DNS] ${hostname} -> ${ipCache.ip} (${new Date() - t} ms)`) log.info(`[DNS] ${hostname} -> ${ipCache.ip} (${new Date() - t} ms)`)
return ipCache.ip return ipCache.ip
} catch (error) { } catch (error) {
logger.debug(`[DNS] cannot resolve hostname ${hostname} (${error})`) log.error(`[DNS] cannot resolve hostname ${hostname} (${error})`)
return hostname return hostname
} }
} }

View File

@ -1,7 +1,7 @@
const { promisify } = require('util') const { promisify } = require('util')
const doh = require('dns-over-http') const doh = require('dns-over-http')
const BaseDNS = require('./base') const BaseDNS = require('./base')
const log = require('../../utils/util.log')
const dohQueryAsync = promisify(doh.query) const dohQueryAsync = promisify(doh.query)
module.exports = class DNSOverHTTPS extends BaseDNS { module.exports = class DNSOverHTTPS extends BaseDNS {
@ -15,18 +15,18 @@ module.exports = class DNSOverHTTPS extends BaseDNS {
const result = await dohQueryAsync({ url: this.dnsServer }, [{ type: 'A', name: hostname }]) const result = await dohQueryAsync({ url: this.dnsServer }, [{ type: 'A', name: hostname }])
if (result.answers.length === 0) { if (result.answers.length === 0) {
// 说明没有获取到ip // 说明没有获取到ip
console.log('该域名没有ip地址解析', hostname) log.info('该域名没有ip地址解析', hostname)
return [] return []
} }
const ret = result.answers.filter(item => { return item.type === 'A' }).map(item => { return item.data }) const ret = result.answers.filter(item => { return item.type === 'A' }).map(item => { return item.data })
if (ret.length === 0) { if (ret.length === 0) {
console.log('该域名没有ipv4地址解析', hostname) log.info('该域名没有ipv4地址解析', hostname)
} else { } else {
console.log('获取到域名地址:', hostname, JSON.stringify(ret)) log.info('获取到域名地址:', hostname, JSON.stringify(ret))
} }
return ret return ret
} catch (err) { } catch (err) {
console.log('dns query error', hostname, err) log.info('dns query error', hostname, err.message)
return [] return []
} }
} }

View File

@ -1,6 +1,9 @@
module.exports = {
module.exports = function createIntercept (context) {
const { log } = context
return {
requestInterceptor (interceptOpt, rOptions, req, res, ssl) { requestInterceptor (interceptOpt, rOptions, req, res, ssl) {
console.log('abort:', rOptions.hostname, req.url) log.info('abort:', rOptions.hostname, req.url)
res.writeHead(403) res.writeHead(403)
res.write('DevSidecar 403: \n\n request abort, this request is matched by abort intercept.\n\n 因配置abort拦截器本请求将取消') res.write('DevSidecar 403: \n\n request abort, this request is matched by abort intercept.\n\n 因配置abort拦截器本请求将取消')
res.end() res.end()
@ -8,4 +11,5 @@ module.exports = {
is (interceptOpt) { is (interceptOpt) {
return !!interceptOpt.abort return !!interceptOpt.abort
} }
}
} }

View File

@ -1,5 +1,7 @@
const url = require('url') const url = require('url')
module.exports = { module.exports = function createInterceptor (context) {
const { log } = context
return {
requestInterceptor (interceptOpt, rOptions, req, res, ssl, next) { requestInterceptor (interceptOpt, rOptions, req, res, ssl, next) {
const proxyTarget = interceptOpt.proxy const proxyTarget = interceptOpt.proxy
// const backup = interceptOpt.backup // const backup = interceptOpt.backup
@ -14,9 +16,10 @@ module.exports = {
rOptions.port = rOptions.protocol === 'https:' ? 443 : 80 rOptions.port = rOptions.protocol === 'https:' ? 443 : 80
} }
console.log('proxy:', rOptions.hostname, req.url, proxyTarget) log.info('proxy:', rOptions.hostname, req.url, proxyTarget)
}, },
is (interceptOpt) { is (interceptOpt) {
return !!interceptOpt.proxy return !!interceptOpt.proxy
} }
}
} }

View File

@ -1,4 +1,6 @@
module.exports = { module.exports = function createInterceptor (context) {
const { log } = context
return {
requestInterceptor (interceptOpt, rOptions, req, res, ssl) { requestInterceptor (interceptOpt, rOptions, req, res, ssl) {
const url = req.url const url = req.url
let redirect let redirect
@ -7,7 +9,7 @@ module.exports = {
} else { } else {
redirect = interceptOpt.redirect(url) redirect = interceptOpt.redirect(url)
} }
console.log('请求重定向:', rOptions.hostname, url, redirect) log.info('请求重定向:', rOptions.hostname, url, redirect)
res.writeHead(302, { Location: redirect }) res.writeHead(302, { Location: redirect })
res.end() res.end()
return true return true
@ -15,4 +17,5 @@ module.exports = {
is (interceptOpt) { is (interceptOpt) {
return interceptOpt.redirect // 如果配置中有redirect那么这个配置是需要redirect拦截的 return interceptOpt.redirect // 如果配置中有redirect那么这个配置是需要redirect拦截的
} }
}
} }

View File

@ -1,7 +1,8 @@
const proxy = require('./impl/proxy') const proxy = require('./impl/proxy')
const redirect = require('./impl/redirect') const redirect = require('./impl/redirect')
const abort = require('./impl/abort') const abort = require('./impl/abort')
const log = require('../../utils/util.log')
const modules = [proxy, redirect, abort] const context = { log }
const modules = [proxy(context), redirect(context), abort(context)]
module.exports = modules module.exports = modules

View File

@ -1,32 +0,0 @@
#!/usr/bin/env node
require('babel-polyfill')
const mitmproxy = require('../mitmproxy')
const program = require('commander')
const packageJson = require('../../package.json')
// const tlsUtils = require('../tls/tlsUtils')
const fs = require('fs')
const path = require('path')
const colors = require('colors')
fs.existsSync = fs.existsSync || path.existsSync
program
.version(packageJson.version)
.option('-c, --config [value]', 'config file path')
.parse(process.argv)
console.log(program.config)
const configPath = path.resolve(program.config)
if (fs.existsSync(configPath)) {
const configObject = require(configPath)
if (typeof configObject !== 'object') {
console.error(colors.red(`Config Error in ${configPath}`))
} else {
mitmproxy.createProxy(configObject)
}
} else {
console.error(colors.red(`Can not find \`config file\` file: ${configPath}`))
}

View File

@ -2,7 +2,7 @@ const url = require('url')
const Agent = require('./ProxyHttpAgent') const Agent = require('./ProxyHttpAgent')
const HttpsAgent = require('./ProxyHttpsAgent') const HttpsAgent = require('./ProxyHttpsAgent')
const tunnelAgent = require('tunnel-agent') const tunnelAgent = require('tunnel-agent')
const log = require('../../../utils/util.log')
const util = exports const util = exports
const httpsAgent = new HttpsAgent({ const httpsAgent = new HttpsAgent({
keepAlive: true, keepAlive: true,
@ -34,7 +34,7 @@ util.getOptionsFormRequest = (req, ssl, externalProxy = null) => {
try { try {
externalProxyUrl = externalProxy(req, ssl) externalProxyUrl = externalProxy(req, ssl)
} catch (e) { } catch (e) {
console.error('externalProxy', e) log.error('externalProxy', e)
} }
} }
} }

View File

@ -1,5 +1,6 @@
const net = require('net') const net = require('net')
const url = require('url') const url = require('url')
const log = require('../../../utils/util.log')
// const colors = require('colors') // const colors = require('colors')
const DnsUtil = require('../../dns/index') const DnsUtil = require('../../dns/index')
const localIP = '127.0.0.1' const localIP = '127.0.0.1'
@ -15,7 +16,7 @@ module.exports = function createConnectHandler (sslConnectInterceptor, fakeServe
fakeServerCenter.getServerPromise(hostname, srvUrl.port).then((serverObj) => { fakeServerCenter.getServerPromise(hostname, srvUrl.port).then((serverObj) => {
connect(req, cltSocket, head, localIP, serverObj.port) connect(req, cltSocket, head, localIP, serverObj.port)
}, (e) => { }, (e) => {
console.error('getServerPromise', e) log.error('getServerPromise', e)
}) })
} else { } else {
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig) connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig)
@ -25,7 +26,7 @@ module.exports = function createConnectHandler (sslConnectInterceptor, fakeServe
function connect (req, cltSocket, head, hostname, port, dnsConfig) { function connect (req, cltSocket, head, hostname, port, dnsConfig) {
// tunneling https // tunneling https
// console.log('connect:', hostname, port) // log.info('connect:', hostname, port)
const start = new Date().getTime() const start = new Date().getTime()
let isDnsIntercept = null let isDnsIntercept = null
try { try {
@ -62,21 +63,21 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig) {
proxySocket.on('timeout', () => { proxySocket.on('timeout', () => {
const end = new Date().getTime() const end = new Date().getTime()
console.log('代理socket timeout', hostname, port, (end - start) + 'ms') log.info('代理socket timeout', hostname, port, (end - start) + 'ms')
}) })
proxySocket.on('error', (e) => { proxySocket.on('error', (e) => {
// 连接失败可能被GFW拦截或者服务端拥挤 // 连接失败可能被GFW拦截或者服务端拥挤
const end = new Date().getTime() const end = new Date().getTime()
console.error('代理连接失败:', e.message, hostname, port, (end - start) + 'ms') log.error('代理连接失败:', e.message, hostname, port, (end - start) + 'ms')
cltSocket.destroy() cltSocket.destroy()
if (isDnsIntercept) { if (isDnsIntercept) {
const { dns, ip, hostname } = isDnsIntercept const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true) dns.count(hostname, ip, true)
console.error('记录ip失败次数,用于优选ip', hostname, ip) log.error('记录ip失败次数,用于优选ip', hostname, ip)
} }
}) })
return proxySocket return proxySocket
} catch (error) { } catch (error) {
console.log('connect err', error) log.error('connect err', error)
} }
} }

View File

@ -2,7 +2,7 @@ const fs = require('fs')
const forge = require('node-forge') const forge = require('node-forge')
const FakeServersCenter = require('../tls/FakeServersCenter') const FakeServersCenter = require('../tls/FakeServersCenter')
const colors = require('colors') const colors = require('colors')
const log = require('../../../utils/util.log')
module.exports = function createFakeServerCenter ({ module.exports = function createFakeServerCenter ({
caCertPath, caCertPath,
caKeyPath, caKeyPath,
@ -20,7 +20,7 @@ module.exports = function createFakeServerCenter ({
caCert = forge.pki.certificateFromPem(caCertPem) caCert = forge.pki.certificateFromPem(caCertPem)
caKey = forge.pki.privateKeyFromPem(caKeyPem) caKey = forge.pki.privateKeyFromPem(caKeyPem)
} catch (e) { } catch (e) {
console.log(colors.red('Can not find `CA certificate` or `CA key`.'), e) log.info(colors.red('Can not find `CA certificate` or `CA key`.'), e)
process.exit(1) process.exit(1)
} }

View File

@ -3,7 +3,7 @@ const https = require('https')
const commonUtil = require('../common/util') const commonUtil = require('../common/util')
// const upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i // const upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i
const DnsUtil = require('../../dns/index') const DnsUtil = require('../../dns/index')
const log = require('../../../utils/util.log')
// create requestHandler function // create requestHandler function
module.exports = function createRequestHandler (requestInterceptor, responseInterceptor, middlewares, externalProxy, dnsConfig) { module.exports = function createRequestHandler (requestInterceptor, responseInterceptor, middlewares, externalProxy, dnsConfig) {
// return // return
@ -43,7 +43,7 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
// const dns = DnsUtil.hasDnsLookup(dnsConfig, rOptions.host) // const dns = DnsUtil.hasDnsLookup(dnsConfig, rOptions.host)
// if (dns) { // if (dns) {
// const ip = await dns.lookup(rOptions.host) // const ip = await dns.lookup(rOptions.host)
// console.log('使用自定义dns:', rOptions.host, ip, dns.dnsServer) // log.info('使用自定义dns:', rOptions.host, ip, dns.dnsServer)
// rOptions.host = ip // rOptions.host = ip
// } // }
// } // }
@ -63,7 +63,7 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
function onFree () { function onFree () {
const url = `${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}` const url = `${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`
const start = new Date().getTime() const start = new Date().getTime()
console.log('代理请求:', url, rOptions.method) log.info('代理请求:', url, rOptions.method)
let isDnsIntercept let isDnsIntercept
if (dnsConfig) { if (dnsConfig) {
const dns = DnsUtil.hasDnsLookup(dnsConfig, rOptions.hostname) const dns = DnsUtil.hasDnsLookup(dnsConfig, rOptions.hostname)
@ -80,11 +80,10 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
} }
} }
} }
proxyReq = (rOptions.protocol === 'https:' ? https : http).request(rOptions, (proxyRes) => { proxyReq = (rOptions.protocol === 'https:' ? https : http).request(rOptions, (proxyRes) => {
const end = new Date().getTime() const end = new Date().getTime()
if (rOptions.protocol === 'https:') { if (rOptions.protocol === 'https:') {
console.log('代理请求返回:', url, (end - start) + 'ms') log.info('代理请求返回:', url, (end - start) + 'ms')
} }
resolve(proxyRes) resolve(proxyRes)
}) })
@ -94,10 +93,15 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
if (isDnsIntercept) { if (isDnsIntercept) {
const { dns, ip, hostname } = isDnsIntercept const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true) dns.count(hostname, ip, true)
console.error('记录ip失败次数,用于优选ip', hostname, ip) log.error('记录ip失败次数,用于优选ip', hostname, ip)
} }
console.error('代理请求超时', rOptions.protocol, rOptions.hostname, rOptions.path, (end - start) + 'ms') log.error('代理请求超时', rOptions.protocol, rOptions.hostname, rOptions.path, (end - start) + 'ms')
reject(new Error(`${rOptions.host}:${rOptions.port}, 代理请求超时`)) // reject(new Error(`${rOptions.host}:${rOptions.port}, 代理请求超时`))
proxyReq.end()
proxyReq.destroy()
res.writeHead(408)
res.write('DevSidecar Warning:\n\n 请求超时')
res.end()
}) })
proxyReq.on('error', (e) => { proxyReq.on('error', (e) => {
@ -105,28 +109,34 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
if (isDnsIntercept) { if (isDnsIntercept) {
const { dns, ip, hostname } = isDnsIntercept const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true) dns.count(hostname, ip, true)
console.error('记录ip失败次数,用于优选ip', hostname, ip) log.error('记录ip失败次数,用于优选ip', hostname, ip)
} }
console.error('代理请求错误', e.errno, rOptions.hostname, rOptions.path, (end - start) + 'ms', e) log.error('代理请求错误', e.code, e.message, rOptions.hostname, rOptions.path, (end - start) + 'ms')
reject(e) reject(e)
}) })
proxyReq.on('aborted', () => { proxyReq.on('aborted', () => {
console.error('代理请求被取消', rOptions.hostname, rOptions.path) log.error('代理请求被取消', rOptions.hostname, rOptions.path)
if (res.finished) {
return
}
reject(new Error('代理请求被取消')) reject(new Error('代理请求被取消'))
}) })
req.on('aborted', function () { req.on('aborted', function () {
console.error('请求被取消', rOptions.hostname, rOptions.path) log.error('请求被取消', rOptions.hostname, rOptions.path)
proxyReq.abort() proxyReq.abort()
if (res.finished) {
return
}
reject(new Error('请求被取消')) reject(new Error('请求被取消'))
}) })
req.on('error', function (e, req, res) { req.on('error', function (e, req, res) {
console.error('请求错误:', e.errno, rOptions.hostname, rOptions.path) log.error('请求错误:', e.errno, rOptions.hostname, rOptions.path)
reject(e) reject(e)
}) })
req.on('timeout', () => { req.on('timeout', () => {
console.error('请求超时', rOptions.hostname, rOptions.path) log.error('请求超时', rOptions.hostname, rOptions.path)
reject(new Error(`${rOptions.hostname}:${rOptions.port}, 请求超时`)) reject(new Error(`${rOptions.hostname}:${rOptions.port}, 请求超时`))
}) })
req.pipe(proxyReq) req.pipe(proxyReq)
@ -191,8 +201,8 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
res.writeHead(500) res.writeHead(500)
res.write(`DevSidecar Warning:\n\n ${e.toString()}`) res.write(`DevSidecar Warning:\n\n ${e.toString()}`)
res.end() res.end()
log.error('request error', e.message)
} }
console.error('request error', e.message)
} }
) )
} }

View File

@ -1,7 +1,7 @@
const http = require('http') const http = require('http')
const https = require('https') const https = require('https')
const util = require('../common/util') const util = require('../common/util')
const log = require('../../../utils/util.log')
// copy from node-http-proxy. ^_^ // copy from node-http-proxy. ^_^
// create connectHandler function // create connectHandler function
@ -11,7 +11,7 @@ module.exports = function createUpgradeHandler () {
const clientOptions = util.getOptionsFormRequest(req, ssl) const clientOptions = util.getOptionsFormRequest(req, ssl)
const proxyReq = (ssl ? https : http).request(clientOptions) const proxyReq = (ssl ? https : http).request(clientOptions)
proxyReq.on('error', (e) => { proxyReq.on('error', (e) => {
console.error(e) log.error('upgradeHandler', e)
}) })
proxyReq.on('response', function (res) { proxyReq.on('response', function (res) {
// if upgrade event isn't going to happen, close the socket // if upgrade event isn't going to happen, close the socket
@ -20,12 +20,11 @@ module.exports = function createUpgradeHandler () {
proxyReq.on('upgrade', function (proxyRes, proxySocket, proxyHead) { proxyReq.on('upgrade', function (proxyRes, proxySocket, proxyHead) {
proxySocket.on('error', (e) => { proxySocket.on('error', (e) => {
console.log('error-----1111') log.error('on upgrade:', e)
console.error(e)
}) })
cltSocket.on('error', function () { cltSocket.on('error', function (e) {
console.log('error-----2222') log.error('upgrade socket ', e)
proxySocket.end() proxySocket.end()
}) })

View File

@ -1,7 +1,7 @@
const tlsUtils = require('../tls/tlsUtils') const tlsUtils = require('../tls/tlsUtils')
const http = require('http') const http = require('http')
const config = require('../common/config') const config = require('../common/config')
const colors = require('colors') const log = require('../../../utils/util.log')
const createRequestHandler = require('./createRequestHandler') const createRequestHandler = require('./createRequestHandler')
const createConnectHandler = require('./createConnectHandler') const createConnectHandler = require('./createConnectHandler')
const createFakeServerCenter = require('./createFakeServerCenter') const createFakeServerCenter = require('./createFakeServerCenter')
@ -27,8 +27,8 @@ module.exports = {
caCertPath = rs.caCertPath caCertPath = rs.caCertPath
caKeyPath = rs.caKeyPath caKeyPath = rs.caKeyPath
if (rs.create) { if (rs.create) {
console.log(colors.cyan(`CA Cert saved in: ${caCertPath}`)) log.info(`CA Cert saved in: ${caCertPath}`)
console.log(colors.cyan(`CA private key saved in: ${caKeyPath}`)) log.info(`CA private key saved in: ${caKeyPath}`)
} }
} }
@ -59,18 +59,18 @@ module.exports = {
const server = new http.Server() const server = new http.Server()
server.listen(port, () => { server.listen(port, () => {
console.log(colors.green(`dev-sidecar启动端口: ${port}`)) log.info(`dev-sidecar启动端口: ${port}`)
server.on('error', (e) => { server.on('error', (e) => {
console.error(colors.red(e)) log.error('server error', e)
}) })
server.on('request', (req, res) => { server.on('request', (req, res) => {
const ssl = false const ssl = false
// console.log('request,', req.url, req.port, req.host) // log.info('request,', req.url, req.port, req.host)
requestHandler(req, res, ssl) requestHandler(req, res, ssl)
}) })
// tunneling for https // tunneling for https
server.on('connect', (req, cltSocket, head) => { server.on('connect', (req, cltSocket, head) => {
// console.log('connect,', req.url) // log.info('connect,', req.url)
connectHandler(req, cltSocket, head) connectHandler(req, cltSocket, head)
}) })
// TODO: handler WebSocket // TODO: handler WebSocket

View File

@ -5,7 +5,7 @@ const forge = require('node-forge')
const pki = forge.pki const pki = forge.pki
// const colors = require('colors') // const colors = require('colors')
const tls = require('tls') const tls = require('tls')
const log = require('../../../utils/util.log')
module.exports = class FakeServersCenter { module.exports = class FakeServersCenter {
constructor ({ maxLength = 256, requestHandler, upgradeHandler, caCert, caKey, getCertSocketTimeout }) { constructor ({ maxLength = 256, requestHandler, upgradeHandler, caCert, caKey, getCertSocketTimeout }) {
this.queue = [] this.queue = []
@ -23,13 +23,13 @@ module.exports = class FakeServersCenter {
if (this.queue.length >= this.maxLength) { if (this.queue.length >= this.maxLength) {
const delServerObj = this.queue.shift() const delServerObj = this.queue.shift()
try { try {
console.log('超过最大服务数量,删除旧服务', delServerObj) log.info('超过最大服务数量,删除旧服务', delServerObj)
delServerObj.serverObj.server.close() delServerObj.serverObj.server.close()
} catch (e) { } catch (e) {
console.log(e) log.info(e)
} }
} }
console.log('add server promise:', serverPromiseObj) log.info('add server promise:', serverPromiseObj)
this.queue.push(serverPromiseObj) this.queue.push(serverPromiseObj)
return serverPromiseObj return serverPromiseObj
} }
@ -64,7 +64,7 @@ module.exports = class FakeServersCenter {
SNICallback: (hostname, done) => { SNICallback: (hostname, done) => {
(async () => { (async () => {
const certObj = await this.certAndKeyContainer.getCertPromise(hostname, port) const certObj = await this.certAndKeyContainer.getCertPromise(hostname, port)
console.log('sni callback:', hostname) log.info('sni callback:', hostname)
done(null, tls.createSecureContext({ done(null, tls.createSecureContext({
key: pki.privateKeyToPem(certObj.key), key: pki.privateKeyToPem(certObj.key),
cert: pki.certificateToPem(certObj.cert) cert: pki.certificateToPem(certObj.cert)
@ -88,7 +88,7 @@ module.exports = class FakeServersCenter {
this.requestHandler(req, res, ssl) this.requestHandler(req, res, ssl)
}) })
fakeServer.on('error', (e) => { fakeServer.on('error', (e) => {
console.error(e) log.error(e)
}) })
fakeServer.on('listening', () => { fakeServer.on('listening', () => {
const mappingHostNames = tlsUtils.getMappingHostNamesFormCert(certObj.cert) const mappingHostNames = tlsUtils.getMappingHostNamesFormCert(certObj.cert)

View File

@ -1,6 +1,7 @@
const interceptors = require('./lib/interceptor') const interceptors = require('./lib/interceptor')
const dnsUtil = require('./lib/dns') const dnsUtil = require('./lib/dns')
const lodash = require('lodash') const lodash = require('lodash')
const log = require('./utils/util.log')
function matchHostname (hostMap, hostname) { function matchHostname (hostMap, hostname) {
const value = hostMap[hostname] const value = hostMap[hostname]
if (value) { if (value) {
@ -57,7 +58,7 @@ module.exports = (config) => {
const hostname = req.url.split(':')[0] const hostname = req.url.split(':')[0]
const inWhiteList = matchHostname(whiteList, hostname) != null const inWhiteList = matchHostname(whiteList, hostname) != null
if (inWhiteList) { if (inWhiteList) {
console.log('白名单域名,不拦截', hostname) log.info('白名单域名,不拦截', hostname)
return false return false
} }
return !!matchHostname(intercepts, hostname) // 配置了拦截的域名,将会被代理 return !!matchHostname(intercepts, hostname) // 配置了拦截的域名,将会被代理
@ -89,7 +90,7 @@ module.exports = (config) => {
} }
} catch (err) { } catch (err) {
// 拦截失败 // 拦截失败
console.error(err) log.error('拦截器执行错误', err)
} }
} }
} }

View File

@ -1,8 +1,9 @@
const os = require('os') const os = require('os')
const log = require('util.log')
const util = { const util = {
getNodeVersion () { getNodeVersion () {
const version = process.version const version = process.version
console.log(version) log.info(version)
} }
} }
util.getNodeVersion() util.getNodeVersion()

View File

@ -0,0 +1,8 @@
const log4js = require('log4js')
const proxyConfig = require('../lib/proxy/common/config')
log4js.configure({
appenders: { std: { type: 'stdout' }, file: { type: 'file', pattern: '.yyyy-MM-dd', daysToKeep: 3, filename: proxyConfig.getDefaultCABasePath() + '/logs/server.log' } },
categories: { default: { appenders: ['file', 'std'], level: 'info' } }
})
const logger = log4js.getLogger('server')
module.exports = logger