使用npm:worker-loader,dexie,ali-oss
监听console,并做本地存储
创建一个浏览器DB
import Dexie from 'dexie';
const db = new Dexie('dbname');
db.version(1).stores({
logs: 'content',
});
export default db;
创建一个 log.worker
import db from './db';
const ctx: DedicatedWorkerGlobalScope = self as any;
// 监听 worker-loader 传递的消息
ctx.onmessage = async (evt: any) => {
if (evt.data) {
if (evt.data.type === 'log') {
if (db.isOpen()) {
// @ts-ignore
await db.logs.put({ content: evt.data.data });
} else {
await db.open();
}
}
}
};
export default null as any;
拦截console
/**
*
* 安装 worker-loader
* ts声明文件添加
declare module 'worker-loader!*' {
class WebpackWorker extends Worker {
constructor();
}
export default WebpackWorker;
}
*/
import LogWorker from 'worker-loader!./log.worker';
export default class Log {
static originConsole = window.console;
// 日志开关
static thread = null;
static init() {
if (!this.thread) {
// @ts-ignore
this.thread = new LogWorker();
this.debugLog();
}
}
static debugLog() {
const thread = this.thread as any;
function proxy(context: any, method: any) {
return function() {
let args = [...arguments];
args.flat().join('');
thread.postMessage({
type: 'log',
data: JSON.stringify([args.flat().join('')]),
});
// log.apply(console,console.log)
method.apply(context, args);
};
}
Object.keys(console)
.filter(e => ['info', 'error', 'warn', 'log', 'debug'].indexOf(e) >= 0)
.forEach((method: any, _) => {
//@ts-ignore
console[method] = proxy(console, console[method]);
});
//@ts-ignore
window.console = console;
}
}
入口文件 Log.init()
上传
/*
* @Author: Mr.pz
* @Date: 2021-01-04 09:59:42
* @Last Modified by: Mr.pz
* @Last Modified time: 2021-01-04 11:40:24
* 日志请求
*/
// 阿里的oss
import OSS from 'ali-oss';
import axios from 'axios';
import db from './db';
async function uploadLog() {
const id = '18546565'; // 传特殊识别号
//@ts-ignore
const logs = await db.logs.toArray();
const logsStr = logs
.reverse()
.map((e: any) => JSON.parse(e.content))
.map((e: any) => (Array.isArray(e) ? e[0] : e))
.join('\n');
//@ts-ignore
window.logsStr = logsStr;
const file = await new File([logsStr], `${+Date.now()}`);
//@ts-ignore
window.file = file;
// 上传到存储服务器
let res = await uploadToOss(id, file, 'log');
await db.delete();
// 上传完成之后删除,重新初始化
if (!(await Dexie.exists(db.name))) {
db.version(1).stores({
logs: 'content',
});
}
await db.open();
// return get(res, 'data.data', -1);
}
/**
*
* @param ownID
* @param file
* @param ext
*/
async function uploadToOss(ownID: string, file: any, ext: string) {
let {
bucketName,
callbackBody,
callbackContentType,
accessKeyId,
accessKeySecret,
securityToken,
ossKey,
} = await fetchStsToken(ownID, ext);
const ossParams = {
bucketName,
callbackBody,
callbackContentType,
accessKeyId,
accessKeySecret,
securityToken,
};
// 创建一个 client
const ossClient = new OSS({
accessKeyId: ossParams.accessKeyId,
accessKeySecret: ossParams.accessKeySecret,
stsToken: ossParams.securityToken,
bucket: ossParams.bucketName,
secure: true,
// TODO: 请传递你自己的oss endpoint
// TODO: Please use your own oss endpoint
endpoint: 'oss-accelerate.aliyuncs.com',
});
const PREFIX: string = 'https://xxx';
try {
return await ossClient.put(ossKey, file, {
callback: {
url: `${PREFIX}/xx/cabllback/api`,
body: callbackBody,
contentType: callbackContentType,
},
});
} catch (err) {
console.log(err);
}
}
/**
*
* @param ownID
* @param fileExt
* 获取token
*/
async function fetchStsToken(ownID: string, fileExt: string) {
// 请求得到oss 参数
let data = await axios(`https://get_params`);
return {
bucketName: data?.bucketName as string,
callbackBody: data?.callbackBody as string,
callbackContentType: data?.callbackContentType as string,
accessKeyId: data?.accessKeyId as string,
accessKeySecret: data?.accessKeySecret as string,
securityToken: data?.securityToken as string,
ossKey: data?.ossKey as string,
};
}
export default uploadLog;