Fastify で特定の URL にアクセスした時にログを出力しないようにする方法

2021.03.11

はじめに

Fastify で構築した Web サービスにアクセスがあった際に、特定の URL だけアクセスログを出力させたくない時に使える Tips です。

例えばヘルスチェックのように機械的なアクセスが頻繁に発生する箇所に効果的に使えるでしょう。

やること

例として /doNotOutputLog にアクセスがあった時だけ、ログに出力しないようにしてみます。

やったこと

server.ts

import Fastify from "fastify";

const fastify = Fastify({
  logger: true,
});

fastify.addHook("onRoute", (opts) => {
  if (opts.path === "/doNotOutputLog") {
    // @ts-ignore silent は Fastify で用意されているログレベルに存在しない
    opts.logLevel = "silent";
  }
});

fastify.get("/", async () => {
  return { hello: "world!" };
});

fastify.get("/doNotOutputLog", async () => {
  return { hello: "world?" };
});

const start = async () => {
  try {
    await fastify.listen(3000);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
start();

これにより / にアクセスした際はアクセスログが出力されますが、/doNotOutputLog にアクセスした際にはアクセスログが出力されないようになりました。

解説

以下で /doNotOutputLog にアクセスがあった際にログレベルを変更してログを出力しないようにしています。

fastify.addHook("onRoute", (opts) => {
  if (opts.path === "/doNotOutputLog") {
    // @ts-ignore silent は Fastify で用意されているログレベルに存在しない
    opts.logLevel = "silent";
  }
});

Fastify で用意されているログレベルは以下の通りになっており silent はありません。

export type LogLevel = 'info' | 'error' | 'debug' | 'fatal' | 'warn' | 'trace'

ですが Fastify がロガーとして使用している pino には silent が定義されていますので silent を使うことができます。

この時以下のように型エラーが出ますので @ts-ignore をしています。

型 '"silent"' を型 'LogLevel' に割り当てることはできません。ts(2322)

※ ログレベル silent は 例外発生時にも何も出力しないので使用場所は十分に検討しましょう。

Fastify のログ周りの挙動を変更したいならば Fastify のドキュメントよりも pino のドキュメントが役に立つでしょう。

まとめ

  • Fastify はパス単位でログレベルを変更することができる。
  • Fastify はロガーとして pino を使用している。
  • pino で用意されているログレベル silent を使ってログを抑制できる。