CloudWatch LogsのログをJavaScriptで取得する

AWS上でServerless系のアプリを開発していると、大体のログはCloudWatch Logsにたまっていきます。 で、このデータを取得してダッシュボードに表示するとか内部処理的なことできたら便利よねーって気がした […]

広告ここから
広告ここまで

目次

    AWS上でServerless系のアプリを開発していると、大体のログはCloudWatch Logsにたまっていきます。
    で、このデータを取得してダッシュボードに表示するとか内部処理的なことできたら便利よねーって気がしたので、とりあえず試してみました。

    Log Streamのデータを取得するコードサンプル

    'use strict'
    
    const aws = require('aws-sdk')
    const cloudwatchlogs = new aws.CloudWatchLogs();
    const params = {
      logGroupName: '/aws/lambda/{YOUR_LAMBDA_NAME}',
      logStreamName: '{YOUR_LOG_STREAM_NAME}',
    }
    cloudwatchlogs.getLogEvents(params, function(err, data) {
      if (err) console.log(err, err.stack);       // an error occurred
      else     console.log(JSON.stringify(data)); // successful response
    });
    

    これを実行すると、以下のようなJSONが取得できます。

    {
      "events": [
        {
          "timestamp": 1502329050066,
          "message": "START RequestId: 78a33025-7d6c-11e7-965d-21381e8db922 Version: $LATEST\n",
          "ingestionTime": 1502329050092
        },
        {
          "timestamp": 1502329050071,
          "message": "2017-08-10T01:37:30.071Z\t78a33025-7d6c-11e7-965d-21381e8db922\tWarning: Application ID is not set\n",
          "ingestionTime": 1502329065157
        },
        {
          "timestamp": 1502329050072,
          "message": "END RequestId: 78a33025-7d6c-11e7-965d-21381e8db922\n",
          "ingestionTime": 1502329065157
        }
      ],
      "nextForwardToken": "f/XXXXXXXXX",
      "nextBackwardToken": "b/XXXXXXXXXXX"
    }
    

    ログを検索する

    filterLogEvents()を使うことで、複数のストリームを跨いだデータ取得や検索ができます。

    ロググループ全体からデータを取得

    'use strict'
    
    const aws = require('aws-sdk')
    var cloudwatchlogs = new aws.CloudWatchLogs();
    var params = {
      logGroupName: '/aws/lambda/{YOUR_LAMBDA_NAME}',
    }
    cloudwatchlogs.filterLogEvents(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     {
        console.log(JSON.stringify(data))
      };           // successful response
    });
    

    件数指定

    'use strict'
    
    const aws = require('aws-sdk')
    var cloudwatchlogs = new aws.CloudWatchLogs();
    var params = {
      logGroupName: '/aws/lambda/{YOUR_LAMBDA_NAME}',
      limit: 10,
    }
    cloudwatchlogs.filterLogEvents(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     {
        console.log(JSON.stringify(data))
      };           // successful response
    });
    

    特定のストリームのみを検索する

    'use strict'
    
    const aws = require('aws-sdk')
    var cloudwatchlogs = new aws.CloudWatchLogs();
    var params = {
      logGroupName: '/aws/lambda/{YOUR_LAMBDA_NAME}',
      logStreamNames: [
        '{YOUR_LOG_STREAM_NAME}'
      ],
      limit: 10,
    }
    cloudwatchlogs.filterLogEvents(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     {
        console.log(JSON.stringify(data))
      };           // successful response
    });
    

    特定のワードで検索する

    'use strict'
    
    const aws = require('aws-sdk')
    var cloudwatchlogs = new aws.CloudWatchLogs();
    var params = {
      logGroupName: '/aws/lambda/{YOUR_LAMBDA_NAME}',
      logStreamNames: [
        '{YOUR_LOG_STREAM_NAME}'
      ],
      filterPattern: 'End',
      limit: 10,
    }
    cloudwatchlogs.filterLogEvents(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     {
        console.log(JSON.stringify(data))
      };           // successful response
    });
    

    利用可能なフィルタについてはドキュメントを確認しましょう。

    レスポンスサンプル

    {
      "events": [
        {
          "logStreamName": "2017/08/10/[$LATEST]fa0459eaca4c47fd8910814a87aa2d6d",
          "timestamp": 1502329050066,
          "message": "START RequestId: 78a33025-7d6c-11e7-965d-21381e8db922 Version: $LATEST\n",
          "ingestionTime": 1502329050092,
          "eventId": "33503057349872421645050596679170442839993300164917788672"
        },
        {
          "logStreamName": "2017/08/10/[$LATEST]fa0459eaca4c47fd8910814a87aa2d6d",
          "timestamp": 1502329050071,
          "message": "2017-08-10T01:37:30.071Z\t78a33025-7d6c-11e7-965d-21381e8db922\tWarning: Application ID is not set\n",
          "ingestionTime": 1502329065157,
          "eventId": "33503057349983925371043249813090712220593683440808296448"
        },
        {
          "logStreamName": "2017/08/10/[$LATEST]fa0459eaca4c47fd8910814a87aa2d6d",
          "timestamp": 1502329050072,
          "message": "END RequestId: 78a33025-7d6c-11e7-965d-21381e8db922\n",
          "ingestionTime": 1502329065157,
          "eventId": "33503057350006226116241780436232247938866331802314276865"
        },
      ],
      "searchedLogStreams": [
        {
          "logStreamName": "2017/08/10/[$LATEST]XXXXXXX",
          "searchedCompletely": false
        }
      ],
      "nextToken": "XXXXXXXXXXXXX"
    }
    

    覚書

    もしCloudWatch Logsのメトリクスフィルターで満足できない検索をしたい場合は、フロント側でlodashなどを使って頑張るか、Amazon Elasticsearch Serviceにデータをストリーミングさせてそちらから検索するといいかなと思います。

    良い方法や事例あればFacebookとかでコメントもらえると嬉しいです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark