メトリクスやログを簡単にAWS CloudWatchに送るNode.jsモジュール「cloudwatch-buddy」

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、せーのです。今日はシステムを組む際に便利なモジュールをご紹介します。

cloudwatch-buddy

cloudwatch-buddy : https://github.com/matthewdfuller/cloudwatch-buddy

CloudWatchにメトリクスを送る方法はAWS CLIやAWS SDKまたはAmazon Linuxに最初から入っているコマンドラインツールを使ってスクリプトを組み、それをcron登録する、というのが王道ですね。
メモリ量やCPU使用率等システム的な値であればこの方法がベストだと思いますが、サイトのページビューやページのロード時間などサービスに関わるものになるとソース内に組み込んでリアルタイムに送信する事が必要です。
今日はこの仕組みをパッケージングしているモジュール「cloudwatch-buddy」をご紹介します。このモジュールを使うと、細かいことは気にせずに簡単にStatを登録できます。また普通のログサービスでログファイルにログを吐くようにCloudWatch Logsにログをストリームさせることができます。

やってみる

早速ためしてみましょう。EC2を立ち上げ必要なモジュールとnvmをインストール、nvmからNode.jsをインストールします。EC2を立ち上げる歳にはIAM Roleをつけることを忘れないようにしましょう。今回はPowerUserをつけました。

[ec2-user@ip-10-0-0-11 ~]$ sudo yum install gcc-c++ make openssl-devel git -y
[ec2-user@ip-10-0-0-11 ~]$ git clone git://github.com/creationix/nvm.git .nvm
[ec2-user@ip-10-0-0-11 ~]$ source ~/.nvm/nvm.sh
[ec2-user@ip-10-0-0-11 ~]$ nvm ls-remote
        v0.1.14
        v0.1.15
        v0.1.16
......
        v0.12.0
        v0.12.1
        v0.12.2
......
[ec2-user@ip-10-0-0-11 ~]$ nvm install v0.12.2
######################################################################## 100.0%
Now using node v0.12.2 (npm v2.7.4)
[ec2-user@ip-10-0-0-11 ~]$ node -v
v0.12.2
[ec2-user@ip-10-0-0-11 ~]$ npm -v
2.7.4

次にcloudwatch-buddyをnpmからインストールします。

[ec2-user@ip-10-0-0-11 ~]$ npm install cloudwatch-buddy
cloudwatch-buddy@0.0.1 node_modules/cloudwatch-buddy
├── async@0.9.0
└── aws-sdk@2.1.26 (xmlbuilder@0.4.2, xml2js@0.2.8, sax@0.5.3)

サンプルを流す前にコードを少し触ります。まだ完成品ではないためか、metricsの送信部分でブロックしてあるようです。metrics.jsの102行目、103行目をコメントアウトします。

        if (params.MetricData.length > 0) {
            console.log(JSON.stringify(params, null, 2));
            //setUploadInterval();  <=ここをコメントアウト
            //return;               <=ここをコメントアウト
            // TODO: Check size before sending and split if needed
            cloudwatch.putMetricData(params, function(err, data){
                console.log(err);
                console.log('Sent');
                
                // TODO: if err, see if retryable
                setUploadInterval();
            });
        } else {
            setUploadInterval();
        }

ではサンプルを流してみましょう。現状では先にCloudWatchグループを作成しておく必要があるようなのでマネージメントコンソールからCloudWatchを開き、[ログ]のタブからCloudWatchグループを作成します。

cloudwatch-buddy1

サンプルを流します。サンプルの内容はこのようになっています。

var CloudWatchBuddy = require(__dirname + '/index.js');

var awsOptions = {
	accessKeyId: '',
	secretAccessKey: '',
	sessionToken: '',
	region: 'us-east-1'
};

var cwbMetricsOptions = {
	namespace: 'test-data',
	timeout: 60
};

var cwbLogsOptions = {
	logGroup: 'test-data',
	timeout: 60,
	addInstanceId: false,
	addTimestamp: true,
	logFormat: 'json' //|| 'json'
};

var cwbMetrics = new CloudWatchBuddy(awsOptions).metrics(cwbMetricsOptions);
var cwbLogs = new CloudWatchBuddy(awsOptions).logs(cwbLogsOptions);

cwbMetrics.increment('pageviews');
cwbMetrics.increment('pageviews');
cwbMetrics.increment('pageviews');
cwbMetrics.increment('pageviews');
cwbMetrics.increment('pageviews');

cwbMetrics.stat('loadtime', 10, 'Milliseconds');
cwbMetrics.stat('loadtime', 15, 'Milliseconds');
cwbMetrics.stat('loadtime', 7, 'Milliseconds');
cwbMetrics.stat('loadtime', 100, 'Milliseconds');

cwbMetrics.stat('pagesize', 10, 'Megabytes');

cwbMetrics.stat('serverload', 10, 'Percent', {serverName:'web01.example.com',region:'us-east-1'});
cwbMetrics.stat('serverload', 10, 'Percent', {serverName:'web02.example.com',region:'us-east-1'});

cwbLogs.log('errors', 'Dual message');
cwbLogs.log('signups', 'Some user');

var i=0;
setInterval(function(){
	i++;
	cwbMetrics.stat('pagesize', 10, 'Megabytes');
	cwbLogs.log('errors', 'Dual message: ' + i);
	cwbLogs.log('signups', 'Some user: ' + i);
},500);
[ec2-user@ip-10-0-0-11 ~]$ node node_modules/cloudwatch-buddy/example.js
upload setInterval
{
  "MetricData": [
    {
      "MetricName": "pageviews",
      "Timestamp": "2015-04-29T11:22:58.622Z",
      "Unit": "Count",
      "Value": 5
    },
    {
      "MetricName": "loadtime",
      "Timestamp": "2015-04-29T11:22:58.622Z",
      "Unit": "Milliseconds",
      "StatisticValues": {
        "Maximum": 100,
        "Minimum": 7,
        "SampleCount": 4,
        "Sum": 132
      }
    },
    {
      "MetricName": "pagesize",
      "Timestamp": "2015-04-29T11:22:58.622Z",
      "Unit": "Megabytes",
      "StatisticValues": {
        "Maximum": 10,
        "Minimum": 10,
        "SampleCount": 120,
        "Sum": 1200
      }
    },
    {
      "MetricName": "serverload",
      "Timestamp": "2015-04-29T11:22:58.622Z",
      "Unit": "Percent",
      "StatisticValues": {
        "Maximum": 10,
        "Minimum": 10,
        "SampleCount": 2,
        "Sum": 20
      },
      "Dimensions": [
        {
          "Name": "serverName",
          "Value": "web02.example.com"
        },
        {
          "Name": "region",
          "Value": "ap-northeast-1"
        }
      ]
    }
  ],
  "Namespace": "test-data"
}
null
Sent

結果を見てみましょう。マネージメントコンソールからCloudWatchを開きます。まずはメトリックスを開き、カスタムメトリクス[test-data]を開きます。example.jsからcwbMetrics.increment()cwbMetrics.stat()で登録した値が確認できます。

cloudwatch-buddy2

続いてはログです。[ログ]のタブから先程作成したロググループ[test-data]を開きます。cwbLogs.log()で登録したログが確認できます。

cloudwatch-buddy3

まとめ

いかがでしたでしょうか。触ってみた感じ、もう少しブラッシュアップが必要かと感じました。作った方もこう言ってます。

ということで皆さんも触ってみて、もし不自由があったら報告してあげましょう。

参考サイト