1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GASのconsole.logを書き換えようと思ったらできなかった話

1
Posted at

何がしたかったのか

下記記事を参考に、console.logの内容を掠め取ろうと思いました
→GASにはLogger.logLogger.getLogという機能があるため、不要かとも思われるのですが、logしか使えないため、
 下記の内容+errorやwarnも追加すれば便利になるのでは?!と思った

レッツトライ(失敗します)

JavaScriptコード(TypeScriptからコンパイルしたやつ)

JSDocはChatGPTに任せました

"use strict";
/**
 * 渡された値がオブジェクトかどうかを判定します。
 * @param {any} value 判定対象の値
 * @returns {boolean} 渡された値がオブジェクトである場合は true、そうでない場合は false を返します。
 */
const isObject = (value) =>
  Object.prototype.toString.call(value) === "[object Object]" && !Array.isArray(value) && value !== null && typeof value !== "undefined";
/**
 * オブジェクトを文字列に変換する関数
 * @param {object} obj - 変換するオブジェクト
 * @return {string} 変換された文字列
 */
const objToString = (obj) =>
  JSON.stringify(obj)
    .split(",")
    .map((element) =>
      element.replace(/(.+:)(.*)/, (string, capture1, capture2) => capture1.replace(/\"/g, "") + capture2).replace(/:/g, ": ")
    )
    .join(", ");
/**
 * 拡張コンソールオブジェクト
 * @typedef {Object} ConsoleExt
 * @property {Function} originalConsoleLog - オリジナルのconsole.log
 * @property {Function} originalConsoleInfo - オリジナルのconsole.info
 * @property {Function} originalConsoleWarn - オリジナルのconsole.warn
 * @property {Function} originalConsoleError - オリジナルのconsole.error
 * @property {Array} result - コンソールに出力されたログの配列
 * @property {Boolean} logOutput - コンソールにログを出力するかどうかのフラグ
 * @property {Function} log - ログを出力する
 * @property {Function} info - 情報を出力する
 * @property {Function} warn - 警告を出力する
 * @property {Function} error - エラーを出力する
 * @property {Function} hook - オリジナルのconsoleオブジェクトに拡張メソッドをフックする
 * @property {Function} unhook - オリジナルのconsoleオブジェクトから拡張メソッドのフックを解除する
 * @property {Function} setup - ログの出力フラグを設定する
 */
const consoleExt = {
  originalConsoleLog: console.log,
  originalConsoleInfo: console.info,
  originalConsoleWarn: console.warn,
  originalConsoleError: console.error,
  original: {...console},
  result: [],
  logOutput: true,
  log: function (message) {
    if (consoleExt.logOutput) consoleExt.originalConsoleLog(message);
    consoleExt.result.push({
      type: "LOG",
      message: isObject(message) ? objToString(message) : message,
      time: new Date(),
    });
  },
  info: function (message) {
    if (consoleExt.logOutput) consoleExt.originalConsoleInfo(message);
    consoleExt.result.push({
      type: "INFO",
      message: isObject(message) ? objToString(message) : message,
      time: new Date(),
    });
  },
  warn: function (message) {
    if (consoleExt.logOutput) consoleExt.originalConsoleWarn(message);
    consoleExt.result.push({
      type: "WARN",
      message: isObject(message) ? objToString(message) : message,
      time: new Date(),
    });
  },
  error: function (message) {
    if (consoleExt.logOutput) consoleExt.originalConsoleError(message);
    consoleExt.result.push({
      type: "ERROR",
      message: isObject(message) ? objToString(message) : message,
      time: new Date(),
    });
  },
  hook: function () {
    if (consoleExt.originalConsoleLog === console.log) console.log = consoleExt.log;
    if (consoleExt.originalConsoleInfo === console.info) console.info = consoleExt.info;
    if (consoleExt.originalConsoleWarn === console.warn) console.warn = consoleExt.warn;
    if (consoleExt.originalConsoleError === console.error) console.error = consoleExt.error;
  },
  unhook: function () {
    if (consoleExt.originalConsoleLog !== console.log) console.log = consoleExt.originalConsoleLog;
    if (consoleExt.originalConsoleInfo !== console.info) console.info = consoleExt.originalConsoleInfo;
    if (consoleExt.originalConsoleWarn !== console.warn) console.warn = consoleExt.originalConsoleWarn;
    if (consoleExt.originalConsoleError !== console.error) console.error = consoleExt.originalConsoleError;
  },
  setup: function ({ logOutput }) {
    if (logOutput !== undefined) consoleExt.logOutput = logOutput;
  },
};
GAS
/* consoleExtは記載済み */
function myFunction() {
  consoleExt.hook();
  console.log("logging");
  console.warn("warning");
  console.info("infomation");
  console.error("errrrrrrrr");
  consoleExt.unhook();
  console.log(consoleExt.result.map(v=>`[${v.type}]\t${Utilities.formatDate(v.time, "JST", "yyyy/MM/dd HH:mm:ss:SSS")}\t${v.message}`).join("\n"));
}

実行してみる

スクリーンショット 2023-02-19 23.11.24.png

(’ω’)ん?

おかしいなーと思い、consoleExt.result.lengthを確認してみると0

consoleよりLoggerの方が詳しい内容が見れるのでLogger.logでhook前後のconsole.logの値を確認してみる

GAS
function myFunction() {
  Logger.log(console.log);
  consoleExt.hook();
  Logger.log(console.log);
}

スクリーンショット 2023-02-19 23.14.58.png

変わってね〜o(´д`o)

直接console.logに何か入れたら変わるかな?(変わらない)

GAS
function myFunction(){
  console.log = "warawara";
  Logger.log(console.log);
}

まとめ

無理だった

console.logのまま掠め取ることは厳しそうなので、
大人しくオブジェクトから呼び出せばロギングしつつ最後まとめてログ出力できるしな〜ってことで諦め。
console.logconsole.warnのまま利用することで、
エラーになった時のメール文にHTMLビューと折り合わせていい感じのログ出力をさせたかったんですが、、、(Ⅲ-ω-)

ChatGPTに聞いてみた

GASでconsole.logを書き換えようと思ったら、書き換えれなかったのですが、なぜかわかりますか

GASの実行環境では、標準のconsole.logなどのグローバルオブジェクトは、実際にはGoogleが提供するLoggerクラスにマッピングされています。このため、通常のJavaScriptとは異なり、console.logを直接書き換えることはできません。

しかし、代わりにLoggerクラスを使用してログを出力することができます。例えば、次のようにしてログを出力することができます。

Logger.log("Hello, world!");

また、console.logを書き換えたい理由が、単に出力されるログを加工したい場合であれば、以下のようなライブラリを使用することができます。

BetterLog: https://github.com/peterherrmann/BetterLog
このライブラリを使用すると、通常のconsole.logと同じようにログを出力することができますが、ログのフォーマットをカスタマイズすることができます。ただし、BetterLogを使用するには、Loggerクラスにアクセスする必要があります。

ChatGPT凄いね

以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?