ちょっとしたTipsまとめ

一年間ほど業務している中で発見した、ちょっとしたTipsを集めてみました。

## digdag

digdagはCronのようにコマンドを定期実行してくれるOSSです。
ちなみに、TreasureDataさんが作成されています。

### sh:>でfor_eachに設定した変数を確認する

```main.dig
# サンプルコード
+load:
  for_each>:
    alphabet: [
      a,
      b,
      c
    ]
  _do:
    sh>: |
      if [ ${alphabet} = "c" ]; then exit 1; fi;
      echo ${alphabet}
    _error: ## ここ
      sh>: env | sort
```

サンプルコードの流れ

- for_eachでalphabetがcのときに、_doでエラーが発生して、実行が止まる
- エラーを_errorでキャッチして、環境変数を表示する

```shell
# 実行結果
> digdag run --rerun --log-level error error_in_for_each.dig
2020-XX-XX XX:XX:XX +0900: Digdag v0.9.41
a
b
2020-XX-XX XX:XX:XX +0900 [ERROR] (0026@[0:default]+error_in_for_each+load^sub+for-0=alphabet=2=c): Task failed with unexpected error: Command failed with code 1
java.lang.RuntimeException: Command failed with code 1
	at io.digdag.standards.operator.ShOperatorFactory$ShOperator.runTask(ShOperatorFactory.java:143)
	at io.digdag.util.BaseOperator.run(BaseOperator.java:35)

## 省略

alphabet=c
```

ShOperator関数の仕様で、sh>: の部分で起きたエラーはexitコードのみを結果として返しているぽいです。
エラー発生時のfor_eachで設定した変数の中身は、_errorをsh:>の直下に移動させると確認できます。

### 参考URL

- https://github.com/treasure-data/digdag/blob/master/digdag-standards/src/main/java/io/digdag/standards/operator/ShOperatorFactory.java#L143

### サンプルコード

- https://github.com/fnaoto/digdag-sample



## Embulk

Embulkはcsvやmysqlなどのデータを別のデータ形式に変換して、データ移行までやってくれるOSSです。

### migrateする元のDBのカラムに `0001-01-01 00:00:00` より小さい日付がある

MySQLからMySQLへデータをマスキングしてmigrateするような使い方の場合、
EmbulkではJDBCのドライバを使うので、その仕様に引っ張られて想定していないデータの変換がありました。

例えば、 `0000-01-01 00:00:00` というデータを持ったカラムがmigrate元のDBにあるとします。
これをEmbulkを通してmigrateすると、 `0001-01-01 00:00:00` という値に自動で変換されます。

Embulkのコード的には、zeroDateTimeBehaviorがconvertToNullなので、Roundされないかなと思ったんですが、しっかりRoundされました。

回避方法としてはafter_loadのオプションを使って、migrate後にデータの書き換えを行いました。

```yaml
out:
  type: mysql
  user: {{ to_user_name }}
  password: {{ to_db_password }}
  database: {{ to_database_name }}
  table: {{ to_table_name }}
  host: {{ to_database_host }}
  select: '*'
  mode: merge
  merge_rule:
    - 'id=VALUES(`id`)'
  create_table_constraint: '
    KEY `index_name` (`name`)
  '
  column_options:
    id: { type: 'int(20) primary key NOT NULL AUTO_INCREMENT' }
    name: { type: 'varchar(20)' }
    deleted_at: { type: 'DATETIME(0) NULL' }

#  ここ
  after_load: '
    UPDATE {{ to_table_name }}
    SET deleted_at = "0000-01-01 00:00:00"
    WHERE deleted_at = "0001-01-01 00:00:00";
  '
```

### Embulkでダミーデータを使いたい

Embulkでは `gem install` が可能です。
GemのバージョンはEmbulk依存なので、多少の調査は必要ですが、Fakerは1.9.1が使えました。

```shell
$ embulk gem install faker -v '1.9.1'
```

filterの項目で、ruby_procと組み合わせて、ダミーデータを挿入可能です。

```_config.yml.liquid
filters:
  - type: ruby_proc
    requires:
      - faker
    columns:
      - name: name
        proc: |
          ->(name) do
            name = Faker::Name.name
          end
```

### 参考URL

- https://komono.jp/contents/memo/java/jdbcmysql/
- https://github.com/embulk/embulk-input-jdbc/blob/master/embulk-input-mysql/src/main/java/org/embulk/input/MySQLInputPlugin.java#L84
- https://qiita.com/joker1007/items/198bd3b6a1b5acf77fde

### サンプルコード

- https://github.com/fnaoto/test-embulk



## Gatling

Gatlingは高機能な負荷試験ツールです。

### 負荷試験中のHTMLレスポンスを後で確認したい

通常では負荷試験中のレスポンスは表示されません。
以下のように、ログレベルをTRACEに変更して、 htmlファイルにパイプすると確認できます。

```logback.xml
	<root level="WARN">
		<appender-ref ref="TRACE" /> // ここ
	</root>
```

```shell
$ docker-compose run gatling gatling/bin/gatling.sh |\
  tee results.html && open results.html
```

### HTMLのタグから値を取得して、次のリクエストに使いたい

例えば、一度レスポンスを取得してから再度、別のリクエスト時にその値を使う場合があります。
そういうときは、cssのコマンドを使うと便利です。
以下の例だと、metaタグ内のnameにcsrf-tokenが設定されているcontentを取得して、POSTのリクエストに使ったりできます。

```scala
    var TestEndpoint = exec(http("get test")
        .get(s"/test")
        .check(css("meta[name=\"csrf-token\"]", "content").saveAs("token"))
        .check(status.is(200))
      )
      .pause(1)
      .exec(http("post test")
        .post(s"/test")
        .formParam("token", "${token}")
        .check(status.is(200))
      )
```

### 参考URL

- https://gatling.io/docs/current/general/debugging/
- https://gatling.io/docs/current/http/http_check/

### サンプルコード

- https://github.com/fnaoto/gatling-mmock-sample