AWS S3 액세스 로그 집계

전제



AWS S3의 액세스 로그는 한 번의 액세스에 대해 지정한 버킷에 하나의 액세스 로그 파일을 생성한다고 가정합니다.
감각적으로는 1회에 1개의 파일이 아니라, 동시에 발행된 로그를 1개의 파일에 정리해 토하고 있는 것 같습니다. 세세한 것은 Amazon S3 서버 액세스 로깅를 보십시오.
즉 「1시간마다 1회, 하루에 총 24회의 액세스가 있었다고 하면 작성되는 로그 파일의 수는 24개」로서 이 기사를 읽어 주세요.

무엇을 하고 싶은가



전제에서 언급했듯이 1회의 액세스로 1개의 로그 파일이 작성되므로, 1000회 액세스 되면 1000개의 로그 파일이 작성되어 버립니다. 「하루에 발행된 로그를 모두 정리해 보고 싶다」라고 하는 때에 모든 로그 파일을 로컬에 다운로드 하는 것은 일하고 싶지 않습니다. S3 의 사양상, 나름대로 비용이 듭니다. 따라서 이러한 로그 파일을 하루에 정리합니다. 1일마다가 아니라 1주일마다나 1개월마다 정리해 버려도 좋을지도 모릅니다. 다만 이 후에 사용하는 AWS 람다 의 사양상 파일이 너무 커지면 무리일지도 모르기 때문에 하루 마다 했습니다.

Direction





위 그림과 같은 흐름으로 처리를 실행합니다.
1. 왼쪽에서 "User"가 "Bucket A"에 액세스한다(2020-09-07-14-30).
2. "Bucket A"는 액세스되면 로그를 "Bucket B"에 씁니다.
3. 「Bucket B」는 로그를 기입하면 「Bucket C」에 있는 「2020_09_07.txt」에 그 로그를 추기한다.

이러한 처리 중, 1과 2의 처리는 Amazon S3 서버 액세스 로깅 의 설정으로 자동으로 행해지므로 할애합니다.

이전 준비



3의 처리를 하기 위해서 람다 보다 함수를 작성합니다. 이번에는 Node.js 배포 패키지를 만들어 함수를 만들었습니다.
Node.js의 Lambda 배포 패키지를 만들려면 어떻게 해야 합니까?

작성할 때는 액세스 권한에 「S3FullAccess」를 가지는 롤을 주어 주세요.

만든 함수의 이름을 sum_logs라고 합니다. sum_logs의 설정, 「트리거 추가」보다, 「Bucket B」에 새로운 오브젝트가 작성되면 sum_logs가 실행되도록 해 둡니다.

또 「Bucket C」에 「2020_09_07.txt」라고 하는 파일을 준비해 두어 주세요.

「Bucket B」나 「Bucket C」라고 쓰고 있습니다만 실제의 Bucket의 이름은 "B"나 "C"로서 이하의 코드를 취급해 주세요.

index.js


var AWS = require("aws-sdk");
const moment = require("moment");
const s3 = new AWS.S3({
  region: "ap-northeast-1",
});

exports.handler = async (event, context, callback) => {
  try {
    //this means Bucket "C"
    const dest_bucket = "C"; 

    var uploaded_params = {
      // event.Records[0].s3.bucket.name means Bucket "B"
      Bucket: event.Records[0].s3.bucket.name,
      Key: event.Records[0].s3.object.key,
    };
    var uploaded_obj = await s3.getObject(uploaded_params).promise();
    var uploaded_body = uploaded_obj.Body.toString();

    var dest_params = {
      Bucket: dest_bucket,
      Key: moment().format("YYYY-MM-DD") + ".txt",
    };
    var dest_obj = await s3.getObject(dest_params).promise();
    var dest_body = dest_obj.Body.toString();
    dest_body += uploaded_body;

    var new_params = {
      Bucket: dest_bucket,
      Key: moment().format("YYYY-MM-DD") + ".txt",
      Body: dest_body,
    };
    var put_obj = await s3.putObject(new_params).promise();

    // delete uploaded logs in Bucket "B"
    var deleted = await s3.deleteObject(uploaded_params).promise();

    return;
  } catch (e) {
    console.log(e);
    return;
  }
};


해설



내용은 대체로 읽으면 알 수 있습니다.
이번 배포 패키지로 한 것은 Moment.js을 사용하고 싶었기 때문입니다. 개인적으로 취급하기 쉽기 때문에 추천합니다.

주의점과 정리



이번에는 날짜별로 파일을 정리하고 있습니다만, 그 베이스가 되는 파일(이번은 2020_09_07.txt)은 미리 특정의 버킷(이번은 Bucket "C")에 작성해 둘 필요가 있습니다.
이 베이스가 되는 파일도 수동으로 작성한다니 바보같은 일은 하지 않기 때문에, 무론 자동으로 실시하게 하는 것입니다만 피곤했기 때문에 신경이 쓰면 씁니다. 처리는 마찬가지로 Lambda를 사용하지만 트리거는 EventBridge을 사용합니다. 매우 간단합니다.

비용 정보



「Log가 토해질 때마다 S3에 파일을 Put하고 있으면, 데이터 전송료는 상당히 걸리지 않나?」라고 생각될지도 모릅니다만, 나는 AWS Lambda 요금 에 쓰여져 있다同じ AWS リージョン内における Amazon S3、Amazon Glacier、Amazon DynamoDB、Amazon SES、Amazon SQS、Amazon Kinesis、Amazon ECR、Amazon SNS、Amazon EFS、または Amazon SimpleDB と AWS Lambda 関数の間でのデータ転送は無料です。
라는 문장을 믿습니다.

참고



S3
Amazon S3 서버 액세스 로깅
람다
EventBridge
AWS Lambda 요금
mermaid.js

좋은 웹페이지 즐겨찾기