foreverで動作しているNode.jsのアプリケーションログをCloudWatchに送る

AWS, CloudWatch, Node.js, forever
2021-06-02

foreverを利用してdaemonで起動しているアプリケーションのログをCloudWatchに流す方法です。

foreverのログファイル

foreverはアプリケーション起動時にデフォルトで ~/.forever 以下に a93c.log のようなランダムなファイル名のログファイルを出力します。

今回はCloudWatch Agentで取得するためファイル名を固定します。

foreverのconfigファイルを作成

foreverは起動引数または設定ファイルを用いることにより起動時の設定を細かく設定することができます。 https://github.com/foreversd/forever#usage

今回はプロジェクトのルートに .forever/config.json ファイルを作成し、起動時に読み込むようにします。 jsonのファイルは以下のようにします。

{
  "uid": "app",
  "append": true,
  "script": "server.js",
  "sourceDir": "dist/src/server",
  "workingDir": ".",
  "logFile": "logs/forever.log",
  "outFile": "/home/ec2-user/.forever/logs/out.log",
  "errFile": "/home/ec2-user/.forever/logs/error.log"
}

uidやディレクトリはお好みでよいのですが、foreverでは3つのログファイルを出力することができます。 それぞれは以下の特徴があり、cwdが微妙に異なります。

  • logFile ... log も error も含んだ総合的なログ。デフォルトだと ~/.forever/[id].log に出力される。(つまり、cwd が.forever になっている)
  • outFile ... log のみが出力される。相対的になパスに出力される(つまり、cwd はプロジェクトのルートとなる)。記載したパスのディレクトリがない場合は、エラーになりなにも出力されないので注意。
  • errFile ... error のみが出力される。パスの位置は outFile と同じ

なので、outFile, errFile は絶対パスにしています。

これで、~/.forever/logs ディレクトリに forever.log , out.log,error.logの3つのログファイルが出力されるようになります。foreverを以下のコマンドで起動し、ログファイルが表示されていることを確認します。

$ forever start .forever/production.json

EC2事前準備

続いてEC2側の設定します。

IAMロールにCloudWatch Agent用のPolicyをアタッチ

EC2インスタンスのIAMロールに CloudWatchAgentServerPolicy,CloudWatchAgentAdminPolicyをアタッチします。

EC2サーバにCloudWatch Agentをインストール

次にサーバにログインし、CloudWatch Agentをインストールします。Amazon Linux 2 を使っている場合はyumを実行するだけで、インストールできます。他のOSの場合は手動でインストールもできます。詳細はこちらを参照ください。

$ sudo yum install amazon-cloudwatch-agent

初回の設定を行う場合は以下のウィザードを実行する

$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

CloudWatch Agentの設定ファイルを修正

CloudWatch Agentの設定でlogs(ログファイル)の設定を以下のようにします。 今回はinfo系のログとerror系のログで別々に表示したいので、それぞれを別のログストリームに表示します。まとめて取得する場合は"forever.log"の方を参照してもよいです。またロググループ、ログストリーム名はお好みで問題ないと思います。

// /opt/aws/amazon-cloudwatch-agent/bin/config.json

{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/home/ec2-user/.forever/logs/out.log",
            "log_group_name": "web-app",
            "log_stream_name": "{instance_id}_app_out_log"
          },
          {
            "file_path": "/home/ec2-user/.forever/logs/error.log",
            "log_group_name": "web-app",
            "log_stream_name": "{instance_id}_app_error_log"
          }
        ]
      }
    }
  },
  "agent": {...},
  "metrics": {...}
}

CloudWatch Agentの起動

設定ファイルができたら、CloudWatch Agentを起動(もしくは再起動)します。

$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s

以上でCloudWatch Agentの設定ができました。設定ができたらnode.jsのアプリケーションをデプロイし、foreverでアプリケーションを起動します。

AWSコンソール上のCloudWatch > ロググループにて設定したログが表示されるようになります。

これでsshでログを見に行かなくてもブラウザでログが見られるようになりました🎉 また、エラーログが流れればそれに応じたアラートを設定することができます 🙌

参考

https://tech.fusic.co.jp/posts/2020-12-12-cloudwatch-agent/

Written by Kyohei Tsukuda who lives and works in Tokyo 🇯🇵 , building useful things 🔧.