Skip to content

ログ

構造化JSON出力、コンテキスト対応ログ、設定オプションを含むKoriのログ機能の使用方法を学びます。

概要

Koriは設定可能なレポーターを持つ構造化ログシステムを提供します。ロガーは構造化ログエントリを生成し、デフォルトのコンソールレポーターは学習と素早い開始のためのシンプルなJSON出力を提供します。

実際のアプリケーション開発では、より良いパフォーマンスと機能のためにPino(Node.js用)、LogTape(ユニバーサル)、または他のプロダクションレベルのログソリューション専用レポーターの使用を検討してください。

ログの種類

Koriは、Koriコンテキストの内外に応じてロガーを提供します:

Koriコンテキスト外

アプリケーションセットアップとシステム全体のイベントにはapp.log()を使用:

typescript
const app = createKori();

// アプリケーション開始前に使用
app.log().info('Setting up application', { port: 3000 });

Koriコンテキスト内

フックとハンドラー内ではctx.log()を使用:

typescript
const app = createKori()
  .onStart(async (ctx) => {
    // ライフサイクルフック内で使用
    ctx.log().info('Initializing database connection');

    const db = await connectDatabase();
    return ctx.withEnv({ db });
  })
  .get('/users', (ctx) => {
    // リクエストハンドラー内で使用(リクエストメタデータを自動的に含む)
    ctx.log().info('Processing user request');
    return ctx.res.json({ users: [] });
  });

ログレベル

Koriは重要度順に5つのログレベルをサポートします:

typescript
app.get('/example', (ctx) => {
  const logger = ctx.log();

  logger.debug('Processing data', { userId: '123' }); // 最も詳細
  logger.info('Request completed successfully');
  logger.warn('Rate limit approaching', { remaining: 5 });
  logger.error('Database connection failed', { err: error });
  logger.fatal('Critical system failure'); // 最も重要

  return ctx.res.json({ result: 'ok' });
});

最小ログレベルを設定:

typescript
const app = createKori({
  loggerOptions: {
    level: 'info', // info以上のみログ(warn、error、fatal)
  },
});

構造化ログ

Koriは構造化ログエントリを生成します。デフォルトのコンソールレポーターは、一貫したフィールドとタイムスタンプを持つJSONとしてこれらを出力します。すべてのメタデータはmetaオブジェクトに配置されます。

typescript
app.get('/users/:id', (ctx) => {
  const logger = ctx.log();

  logger.info('Fetching user', { userId: ctx.req.pathParams().id });

  return ctx.res.json({ user: { id: '123', name: 'John' } });
});

出力(読みやすさのためにフォーマット、実際の出力は1行):

json
{
  "time": 1754201824386,
  "level": "info",
  "channel": "app",
  "name": "request",
  "message": "Fetching user",
  "meta": {
    "userId": "1"
  }
}

ロガー設定

アプリケーション起動時にログ動作を設定:

typescript
const app = createKori({
  loggerOptions: {
    level: 'debug',
    bindings: {
      service: 'user-api',
      version: '1.2.0',
    },
  },
});
  • level:最小ログレベルを設定(このレベル以下のログは無視される)
  • bindings:すべてのログエントリに自動的に追加されるキー値ペア

パフォーマンス最適化

レベルチェック

ログが無効な場合の高コスト操作を回避:

typescript
app.get('/debug', (ctx) => {
  const logger = ctx.log();

  // 高コストな計算の前にデバッグレベルが有効かチェック
  if (logger.isLevelEnabled('debug')) {
    const expensiveData = computeSystemMetrics(); // 必要な場合のみ実行
    logger.debug('System metrics', { metrics: expensiveData });
  }

  return ctx.res.json({ status: 'ok' });
});

遅延メタデータ生成

ログが有効な場合のみ実行される高コストなメタデータ計算には関数を使用:

typescript
app.get('/profile', (ctx) => {
  const logger = ctx.log();

  // infoレベルが有効な場合のみ関数が呼ばれる
  logger.info('User profile accessed', () => {
    return {
      userStats: calculateUserStatistics(ctx.req.pathParams().id),
      memoryUsage: process.memoryUsage(),
      timestamp: Date.now(),
    };
  });

  return ctx.res.json({ profile: getUserProfile() });
});

メタデータ関数は遅延実行されます - ログレベルが有効な場合のみ実行され、不要な計算を回避します。

Released under the MIT License.