TerminalからMackerelのホスト画面を一発で開く


最近、監視サービスの[Mackerel](mackerel.io)に乗り換えました。
ほぼ毎日Mackerelを眺めているのですが、ふと「あのサーバの詳細画面を見たい」となった場合、MackerelのTOPページから辿るには、「Services -> サーバ一覧 -> (必要であれば)絞込 -> ホスト詳細画面」と踏まなくてはならず、少々面倒です。本記事はそんな手間を省く方法を紹介します。

## 実行環境

少なくとも、jq, pecoコマンドはインストールしておいてください。Zsh, mkrはあったら便利ですが、無くてもOKです。

* MacOS X El Capitan 10.11.6
* Google Chrome (開きたいブラウザ。何でも良い)
* [jq](https://stedolan.github.io/jq/) 1.5
* [peco](https://github.com/peco/peco) 0.4.3
* Zsh 5.2 (キーバインドを使わなければ不要)
* [mkr](https://github.com/mackerelio/mkr) 0.11.3 ([Mackerel API](https://mackerel.io/ja/api-docs/)を使う場合は不要)

## mkrコマンドを使う場合

### 基本形

```bash
$ mkr hosts --status working --status standby --status maintenance --status poweroff | jq -sr '.[] | sort_by(if .displayName != null then .displayName else .name end)[] | [.id, .status, if .displayName != null then .displayName else .name end] | @tsv' | peco | awk {'print $1'} | xargs -I{} open -a "Google Chrome.app" https://mackerel.io/orgs/<Organization>/hosts/{}
```

mkrコマンドで登録しているホストのID, ステータス、ホスト名を一覧表示させたものをpecoでインクリメンタルサーチし、その結果をブラウザで開いています。ホスト名は`displayName`を使っているホストがあるため、設定していればそれを表示させ、無ければ`host`を表示させています。

### エイリアス

これをこのまま使うのは面倒なので、エイリアスを登録します。

```bash
$ alias mou="mkr hosts --status working --status standby --status maintenance --status poweroff | jq -sr '.[] | sort_by(if .displayName != null then .displayName else .name end)[] | [.id, .status, if .displayName != null then .displayName else .name end] | @tsv' | peco | awk {'print \$1'} | xargs -I{} open -a 'Google Chrome.app' https://mackerel.io/orgs/<Organization>/hosts/{}"
$ mou
```

### キーバインド

Zshの場合ですが、キーバインドを設定することでより便利にできます。
`.zshrc`に次の設定を記述します。

```~/.zshrc
bindkey '^]' open-mackerel-url
function open-mackerel-url() {
  local app="Google\ Chrome.app"
  local hosts=$(mkr hosts --status working --status standby --status maintenance --status poweroff | jq -sr '.[] | sort_by(if .displayName != null then .displayName else .name end)[] | [.id, .status, if .displayName != null then .displayName else .name end] | @tsv')
  local selected_host=$(echo $hosts | peco | awk {'print $1'})
  if [ -n "$selected_host" ]; then
    BUFFER="open -a $app https://mackerel.io/orgs/<Organization>/hosts/$selected_host"
    zle accept-line
  fi
  zle clear-screen
}
zle -N open-mackerel-url
```

```bash
$ source ~/.zshrc
```

`Ctrl + ]`で上のコマンドと同じことができます。

## Mackerel APIを使う場合

Mackerelの[ホスト一覧API](https://mackerel.io/ja/api-docs/entry/hosts#list)を使っても同じことができます。Mackerel APIの場合、mkrコマンドよりも多くの情報が取得できるので僕はこっちを使っています。

### 基本形

```bash
$ curl -s -H 'X-Api-Key:<APIキー>' 'https://mackerel.io/api/v0/hosts?status=working&status=standby&status=maintenance&status=poweroff' | jq -sr '.[].hosts | sort_by(if .displayName != null then .displayName else .name end)[] | [.id, .meta.cloud.provider, .status, , if .displayName != null then .displayName else .name end, .customIdentifier] | @tsv'
```

[AWSインテグレーション](https://mackerel.io/ja/docs/entry/integrations/aws)でEC2, RDS, ElastiCache, ELBもホストに登録しているので、`.meta.cloud.provider`でどのサービスかを絞込みすることができて便利です。

### エイリアス

```bash
$ alias mou="curl -s -H 'X-Api-Key:<APIキー>' 'https://mackerel.io/api/v0/hosts?status=working&status=standby&status=maintenance&status=poweroff' | jq -sr '.[].hosts | sort_by(if .displayName != null then .displayName else .name end)[] | [.id, .meta.cloud.provider, .status, if .displayName != null then .displayName else .name end, .customIdentifier] | @tsv' | peco | awk {'print \$1'} | xargs -I{} open -a 'Google Chrome.app' https://mackerel.io/orgs/<Organization>/hosts/{}"
$ mou
```

### キーバインド

```~/.zshrc
bindkey '^]' open-mackerel-url
function open-mackerel-url() {
  local api_key="<APIキー>"
  local app="Google\ Chrome.app"
  local hosts=$(curl -s -H "X-Api-Key:$api_key" 'https://mackerel.io/api/v0/hosts?status=working&status=standby&status=maintenance&status=poweroff' | \
    jq -sr '.[].hosts | sort_by(if .displayName != null then .displayName else .name end)[] | [.id, .meta.cloud.provider, .status, if .displayName != null then .displayName else .name end, .customIdentifier] | @tsv')
  local selected_host=$(echo $hosts | peco | awk {'print $1'})
  if [ -n "$selected_host" ]; then
    BUFFER="open -a $app https://mackerel.io/orgs/<Organization>/hosts/$selected_host"
    zle accept-line
  fi
  zle clear-screen
}
zle -N open-mackerel-url
```