Kinesis shardの Open/Close を AWS CLI から一発で確認するワンライナー


必要な環境
==============

下記環境が必要になりますのであらかじめインストールしてください

- aws cli
- jq



従来の問題点
==============

kinesis の describe-stream コマンドだと、JSONがどばーってでてきて、現在有効なshardId がひと目でわからないといった問題がありました

下記が例です。この例だと、shardId-000000000003 以外は、データレコードを put できない shard なのですが、わからないですよね！(close な shard は、shard の分割、マージによって発生します）

```bash:command
aws kinesis describe-stream --stream-name <ストリーム名>
```


```JSON:結果例
{
    "StreamDescription": {
        "StreamStatus": "ACTIVE", 
        "StreamName": "<ストリーム名>", 
        "StreamARN": "arn:aws:kinesis:ap-northeast-1:XXXXXXXXXXXX:stream/handson", 
        "Shards": [
            {
                "ShardId": "shardId-000000000000", 
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455", 
                    "StartingHashKey": "0"
                }, 
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49550864092662459711139433817050545721599481607404650498", 
                    "StartingSequenceNumber": "49550864092651309338540168505480986788282674130572017666"
                }
            }, 
            {
                "ShardId": "shardId-000000000001", 
                "HashKeyRange": {
                    "EndingHashKey": "170141183460469231731687303715884105727", 
                    "StartingHashKey": "0"
                }, 
                "ParentShardId": "shardId-000000000000", 
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49550864601498562906012662037471029548617289644346703890", 
                    "StartingSequenceNumber": "49550864601487412533413396725901470615300436606500995090"
                }
            }, 
            {
                "ShardId": "shardId-000000000002", 
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455", 
                    "StartingHashKey": "170141183460469231731687303715884105728"
                }, 
                "ParentShardId": "shardId-000000000000", 
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49550864601520863651211192660612565266889938005852684322", 
                    "StartingSequenceNumber": "49550864601509713278611927349043006333573084968006975522"
                }
            }, 
            {
                "ShardId": "shardId-000000000003", 
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455", 
                    "StartingHashKey": "0"
                }, 
                "ParentShardId": "shardId-000000000001", 
                "AdjacentParentShardId": "shardId-000000000002", 
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49550865346912121539498005854874389596844711860389281842"
                }
            }
        ]
    }
}
```


解決策
==============

そこでワンライナー作りました。
出力されるjsonを加工して、あとは awk でこねくり回しています。

```bash:command
STREAM_NAME=<ストリーム名>
```

```bash:command
aws kinesis describe-stream --stream-name ${STREAM_NAME} | jq -r '.StreamDescription | .Shards[] | "\(.ShardId) \(.ParentShardId) \( .AdjacentParentShardId) \(.HashKeyRange | .StartingHashKey)"' | sed s/shardId-//g |awk 'BEGIN{i=0;print}{hashKey[i]=$4;state[i]="Open";if($2 != "null"){state[$2/1]="Close"};if($3 != "null"){state[$3/1]="Close"};i++}END{for(j=0;j<i;j++) printf("shardId-%012d %5s start: %s\n",j,state[j],hashKey[j]);}'
```

出力結果は下記のような感じ。
左からshardId, 現在有効/無効なshardはOpen/close、"Start: 数値"は shardの "StartingHashKeyを表しています
 
```bash:result
shardId-000000000000 Close Start: 0
shardId-000000000001 Close Start: 0
shardId-000000000002 Close Start: 170141183460469231731687303715884105728
shardId-000000000003  Open Start: 0
```

ぜひ使ってくださいね！

シェルスクリプト
======


上記だと分かりにくいので、一応スクリプト化しておきます。

"ParentShardId" もしくは "AdjacentParentShardId" に書かれているShardIdはすでに close されています。この性質を利用して、Open、か Closeを判定しています。shardIdの"Id"のみを抜き出して、state 配列の Index に入れることがポイントです

アルゴリズムの詳細は下記 3STEP です。

1. Shardのステータスを保持する`state[i]`に対し、まず、Open で 初期化する
2. "ParentShardId" もしくは "AdjacentParentShardId" が あれば、そのShardIdの"数字のみ"を取得する(例：shardId-000000000001なら、"1")
3. 取得した数字を Shardのステータスを保持するstate配列のIndexに入れ、値を Open から Close に上書きする(state[$2/1]のように1で割っているのは強引にInt型にキャストするため)


```bash:script
#!/bin/bash

STREAM_NAME=$1

#
# open/close 判定
#
shardChecker()
{

awk '
BEGIN{
    i=0;
	printf("\n");
}
{
    hashKey[i]=$4;
    state[i]="Open";
    if($2 != "null"){state[$2/1]="Close"};
    if($3 != "null"){state[$3/1]="Close"};
    i++;
}
END{
    for(j=0;j<i;j++) {
        printf("shardId-%012d %5s start: %s\n",j,state[j],hashKey[j]);
    }
}'

}

#
# main
#
aws kinesis describe-stream --stream-name ${STREAM_NAME} \
| jq -r '.StreamDescription | .Shards[] | "\(.ShardId) \(.ParentShardId) \( .AdjacentParentShardId) \(.HashKeyRange | .StartingHashKey)"'\
| sed s/shardId-//g \
| shardChecker
```