AWS CLIでAmazon CloudWatch Logsに保存されたログを見たい

# Whats'？

Amazon CloudWatch Logsに保存されたログを参照する方法について、まとめておきたいなと。

AWS CLI使用前提ですが。

# 環境

今回の環境は、こちらです。

```shell
$ aws --version
aws-cli/2.7.12 Python/3.9.11 Linux/5.4.0-121-generic exe/x86_64.ubuntu.20 prompt/off
```

AWSのクレデンシャルは、環境変数で設定しているものとします。

```shell
$ export AWS_ACCESS_KEY_ID=.....
$ export AWS_SECRET_ACCESS_KEY=.....
$ export AWS_DEFAULT_REGION=.....
```

# `aws logs`でAmazon CloudWatch Logsに保存されたログを参照する

参照するドキュメントは、このあたりでしょう。

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/index.html

[フィルターパターンを使用してログデータを検索する / AWS CLI を使用したログエントリの検索](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/SearchDataFilterPattern.html#search-log-entries-cli)

## ロググループの一覧を見る

ログを見るには、少なくともどのロググループを見るか決める必要があるわけですが。

ロググループの一覧を見るには、`describe-log-groups`を使います。

```shell
$ aws logs describe-log-groups
```

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/describe-log-groups.html

## リアルタイムにログを参照し続ける

いわゆる`tail`。`--follow`で継続的にログを参照し続けます。

```shell
$ aws logs tail --follow [ロググループ名]
```

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/tail.html

デフォルトで過去10分のログを参照するようですが、`--since`で調整可能なようです。

ログを絞り込むには、`--filter-pattern`を使用します。

```shell
$ $ aws logs tail --follow [ロググループ名] --filter-pattern [フィルターパターン]
```

フィルターパターンの書式はこちら。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html

## ログを検索する

ログイベントを表示するには、`filter-log-events`を使います。

```shell
$ aws logs filter-log-events --log-group-name [ロググループ名] [その他オプション]
```

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/filter-log-events.html

実際の利用には、オプションをもう少し指定することになります。

よく使いそうなのは、このあたりでしょうか。

- `--filter-pattern` … ログの絞り込み条件を指定
- `--start-time` … 表示するログの開始時間をエポックで指定
- `--end-time` … 表示するログの終了時間をエポックで指定

また、AWS CLI共通のオプションとして以下も利用することになるでしょう。

- `--query` … AWS CLI側で結果のフィルタリングや関数適用を行う
- `--output` … 出力形式の指定

`--query`はクライアント側のフィルタリングの仕組みで、サーバー側のフィルタリングは`--filter-pattern`が相当します。

テンプレート的には、こんな感じで指定することになるのかな、と。

```shell
$ aws logs filter-log-events \
  --log-group-name [ロググループ名] \
  --filter-pattern [フィルターパターン] \
  --start-time $(date [オプション指定]) \
  --end-time $(date [オプション指定]) \
  --query 'sort_by(events, &timestamp)[].{message:message}' \
  --output text
```

以降、少し詳細を。

### サーバー側のフィルタリングの指定

フィルターパターンの書式はこちら。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html


ログの中身がJSONの場合は、こちらを見るとよいでしょう。

[フィルターとパターンの構文 / 語句を照合し、JSON ログイベントから値を抽出するメトリクスフィルターの使用](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html#metric-filters-extract-json)

### 時間の指定

`--start-time`および`--end-time`の指定には、`date`コマンドの結果を使うのが良いでしょう。

```shell
# 相対時間指定
$ date --date='15minutes ago' +%s%3N

# 絶対時間指定
$ date --date='2022-07-05 17:30:10' +%s000
```

### クライアント側のフィルタリングの指定

[AWS CLI 出力をフィルタリングする / クライアント側のフィルタリング](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-filter.html#cli-usage-filter-client-side)

`sort_by`でソートしつつ、必要な項目に絞り込むとよいのではないでしょうか。

以下あたりですかね。

```shell
--query 'sort_by(events, &timestamp)[].{message:message}'

--query 'sort_by(events, &timestamp)[].{timestamp:timestamp,message:message}'
```

なお、絞り込まない場合の出力項目は以下になります。

- logStreamName
- timestamp
- message
- ingestionTime
- eventId

### 出力形式の指定

`json`または`text`あたりを指定するとよいのかな、と。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-output-format.html