Flink task managerのhostnameをGrafana Dashboardで表示する

## 想定読者

- FlinkクラスターをMesos上で運用する人（より広範には、master/workerモデルで動くresource manager）
  - https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/deployment/mesos.html 
- Flinkのバージョンを1.11にアップグレードする人
- FlinkのmetricsをGrafana上で可視化・モニタリングしている人

## 事象

Flinkのtask managerが`taskmanager-hostname.com`上にホストされていると仮定。

task managerの`hostname`（`taskmanager-hostname`）が見えて欲しいが、代わりにハイフン区切りのIPアドレス（`100-XX-XX-XX`）が見える。

アップグレード前のFlink 1.8では特に問題なく見れていた。

Job managerは問題ない。

Grafana関連の設定

```yaml:flink-conf.yaml
metrics.reporter.grph.factory.class: org.apache.flink.metrics.graphite.GraphiteReporterFactory
metrics.reporter.grph.host: grafana-hostname.com
metrics.reporter.grph.port: 2003
metrics.reporter.grph.protocol: TCP
```

## 参考リンク

[Re: Hostname for taskmanagers when running in docker](https://lists.apache.org/thread/cjpmq3ql39xrhjb1t5t4tyxj9nyflkbj)

> There is no convenient cosmetic way to achieve what you want.
The only approach that would currently work is hard-coding the host into
the configuration of each taskmanager via the metrics.scope.*
configuration options.

> As it is there are 2 ways to configure the hostname 1) using docker's
hostname property under a service 2) using flink's explicit
taskmanager.host configuration.
Prior to 1.11 the taskmanager.host variable was not needed. ...

> I will try to use the metrics scope and pass the name of the hostname there
instead.


## 解決策: `metrics.scope.*`にホストネームを設定

[`metrics.scope.*`](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#metrics-scope-operator)にホストネームを設定する。Task managerに関係するのは以下。

- [metrics.scope.operator](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#metrics-scope-operator)
- [metrics.scope.task](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#metrics-scope-task)
- [metrics.scope.tm](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#metrics-scope-tm)
- [metrics.scope.tm.job](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#metrics-scope-tm-job)

上記設定のデフォルト値に含まれる`<host>`という文字列は、task managerの実行時に実際のホストに置き換わるようだが、Flink 1.11ではIPアドレスになってしまう模様。

Task manager上で実行した`$(hostname)`の実行結果を取得して利用したいので、[mesos-taskmanager.sh](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/deployment/mesos.html#flink-session-cluster-on-mesos)の[このあたり](https://github.com/apache/flink/blob/release-1.11.2/flink-dist/src/main/flink-bin/mesos-bin/mesos-taskmanager.sh#L36)に処理を追加する。

```sh:mesos-taskmanager.sh
...
TASKMANAGER_HOSTNAME=$(hostname)
METRICS_SCOPE_OPERATOR="${TASKMANAGER_HOSTNAME}.taskmanager.<tm_id>.<job_name>.<operator_name>.<subtask_index>"
METRICS_SCOPE_TASK="${TASKMANAGER_HOSTNAME}.taskmanager.<tm_id>.<job_name>.<task_name>.<subtask_index>"
METRICS_SCOPE_TM=...
METRICS_SCOPE_TM_JOB=...
export FLINK_ENV_JAVA_OPTS_TM="${FLINK_ENV_JAVA_OPTS_TM} -Dmetrics.scope.operator=${METRICS_SCOPE_OPERATOR} -Dmetrics.scope.task=${METRICS_SCOPE_TASK} ..."
...
```

## その他検討したアイデア

### [`taskmanager.host`](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#taskmanager-host-1)

> The external address of the network interface where the TaskManager is exposed. Because different TaskManagers need different values for this option, usually it is specified in an additional non-shared TaskManager-specific config file.

影響範囲が大きくなりそうなので不採用。

### [`mesos.resourcemanager.tasks.bootstrap-cmd`](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#mesos-resourcemanager-tasks-bootstrap-cmd)

> A command which is executed before the TaskManager is started.

`flink-conf.yaml`に`metrics.scope.*`を記載しておき、このオプション内で`$hostname`の実行結果を使って置換（`sed`コマンド等）することも検討したが、上記の解決策がワークしたので詳細に検討していない。

### [`mesos.resourcemanager.tasks.taskmanager-cmd`](https://nightlies.apache.org/flink/flink-docs-release-1.11/ops/config.html#mesos-resourcemanager-tasks-taskmanager-cmd)

> default "$FLINK_HOME/bin/mesos-taskmanager.sh"

「`flink-conf.yaml`の置換」という方向でこちらは試してみた。
置換自体はうまくできたが、task managerが起動した時点で`flink-conf.yaml`が既に読み込まれているようで、置換した結果をtask managerが使っていない模様。