Функции AWS SDK, как правило, асинхронные, поэтому важно понимать, как программировать асинхронный JavaScript с помощью Promises и async / await.
Вот один из способов сделать это немного более линейными, надеюсь, немного легче следовать.
const AWS = require('aws-sdk');
const _ = require('lodash');
const S3 = new AWS.S3({
region: 'ap-south-1',
apiVersion: '2006-03-01',
});
const cloudwatch = new AWS.CloudWatch({
region: 'ap-south-1',
apiVersion: '2010-08-01',
});
const metrics = async (bucketName) => {
const params = {
EndTime: 1536128999,
MetricDataQueries: [{
Id: 'm17',
MetricStat: {
Metric: {
Dimensions: [
{
Name: 'BucketName',
Value: bucketName,
},
{
Name: 'StorageType',
Value: 'StandardStorage',
},
],
MetricName: 'BucketSizeBytes',
Namespace: 'AWS/S3',
},
Period: 86400,
Stat: 'Sum',
Unit: 'Bytes',
},
ReturnData: true,
}],
StartTime: 1536085800,
};
return cloudwatch.getMetricData(params).promise();
};
exports.handler = async (event) => {
try {
// List all bucket data
const bucketData = await S3.listBuckets({}).promise();
// Use map to transform bucket data to just the bucket names
const bucketNames = _.map(bucketData.Buckets, bucket => bucket.Name);
// Get metrics for each bucket by name
const bucketMetrics = await Promise.all(_.map(bucketNames, bucket => metrics(bucket)));
// Use map to transform bucket metrics to just the bucket sizes
const bucketSizes = bucketMetrics.map(m => m.MetricDataResults[0].Values[0] || 0);
// Use zipWith to combine the bucket names and corresponding bucket sizes
return _.zipWith(bucketNames, bucketSizes, (bn, bs) => ({ bucket: bn, size: bs }));
} catch (err) {
console.log(err.message);
throw err;
}
};
Результат этого кода выглядит следующим образом:
[
{
"bucket": "mybucket-of-images",
"size": 1209721781
},
{
"bucket": "backup-project",
"size": 2048
}
]