前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NodeJS日志记录(Electron项目)

NodeJS日志记录(Electron项目)

作者头像
码客说
发布2021-07-07 17:56:46
2.8K0
发布2021-07-07 17:56:46
举报
文章被收录于专栏:码客

普通日志收集

主进程

log4js

下载依赖

代码语言:javascript
复制
npm install log4js --save

工具类

代码语言:javascript
复制
const log4js = require('log4js');
log4js.configure({
    appenders: {
        myLogFile: {
            type: "dateFile",
            filename: './logs/mylog',//您要写入日志文件的路径及文件名前缀
            pattern: "yyyy-MM-dd-hh.log",//(可选,默认为.yyyy-MM-dd) - 文件名后缀。格式:.yyyy-MM-dd-hh:mm:ss.log
            alwaysIncludePattern: true,//(默认为false) - 将模式包含在当前日志文件的名称以及备份中
            compress: false,//(默认为false) - 在滚动期间压缩备份文件(备份文件将具有.gz扩展名)
            encoding: 'utf-8',//default "utf-8",文件的编码
            maxLogSize: 1024 * 1024 // 1M 文件最大存储空间,当文件内容超过文件存储空间会自动生成一个文件xxx.log.1的序列自增长的文件
        },
        myLogConsole: {
            type: 'console'
        }
    },
    categories: {
        default: {
            appenders: ['myLogFile', 'myLogConsole'],
            level: log4js.levels.ALL
        },
        myLogFile: {
            appenders: ['myLogFile'],
            level: log4js.levels.ALL
        },
        myLogConsole: {
            appenders: ['myLogConsole'],
            level: log4js.levels.ALL
        }
    }
});
let log = log4js.getLogger('myLogFile');
module.exports.logger = log;

开发时在Console窗口中显示日志

代码语言:javascript
复制
log4js.getLogger('myLogConsole');

正式部署后改为

代码语言:javascript
复制
log4js.getLogger('myLogFile');

使用

代码语言:javascript
复制
const logger = require('./assets/js/MyLog').logger;
logger.info("app init");

logger对象暴露到全局(main.js)

代码语言:javascript
复制
global.zlog = logger;

注意

使用Electron和Webpack结合的时候,建议日志在main.js中引用,页面中通过ipc方式进行调用。 工具类MyLog.js我是配置在assets/js/MyLog.js。 package.json中配置build下的files配置。

package.json

代码语言:javascript
复制
{
  "name": "xhlive",
  "productName": "我的博客",
  "version": "1.3.6",
  "description": "",
  "main": "main.js",
  "build": {
    "asar": true,
    "files": [
      "build/*",
      "main.js",
      "*.html",
      "image",
      "assets",
      "app.ico",
      "node_modules/**/*"
    ],
    "appId": "cn.psvmc.myblog",
    "win": {
      "icon": "app.ico",
      "target": [
        "zip"
      ]
    },
    "nsis": {
      "oneClick": false,
      "allowElevation": true,
      "allowToChangeInstallationDirectory": true,
      "installerIcon": "app.ico",
      "uninstallerIcon": "app.ico",
      "installerHeaderIcon": "app.ico",
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "license": "LICENSE.txt"
    },
    "extraResources": [
    ],
    "mac": {
      "hardenedRuntime": false
    }
  },
  "scripts": {
    "start": "webpack --mode development && cross-env ELECTRON_DISABLE_SECURITY_WARNINGS=true electron .",
    "webpack": "webpack --mode development",
    "dist": "webpack --mode development && electron-builder --win --ia32",
    "dist_dir": "webpack --mode development && electron-builder --dir --win --ia32"
  },
  "devDependencies": {
  },
  "dependencies": {
  }
}

Electron-log(推荐)

Electron-log日志记录工具

首先我们安装依赖:

代码语言:javascript
复制
npm i electron-log --save

在项目里面引入依赖项:

代码语言:javascript
复制
const zlog = require('electron-log');
let filepath = path.join(app.getPath("documents"), 'xhlive/logs/');
let nowdate = new Date();
let nowdate_str = nowdate.getFullYear() + "_" + (nowdate.getMonth() + 1) + "_" + nowdate.getDate() + "_" + nowdate.getHours();
let filename = "mylog_" + nowdate_str + ".log";
zlog.transports.file.resolvePath = () => path.join(filepath, filename);
zlog.transports.file.level = true;
zlog.transports.console.level = false;
global.zlog = zlog;

然后在我们的主线程加入以下代码:

代码语言:javascript
复制
zlog.info('这是个提示日志');
zlog.warn('这是个警告日志');
zlog.error('这是个错误日志');

electron-log supports the following log levels:

代码语言:javascript
复制
error, warn, info, verbose, debug, silly

以上代码通过不同级别记录日志,默认情况下会在控制台打印出和保存到本地文件,

日志默认保存在app.getPath('userData')目录下的log.log文件中,

这个时候你会发现日志的时间和日志级别,日志内容都记录下来了,有这些信息我们就可以更好的跟踪bug等信息了。当然这个依赖不止这些功能:

我们可以设置log路径和文件名:

代码语言:javascript
复制
zlog.transports.file.resolvePath = () => path.join(filepath, filename);

我们可以格式化日志内容:

代码语言:javascript
复制
zlog.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}'

也可以通过log.transports.file.levellog.transports.console.level来分别设置日志输出目标和日志输出等级。

如果想禁止Console中输出可以设置对应项为false

代码语言:javascript
复制
zlog.transports.file.level = true;
zlog.transports.console.level = false;

虽然有了这些日志信息,但是都在不同用户的电脑上,我们可以开发一个程序,在适当的时候把用户日志传送到web服务器上去,这样让我们更好的跟踪!

