Express.jsのログ出力設定(Morgan、Winston、log4js比較)
更新日:2025/03/15
            
            
Express.jsのロギングモジュール比較
| 機能 | Morgan | Winston | log4js | 
|---|---|---|---|
| Express用ミドルウェア | ✓ (専用) | △ (要設定) | △ (要設定) | 
| カスタムログフォーマット | △ (限定的) | ✓ (高度) | ✓ (高度) | 
| 複数出力先サポート | ✗ | ✓ | ✓ | 
| ログレベル対応 | ✗ | ✓ | ✓ | 
| ログローテーション | ✗ (要別モジュール) | △ (拡張必要) | ✓ (標準機能) | 
| JSONフォーマット | △ (限定的) | ✓ | ✓ | 
| 非同期処理 | △ | ✓ | ✓ | 
| 人気度 (npmダウンロード数) | ★★★★★ | ★★★★★ | ★★★★☆ | 
| メンテナンス状況 | ★★★☆☆ | ★★★★★ | ★★★★☆ | 
| 実装の容易さ | ★★★★★ (もっとも簡単)  | ★★★☆☆ (設定が複雑)  | ★★★★☆ (標準的)  | 
| 拡張性 | ★★★☆☆ | ★★★★★ | ★★★★☆ | 
| プラグインエコシステム | ★★★☆☆ (限定的)  | ★★★★★ (豊富)  | ★★★★☆ (充実)  | 
| 学習曲線 | ★★★★★ (低い)  | ★★★☆☆ (高い)  | ★★★★☆ (中程度)  | 
それぞれの特徴と利用シーン
| ロギングモジュール | 主な特徴 | 最適な利用シーン | 実装の簡単さ | 
|---|---|---|---|
| Morgan | HTTPリクエストのロギングに特化 Express.jsに最適化された設計 プリセットされたログフォーマット シンプルな設定 | アクセスログのみが必要な場合 小〜中規模のアプリケーション 迅速な実装が必要な場合 他のロギングシステムとの併用 | ★★★★★app.use(morgan('combined'));のみで実装可能  | 
| Winston | 高度にカスタマイズ可能なロギング 複数のトランスポート(出力先) 豊富なプラグイン 非同期ロギング 強力なクエリ機能 | エンタープライズアプリケーション 複雑なロギング要件 カスタムログフォーマットが必要な場合 複数の出力先(ファイル、DB、APIなど) 高度なエラー処理とモニタリング | ★★★☆☆ 設定はより複雑だが、柔軟性が高い  | 
| log4js | log4jに似た使い慣れたAPI 組み込みのログローテーション 階層的なロガー設定 複数の出力先サポート クラスタモードサポート | Java開発者に馴染みのある環境 ログローテーションが重要な場合 中〜大規模アプリケーション 階層的なログ構造が必要な場合 Expressと他のサーバーロジックの両方でロギング | ★★★★☆ Morganよりは複雑だが、Winstonより直感的  | 
結論
- もっとも一般的: Winstonが現在のNode.jsエコシステムでもっとも広く採用され、活発にメンテナンスされています。
 - もっともシンプル: Morganは実装が最も簡単で、特にHTTPリクエストのロギング専用です。
 - バランス良好: log4jsは機能とシンプルさのバランスが良く、特にログローテーション機能が標準装備されている点が優れています。
 
推奨アプローチ
- 小規模プロジェクト: Morganのみ(シンプルなアクセスログ)
 - 中規模プロジェクト: Morgan + log4js(アクセスログとアプリケーションログの分離)
 - 大規模プロジェクト: Morgan + Winston(最大の拡張性と柔軟性)
 
