この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
最近、Lambda Functionの開発をしてたりするのですがマネジメントコンソール上でCloudWatch Logsに保存されるLambda Functionログを確認するのがかなり辛いということがありました。そこでlambchop-tailも試してみたんですが元々node-aws-lambdaを利用してデプロイ1を行っていることもあり、直近のLambda FunctionのログをCloudWatch Logsから取得するgulpタスクを作りました。
ソースコード
node-aws-lambdaのGulp exampleに以下のソースコードを追加すると動作します。なお、取得するLogStreamの数をgulpコマンドのオプションとして指定できるようにしたかったのでminimist2を利用しています。
var AWS = require("aws-sdk");
var minimist = require('minimist');
var knownOptions = {
string: 'logslimit',
'default' : {
'logslimit' : 1
}
};
var options = minimist(process.argv.slice(2), knownOptions);
gulp.task('logs', function(callback) {
var config = require("./lambda-config.js");
var cloudwatchlogs = new AWS.CloudWatchLogs({
region : config.region
});
var logGroupName = '/aws/lambda/' + config.functionName;
cloudwatchlogs.describeLogStreams({
logGroupName : logGroupName,
descending : true, // 直近のログを取得する
limit : options.logslimit, // --logslimit オプションで指定可能
orderBy : 'LastEventTime'
}, function(err, data) {
if (err) {
console.log(err, err.stack);
return;
}
data.logStreams.forEach(function(logStream) {
// ログの取得。paginationは未実装
cloudwatchlogs.getLogEvents({
logGroupName : logGroupName,
logStreamName : logStream.logStreamName
}, function(err, data) {
if (err) {
console.log(err, err.stack);
return;
}
// ログ出力
data.events.forEach(function(event) {
var lines = event.message.split('\n');
lines.pop(); // 最後に付与されている改行文字を除去
// 先頭行を出力
console.log(lines.shift());
// 1ログに2行以上ログがあれば出力。その際にインデントする
for ( var i in lines) {
console.log('\t' + lines[i]);
}
});
});
});
});
});
コメントにもあるようにgetLogEventsメソッドのpaginationは未実装です。今の所、アプリの規模が小さくそこまでログがなかったので。paginationが必要な場合は追加実装してください。
実行
hello-world blueprintのログを取得してみます。まずはhello-world blueprintのソースを貼っておきます。
console.log('Loading function');
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
console.log('value1 =', event.key1);
console.log('value2 =', event.key2);
console.log('value3 =', event.key3);
context.succeed(event.key1); // Echo back the first key value
// context.fail('Something went wrong');
};
このFunctionに対してlogsタスクを実行すると以下の様な感じでログを取得できます。引数の--logslimitオプションはデフォルト値が1なので、1でよい場合は指定不要です。以下ではオプションがあることを示すため指定しています。
$ gulp logs --logslimit 1
[13:18:15] Using gulpfile ~/gulpfile.js
[13:18:15] Starting 'logs'...
2015-07-01T08:34:04.329Z 8lkpgcs36e4jsizq Loading function
START RequestId: edb60818-1fcb-11e5-abb3-c31e55314433
2015-07-01T08:34:04.332Z edb60818-1fcb-11e5-abb3-c31e55314433 Received event: {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
2015-07-01T08:34:04.332Z edb60818-1fcb-11e5-abb3-c31e55314433 value1 = value1
2015-07-01T08:34:04.332Z edb60818-1fcb-11e5-abb3-c31e55314433 value2 = value2
2015-07-01T08:34:04.332Z edb60818-1fcb-11e5-abb3-c31e55314433 value3 = value3
END RequestId: edb60818-1fcb-11e5-abb3-c31e55314433
REPORT RequestId: edb60818-1fcb-11e5-abb3-c31e55314433 Duration: 2.03 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 27 MB
$
ソースを読むと分かりますが、1ログの中で改行が存在する場合は2行目以降はインデントしています。
まとめ
これを作ったおかげでマネジメントコンソール上でログを確認するというストレスから開放されました。ただ、Lambda FunctionからCloudWatch Logsへのログの出力にはタイムラグがあるので、そこは待ちが発生するのが残念です(´・ω・`)
よければご利用下さい。
- node-aws-lambdaの利用方法はAWS LambdaファンクションをGulpでデプロイを参照して下さい。 ↩
- Pass arguments from the command lineというレシピがあったのでgulpで引数を利用する際はminimistを利用するのがよいようです。 ↩