前端简单的日志系统

该博客介绍了如何在前端实现一个简单的日志系统,包括监听console并将其存储到本地浏览器DB,创建log.worker,拦截console操作。还提到了使用worker-loader、dexie库进行数据管理,并利用ali-oss进行日志上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值