CloudWatch Logs의 모든 로그 이벤트는 이미 gzip 형식으로 압축되어 있으므로 Firehose의 압축 구성을 비압축으로 유지해야 이중으로 압축되는 것을 방지할 수 있습니다.
- AWS Document
import {S3} from 'aws-sdk';
import {S3Event} from 'aws-lambda';
import {Buffer} from 'buffer';
const s3Client = new S3({ apiVersion: 'latest', region: process.env.AWS_REGION });
export async function bucketHandler (event: S3Event) {
console.dir(event.Records);
// Get the object from the event and show its content type
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
const params : GetObjectCommandInput = {
// Bucket: the bucket name containing the object
Bucket: bucket,
// Key: Key of the object to get (file name)
Key: key,
ResponseContentEncoding: 'gzip',
ResponseContentType: 'text/plain; charset=utf-8'
};
try {
// Body — (Buffer(Node.js), Typed Array(Browser), ReadableStream) // 2006 version, aws-sdk
const { Body } = await s3Client.getObject(params).promise();
const resultString = Body.toString('utf-8');
// 이 부분이 잘못되었다.
console.log(resultString);
return resultString;
} catch (error) {
console.log(error);
const message = `Error getting object from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
console.log(message);
throw new Error(message);
}
};
다음 부분에 잘못된게 있다.
const { Body } = await s3Client.getObject(params).promise(); const resultString = Body.toString('utf-8'); // 이 부분이 잘못되었다. console.log(resultString);
S3 에 올라가있는 파일 오브젝트의 Body
만 읽어오면 된다고 생각했는데
막상 로그를 찍어보니 왠 Uint8Array
Buffer 가 출력된다.
바로 toString('utf-8')
해보니 인코딩된게 깨져보이는 것을 확인할 수 있었다.
별도의 압축형식을 지정하지 않아도 모든 파일은 .gz
형식으로 압축되어있다.
즉, .gz
파일을 Uint8Array || toString 한 값이 '압축된 파일 스트림' 그 자체인것이다.
.gz
파일은 압축된 파일이므로 압축을 풀어주기만 하면된다.
import * as zlib from 'zlib';
// Body 는 .gz 파일의 스트림 (TypedArray) 이므로 압축을 해제해주자.
const bufferedString = zlib.gunzipSync(Body as Uint8Array);
// ...
// processing..
🙂 S3 Object 파일 파싱성공!