InfluxDB と Grafana で可視化して Puppeteer で PDF を生成
はじめに
計測データのグラフや表をまとめたいことが 何度かあったんですがちょうどいいツールを見つけられていませんでした。
エクセルでグラフを作ったりgnuplotでグラフを作ったりもできますが 見た目をかっこよくまとめるのは慣れないと難しそうに感じました。
Grafana は前に目にしたことがあったんですが 常時計測したデータの可視化用でちょっと使いたい用途には合わないかなと思ってました。
ただ docker-compose を使って CLI ツールのようにまとめることで やりたい用途にも使えそうだなと思い試してみました。
実験に使ったリポジトリはここに置いています。
やり方
InfluxDB, Grafana, Puppeteer のコンテナを docker-compose で連携させるというやり方です。 なんでも docker でやってみたくなっている感じが少しあります。 色々なツールを使っていて全部直接入れるのはちょっと気が引けるし、環境構築も大変なので実際こういう用途では便利だと思います。
InfluxDB
InfluxDB は時系列データを扱うデータベースで Go 言語で書かれているようです。 Grafana とセットでよく使われているのを目にする気がします。 データの有効期限を設定できるようで常時計測しているデータの保存などに使うことが多いようです。
InfluxDB Line Protocol reference | InfluxData Documentation
Writing data with the HTTP API | InfluxData Documentation
Line Protocol の書き方と curl での API 呼び出し方の例を真似してデータを取り込むことができました。
公式のイメージが Docker Hub にありました。
https://hub.docker.com/r/library/influxdb/
Grafana
Grafana はデータの可視化用のウェブサーバーで GUI でダッシュボードに色々なグラフを表示したりできます。 InfluxDB 以外にも色々なデータソースを扱うことができるようです。 Grafana もサーバー部分は Go 言語のようです。
Grafana も Docker Hub にイメージがありました。
https://hub.docker.com/r/grafana/grafana/
Puppeteer
Puppeteer は Chrome の開発用 API を利用できる Node ライブラリです。
ウェブページの PDF を作るのに他のツールも少し使ってみたのですが
表示が終わるのを待つなど細かい制御をするには Puppeteer を使ったほうがうまく行きそうだったので使ってみることにしました。
下のような感じで PDF の保存ができました。
const puppeteer = require('puppeteer'); const url = process.argv[2]; const output_path = process.argv[3]; const width = 1080; const height = 1920; (async() => { const browser = await puppeteer.launch({ headless: true, executablePath: 'chromium-browser', args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); await page.setExtraHTTPHeaders({ Authorization: 'Basic ' + new Buffer('admin:admin').toString('base64') }); await page.setViewport({ width: width, height: height, isMobile: false }); await page.goto(url, {waitUntil: 'networkidle2'}); await page.pdf({ path: output_path, width: width + 'px', height: height + 'px', }); await browser.close(); })();
puppeteer/troubleshooting.md at master · GoogleChrome/puppeteer · GitHub
ここの Dockerfile の書き方を参考にイメージを作りました。
docker-compose 設定
docker-compose 設定は下のようになりました。
Grafana のダッシュボードとデータソースの設定は
/etc/grafana/provisioning/
以下に設定ファイルを置くと反映されるので
設定ファイルを置いたディレクトリをマウントするようにしています。
version: "3" services: influxdb: image: influxdb:1.6.2 ports: - "8086:8086" grafana: image: grafana/grafana:5.2.4 ports: - "3000:3000" volumes: - ./grafana/dashboards:/etc/grafana/provisioning/dashboards - ./grafana/datasources:/etc/grafana/provisioning/datasources depends_on: - influxdb puppeteer: build: context: . dockerfile: Dockerfile.puppeteer volumes: - ./volume:/volume entrypoint: - ./run-puppeteer.sh depends_on: - grafana - influxdb
生成した PDF
一連の流れを試してみるのが目的だったので見栄えしないグラフ一つしかありませんが下のような感じで生成できました。
Grafana のダッシュボードは kiosk=true
の GET パラメーターを付けるとメニューを非表示にできるようです。
やろうと思えば Puppeteer で少し見た目を加工するなどもできるのかなと思います。
まとめ
InfluxDB にデータを取り込み Grafana で表示して Puppeteer で PDF 作成という一連の流れをdocker-compose で CLI 化することができました。 はじめて使うものが多かったので少し時間がかかりましたが今後も使う機会がありそうなので少しは慣れることができてよかったと思います。
Puppeteer で PDF 生成する前に Grafana のサーバーが立ち上がるのを少し待つ必要があるのを今回は10秒スリープするといういい加減な方法で対応しました。 こういう用途には wait-for-it や dockerise が使えるらしいです。
Docker 内で GLFW のプログラムを動かすサンプル
はじめに
Docker の利用は CLI やサーバーサイドの利用が主なのかなと思っていましたが GUI のプログラムもある程度は動かせるようです。
軽いゲームなどを作る場合も使えるかもしれません。
実験用に GLFW のデモアプリを動かす Docker イメージを作ってみました。
Dockerfile などはここのリポジトリに置きました。
マウントしたり特権コンテナにしたりという設定があるため docker-compose を使っています。
Docker での GUI
以下のページなどを参考にさせてもらいました。
docker/Tutorials/GUI - ROS Wiki
https://unskilled.site/dockerコンテナの中でguiアプリケーションを起動させる/
https://tail-island.github.io/programming/2017/07/11/docker-for-development-container-on-linux.htmltail-island.github.io
いくつか方法があるようです。
- X11 ソケットを共有する
- ホストの X サーバーとコンテナの X クライアントがソケット通信
- コンテナで X サーバーを動かす
- コンテナで X サーバーも X クライアントも動かす
- ssh を使った X11 forwarding
- VNC を使う
ホスト側も X ウィンドウシステムの場合は上の二つの方法が使えそうです。
自分ではホストも Ubuntu などで動かすと思うので一番簡単そうな X11 ソケットを共有する方法を試してみました。
Docker イメージ
前に作った haskell 用のイメージを元にして作っています。
開発用として使う想定なので他の言語ではそれぞれの開発環境が入ったイメージを元にして必要なパッケージをいれることになると思います。
FROM tkaaad97/haskell-docker:8.2.2 # install dev tools RUN apt-get update && \ apt-get install -y --no-install-recommends \ make \ pkgconf \ xz-utils \ xorg-dev \ libgl1-mesa-dev \ libglu1-mesa-dev \ libxrandr-dev \ libxinerama-dev \ libxcursor-dev \ libxi-dev \ libxxf86vm-dev WORKDIR /app/ ENTRYPOINT [] CMD ["bash"]
下は docker-compose 設定ファイルです。
/tmp/.X11-unix:/tmp/.X11-unix:rw
の部分で X11 ソケットをマウントして共有しています。
command で GLFW-b-demo のパッケージをインストールして起動しています。
version: "2" services: app: build: . command: bash -c 'stack install GLFW-b-demo && /root/.local/bin/GLFW-b-demo' working_dir: /app privileged: true environment: - DISPLAY=${DISPLAY} volumes: - .:/app - .stack:/root/.stack - /tmp/.X11-unix:/tmp/.X11-unix:rw
xhost
コンテナとホストで X11 ソケット共有して通信する必要があるのですが コンテナ上のユーザーとホスト側で接続しているユーザーが 違う場合にそのままでは通信が許可されません。 この場合に xhost を使って許可することができます。
xhost local:
これを実行するとローカルの接続であればユーザーが違っても許可されます。
ただしあまり安全な方法では無いらしくコンテナのユーザーとホストのユーザーを合わせる方法なども紹介されていました。
スクリーンショット
以下のようにデモアプリが表示されました。
Amazon Aurora オートスケーリングでも ScheduledAction が使えた
はじめに
オートスケーリング機能でよく使われるのは EC2 のオートスケーリング機能だと思います。 ポリシーを設定すると自動でインスタンスを増減させてスケールアウト、スケールインできます。 またスケジュールされたアクションも設定することができて、これで最大、最小、希望のインスタンス数を変えることができます。 時間が予定されるイベントなどではスケジュールされたアクションを使うことがあります。
Aurora では Read Replica のオートスケーリング機能があります。 CPU 使用率やデータベース接続数でのオートスケーリングポリシーを設定して自動で Read Replica 数を増減することができます。 Aurora Read Replica でもスケジュールされたアクションが使えるようで便利だと思うんですが、これについて書いてる記事があまりなかったので書いておきます。
使えそうなケース
時間が決まっていて負荷がかかることがわかっているイベントであらかじめ Read Replica 数を増やしておくというのがあると思います。
cron 式でのスケジュール設定もできるので毎週のスケジュールや毎日のスケジュールなどで Read Replica 数を変えたりもできます。 アクセスが少ない時間帯に Read Replica 数を減らしておくなどしてコスト削減できるかもしれません。
やり方
- スケーラブルターゲットとオートスケーリングポリシー作成
- ScheduledAction 作成
という感じでできました。
オートスケーリングポリシー作成は AWS のウェブ上からもできたんですが ScheduledAction は RDS の画面からは表示も編集もできませんでした。 今のところは CLI か API などを使ってやる必要があるようです。 もしかするとオートスケーリングのサービスの方から設定したりできるのかもしれないんですが ap-northeast-1 リージョンではまだ提供されていないので使えませんでした。
スケーラブルターゲットとオートスケーリングポリシー作成はこちらのドキュメントの方法でできました。
ScheduledAction の設定は put-scheduled-action で行います。 autoscaling サブコマンドではなく application-autoscaling サブコマンドを使います。
put-scheduled-action — AWS CLI 1.15.76 Command Reference
aws application-autoscaling put-scheduled-action \ --service-namespace rds \ --schedule at(2018-12-31T20:00:00) \ --scheduled-action-name '{{schedule_name}}' \ --resource-id 'cluster:{{db_cluster}}' \ --scalable-dimension rds:cluster:ReadReplicaCount \ --scalable-target-action 'MinCapacity=2,MaxCapacity=2'
describe-scheduled-actions — AWS CLI 1.15.76 Command Reference
describe-scheduled-actions で登録されているスケジュールが取得できます。
aws application-autoscaling describe-scheduled-actions --service-namespace rds --resource-id 'cluster:{{db_cluster}}'
参考
VS Code でも intero が使えてなかなか便利
はじめに
前に haskell-ide-engine について書いたんですがビルドが面倒などの理由であまり使わなくなりました。 intero は Emacs だけかと思ってたんですがいつの間にか VS Code や neovim でも使えるようになってたため導入してしばらく使ってみています。 intero は stack で簡単に入れられて自分でビルドする必要が無いというのがとても良いです。 VS Code + intero は docker 内の ghc や stack を使っている場合でも導入できました。
intero (haskero)
intero は haskell 開発用のツールでいくつかのエディタや IDE から利用できます。
VS Code 用の intero プラグインが haskero です。
他に Haskelly というプラグインもあるんですが haskero.intero.stackPath に相当する設定がなくて docker 環境で使う場合は haskero の方が使える可能性ありそうということで haskero を選びました。
下のページで gif で動作している様子が見られるのでわかりやすいと思います。
マウスホバーで変数の型を表示したり、ファイルを保存した時にエラーや警告を教えてくれます。 定義にジャンプしたり補完したりもできます。
docker 環境の場合
docker 環境を使っていない場合は多分すごく簡単で特にはまるところなく導入できると思います。 docker 環境の場合は前に haskell-ide-engine を使ったときと同じような方法で導入できました。
ちょっと導入してから時間が経っているためうろ覚えですが下の感じでできたと思います。
stack install intero
でプロジェクト内に intero をインストール- プロジェクトのディレクトリをホスト側と同じパスでマウントする
- stack 設定で
allow-different-user: true
にしておく - VS Code ワークスペース設定で
haskero.intero.stackPath
で docker 内の stack を実行するスクリプトを設定する - VS Code ワークスペース設定で
"haskero.intero.ghciOptions": []
に設定する (何かエラー出てしまったため)
haskero.intero.stackPath
で設定したスクリプトは現在 docker-compose を使っていたため下のような感じにしました。
#!/bin/bash docker-compose run --rm --no-deps app stack $@
VS Code でも使えたその他の haskell 関連ツール
intero の他にもいくつか便利なツールが使えました。
現在は hlint と stylish-haskell のプラグインを入れて使っています。
hlint と stylish-haskell は基本的に開いているファイルしか見ないようなので docker 環境でもあまり関係なく使えそうです。 また両方とも github で実行ファイルも配布されているので無理に docker 環境に入れなくても手軽に導入できると思います。
hlint は以下のプラグインを使いました。
GitHub - hoovercj/vscode-haskell-linter: An extension to bring hlint to vscode
GitHub - ndmitchell/hlint: Haskell source code suggestions
stylish-haskell は下のプラグインを使いました。
GitHub - vigoo/stylish-haskell-vscode: stylish-haskell support for VS code
Tiled フォーマットの覚え書き
Tiled
ゲームを作る時に使ってみたいと思って前に Tiled について調べたことについて書いて置きます。
Tiled はアクションゲームや RPG などのマップをタイルで構成するためのツールです。
Tiled Map Editor | A flexible level editor
ゲームのマップ数が少ない場合はマップごとに一枚の画像を使うことも可能だと思いますが データ量を抑えたり、マップを動的に生成したりなどする場合は Tiled のようにタイルに分割して描画することになると思います。
ソースも公開されていて、色々な言語でのライブラリも作られていて利用しやすそうです。
GitHub - bjorn/tiled: A flexible level editor
Libraries and Frameworks — Tiled 1.1.0 documentation
フォーマット
Tiled で使われるのは基本的にはマップファイルとタイルセットファイルそれからタイルセットの画像ファイルのようです。
JSON Map Format — Tiled 1.1.0 documentation
TMX Map Format — Tiled 1.1.0 documentation
マップファイルとタイルセットファイルは普通分けて使われるようです。
ソースコードにいくつか例が含まれていました。
tiled/examples at master · bjorn/tiled · GitHub
例は XML のものしか無いんですが、これを読み込んで JSON にエクスポートすることもできました。 JSON の方が慣れているので使うときは JSON 使おうかと考えています。
tiled/examples/perspective_walls.tmx を JSON エクスポートすると下のようになりました。 (長いため一部省略しています)
{"height":32, "infinite":false, "layers":[ { "data":[0, 0, 0, 0, 0...], "height":32, "name":"Walls", "opacity":1, "type":"tilelayer", "visible":true, "width":32, "x":0, "y":0 }], "nextobjectid":1, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.1.5", "tileheight":31, "tilesets":[ { "firstgid":1, "source":"perspective_walls.tsx" }], "tilewidth":31, "type":"map", "version":1, "width":32 }
タイルセットは下のようになりました。
{"columns":4, "image":"perspective_walls.png", "imageheight":256, "imagewidth":256, "margin":0, "name":"perspective_walls", "spacing":0, "tilecount":16, "tileheight":64, "tileoffset": { "x":-32, "y":0 }, "tileproperties": { "13": { "door":"true" }, "14": { "door":"true" }, "15": { "pickup":"true" } }, "tilepropertytypes": { "13": { "door":"string" }, "14": { "door":"string" }, "15": { "pickup":"string" } }, "tilewidth":64, "type":"tileset" }
Map
http://doc.mapeditor.org/en/stable/reference/json-map-format/#map
Map はゲームのマップでどのようにタイルを配置するか、それからマップのサイズなどが定義されています。
Tile Layer
http://doc.mapeditor.org/en/stable/reference/json-map-format/#layer
Tile Layer はマップ中のタイル配置です。 data のフィールドで GID で各マスに配置するタイルを指定します。 data のマスは行優先順 (raw-major order) で左上から順番になっています。 GID は tileset の firstgid を使ってタイルセット中の各タイル定義に固有に振られた global id になります。 GID が0は何もないという意味になるようです。 タイルセットを複数使う場合は GID が被らないように firstgid 指定する必要があると思います。
perspective_walls の例を見るとタイルのサイズとオフセットの関係は下の図のようになっているようです。
かなり分かりにくいですがマスやタイルの順番は左上原点になっているのに オフセットの座標計算については左下原点となっているようでした。
関連すると思われる issue がありました。
Tile object Y coordinate not saved properly · Issue #386 · bjorn/tiled · GitHub
Object Layer
Tile Layer の他に Object Layer というのもあるようです。 これはおそらく描画には関係ないデータで床や壁の当たり判定やリスポーン位置などの定義に使われるのではないかと思います。
Tileset
Tileset は各タイルの定義で画像のサイズやオフセットなどです。 Tileset に使う画像は全て同じサイズで、行優先順 (row-major order) で並べる想定になっています。
Tiled の描画方法
ライブラリが色々な言語で作られていて利用できる場合もありますが、パーサーしかなかったり描画は自前で書く場合もあると思います。 基本的にはタイルの画像がそれぞれのマスに描画できればいいのでそんなに難しくは無いと思います。
OpenGL では下のような流れでの描画になると思います。
- タイルセット画像を読み込みテクスチャを作成する
- GID からテクスチャ座標を取得できるようにしておく
- 描画するマス座標とテクスチャ座標、オフセットから頂点バッファを作る
- 三角形にテクスチャを貼り付けるシェーダで描画する
IAM ポリシーでのリソースに対する設定について
はじめに
AWS IAM の機能を使うとユーザーや EC2 に付けるロールの権限を細かく設定できて不慮の事故などを防ぐことができます。
IAM ポリシーの設定をリソースに対して行うと例えば本番環境へのリソースを間違って削除したり更新する事故を予防できると思います。
開発環境で色々な機能を扱うときに本番リソースに影響がないかなど不安が出てきて IAM 設定方法を調べて見たためまとめておきます。
権限の評価方法
IAM JSON ポリシーの評価論理 - AWS Identity and Access Management
こちらに書かれていました。
以下のような流れで評価されるようです。
- 一つでも Deny ポリシーが当てはまると explicit deny
- 一つでも Allow ポリシーが当てはまると Allow
- なにも無いと Deny
リソースに対する設定が難しい
リソースに対するポリシーの付け方は難しくなっていると感じました。
例えば EC2 だと関連する IAM 権限についてはこちらに書かれていますが
Actions, Resources, and Condition Keys for Amazon EC2 - AWS Identity and Access Management
これを見てもリソースは インスタンスやイメージ、サブネット、VPC など様々あって しかもアクションによって関連するリソースも違うためどうやって設定すればいいのか全然わかりません。
この記事によくある間違った設定方法が書かれていましたが、このように書きたいというのはよく分かります。
This policy does not work. Do not copy. { "Version": "2012-10-17", "Statement": [ { "Sid": "ThisPolicyDoesNotGrantAllListandGetActions", "Effect": "Allow", "Action": ["s3:List*", "s3:GetObject"], "Resource": ["arn:aws:s3:::HumanResources"] } ] }
これがうまく動かないのはリソースが関連しないIAMアクションが有効にならないからです。
記事の後半の方に正しい設定方法について書かれています。 リソースが関係ないIAMアクションについては別にしてステートメントにレコードを追加するというやり方です。
しかしリソースからアクションを絞り込んで設定するというのが手動で簡単にできるとは思えません。
アクションを一つ一つ見て設定していくことは時間をかければできると思いますが、メンテナンスすることは難しい気がします。 複雑なポリシーを書いてそれが正しいことを確認することもかなり難しいと思います。
しばらく悩んでリソースについての権限は Deny のポリシーを活用するといいのではないかという考えが浮かびました。
例えば EC2 インスタンスに Environment のタグを付けて、これが development でないインスタンスへの全てのアクションを禁止するには下のように書けます。 Condition の Null の条件はインスタンスの起動時などタグがついてない場合に禁止にならないようにするために付けました。 これだとアクションを一つ一つ書かなくてすみます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "ec2:*" ], "Resource": [ "arn:aws:ec2:*:accountid:instance/*" ], "Condition": { "StringNotEquals": { "ec2:ResourceTag/Environment": "development" }, "Null": { "ec2:ResourceTag/Environment": "false" } } } ] }
これだけだと Deny だけで何もできないのでユーザーまたはロールに別に AmazonEC2FullAccess のポリシーをつけます。 FullAccess だとつけすぎかもしれませんがその場合は許可用のポリシーを用意するなどします。 タグを付ける部分の権限もポリシーに入れる方がいいかもしれません。
意図したように権限設定できていることを aws cli で確認してみました。
ec2 に関するアクションは --dry-run
というオプションを使うと簡単に試すことができます。
上のは development 以外禁止というポリシーですが逆に production のみ禁止なども書けます。 またサブネットや VPC のリソースについて Deny で同様に設定を作るということができます。
まとめ
IAM でのリソースに関する権限設定の方法について検討してみました。 個人的には Deny を使った設定を活用すると設定しやすいのではという結論になりました。 Allow のみで細かい設定を作る場合は手動でポリシーを作成するのは難しいので、 設定項目を管理可能なパラメーターで入力してポリシーを生成するようなツールを作ったりする方法もあるかなと思いました。
S3 Select の機能を awscli から使ってみた
S3 Select
S3 Select は去年の AWS re:Invent で話に上がっていて少し気になっていたものの忘れていました。
S3 Select と Glacier Select – オブジェクトのサブセットを取得 | Amazon Web Services ブログ
S3 Select(Preview)を試してみました #reinvent | Developers.IO
もう二ヶ月ぐらい前ですが今年の四月に一般公開で使えるようになっていました。
S3 Select は S3 に保存しているログなどから SQL で必要なデータを絞り込んで検索したり、集計したりに使えるようです。
ログの量が膨大で全てダウンロードして処理すると時間がかかってしまうようなケースで使えるのかなと思います。
この S3 Select を awscli から少し試してみました。
Amazon Athena
似たようなサービスとして Amazon Athena というものもあります。
Amazon Athena (サーバーレスのインタラクティブなクエリサービス) | AWS
Athena は S3 を内部で使っている別のサービスで、機能としては Athena の方が色々と充実していてできることが多いのかなと思います。
ただ S3 Select は S3 に組み込まれているので単純な処理を素早くすませたいという場合には使えるのではないかと思います。
awscli からの利用
select-object-content
というのが S3 Select の機能にあたるようです。
新し目の機能なので awscli 更新しないと使えない可能性があります。
CSV と JSON に対応していて、GZIP 圧縮されているファイルも対応されています。
select-object-content — AWS CLI 1.15.31 Command Reference
API もありました。
SELECT Object Content - Amazon Simple Storage Service
SQL の仕様はここにありました。SQL といってもかなり機能が限られていて、JOIN
や GROUP BY
などは使えません。
Amazon S3 Select および Amazon Glacier Select の SQL リファレンス - Amazon Simple Storage Service
単純な例: ログの検索
CSVファイルから ERROR
という文字列を含む行だけを絞り込んで取得するという例です。
下のコマンドで実行できました。
aws s3api select-object-content \ --bucket=[バケット名] --key=[オブジェクトキー] \ --input-serialization '{"CSV":{"QuoteEscapeCharacter":"\\"}}' \ --output-serialization '{"CSV":{"QuoteFields":"ALWAYS","QuoteEscapeCharacter":"\\"}}' \ --expression "select * from s3object s where _3 LIKE '%ERROR%'" \ --expression-type SQL tmp.txt
そこまで複雑では無いもののこの書き方を覚えて毎回打ち込むというのはつらいので 実際使うときはシェルスクリプトなどを書いてフォーマットなどは決め打ちで使うのが楽かなと思います。
S3 に置いたテストデータ
1,2018-06-04T10:00:01,"hello, world" 2,2018-06-04T10:00:02,"log1" 3,2018-06-04T10:00:03,"log2" 4,2018-06-04T10:00:04,"aaa" 5,2018-06-04T10:00:05,"bbb" 6,2018-06-04T10:00:06,"ERROR: unknown error" 7,2018-06-04T10:00:07,"ERROR: timeout" 8,2018-06-04T10:00:08,"INFO: xxx" 9,2018-06-04T10:00:09,"ERROR: some error" 10,2018-06-04T10:00:10,"\"hello, world\""
取得された結果
"6","2018-06-04T10:00:06","ERROR: unknown error" "7","2018-06-04T10:00:07","ERROR: timeout" "9","2018-06-04T10:00:09","ERROR: some error"
集計関数
GROUP BY
は無いですが AVG, COUNT, MAX, MIN, SUM の集計関数がありました。where で絞り込んだ範囲全体で集計するようです。
集計関数 (Amazon S3 Select のみ) - Amazon Simple Storage Service
どうも集計関数を使う場合は数値型に cast しないとエラーになってしまうようでした。下の記事がとても参考になりました。
Amazon S3 Select で扱う JSON データの形式と Type 指定について | Developers.IO
複数ファイルから検索する例
複数ファイルから検索するには list-objects-v2
などと組み合わせてパイプでつなげれば一応はできそうです。
ただこれもかなり長くなるのでスクリプトなどを書いておくか python などから使うほうが簡単かもしれません。
下のような感じでスクリプトを書いてみました。
#!/bin/bash if [ $# -lt 3 ]; then echo "$0 [BUCKET] [KEY_PREFIX] [OUTPATH]" exit 1 fi bucket=$1 prefix=$2 outpath=$3 aws s3api list-objects-v2 --bucket $bucket --prefix $prefix \ --query 'Contents[].[Key]' --output text 2>/dev/null |\。 xargs -n1 bash -c "aws s3api select-object-content \ --bucket=\"$bucket\" --key=\"\$0\" \ --input-serialization '{\"CSV\":{\"QuoteEscapeCharacter\":\"\\\\\"}}' \ --output-serialization '{\"CSV\":{\"QuoteFields\":\"ALWAYS\",\"QuoteEscapeCharacter\":\"\\\\\"}}' \ --expression \"select * from s3object s\" \ --expression-type SQL \"$outpath/\$0.select\" || true"
まとめ
S3 Select の機能を awscli から試してみました。
コマンドの引数など色々あって面倒さはありますがドキュメントなど読めばすぐ使える感じでした。
ログからのデータ抽出など使いどころは色々とありそうなので機会があれば使っていきたいです。