クライアントでログ設計
こんにちは!CURUCURU エンジニアの笠原です! 今回はクライアントサイド(SPAなど)でのログの設計についてお話します。
ログとは
データログは出来事(イベント)とその時刻の記録である。例えば日記は出来事と日付のあつまりである[要出典]。データログを生成・記録する行為をロギング(logging)という
出典:データログ
クライアントサイドでログのといえば console.log()
があります。
devtool の console にログを出力するだけの簡単なメソッドです。
開発を行ってると、「開発環境ではこのログを出したけど、本番では出したくない」「特定のログレベルのログはエラー収集ツールに送信したい」といった要望が出てくると思います。 そんなときに console.log() だけでは力不足になるので、最低限の機能を備えた logger を設計しょうと思います。
loglevel
全て一から作成するのではなく loglevel パッケージをベースに開発します。
loglevel は軽量で単純なロギングパケージです。 ログを出力するには次のいずれかのメソッドを使います。
log.trace(msg);
log.debug(msg);
log.info(msg);
log.warn(msg);
log.error(msg);
また log.setLevel(level, [persis])
メソッドでログレベルを指定すると、指定されたレベルより下のロギングが無効になります。
log.setLoglevel('warn');
// 出力されない
log.info('ログ');
// 出力される
log.warn('警告');
log.error('エラー');
logger
では logger の設計です。 基本的には loglevel を wrap するだけですが、wrap することによって loglevel 以外のパッケージに変えたくなっても変更が容易になります。
import loglevel from 'loglevel';
import * as Sentry from '@sentry/react';
if (process.env.NODE_ENV === 'test') {
loglevel.setLevel('silent');
} else if (process.env.NODE_ENV === 'production') {
loglevel.setLevel('info');
} else {
loglevel.setLevel('debug');
}
export const logger = {
...loglevel,
info: (...msg: any[]) => {
loglevel.info(...msg);
const json = JSON.stringify(msg);
Sentry.addBreadcrumb({ message: json, level: 'info' });
},
error: (...msg: any[]) => {
loglevel.error(...msg);
const json = JSON.stringify(msg);
Sentry.addBreadcrumb({ message: json, level: 'error' });
},
fatal: (...msg: any[]) => {
loglevel.error(...msg);
Sentry.captureException(msg);
},
} as const;
info, error 単純にラップしていて + Sentry にユーザーの操作ログを送信するようにしています。 fatal は loglevel にはないので追加で実装し、キャプチャしたエラーを Sentry に送信しています。
まとめ
ログを整備することでデバッグに役立ちます。Sentry のようなサービスを使えば、開発時のテストだけでは見つけられないようなバグを詳細なログ付きで確認できるようになります。 ぜひクライアントでもログを活用してください。
CURUCUR のエンジニアチームは依頼されたことをこなすだけではなく、自分たちがもっと成長して、より会社に貢献するにはどうすればいいかと常に考え、いろいろなことに取り組んでいます。
CURUCURU でエンジニアとして働くことに興味がある方はよければオンラインでカジュアルにお話しましょう! https://www.wantedly.com/companies/curucuru/projects