Ruby AWS SDK v2でディレクトリ階層をlistする

Goal

  • s3で以下のように保存されているログを取得したい
  • instance-idごとにディレクトリが切られ、ログが保存される
  • instanceは常に起動したり破棄されたりするためinstance-idが不明なので、多重ループでスキャンする必要がある
- (bucket)blog
  - app
    - config
    - logs
      - instance-id-1
        - nginx-access-log-2016-12-01.gz
        - nginx-access-log-2016-12-02.gz
        - nginx-access-log-2016-12-03.gz
        - nginx-error-log-2016-12-01.gz
        - nginx-error-log-2016-12-02.gz
        - nginx-error-log-2016-12-03.gz
        - php-error-log-2016-12-01.gz
        - php-error-log-2016-12-02.gz
      - instance-id-2
      - instance-id-3
      - instance-id-4
    - tools
    - ...
  - api
    - ...
  - batch
    - ...

Solution

http://docs.aws.amazon.com/AmazonS3/latest/dev/ListingKeysHierarchy.html

  • list_objectsメソッドでprefixの末尾をスラッシュで指定する
  • delimiterに"/"を指定する
  • common_prefixesでサブフォルダ一覧を取得できる
require "aws-sdk"

client = Aws::S3::Client.new(
  access_key_id: "***",
  secret_access_key: "***",
  endpoint: "https://s3.amazonaws.com"
)

instance_list = client.list_objects(
  bucket: "blog",
  prefix: "app/logs/",
  delimiter: "/"
)

instance_list.common_prefixes.each do |instance|
  puts instance.prefix
  logs = client.list_objects(bucket: "blog", prefix: instance.prefix)
  logs.contents.each do |content|
    puts content.key
  end
end

Environment

% ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]

% gem list aws-sdk

*** LOCAL GEMS ***
aws-sdk (2.6.41, 2.2.24)
aws-sdk-core (2.6.41, 2.2.24)
aws-sdk-resources (2.6.41, 2.2.24)