Pinoをインストール
ロガーとしてPinoをインストールします。
yarn add pino
Pinoの設定ファイルを作成
Pinoの設定をするためにlogger.js
を作成します。
logger.js
import pino from 'pino'
const logLevel = process.env.NODE_ENV === 'production' ? 'info' : 'trace'
const frontendOrigin = process.env.NEXT_PUBLIC_FRONTEND_ORIGIN
const logUrl = `${frontendOrigin}/api/log`
export const logger = pino({
level: logLevel, // 出力するログレベルを設定。指定したレベル以上のログが出力される
timestamp: pino.stdTimeFunctions.isoTime, // タイムスタンプの形式の設定
browser: {
// see https://github.com/pinojs/pino/issues/1795
write: () => {}, // ブラウザのコンソールにログを出力しないようにする
// ブラウザやミドルウェアのログをサーバーに送信するための設定
transmit: {
send: (level, logEvent) => {
// childを使用する場合にはlogEvent.messagesだけでなく、bindingsもサーバーに送信する必要がある
const messages = logEvent.messages
// ミドルウェアではnavigator.sendBeaconは使用できないため、keepalive:true の fetch を使用
// /api/logにリクエスト
void fetch(logUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ level, messages }),
keepalive: true,
})
},
},
},
})
middleware.js
はEdgeランタイムのみに対応しており、Node.jsランタイムに対応していないため、middleware.js
でログを記録した場合にもlogger.js
のbrowser
の設定が必要です。
Pinoの設定については以下をご参照ください。
- browser
childを使用する場合の参考
ログのためのRoute Handlerを実装する
サーバー側でログを記録するためにRoute Handerを以下のように実装します。
/api/log
にリクエストするとサーバー側でログが記録されます。
app/api/log/route.js
import { logger } from '@/lib/pino/logger'
export async function POST(req) {
const data = await req.json()
logger[data.level](...data.messages)
return new Response('Message has been successfully logged on the server', {
status: 200,
})
}
使用方法
クライアントコンポーネントに以下のように記述します。
'use client'
import { useEffect } from 'react'
export default function Sample() {
useEffect(() => {
logger.info('コンポーネントが表示されました。')
}, [])
return null
}
Sample
コンポーネントが表示されるとターミナルに以下のようなログが出力されます。
{"level":30,"time":"2024-03-11T15:51:47.156Z","pid":13565,"hostname":"39f2edc6b1ea","msg":"コンポーネントが表示されました。"}
pino-prettyを使用すると以下のように出力されます。
[00:54:06.999] INFO (14420): コンポーネントが表示されました。
middleware.js
でlogger
を使用した場合も上記と同じようにターミナルに出力されます。
Pinoの使用方法については以下をご参照ください。
参考