Morgan実装手順
必要なパッケージのインストール
npm install express morgan winston基本的なMorganを使ったログ出力
const express = require('express');
const morgan = require('morgan');
const fs = require('fs');
const path = require('path');
const app = express();
// ログディレクトリの作成
const logDirectory = path.join(__dirname, 'logs');
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);
// ログファイルストリームの作成
const accessLogStream = fs.createWriteStream(
  path.join(logDirectory, 'access.log'), 
  { flags: 'a' }
);
// morganミドルウェアの設定
app.use(morgan('combined', { stream: accessLogStream }));
app.get('/', (req, res) => {
  res.send('Hello World!');
});
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});log4jsの導入手順
log4jsをプロジェクトにインストールします
npm install log4jsWinstonを使った高度なログ管理
const express = require('express');
const morgan = require('morgan');
const winston = require('winston');
const { format, transports } = winston;
const app = express();
// Winstonロガーの設定
const logger = winston.createLogger({
  level: 'info',
  format: format.combine(
    format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss'
    }),
    format.errors({ stack: true }),
    format.splat(),
    format.json()
  ),
  defaultMeta: { service: 'express-app' },
  transports: [
    new transports.File({ filename: 'logs/error.log', level: 'error' }),
    new transports.File({ filename: 'logs/combined.log' })
  ]
});
// 開発環境ではコンソールにも出力
if (process.env.NODE_ENV !== 'production') {
  logger.add(new transports.Console({
    format: format.combine(
      format.colorize(),
      format.simple()
    )
  }));
}
// Morganの出力をWinstonに流す
app.use(morgan('combined', {
  stream: {
    write: (message) => logger.info(message.trim())
  }
}));
app.get('/', (req, res) => {
  res.send('Hello World!');
});
// エラーログの例
app.get('/error', (req, res, next) => {
  try {
    throw new Error('Something went wrong');
  } catch (error) {
    logger.error(`Error occurred: ${error.message}`, { 
      stack: error.stack, 
      url: req.originalUrl 
    });
    res.status(500).send('Error');
  }
});
app.listen(3000, () => {
  logger.info('Server is running on port 3000');
});ログローテーション機能の追加
// まず、パッケージをインストール
// npm install winston-daily-rotate-file
const express = require('express');
const morgan = require('morgan');
const winston = require('winston');
const { format, transports } = winston;
require('winston-daily-rotate-file');
const app = express();
// ログローテーション設定
const fileRotateTransport = new winston.transports.DailyRotateFile({
  filename: 'logs/application-%DATE%.log',
  datePattern: 'YYYY-MM-DD',
  maxSize: '20m',
  maxFiles: '14d',
  format: format.combine(
    format.timestamp(),
    format.json()
  )
});
// Winstonロガーの設定
const logger = winston.createLogger({
  level: 'info',
  format: format.combine(
    format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss'
    }),
    format.errors({ stack: true }),
    format.splat(),
    format.json()
  ),
  defaultMeta: { service: 'express-app' },
  transports: [
    new transports.File({ filename: 'logs/error.log', level: 'error' }),
    fileRotateTransport
  ]
});
// 開発環境ではコンソールにも出力
if (process.env.NODE_ENV !== 'production') {
  logger.add(new transports.Console({
    format: format.combine(
      format.colorize(),
      format.simple()
    )
  }));
}
// Morganの出力をWinstonに流す
app.use(morgan('combined', {
  stream: {
    write: (message) => logger.info(message.trim())
  }
}));
app.get('/', (req, res) => {
  res.send('Hello World!');
});
app.listen(3000, () => {
  logger.info('Server is running on port 3000');
});環境ごとにログレベルを変更する設定
// config.js
module.exports = {
  logging: {
    development: {
      level: 'debug',
      console: true
    },
    production: {
      level: 'info',
      console: false
    }
  }
};
// app.js
const express = require('express');
const morgan = require('morgan');
const winston = require('winston');
const { format, transports } = winston;
const config = require('./config');
const app = express();
const environment = process.env.NODE_ENV || 'development';
const logConfig = config.logging[environment];
// Winstonロガーの設定
const logger = winston.createLogger({
  level: logConfig.level,
  format: format.combine(
    format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss'
    }),
    format.errors({ stack: true }),
    format.splat(),
    format.json()
  ),
  defaultMeta: { service: 'express-app', environment },
  transports: [
    new transports.File({ filename: `logs/${environment}-error.log`, level: 'error' }),
    new transports.File({ filename: `logs/${environment}-combined.log` })
  ]
});
// 開発環境ではコンソールにも出力
if (logConfig.console) {
  logger.add(new transports.Console({
    format: format.combine(
      format.colorize(),
      format.simple()
    )
  }));
}
// 異なるログ形式の設定
const morganFormat = environment === 'production' ? 'combined' : 'dev';
// Morganの出力をWinstonに流す
app.use(morgan(morganFormat, {
  stream: {
    write: (message) => logger.info(message.trim())
  }
}));
app.get('/', (req, res) => {
  // デバッグログの例
  logger.debug('デバッグ情報:ホームページにアクセスがありました');
  logger.info('ホームページにアクセスがありました');
  res.send('Hello World!');
});
app.listen(3000, () => {
  logger.info(`Server is running on port 3000 in ${environment} mode`);
});
    - 
        
