🐍

FireLens に流れるログを Lambda で抽出する

2021/05/20に公開

ECS に乗っているコンテナのログを FireLens を経由して Kinesis Firehose -> S3 にログを出しました.ただ,下記の JSON 形式でログが保存されているため,Athena でクエリしようとするとしてもログの詳細を見る時辛いなと思っていました.

{
    "container_id": "xxx",
    "container_name": "xxx",
    "ecs_cluster": "xxx",
    "ecs_task_arn": "arn:aws:ecs:xxx:xxx:task/xxx/xxx",
    "ecs_task_definition": "xxx:xxx",
    "log": "xxx"
}

そこで,Lambda を使って log の部分だけ抽出して S3 に保存したいと思ってやってみました.

ログを抽出するためのコード

Lambda は Python 3.8 で書いているのですが,ログを抽出し,S3に保存するところのみの部分を抜粋してます.Firehose から送られてくるデータからログの詳細を抽出して Fireshose に戻し S3 に保存されます.

import json
import base64
from botocore.exceptions import ClientError

def lambda_handler(event, context):  
    log_output = []  
    for record in event['records']:
        payload = json.loads(base64.b64decode(record['data']))
        log_detail = payload["log"]

     output_record = {
        'recordId': record['recordId'],
        'result': 'Ok',
        'data': base64.b64encode(json.dumps(log_detail).encode('utf-8')).decode('utf-8')
    }
    
    try:
        log_output.append(output_record)
    except ClientError as e:
        print(e.response['Error']['Message'])
    return {'records': log_output} 

S3 に保存されたログのイメージ

S3 に保存されたイメージが下記の画像みたく指定したパスで年月日でフォルダが作られ,ログファイルが作られます.

ファイルを開くと,ログ詳細だけが保存されるようになったのでこれで Athena でいい感じにクエリしていけそうです.

{
    "request_headers": {
        "host": "xx.xx.xx.xx:xx",
        "user-agent": "ELB-HealthChecker/2.0",
    },
    "remote_addr": "xx.xx.xx.xx",
    "request_uri": "/",
    "request_method": "GET",
    "request_time": "2021/05/20 06:30:39",
    "response_time": "0.0004",
    "response_status": 200
}

参考情報

https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/data-transformation.html#data-transformation-status-model

Discussion