GAS サンプルあり

[GAS] 長すぎるログを表示するときに使える3つの方法

2021年2月12日

GASで実行結果を見たいときに、「ログ出力のサイズが大きすぎます。出力を切捨てます。」というメッセージとともに、ログが途中で切られてしまい肝心の中身が見えない…!なんていうことに遭遇されている方はいらっしゃいませんでしょうか?

(僕はスクレイピングしたときのHTMLコードを確認したいときにしばしば遭遇します、、)

確認したいのに見れない、でも専用のプログラムを1から書くのが面倒…という方に、今回は3つの方法でのログ確認用のサンプルプログラムをご紹介したいと思います!

はじめに

そもそも1度のログの出力文字数の限界ですが、GASでは8192文字を超えると出力が省略される仕様になっています。

蛇足ですが文字数の限界を超えると「ログ出力のサイズが大きすぎます。出力を切捨てます。」という表示も含めて8192文字になるので、少しだけ出力される文字数が減ったりもします。笑

 

方法① ログを分割して出力

お手軽さ  
有用性   
おすすめ度 

まず1つ目はログを限界の8192文字を超えないように分割して出力する方法です。

こちらの方法ではとても手軽にログを見ることはできますが、1つのまとまった出力として扱うことはできないので、ちょっと中身を見たいのに使う程度に留めておいたほうが良いかもしれません。

/**
 * 長ーいログを分割して出力
 * @param {String} text ログに出したい文字列
 */
function outputSplitLog(text) {
  const LENGTH = 8000;
  for (let i = 0; i <= text.length; i += LENGTH) {
    const fromIndex = i;
    const toIndex   = i + LENGTH;
    const subString = text.substring(fromIndex, toIndex);
    Logger.log(subString);
  }
}

 

方法② ファイルに書き出す

お手軽さ  
有用性   
おすすめ度 

次に2つめはテキストファイルに書き出しちゃおうという方法です。GASですとGoogleDrive上に手軽にファイルを書き出すことができるのでそちらを利用します。

GoogleDriveに確認しにいく手間はありますが、確実に全文を確認することができファイルとしても残るというメリットもあります。

/**
 * ログをGoogleDriveのファイルとして書き出し
 * @param {String} text 書き出したい文字列
 * @return {String} 書き出したファイルのURL
 */
function outputLog(text) {
  // 保存ファイル設定
  const now = new Date();
  const fileName    = 'log_' + formatDate(now, 'YYYYMMDDhhmmss') + '.txt';
  const contentType = 'text/plain';
  const charset     = 'utf-8';

  // ファイルを作成する
  const blob = Utilities.newBlob('', contentType, fileName).setDataFromString(text, charset)
  const file = DriveApp.createFile(blob);
  return file.getUrl();
}

/**
 * 時刻を指定したフォーマットに沿った文字列に変換
 * @param {Date}   date   日付
 * @param {String} format フォーマット
 * @return {String} 時刻文字列
*/
function formatDate(date, format) {
  let dateText = (format == null) ? 'YYYY-MM-DD' : format;
  dateText = dateText.replace(/YYYY/g, date.getFullYear());
  dateText = dateText.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
  dateText = dateText.replace(/DD/g, ('0' + date.getDate()).slice(-2));
  dateText = dateText.replace(/hh/g, ('0' + date.getHours()).slice(-2));
  dateText = dateText.replace(/mm/g, ('0' + date.getMinutes()).slice(-2));
  dateText = dateText.replace(/ss/g, ('0' + date.getSeconds()).slice(-2));
  dateText = dateText.replace(/M/g,  (date.getMonth() + 1));
  dateText = dateText.replace(/D/g,  (date.getDate()));
  dateText = dateText.replace(/h/g,  (date.getHours()));
  dateText = dateText.replace(/m/g,  (date.getMinutes()));
  dateText = dateText.replace(/s/g,  (date.getSeconds()));
  return dateText;
};

ちなみにこちらのサンプルでは現在時刻に合わせてファイル名を変えているので同じファイルがたくさん…!ということも避けられるつくりになっています。


方法③ シートに書き出す

お手軽さ  
有用性   
おすすめ度 

3つ目はシートに書き出しちゃおうという方法です。

シートの1セルに書き込める上限にも50000文字までという制約があるため、方法①のようにテキストを分割しセルを分けて書き出すことになります。

事前に出力用のシートを作る必要があったり、1セルに収まらない場合はテキストが分割されてしまうというデメリットがありますが、スプレッドシート内の作業であればすぐに確認ができるというのが大きなメリットです。

/**
 * ログをシートに出力
 * @param {String} text ログに出したい文字列
 */
function outputLogToSheet(text) {
  // 書き出し先シートを取得
  const SHEET_NAME = 'log';
  const sheet = SpreadsheetApp.getActive().getSheetByName(SHEET_NAME);
  
  // A1セルに書き出した日時を記載
  sheet.getRange('A1').setValue(new Date());
  
  // A2セル以降はいったんすべて消す
  sheet.getRange('A2:A').clearContent();
  
  // 50000文字ずつ分割してA列のセルに上から順番に入れる
  const LENGTH = 50000;
  let insertValues = [];
  for (let i = 0;  i < text.length; i += LENGTH) {
    const fromIndex = i;
    const toIndex   = i + LENGTH;
    const subString = text.substring(fromIndex, toIndex);
    insertValues.push([subString]);
  }
  sheet.getRange(2, 1, insertValues.length, insertValues[0].length).setValues(insertValues);
}

-GAS, サンプルあり
-,

© 2023 スプレッドシートで困ったときに見るサイト