🔍
Next.jsのログをApplication Insightsに送る
Next.jsのログをApplication Insightsのtraceに送るのでハマったので手順をメモ
コードはここに置いてある
前提
- App Service から Application Insights へ
- App ServiceはDockerイメージ利用
- Next.js
- ロガーはwinston
手順
Azureのリソースを作成する
次のような感じでリソースを定義して、terraform apply
する。
注意点として、App Serviceの環境変数にはAPPLICATIONINSIGHTS_CONNECTION_STRING
を設定しておく。
main.tf
app_settings = {
APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.this.connection_string
}
Next.jsのコードを書く
必要なライブラリを追加する
npm install @azure/monitor-opentelemetry @opentelemetry/winston-transport winston
instrumentation.ts
でAzure Monitorの初期設定をする
instrumentation.ts
import { useAzureMonitor } from "@azure/monitor-opentelemetry";
export function register() {
console.log("Registering Azure Monitor instrumentation...");
// eslint-disable-next-line react-hooks/rules-of-hooks
useAzureMonitor();
console.log("Azure Monitor instrumentation registered successfully.");
}
どこでも良いが、今回はpage.tsx
でログを出すことにする
page.tsx
import winston from "winston";
import { OpenTelemetryTransportV3 } from "@opentelemetry/winston-transport";
export const dynamic = "force-dynamic";
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new OpenTelemetryTransportV3({}),
],
});
export default function Home() {
logger.info("ほげほげ");
...
イメージをpushする
特別変なことはしていないが、流れをメモ
az login
az acr login --name registryappinextjs
docker build -t registryappinextjs.azurecr.io/app --platform=linux/amd64 .
docker push registryappinextjs.azurecr.io/app
動作確認
イメージを更新するために、App Serviceを再起動して...
App Serviceにアクセスする
念の為、App Serviceのログストリームにログが表示されていることを確認して...
Application Insightsにtraceが表示されているはず。反映まで少しラグがあるので注意
ハマったところ
Next.jsのmiddlewareを使っている場合
middleware.ts
が配置されていると、Edge Runtimeでの処理が走る(instrumentation.ts
にも波及する)
useAzureMonitor
の処理はNode.js Runtimeでしか動作しないので、Edge Runtimeではエラーとなる。
に記載の通り、NEXT_RUNTIME
による分岐を挟む必要が出てくる。
instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
await import("./instrumentation-node");
}
}
instrumentation-node.ts
import { useAzureMonitor } from "@azure/monitor-opentelemetry";
console.log("Registering Azure Monitor instrumentation...");
// eslint-disable-next-line react-hooks/rules-of-hooks
useAzureMonitor();
console.log("Azure Monitor instrumentation registered successfully.");
instrumentationOptions
でwinstonをenableにしてもtraceは出力されない
.NET、Java、Node.js、Python アプリケーション用の Azure Monitor OpenTelemetry を追加および変更するに記載されているinstrumentationOptions
を利用して次のように設定してもtraceは出力されない。
instrumentation.ts
import { useAzureMonitor } from "@azure/monitor-opentelemetry";
export function register() {
console.log("Registering Azure Monitor instrumentation...");
// eslint-disable-next-line react-hooks/rules-of-hooks
useAzureMonitor({
instrumentationOptions: {
winston: {
enabled: true,
}
}
});
console.log("Azure Monitor instrumentation registered successfully.");
}
参考
Discussion