Code for final

ふぁいなる向けのコード置き場です。すでにコードじゃないこともいっぱい。

Electron with TypeScriptアプリで開発に耐えうるログの出力をする

Electronのログの出力はlog4jsを使えばできることがわかりましたが、サンプル程度に出力する記事しかなかったので実際にアプリを開発して アプリ開発に耐えうるログ出力についてまとめます。

log4jsをいれる

javaを使ったことある方ならおなじみのlog4jそのNode.jsバージョンが"log4js"です。

log4js-node.github.io

今回はTypeScriptで使うので型定義もインストールします。
vscodeのターミナルで以下のコマンドをたたきます。

npm install log4js
npm install @types/log4js

設定ファイルをおく

log4js用の設定ファイル(log4js.config.json)をルート(.gitignoreと同じ場所)に配置します。
一般的なアプリ開発でよく使うレベル別にインフォログ(app.log)とデバッグログ(debug.log)とエラーログ(error.log)の3つのファイルに分けて出力する設定になっています。
ログはルートの"logs"フォルダに出力されます。

ロガーの宣言をいれる

コード中にログ出力処理をいれます。
クラスごとに以下の宣言をいれればメインプロセス、レンダラープロセス問わずどこでも出力できます。
以下の例ではロガー設定ファイルのパスは内部設定から取得しています。

import { configure, getLogger } from "log4js";
import AppConfig from "../models/AppConfig";

configure(AppConfig.LoggerConfigFile); // configure("./log4js.config.json");でもOK
const logger = getLogger();

ロガーを使ってログを出力する

宣言したロガーを使ってソースコード中でログを出力します。
例えば検索処理で検索パラメタをデバッグログで出力する場合は以下のような感じになります。

async search() {
    try {
      logger.debug("Search Directory Path:[ %s ]", this.mainData.searchDirectory);
// ...

メッセージのフォーマットは以下のutil.format()に準拠しているみたいです。
ちなみにメッセージにフォーマットを指定せずに引数に渡した場合は末尾に追加されます。

nodejs.org

出力されるログは以下です。

[2020-06-21 15:59:07.604] [DEBUG] Search Directory Path:[ E:\test ]

スタックトレースを出力する

log4jsではログ出力設定でenableCallStackをtrueにしたらスタックトレースが出力されます。
上記の設定ではerrorレベルのみログ出力フォーマットにスタックトレースの出力情報を追加しているため、 errorレベルでのみスタックトレースが出力されます。

以下のようにディレクトリ削除処理でエラーとなった場合、エラーログを出力するとします。

ipcMain.handle("deleteDirectory", async (event, dirPath) => {
  const succesDirectories: string[] = [];

  await trash(dirPath)
    .then(() => {
      succesDirectories.push(dirPath);
    })
    .catch(() => {
      logger.error("error trash directory.", dirPath);
  });

  return succesDirectories;
});

出力されるログは以下になります。

[2020-06-21 16:19:32.357] [ERROR] error trash directory. E:\test\aaa
d:\finalstream\newdev\edc\dist_electron\index.js 28738 20
    at d:\finalstream\newdev\edc\dist_electron\index.js:28738:20
    at async d:\finalstream\newdev\edc\dist_electron\index.js:28733:9
    at async electron/js2c/browser_init.js:6152:30

・・・???。 そうです。Electronはjavascriptで動いているため、実際動作しているjsファイルの行数が出力されます。
あまり見ても役に立ちそうはないので、スタックトレースは出力しなくてもいいかもですね。

パッケージにログ出力設定ファイルを含める

このままパッケージングしてできたものを実行すると"log4js.config.json"が見つからないというエラーになってしまいます。
なので、electron-builderの設定で"log4js.config.json"をパッケージに含める設定を追加します。

module.exports = {
  // debug
  configureWebpack: {
    devtool: "source-map",
  },
  pluginOptions: {
    electronBuilder: {
      nodeIntegration: true,
      builderOptions: {
        extraFiles: ["log4js.config.json"],  // この設定を追加
      },
    },
  },
};

これだけ知っていればアプリでのログ出力は十分だと思います。
ただ、Electronアプリを開発始めたばかりなのでほかにも必要なことがあれば追記していきたいと思います。