検索
(例) debug search etc.. - 
        
カテゴリー
 
- 
                
                  
                    mixhostでのWordPress利用について
更新日:2024/04/02
303 view
 - 
                
                  
                    scrollHint
更新日:2024/03/13
251 view
 - 
                
                  
                    XML Sitemap Generator for Google不具合のダウングレード対応、代替プラグイン
更新日:2024/06/13
243 view
 - 
                
                  
                    【SnowMonkey】納品までのフローまとめ
更新日:2025/02/15
164 view
 - 
                
                  
                    【Snow Monkey】ショートコードで編集画面で任意の場所にHTMLファイルを挿入
更新日:2025/04/18
131 view
 - 
                
                  
                    【Googleサーチコンソール】検索画面で表示させたくない「Googleのインデックス削除」
更新日:2024/06/07
131 view
 - 
                
                  
                    tailwindcss使い方
更新日:2024/03/13
125 view
 - 
                
                  
                    キーワード検索で上位表示させる方法【SEO】
更新日:2023/10/28
120 view
 - 
                
                  
                    Recline: GitHub Copilotで動作するClaude 3.5 Sonnet搭載の開発支援ツール
更新日:2025/01/20
115 view
 - 
                
                  
                    WordPressプラグイン「All-in-One WP Migration」のトラブル
更新日:2022/03/31
84 view
 - 
                
                  
                    ワードプレスセキュリティー対策まとめ【2025年】「site guard wordpress」「BackWPup バージョン5でUI変更!?」
更新日:2025/02/25
77 view
 - 
                
                  
                    VSCodeで開発効率を劇的に向上させる!Roo Code(Roo-Cline)プラグイン完全ガイド
更新日:2025/04/06
75 view
 - 
                
                  
                    Express、FastAPIを使用し、二重fetch構成のメリット
更新日:2025/04/26
51 view
 - 
                
                  
                    SSHを使用してGitHubのリポジトリをクローン、複数の接続元で公開鍵をディレクトリで区別する方法
更新日:2025/01/13
49 view
 - 
                
                  
                    Supabase 初心者向け解説、Supabase CLI インストール(Scoop)
更新日:2025/06/07
45 view
 - 
                
                  
                    「JSONスキーマ」と「Few-shot Learning」で実現する次世代生成AIソフトウェア開発の可能性
更新日:2025/07/06
44 view
 - 
                
                  
                    Windowsショートカットエラーの原因と解決方法「このショートカットは、リンク先のファイルが変更または移動されているので、正しく機能しません」
更新日:2025/02/09
41 view
 - 
                
                  
                    リファクタリング【VSCode Javasctipt Python】
更新日:2025/03/09
37 view
 - 
                
                  
                    Next.jsでAWS Amplifyを使ってPDFアップロード機能を実装、Fast APIにPOST(こちらはApp runner)
更新日:2025/06/06
37 view
 - 
                
                  
                    形態素解析とは?初心者でもわかるツールの使い方と実践例
更新日:2025/02/08
34 view