渲染进程

工具类

代码语言:javascript
复制
const remote = window.require("electron").remote;
const app = remote.app;
let zlog = remote.getGlobal('zlog');
const isDevelopment = !app.isPackaged;
window.zlog = zlog;

function get_log_func(m_args) {
    let temp_arr = [];
    for (let m_arg of m_args) {
        if (m_arg) {
            if (m_arg instanceof Object) {
                temp_arr.push(JSON.stringify(m_arg));
            } else {
                temp_arr.push(m_arg);
            }
        }
    }
    return temp_arr.join(" | ");
}

let logger = {
    log: function (...args) {
        if (zlog) {
            zlog.info(get_log_func(args));
        }
        if (isDevelopment) {
            console.log(...args)
        }
    },
    info: function (...args) {
        if (zlog) {
            zlog.info(get_log_func(args));
        }
        if (isDevelopment) {
            console.info(...args)
        }
    },
    warn: function (...args) {
        if (zlog) {
            zlog.warn(get_log_func(args));
        }
        if (isDevelopment) {
            console.warn(...args)
        }
    },
    error: function (...args) {
        if (zlog) {
            zlog.error(get_log_func(args));
        }
        if (isDevelopment) {
            console.error(...args)
        }
    },
}

export {logger}

页面中引用

代码语言:javascript
复制
import {logger} from "./assets/js/mylog";
logger.info("登录初始化");

主进程网络日志

Electron有主进程和渲染进程,一般呢我们通过渲染进程的控制台network就可以看到程序发起的网络请求。但是使用这个方法呢会有三个问题:

  1. 无法监控主进程发起的网络请求;
  2. Electron呢可能会有多个窗口,不同的窗口发起不同的请求可能存在关联关系,就需要联合监控,就非常麻烦。
  3. 无法精确的分析某个时段的网络请求。

为了弥补这方面的不足,Electron提供了netLog模块,允许开发人员通过编程的方式记录网络请求。

代码语言:javascript
复制
const { remote } = require('electron') 
let filepath = path.join(app.getPath("documents"), 'xhlive/logs/');
let nowdate = new Date();
let nowdate_str = nowdate.getFullYear() + "_" + (nowdate.getMonth() + 1) + "_" + nowdate.getDate() + "_" + nowdate.getHours();
let filename = "mynet_" + nowdate_str + ".log";
await remote.netLog.startLogging(path.join(filepath, filename)); 
let ses = remote.getCurrentWebContents().session;
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.baidu.com');
xhr.onload = async () => { 
  log.info(xhr.responseText); 
  await remote.netLog.stopLogging() 
} 
xhr.send()

netLog模块是一个主进程模块,所以我们需要通过remote来使用他,

它的startLogging接收两个参数,第一个参数是日志文件记录的路径,也可以通过app.getPath('userData')来指定路径,第二个参数是一个配置对象,具体参考文档。

接着我们发起一个网络请求,得到响应后,我们通过stopLogging()来停止网络监控。

tips: 低版本的Electron可以使用以下方法:

app.commandLine.appendSwitch('log-net-log', 'net-log'),net-log为文件名称,可以自定义,文件会保存在项目根目录下,

也可以根据app.commandLine.hasSwitch('log-net-log')查看网络日志开关是否被打开,返回truefalse

崩溃日志收集

官方文档:https://www.electronjs.org/docs/api/crash-reporter#crashreporter

代码语言:javascript
复制
const {crashReporter} = require('electron')

crashReporter.start({
    productName:'myblog',
    companyName:'psvmc',
    submitURL:'https://www.psvmc.cn',
    uploadToServer:false
})

console.info(crashReporter.getCrashesDirectory());

可以调用以下方法模拟崩溃

代码语言:javascript
复制
process.crash()

官方说可以设置崩溃日志的目录,但是我这里设置无效

代码语言:javascript
复制
let logpath = path.resolve(app.getPath("documents") + '/myblog/logs/');
console.info(logpath);
app.setPath('crashDumps', logpath)

官方说的设置uploadToServer:false,就不需要设置submitURL,但是实际测试并非如此。

另外这种方法生成的错误日志也没法通过文本文档查看,所以我就没有使用。

但是我们可以监听事件child-process-gone

https://www.electronjs.org/docs/api/app#%E4%BA%8B%E4%BB%B6-render-process-gone

代码

代码语言:javascript
复制
const { app } = require('electron')

app.on('child-process-gone', (event, details) => {
    console.log(details);
})

崩毁重启

代码语言:javascript
复制
import { BrowserWindow, app, dialog} from 'electron';

const mainWindow = BrowserWindow.fromId(global.mainId);
mainWindow.webContents.on('crashed', () => {
   const options = {
      type: 'error',
      title: '进程崩溃了',
      message: '这个进程已经崩溃.',
      buttons: ['重载', '退出'],
    };    
   recordCrash().then(() => {
      dialog.showMessageBox(options, (index) => {
        if (index === 0) reloadWindow(mainWindow);
        else app.quit();
      });
    }).catch((e) => {
      console.log('err', e);
    });
})

function recordCrash() { 
    return new Promise(resolve => { 
       // 崩溃日志请求成功.... 
      resolve();
    })
}
  
function reloadWindow(mainWin) {
  if (mainWin.isDestroyed()) {
    app.relaunch();
    app.exit(0);
  } else {
    BrowserWindow.getAllWindows().forEach((w) => {
      if (w.id !== mainWin.id) w.destroy();
    });
    mainWin.reload();
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 普通日志收集
    • 主进程
      • log4js
      • Electron-log(推荐)
    • 渲染进程
    • 主进程网络日志
    • 崩溃日志收集
    相关产品与服务
    日志服务
    日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档