◆ 長時間開くページでは低頻度の console.log も結構な量になる
◆ console.log の出力が多いと devtools を開いたときに固まる
◆ console.clear で直近のある程度だけ残してクリアしたいけど全消ししかできなそう
◆ console 関数を置き換えて独自に履歴を保持して対処

問題点

長時間開くページで定期的な処理の情報を console.log でログに残したいです
常時開いてるようなページで サーバとの通信は fetch などのバックグラウンドで行うので 何日も開いたままにするページや ブラウザを開いてる間ずっと動作している拡張機能のバックグラウンドスクリプトが対象です

頻繁ではない console.log も長時間開いたままにするページでは大量のログになります
通常のページ閲覧者視点では console.log が多くても少しメモリ使用量が増えるくらいで特にページが重いと感じることはないです
ですが そのログを見る人にとっては少し問題になります
console.log による出力が多すぎると devtools を開いた瞬間にそれらを表示しようとするので すごく重くなります
F12 キーを押した直後に数秒~数十秒ブラウザが固まることもあります
ログが多ければ数分になるかもですし 場合によってはタブがクラッシュするかもしれません

console.clear

console.clear を使えばログをクリアできるのですが 調べてみても console.clear で柔軟なクリアはできず「これまでのログを全部消す」ということしかできないようです
直近 100 件だけ残すようなことはできません

100 回 console.log するごとに console.clear とすると devtools を開いたタイミングが 100 回目の console.log の直後だと全くログがない状態です
直近のある程度は常に出ていてほしいものです

console の関数置き換え

グループを使うなど色々方法を探したのですが 標準機能ではできなさそうだったので console 関数を置き換えることで対処することにしました

こういうモジュールファイルをロードします

const max_history = 1000
const clear_interval = 50

const history = []
let count = 0

const logger = (fn, save_num) => {
const log = (...args) => {
count = (count + 1) % clear_interval
if (count === 0) console.clear()

history.push([fn.name, ...args.slice(0, save_num || Infinity)])
if (history.length > max_history) history.shift()
fn(...args)
}
log.getHistory = getHistory
log.clearHistory = clearHistory
log.raw = fn
return log
}

const getHistory = (limit) => {
return history.slice(limit > 0 ? -limit : 0)
}

const clearHistory = (keep) => {
history.splice(0, keep || Infinity)
}

console.log = logger(console.log)
console.debug = logger(console.debug)
console.info = logger(console.info)
console.warn = logger(console.warn)
console.error = logger(console.error)
console.dir = logger(console.dir, 1)
console.dirxml = logger(console.dirxml, 1)

console.log の呼び出し時に引数を保存し独自に console.log の履歴を持ちます
重くならないようにコンソールへの出力は定期的に console.clear でクリアしますが 履歴を参照できるので クリア直後に devtools を開いても大丈夫という方針です

使い方

最初の max_history が履歴に保持する呼び出し回数です
1000 だと直近 1000 回分の console.log を履歴に保存します
多すぎるとメモリ使用量が増えるので必要な数に設定します
clear_interval が console.clear の呼び出し間隔です
console.log を指定回数呼び出すと console.clear を呼び出します

console.log と書いてますがライブラリや既存コードなどでは info を使うところがあったり error や warn も保存できたほうが良いかなと思って debug ~ error に dir/dirxml まで置き換えてます
assert や table は対象外です

履歴の参照は

console.log.getHistory()

でできます
配列形式で取得できるので コンソールで上のコードを実行するとすぐに見れます
console.log 以外に info や dir にも getHistory メソッドがありますが 履歴は 1 つにまとめているので得られる結果はすべて同じです
履歴のエントリに呼び出し関数名もあるので warn のみがほしいならフィルタすることはできます

履歴を消したいときは

console.log.clearHistory()

で消せます
これも log 以外の console.error.clearHistory などにしても同じ結果になります

また console.log.raw のように raw にアクセスすると本来の関数にアクセスできます
ここは console.log.raw と console.error.raw などで別物です

フォーマット文字列を使って

console.log("%cmessage", "color: red")

と書くと赤色で message と出力されますが 履歴では

["log", "%cmessage", "color: red"]

のように引数がそのまま保存されます

const hist = console.log.getHistory()
const [fn, ...args] = hist[0]
console[fn].raw(...args)

とすれば同じように フォーマット文字列付きで console.log した結果を表示できます