CloudWatchのログをBoto3(AWS SDK for Python)でローカルファイルに出力してみた
こんにちは、みかみです。
au 金曜日クーポンで、沖縄だったらブルーシールアイスがもらえるんですって(いいなーv
はじめに
AWS管理コンソールからCloudWatchのログ確認してたのですが、長くなるとスクロールするたびロードで待たされてつらい。。
S3にエクスポートできるものの、パーミッション設定必要だったり、gzipなのでWindowsだと地味にめんどくさかったり。。
やりたいこと
- CloudWatch のログをS3を経由しないでローカルにファイル保存したい
- boto3 の CloudWatchLogs で取れるものを確認してみたい
前提条件
- Python(3.6.0)インストール済み
- AWS CLIインストール&設定済み(AWS CLI のインストールと設定)
- boto3 を pip install 済み
やってみよう
ロググループを取得
まずは、prefixを指定して、ロググループを取得してみます。
お目当てのログのディレクトリを検索するイメージです。
import boto3 prefix = '/aws/lambda/test' client = boto3.client('logs') response = client.describe_log_groups( logGroupNamePrefix=prefix ) print(response)
実行してみると、こんなレスポンスが返ってきました。
{ 'ResponseMetadata': { 'HTTPHeaders': { 'content-length': '660', 'content-type': 'application/x-amz-json-1.1', 'date': 'Thu, 09 Mar 2017 01:51:02 GMT', 'x-amzn-requestid': 'da60f054-046a-11e7-bca8-dda7a1313588' }, 'HTTPStatusCode': 200, 'RequestId': 'da60f054-046a-11e7-bca8-dda7a1313588', 'RetryAttempts': 0 }, 'logGroups': [ { 'arn': 'arn:aws:logs:ap-northeast-1:109054975408:log-group:/aws/lambda/test-get-sqs-message:*', 'creationTime': 1488869579001, 'logGroupName': '/aws/lambda/test-get-sqs-message', 'metricFilterCount': 0, 'storedBytes': 3300 }, (中略) { 'arn': 'arn:aws:logs:ap-northeast-1:109054975408:log-group:/aws/lambda/test-sqs-lambda-func:*', 'creationTime': 1488949191347, 'logGroupName': '/aws/lambda/test-sqs-lambda-func', 'metricFilterCount': 0, 'storedBytes': 0 } ] }
ログストリームを取得
今度は見つかったロググループを指定して、ログストリームの一覧を取得してみます。
ディレクトリ内のログファイル名を取得するイメージです。
import boto3 group_name = '/aws/lambda/test-get-sqs-message' client = boto3.client('logs') response = client.describe_log_streams( logGroupName=group_name, orderBy='LastEventTime', descending=True ) print(response)
実行します。
{ 'ResponseMetadata': { 'HTTPHeaders': { 'content-length': '1865', 'content-type': 'application/x-amz-json-1.1', 'date': 'Thu, 09 Mar 2017 02:11:17 GMT', 'x-amzn-requestid': 'ae3dc71f-046d-11e7-9461-23784152c415' }, 'HTTPStatusCode': 200, 'RequestId': 'ae3dc71f-046d-11e7-9461-23784152c415', 'RetryAttempts': 0 }, 'logStreams': [ { 'arn': 'arn:aws:logs:ap-northeast-1:109054975408:log-group:/aws/lambda/test-get-sqs-message:log-stream:2017/03/07/[$LATEST]a723d0594e6f41808989fe603b4fd205', 'creationTime': 1488875487417, 'firstEventTimestamp': 1488875487686, 'lastEventTimestamp': 1488875488722, 'lastIngestionTime': 1488875503816, 'logStreamName': '2017/03/07/[$LATEST]a723d0594e6f41808989fe603b4fd205', 'storedBytes': 454, 'uploadSequenceToken': '49570236197125197928892515127748130759845332711823640194' }, (中略) { 'arn': 'arn:aws:logs:ap-northeast-1:109054975408:log-group:/aws/lambda/test-get-sqs-message:log-stream:2017/03/07/[$LATEST]aa2e39e31057441c9547b10f4bae7476', 'creationTime': 1488869579056, 'firstEventTimestamp': 1488869579039, 'lastEventTimestamp': 1488869579705, 'lastIngestionTime': 1488869594261, 'logStreamName': '2017/03/07/[$LATEST]aa2e39e31057441c9547b10f4bae7476', 'storedBytes': 680, 'uploadSequenceToken': '49568106864214712160805596000628551033956595763377078690' } ] }
ログストリーム一覧が取得できました。
ログを取得してjsonファイルに書き出す
ロググループとログストリームを指定して、ログを取得します。
ログファイルを開いて中身を見てみるイメージです。
import boto3 group_name = '/aws/lambda/test-get-sqs-message' stream_name = '2017/03/07/[$LATEST]a723d0594e6f41808989fe603b4fd205' client = boto3.client('logs') response = client.get_log_events( logGroupName=group_name, logStreamName=stream_name, startFromHead=True ) print(response)
こんなレスポンスが返ってくるので、
{ 'ResponseMetadata': { 'HTTPHeaders': { 'content-length': '1311', 'content-type': 'application/x-amz-json-1.1', 'date': 'Thu, 09 Mar 2017 02:31:37 GMT', 'x-amzn-requestid': '855ca9a7-0470-11e7-93ac-912c20609353' }, 'HTTPStatusCode': 200, 'RequestId': '855ca9a7-0470-11e7-93ac-912c20609353', 'RetryAttempts': 0 }, 'events': [ { 'ingestionTime': 1488875487703, 'message': 'START RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0 Version: $LATEST\n', 'timestamp': 1488875487686 }, (中略) { 'ingestionTime': 1488875503816, 'message': 'REPORT RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0\tDuration: 1034.75 ms\tBilled Duration: 1100 ms \tMemory Size: 128 ' 'MB\tMax Memory Used: 30 MB\t\n', 'timestamp': 1488875488722 } ], 'nextBackwardToken': 'b/33203032883223504422259409965453248701700005246959026176', 'nextForwardToken': 'f/33203032906327076447937135559563551360914771704139022338' }
ログ本体('events')部分をjsonファイルに書き出しました。
import json (中略) with open('log.json', 'w') as f: json.dump(response['events'], f, sort_keys=True, indent=4)
できたjsonファイルを見てみます。
[ { "ingestionTime": 1488875487703, "message": "START RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0 Version: $LATEST\n", "timestamp": 1488875487686 }, (中略) { "ingestionTime": 1488875503816, "message": "REPORT RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0\tDuration: 1034.75 ms\tBilled Duration: 1100 ms \tMemory Size: 128 MB\tMax Memory Used: 30 MB\t\n", "timestamp": 1488875488722 } ]
とりあえず出力してみたものの、なにしろJSONだし、UNIXタイムスタンプだし。。(見にくいし、grepするにも微妙だし。。
なんか、いまいち。。
ログを整形してファイル出力する
ちゃんとログファイル的なものに整形して出力することにします。
ロググループを指定して、すべてのログストリームのログを出力してみます。
import boto3 from datetime import datetime # ロググループ名 group_name = '/aws/lambda/test-get-sqs-message' # ログストリーム一覧を取得 client = boto3.client('logs') response = client.describe_log_streams( logGroupName=group_name, orderBy='LastEventTime', descending=True ) # 全てのストリームのログを取得 for stream in response['logStreams']: stream_name = stream['logStreamName'] log_timestamp = (datetime.fromtimestamp(int(str(stream['creationTime'])[:10]))).strftime('%Y%m%d%H%M%S') # ログファイル名:[ストリーム名]_[作成日時].log(Windowsだとファイル名に '/' を入れられないので取り除く) file_name = '{}_{}.log'.format(stream_name, log_timestamp).replace('/', '') # ログを取得 logs = client.get_log_events( logGroupName=group_name, logStreamName=stream_name, startFromHead=True ) # 'timestamp' と 'message' をログファイルに出力 body = logs['events'] with open(file_name, 'w') as f: for line in body: message = '[{}] {}'.format(datetime.fromtimestamp(int(str(line['timestamp'])[:10])), line['message']) f.write(message)
ログファイルが出力できました!
[2017-03-07 17:31:27] START RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0 Version: $LATEST [2017-03-07 17:31:28] msg_3 [2017-03-07 17:31:28] msg_1 [2017-03-07 17:31:28] msg_2 [2017-03-07 17:31:28] END RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0 [2017-03-07 17:31:28] REPORT RequestId: 74d22ae4-0310-11e7-9f8d-11c318320fa0 Duration: 1034.75 ms Billed Duration: 1100 ms Memory Size: 128 MB Max Memory Used: 30 MB
おわりに(所感)
今回は全てのログをファイル出力しただけですが、どう処理するかはコードで好きに書けるので、用途に合わせてフィルタかけたり、データベースに出力したり。
Lambdaと連携させれば、ログ監視機能も手軽に実装できちゃいますねv
- 【新機能】Amazon CloudWatch LogsのログデータをAWS Lambdaでリアルタイムに処理する | Developers.IO
- CloudWatch LogsのLambdaによるログ監視 | Developers.IO