Skip to content

Commit ee7022b

Browse files
committed
优化实现
1 parent 628894a commit ee7022b

File tree

12 files changed

+172
-150
lines changed

12 files changed

+172
-150
lines changed

src/logger.ts

Lines changed: 0 additions & 72 deletions
This file was deleted.

src/logger/index.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { reportV3, V3LogInfo } from './report-v3'
2+
3+
export type LogLevel = 'INFO' | 'WARN' | 'ERROR' | 'OFF'
4+
5+
export class Logger {
6+
// 为每个类分配一个 id
7+
// 用以区分不同的上传任务
8+
private id = Logger.id += 1
9+
private static id: number = 0
10+
11+
constructor(
12+
private token: string,
13+
private disableReport = true,
14+
private level: LogLevel = 'OFF'
15+
) { }
16+
17+
/**
18+
* @param {V3LogInfo} data 上报的数据。
19+
* @param {boolean} retry 重试次数,可选,默认为 3。
20+
* @description 向服务端上报统计信息。
21+
*/
22+
report(data: V3LogInfo, retry?: number) {
23+
if (this.disableReport) return
24+
try { reportV3(this.token, data, retry) }
25+
catch (error) { console.warn(error) }
26+
}
27+
28+
/**
29+
* @param {unknown[]} ...args
30+
* @description 输出 info 级别的调试信息。
31+
*/
32+
info(...args: unknown[]) {
33+
const allowLevel: LogLevel[] = ['INFO']
34+
if (allowLevel.includes(this.level)) {
35+
console.log(`Qiniu-JS-SDK [INFO][${this.id}]: `, ...args)
36+
}
37+
}
38+
39+
/**
40+
* @param {unknown[]} ...args
41+
* @description 输出 warn 级别的调试信息。
42+
*/
43+
warn(...args: unknown[]) {
44+
const allowLevel: LogLevel[] = ['INFO', 'WARN']
45+
if (allowLevel.includes(this.level)) {
46+
console.warn(`Qiniu-JS-SDK [WARN][${this.id}]: `, ...args)
47+
}
48+
}
49+
50+
/**
51+
* @param {unknown[]} ...args
52+
* @description 输出 error 级别的调试信息。
53+
*/
54+
error(...args: unknown[]) {
55+
const allowLevel: LogLevel[] = ['INFO', 'WARN', 'ERROR']
56+
if (allowLevel.includes(this.level)) {
57+
console.error(`Qiniu-JS-SDK [ERROR][${this.id}]: `, ...args)
58+
}
59+
}
60+
}

src/logger/report-v3.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { createXHR, getAuthHeaders } from '../utils'
2+
3+
export interface V3LogInfo {
4+
code: number
5+
reqId: string
6+
host: string
7+
remoteIp: string
8+
port: string
9+
duration: number
10+
time: number
11+
bytesSent: number
12+
upType: 'jssdk-h5'
13+
size: number
14+
}
15+
16+
/**
17+
* @param {string} token 上传使用的 token
18+
* @param {V3LogInfo} data 上报的统计数据
19+
* @param {number} retry 重试的次数,默认值 3
20+
* @description v3 版本的日志上传接口,参考文档 https://github.com/qbox/product/blob/master/kodo/uplog.md#%E7%89%88%E6%9C%AC-3。
21+
*/
22+
export function reportV3(token: string, data: V3LogInfo, retry = 3) {
23+
const xhr = createXHR()
24+
xhr.open('POST', 'https://uplog.qbox.me/log/3')
25+
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
26+
xhr.setRequestHeader('Authorization', getAuthHeaders(token).Authorization)
27+
xhr.onreadystatechange = () => {
28+
if (xhr.readyState === 4 && xhr.status !== 200 && retry > 0) {
29+
reportV3(token, data, retry - 1)
30+
}
31+
}
32+
33+
// 顺序参考:https://github.com/qbox/product/blob/master/kodo/uplog.md#%E7%89%88%E6%9C%AC-3
34+
const stringifyData = [
35+
data.code || '',
36+
data.reqId || '',
37+
data.host || '',
38+
data.remoteIp || '',
39+
data.port || '',
40+
data.duration || '',
41+
data.time || '',
42+
data.bytesSent || '',
43+
data.upType || '',
44+
data.size || ''
45+
].join(',')
46+
47+
xhr.send(stringifyData)
48+
}

src/statisticsLog.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/upload/base.ts

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,14 @@ export default abstract class Base {
119119
...options.config
120120
}
121121

122-
logger.info('inited Config', this.config)
122+
logger.info('config inited.', this.config)
123123

124124
this.putExtra = {
125125
fname: '',
126126
...options.putExtra
127127
}
128128

129-
logger.info('inited putExtra', this.putExtra)
129+
logger.info('putExtra inited.', this.putExtra)
130130

131131
this.file = options.file
132132
this.key = options.key
@@ -139,11 +139,21 @@ export default abstract class Base {
139139
try {
140140
this.bucket = utils.getPutPolicy(this.token).bucket
141141
} catch (e) {
142-
this.onError(e)
143142
logger.error('get bucket from token failed.', e)
143+
this.onError(e)
144144
}
145145
}
146146

147+
private handleError(message: string) {
148+
const err = new Error(message)
149+
this.logger.error(message)
150+
this.onError(err)
151+
}
152+
153+
154+
/**
155+
* @description 上传文件,状态信息请通过 [Subscriber] 获取。
156+
*/
147157
public async putFile(): Promise<void> {
148158
this.aborted = false
149159
if (!this.putExtra.fname) {
@@ -152,41 +162,32 @@ export default abstract class Base {
152162
}
153163

154164
if (this.file.size > 10000 * GB) {
155-
const errorMessage = 'file size exceed maximum value 10000G'
156-
const err = new Error(errorMessage)
157-
this.logger.error(errorMessage)
158-
this.onError(err)
159-
throw err
165+
this.handleError('file size exceed maximum value 10000G.')
166+
return
160167
}
161168

162169
if (this.putExtra.customVars) {
163170
if (!utils.isCustomVarsValid(this.putExtra.customVars)) {
164-
const errorMessage = 'customVars key should start width x:'
165-
const err = new Error(errorMessage)
166-
this.logger.error(errorMessage)
167-
this.onError(err)
168-
throw err
171+
this.handleError('customVars key should start width x:.')
172+
return
169173
}
170174
}
171175

172176
if (this.putExtra.metadata) {
173177
if (!utils.isMetaDataValid(this.putExtra.metadata)) {
174-
const errorMessage = 'metadata key should start with x-qn-meta-'
175-
const err = new Error(errorMessage)
176-
this.logger.error(errorMessage)
177-
this.onError(err)
178-
throw err
178+
this.handleError('metadata key should start with x-qn-meta-.')
179+
return
179180
}
180181
}
181182

182183
try {
183-
this.logger.info('getUploadUrl')
184184
this.uploadUrl = await getUploadUrl(this.config, this.token)
185+
this.logger.info('get uploadUrl from api.', this.uploadUrl)
185186
this.uploadAt = new Date().getTime()
186187

187188
const result = await this.run()
188189
this.onComplete(result.data)
189-
this.sendLog(result.reqId, 200) // 收集成功的日志感觉没啥用?
190+
this.sendLog(result.reqId, 200)
190191
return
191192
} catch (err) {
192193
this.logger.error(err)
@@ -204,17 +205,23 @@ export default abstract class Base {
204205
// 1. 满足 needRetry 的条件且 retryCount 不为 0
205206
// 2. uploadId 无效时在 resume 里会清除本地数据,并且这里触发重新上传
206207
if (needRetry && notReachRetryCount || err.code === 612) {
207-
this.logger.warn(`error auto retry: ${this.retryCount}/${this.config.retryCount}`)
208-
return this.putFile()
208+
this.logger.warn(`error auto retry: ${this.retryCount}/${this.config.retryCount}.`)
209+
this.putFile()
210+
return
209211
}
210212

211213
this.onError(err)
212214
}
213215
}
214216

215217
private clear() {
218+
// abort 会触发 onreadystatechange
219+
// MDN 文档表示:readyState 为 0 并且 status 为 0
216220
this.logger.info('start cleaning all xhr.')
217-
this.xhrList.forEach(xhr => xhr.abort())
221+
this.xhrList.forEach(xhr => {
222+
xhr.onreadystatechange = null
223+
xhr.abort()
224+
})
218225
this.logger.info('cleanup completed.')
219226
this.xhrList = []
220227
}
@@ -230,7 +237,7 @@ export default abstract class Base {
230237
}
231238

232239
private sendLog(reqId: string, code: number) {
233-
this.logger.info({
240+
this.logger.report({
234241
code,
235242
reqId,
236243
host: utils.getDomainFromUrl(this.uploadUrl),

src/upload/direct.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ export default class Direct extends Base {
1616
formData.append('fname', this.putExtra.fname)
1717

1818
if (this.putExtra.customVars) {
19-
this.logger.info('inited customVars.')
19+
this.logger.info('init customVars.')
2020
const { customVars } = this.putExtra
2121
Object.keys(customVars).forEach(key => formData.append(key, customVars[key].toString()))
22+
this.logger.info('customVars inited.')
2223
}
2324

24-
this.logger.info('inited formData.')
25-
25+
this.logger.info('formData inited.')
2626
const result = await request<UploadCompleteData>(this.uploadUrl, {
2727
method: 'POST',
2828
body: formData,
@@ -32,7 +32,7 @@ export default class Direct extends Base {
3232
onCreate: xhr => this.addXhr(xhr)
3333
})
3434

35-
this.logger.info('finishDirectProgress.')
35+
this.logger.info('Direct progress finish.')
3636
this.finishDirectProgress()
3737
return result
3838
}
@@ -46,7 +46,7 @@ export default class Direct extends Base {
4646
private finishDirectProgress() {
4747
// 在某些浏览器环境下,xhr 的 progress 事件无法被触发,progress 为 null,这里 fake 下
4848
if (!this.progress) {
49-
this.logger.warn('progress is null')
49+
this.logger.warn('progress is null.')
5050
this.progress = { total: this.getProgressInfoItem(this.file.size, this.file.size) }
5151
this.onData(this.progress)
5252
return

src/upload/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ export default function createUploadManager(
2222
return new Resume(options, handlers, logger)
2323
}
2424

25-
logger.info('file size less than 4M, use Direct.')
25+
logger.info('file size less or equal than 4M, use Direct.')
2626
return new Direct(options, handlers, logger)
2727
}

0 commit comments

Comments
 (0)