Windows の開発環境を作りなおした ver.2019

2016 年頃に WSL が使えるようになってからというもの
ずっと WSL で開発を続けてきました。
JavaScala に js に fish shell に Emacs
最近では Visual Studio Code と Remote WSL でかなり快適でした。
ファイルアクセスが遅いので git やビルドがもたつくことと、
WSL のプロセスが動いていると WMI Provider Host が
CPU を数 % だけずっと消費しつづけることが少し不満でしたが、
それでも昔に比べれば随分と快適でした。

にもかかわらず、魔が差して全てを消してしまったのでした。。

最近使えるようになった WSL2 を試してみたのが全てのきっかけ。
WSL1 に超最適化された環境と比べるといまひとつなところが多かったので
Insider Preview から戻したのですが気がついた時は手遅れ。
WSL2 から WSL1 に戻さずに Windows のバージョンを戻してしまったのです。
結果、WSL 環境がまっさらになりました。(*自分の責任)
もう一度 Insider に上げてみても状況は変わらず。。

ということで 1 から開発用の環境を構築しはじめたのでした……。

VirtualBox

もとのとおり WSL1 を使っても良かったのですが、
せっかくなので WSL 以前に使っていた VirtualBox を使うことにしました。

通常どおりインストールして、
ホストマシンとはホストオンリーアダプタで通信するように設定。
OS は趣味で Manjaro にしてみました。

あとは起動用にウィンドウを表示しないオプション headless を付けた

VBoxManage startvm manjaro --type headless

と bat ファイルを用意しておいて、
Windows のタスクスケジューラでホストマシン起動時に
この bat を実行させることで、
VM も自動でバックグラウンド起動するようにしています。

SSH

Windows 用の OpenSSH-Win64 が一番動きが良く表示崩れが無いようでした。
一番新しい v7.9.0.0p1-Beta でないと接続時に

warning: agent returned different signature type ssh-rsa (expected rsa-sha2-512)

と表示され鍵認証できませんでした。
はじめから入っている ssh は 7.7p1、署名のアルゴリズムが古い……。

Samba or SSHFS

vboxsf でホストのディレクトリをゲストと共有できますが、
ビルドなど主な作業をおこなうゲスト側からのアクセスが遅く
git や sbt でのビルド・パッケージングの際にもっさり感があります。
ソースをゲストに置けば速度の問題は解決しますが、
今度はホストの Windows で動かしたい IDE などが使えないことに。

そこでゲストマシンで Samba の設定をしておいて、
開発に使うリポジトリソースコードの類はゲスト側に置いて、
Windows からはネットワークドライブとしてマウントしています。

また、Samba と併用してみているのが SSHFS。
Samba の設定が面倒なのとファイルの権限や所有者の問題が発生したので
SSHFS ならどうかなとテスト中です。
利用したのは

の 2 つ。
WinFsp 2019.3 B1 をインストール後に SSHFS-Win 3.5 BETA をインストールしました。

するとエクスプローラのアドレスバーに
\\sshfs\ユーザー名@ゲストVMのIP と入力すれば SSHFS にアクセスできるようになります。
GUI でマウントの管理をするなら sshfs-win の README で

が紹介されていましたが、少し UI が独特でなんとも……。
単にネットワークドライブとして割り当ててしまえば良い気がします。
Samba よい安定していて良ければ乗り換え予定。

クリップボード共有

Windows 側から Hyper や Windows Terminal で Manjaro に繋いでいますが、
そのままでは tmux でコピーしても Windowsクリップボードに入りません。
これを lemonade で解決しています。

Manjaro は AUR にあるので

yay -S lemonade-git

でインストール完了。
Windows 用には実行時に黒い窓無しのバックグラウンドで起動できるように
-ldflags="-H windowsgui" を付けてビルドしたいので、
Manjaro の yay がビルドに使ったファイルを流用して

GOOS=windows GOARCH=amd64 go get -u -ldflags="-H windowsgui" github.com/pocke/lemonade

とすると Windows 用の exe が $GOPATH/bin/windows_amd64 にできるので、
これを Windows へコピーします。

Windows 側は

start /b C:\Users\ko-yamamoto\bin\lemonade.exe server --allow="VMのIP"

のような bat を作っておいて、
これもタスクスケジューラでログイン時に起動するようにしています。

tmux の設定は ↓ を参考にさせていただきました。

if-shell 'which lemonade' \
  'bind ] run-shell "lemonade paste | tmux load-buffer -" \; paste-buffer ; \
   bind -T copy-mode-vi y send -X copy-pipe-and-cancel "lemonade copy"'

google-ime-skk

Windows では CorvusSKK を使って日本語を入力しています。

辞書に無い言葉を簡単に変換できるように google-ime-skk を利用します。
Manjaro 側で

gem install google-ime-skk

としてインストールしたら、

sudo vim /etc/systemd/system/google-ime-skk.service

ExecStart のパスは環境にあわせて変更してください。
以下は linuxbrew で Ruby をインストールしている場合です。

[Unit]
Description=google-ime-skk

[Service]
ExecStart=/home/linuxbrew/.linuxbrew/bin/google-ime-skk

[Install]
WantedBy=multi-user.target

あとは

sudo systemctl enable google-ime-skk
sudo systemctl status google-ime-skk

としておけば Manjaro 起動時、上で設定したので Windows 起動時に
自動的に google-ime-skk が使えるようになっています。

CorvusSKK の設定から VM の IP を「SKK辞書サーバ」に指定すれば OK です。

その他

  • Windows 側では Git Bash を使っています
  • Visual Studio Codecode に PATH を通すと Git Bash から VScode が起動できて便利
  • Hyper も見た目が良いけど Windows Terminal が表示崩れが少ない気がします

おわりに

バックグラウンド起動とコピペ(クリップボード)共有は
設定しておくと使い勝手がかなり良くなるので良いですね。

WSL に慣れてしまっていたので VM の git や sbt がきびきび動いて気持ち良いです!

2019/05/14版_Windows Terminal をビルドしてみる(VS2019)・設定とキーバインド変更

はじめに

Windows Terminal はどんどん開発が進んでいます。
この記事は 2019/05/14 時点でのメモなので
数日後には使えなくなっている可能性があります。

準備

Visual Studio

現時点では Visual Studio 2017 でビルドするのが一番安定するみたいですが
手に入る Visual Studio 2019 の Community を使います。
これは通常どおりインストールするだけ。

WinRT C++ library

いろいろ試した結果 winrt/TerminalApp.h が無いぞとエラーになったので
はじめからインストールしておいた方が無難そう。
むしろこれが原因と思っている。

ここからダウンロードしてインストール。

Windows Terminal のソース

これはふつうに以下から git clone する。

nuget

インストールしていない人は nuget を使えるようにする。 通常どおりの手順でインストールするのが良いはずだが、 Windows Terminal のソース中 dep\nuget\nuget.exe にあるので
PATH のとおったところにコピーしても動作した。

ビルド

  1. cmd.exe で git clone した Windows Terminal のディレクトリへ移動する
  2. git submodule update --init --recursive
  3. nuget restore OpenConsole.sln
  4. Windows Terminal のソースにある OpenConsole.sln を開いて Visual Studio を起動する。
  5. 日本語 Windows だと文字コードの問題があるので以下のソースを UTF-8 BOM 付きで保存しなおす。 diff は下の方に。
    • src\tools\vtpipeterm\main.cpp
    • src\inc\test\CommonState.hpp
    • src\terminal\parser\ut_parser\InputEngineTest.cpp
  6. 同様に src\tools\vtpipeterm\main.cppUTF-8 な文字列に u8 を追加する。
  7. Visual Studio のメニューバー下で「Release」「x64」「CascadiaPackage」を選択
  8. Visual Studio のメニューから「ビルド」→「ソリューションのビルド」を選択してビルド開始
    • ここで winrt/TerminalApp.h が見つからないのエラーが出ていた → WinRT C++ library のインストール
    • ここで 文字コード 932 では表現できないというエラーが出ていた → BOM 付き UTF-8 で保存しなおし & u8 を付ける
  9. 無事ビルドが成功したら Visual Studio のメニューから「ビルド」→「ソリューションの配置」を選択して Windows に登録

9 まで完了すると Windows のスタートメニューに Windows Terminal (Dev Build) が追加されている。

なお、手順によってはプラットフォームツールセットを v142 にせよとも見たが
上記の手順では v141 のままで成功している。

src\tools\vtpipeterm\main.cpp の文字列に u8 を付ける diff は以下。

   switch(lang)
         {
             case TEST_LANG_CYRILLIC:
       -                str = "Лорем ипсум долор сит амет, пер цлита поссит ех, ат мунере фабулас петентиум сит.";
+                str = u8"Лорем ипсум долор сит амет, пер цлита поссит ех, ат мунере фабулас петентиум сит.";
                 break;
             case TEST_LANG_CHINESE:
-                str = "側経意責家方家閉討店暖育田庁載社転線宇。";
+                str = u8"側経意責家方家閉討店暖育田庁載社転線宇。";
                 break;
             case TEST_LANG_JAPANESE:
-                str = "旅ロ京青利セムレ弱改フヨス波府かばぼ意送でぼ調掲察たス日西重ケアナ住橋ユムミク順待ふかんぼ人奨貯鏡すびそ。";
+                str = u8"旅ロ京青利セムレ弱改フヨス波府かばぼ意送でぼ調掲察たス日西重ケアナ住橋ユムミク順待ふかんぼ人奨貯鏡すびそ。";
                 break;
             case TEST_LANG_KOREAN:
-                str = "국민경제의 발전을 위한 중요정책의 수립에 관하여 대통령의 자문에 응하기 위하여 국민경제자문회의를 둘 수 있다.";
+                str = u8"국민경제의 발전을 위한 중요정책의 수립에 관하여 대통령의 자문에 응하기 위하여 국민경제자문회의를 둘 수 있다.";
                 break;

設定変更

git リポジトリにも説明があるので変更したところだけ。

プロファイル

起動するターミナルやカラーテーマを指定するプロファイル。
WSL を使いたかったので profiles に以下を追加した。 guid は適当に指定したが正しいか調べられていない。 あとはフォントの種類やサイズ等を指定。

    {
      "guid": "{cmd のプロファイルをもとに適当に指定}",
      "name": "wsl",
      "colorscheme": "nord wave",
      "historySize": 9001,
      "snapOnInput": true,
      "cursorColor": "#FFFFFF",
      "cursorShape": "bar",
      "commandline": "wsl.exe",
      "fontFace": "Noto Sans Mono CJK JP",
      "fontSize": 11,
      "acrylicOpacity": 0.75,
      "useAcrylic": true,
      "closeOnExit": false,
      "padding": "10, 10, 10, 10"
    }

タブ関連

タイトルバーの中にタブを表示したかったので以下を追加。
追加位置は defaultProfileprofiles と同階層。

"alwaysShowTabs": false,
"showTerminalTitleInTitlebar": true,

デフォルトのターミナル設定

defaultProfile に上で追加した WSL のプロファイルの guid を指定した。

カラーテーマ

Visual Studio Code でも使っている Nord Wave からカラーパレットを移植した。

以下を schemes 以下に追加すると profiles 以下で指定するプロファイルで使えるようになる。

    {
      "name": "nord wave",
      "foreground": "#d8dee9",
      "background": "#212121",
      "colors": [
        "#3b4252",
        "#bf616a",
        "#a3be8c",
        "#ebcb8b",
        "#81a1c1",
        "#b48ead",
        "#88c0d0",
        "#e5e9f0",
        "#4c566a",
        "#bf616a",
        "#a3be8c",
        "#ebcb8b",
        "#81a1c1",
        "#b48ead",
        "#8fbcbb",
        "#eceff4"
      ]
    }

キーバインド変更

このままでは

  • C-t でタブを開く
  • C-w でタブを閉じる

の動作をしてしまい、
シェルの操作や tmux 等に割り当てたキーとバッティングしてしまうので都合が悪い。
特に C-w はシェルで前方語消去のキーなので
間違えてタブを閉じる事故が頻発してしまうのでなんとかしたかった。

キーバインド変更はいずれ設定できるようになると思われるが
現時点ではハードコーディングされていそうなので
src\cascadia\TerminalApp\CascadiaSettings.cpp のソースを変更して対応した。

Ctrl の代わりに Alt でタブを操作するようにしている。

 +    // keyBindings.SetKeyBinding(ShortcutAction::NewTab,
+    //                            KeyChord{ KeyModifiers::Ctrl,
+    //                                      static_cast<int>('T') });
     keyBindings.SetKeyBinding(ShortcutAction::NewTab,
-                               KeyChord{ KeyModifiers::Ctrl,
+                               KeyChord{ KeyModifiers::Alt,
                                          static_cast<int>('T') });

+    // keyBindings.SetKeyBinding(ShortcutAction::CloseTab,
+    //                            KeyChord{ KeyModifiers::Ctrl,
+    //                                      static_cast<int>('W') });
     keyBindings.SetKeyBinding(ShortcutAction::CloseTab,
-                               KeyChord{ KeyModifiers::Ctrl,
+                               KeyChord{ KeyModifiers::Alt,
                                          static_cast<int>('W') });

きっとすぐにキー変更機能もつくだろうからその時には上記変更は戻す予定。

おわりに

こんな感じになりました。

f:id:nishikawasasaki:20190514200958p:plain

なぜそこまでして使うのか……という気もしないでもないですが
新しいものが使ってみたい試してみたいというのと、
どんどん開発が進んでいくプロダクトに触れてみたいという感じです。

追記(2019/05/21)

git から最新ソース取得したところエラーが発生するようになった。 C++/WinRT 関連だったので NuGet で

Install-Package Microsoft.Windows.CppWinRT -Version 2.0.190506.1

を実行したところ解消した。

気分転換に日本語入力の方法を変えてみる

タイトルのとおり変えてみる

SKK はどうも 5 から 6 年ぶりくらいに使うらしい。
効率とかよりも気分転換がメインなので
「予測変換が優秀な方が早く……」とかは一回忘れてみようと思う。

これを入力している今も SKK で若干もたついているので
いつまで続けるかはわからないけれどそんな記録。
(片手入力派なので Godan はもしかするとすぐにでもやめそう……)

記録だけだとなんだか申し訳ないので少し設定の紹介を。
Win では crvskkserv を利用させてもらって Google から変換候補をとれるように、
Mac では AquaSKK で skkserv を有効にして Gem の google-ime-skk を利用して同じようにしてます。
Emacs からは Win でも Mac でも skkserv に接続させてます。
これで変換がまとまる感じに。

SKK は日本語を入力というか打ち込んでる感じがしていて楽しい。

Scala福岡2019に参加してきた

この週末にScala福岡2019に参加してきました。

scala-fukuoka.org

関西から片道2時間ちょっとの旅。

地元が福岡に近いので、
あまり考えずに申し込んでみたら関西からはちょっと遠かった。
でも行って良かった!

個人的には内容について、
Scalaの話ではあるものの
Scalaそのものよりもその周辺にフォーカスしていたのが
とても勉強・参考になったなと思います。
他言語との比較、アーキテクチャ、DDD、ETL、活かし方、パーザコンビネータ。
Scalaのツッコんだ話がききたい!」人にはもしかするとかもしれませんが、
私のいまの興味関心がその周囲にあるのでとてもタイムリー。
福岡まで行って参加して良かったなと思います。
運営のみなさま、登壇者のみなさま、参加者のみなさまありがとうございました!

あと、みなさんにどっちが目的だよと散々ツッコまれましたが
福岡のお酒、食べ物は最高でした。

ゴマサバをはじめお魚は刺身(お造りとは言わない)でも火を通しても最高。

うどんにラーメン(食べてない)に麺類も最高。

もつ鍋も水炊き(食べてない)も素晴らしい。。

こじゃれたお店もありながら屋台(行けてない)もあって楽しいし、
深夜回ってもやたら活気のあふれた街に驚かされました。
九州というと焼酎のイメージですが、
北側の方は日本酒も多くてとてもおいしいのでさらに良い🍶

食べてない・行けてないところが多いので
ぜひまた福岡に行きたい!!

mozc-mode有効時にmultiple-cursorsが使えないので

ふと気がついた。
multiple-cursorsを使おうとしてもなぜか1つ目のカーソルにしか編集が有効にならない。

例えば以下のようにmultiple-cursorsで1から4行目の行頭にカーソルを作っておいて

f:id:nishikawasasaki:20190122220626p:plain

この状態で例えば 1 と入力すれば、全ての行頭に 1 が入力されるはず。
それなのになぜかたまに(必ずではなく)

f:id:nishikawasasaki:20190122220838p:plain

のようになることに気がついた。
なぜだろう?

いろいろ設定を有効・無効切り替えて試していると、
日本語入力のためにmozc-modeが有効になっていると発生することがわかった。
かといって日本語入力しないわけにもいかないし
いまさら数年ぶりにskkに戻るのもなぁと。

本質的には何が原因なのかまで突き止められていないけれど、
ひとまずはmultiple-cursorsを使いたいときにmozc-modeを無効にすればワークアラウンド

ただ、ATOKを普段は使っていて

  • 変換 → 日本語入力オン
  • 無変換 → 直接入力

としているので、
Emacsでも同じような挙動にしようと
どのバッファでもmozc-modeをオンにしておいて

  • 変換 → 日本語入力有効
  • 無変換 → 日本語入力無効

としていたのだけれど、
これだと常にmozc-modeがオンなのでmultiple-cursorsが使えない……。

ということはEmacsでのキーの挙動が

  • 変換 → mozc-mode有効にしてさらに日本語入力有効
  • 無変換 → mozc-mode無効

となれば良い。

少し悩んだのがmozc-mode有効時に直接mozc-modeを無効にする方法。
というのも、mozc-modeを有効にしていると
キーがmozc(WSLなのでGoogle日本語入力)に取られてしまうので
無変換キーを押すと日本語がオフになるだけでmozc-modeは有効のまま。
無変換キーを2回連打すればmozc-modeもオフになるけどなんだか微妙。
無変換キーを1回押すだけでmozc-modeがオフになってほしい。

けっきょく下のようにmozc-handle-event に無変換キー入力の場合の挙動をdefadviceして
無変換キー入力時はそのままmozc-modeをオフにするようにしてみた。

  ;; mozcオンでも無変換キーはEmacsにわたすようにキーイベントを横取りする
  (defadvice mozc-handle-event (around intercept-keys (event))
    (if (member event (list 'zenkaku-hankaku 'muhenkan))
        (progn
          (mozc-clean-up-session)
          ;; (toggle-input-method)
          (mozc-mode nil)
          (deactivate-input-method))
      (progn ;(message "%s" event) ;debug
        ad-do-it)))
  (ad-activate 'mozc-handle-event)

ついでに変換キーを押すとmozc-modeをオンにした上で
日本語入力モードもオンにするように以下の設定も追加。

  ;; 変換キーでon
  (global-set-key [henkan]
                  (lambda () (interactive)
                    (mozc-mode 1)
                    (when (null current-input-method) (toggle-input-method))))
  ;; 無変換キーでoff
  (global-set-key [muhenkan]
                  (lambda () (interactive)
                    (deactivate-input-method)))

あわせると以下のような感じになりました。

  ;; 変換キーでon
  (global-set-key [henkan]
                  (lambda () (interactive)
                    (mozc-mode 1)
                    (when (null current-input-method) (toggle-input-method))))
  ;; 無変換キーでoff
  (global-set-key [muhenkan]
                  (lambda () (interactive)
                    (deactivate-input-method)))

  ;; mozcオンでも無変換キーはEmacsにわたすようにキーイベントを横取りする
  (defadvice mozc-handle-event (around intercept-keys (event))
    (if (member event (list 'zenkaku-hankaku 'muhenkan))
        (progn
          (mozc-clean-up-session)
          ;; (toggle-input-method)
          (mozc-mode nil)
          (deactivate-input-method))
      (progn ;(message "%s" event) ;debug
        ad-do-it)))
  (ad-activate 'mozc-handle-event)

いまのところ変換・無変換キーで違和感無く日本語入力の切り替えができていて満足。

そもそもの日本語入力中にmultiple-cursorsを使いたいときは
multiple-cursorsの前に無変換キーを1回押す必要があるけれど

f:id:nishikawasasaki:20190122222305p:plain

まあ許容範囲かな……。

これを書いてて気がついたけど、
multiple-cursorsがはじまるのをフック(multiple-cursors-mode-hook)して
mozc-modeをオフにしても良い気もする。
こんな感じ。

  (add-hook 'multiple-cursors-mode-hook
            (lambda ()
              (mozc-mode nil)
              (deactivate-input-method)))

それにしても調べても見かけなかったから
mozc-modeとmultiple-cursorsの併用はニッチなのだろう……。

Mac の ssh-agent と fish shell(4年ぶり2回目)

4年前の環境で設定したときは
nishikawasasaki.hatenablog.com
と記事を書いたとおり設定を紹介していましたが、
ひさしぶりにfishを使ってみるとうまくうごきませんでした。
Linux環境で大丈夫だったからMacの方の仕様が変わったのかな……?

色々探したり試してみると以下のgistで紹介されていた設定が良い感じでした。

Auto-launching ssh-agent in fish shell · GitHub

gist.github.com

コピペによっては " がおかしくなるかもなので
そこだけ修正が必要かもしれません。
LinuxUbuntu)とMac(Mojabe)で動作してます。

あと、関係無いけど日本語英数混じりの文章の時に
英数の前後にスペースを入れないようにしてみています。

  • 以前
    • Macssh-agent と fish shell
    • Macssh-agentとfish shell

スペースありの方が好きだけれどなんとなく……

Mackerel の式グラフで叶える夢 (式グラフの便利な使い方)

前置き

サイドバーにあるように、
10 月頃から Pixela で飲酒量を記録してみたら
どうかしてるんじゃないかと自分で自分を思うようになりました……。

さて、せっかくここまで続いてきた Mackerel アドベントカレンダー
このまま途切れてしまうのは悲しいので
計測してみた系の記事ではなくて機能を使ってみた系でお邪魔します。
24 日目の記事です!

qiita.com

前日はのにれんさん (id:nonylene) の「mackerel-plugin-strongswan を作った」でした。

nonylene.hatenablog.jp

式グラフ

みなさん式グラフはご利用されているでしょうか?
「カスタマイズされたグラフ」としても表現されている機能で、
いまのところ (2018/12/24) 実験的機能として提供されています。

mackerel.io

Mackerel ではそのままでも便利にサーバーやいろいろなもののグラフ化が可能ですが、
式グラフを使うとよりいっそう表現の幅が広がります!
使い方次第なものって具体例があるとより良いかなと思いますので
作業や仕事で使っている例をいくつか紹介します。

※もっと良いやり方もあると思いますので「ん?」と思った方はおしえてください!!

いくつかのメトリックを合計したグラフがほしいとき

例えば同じロールに属するサーバーそれぞれに nginx が入っていて、
個別のリクエスト数だけではなくロール全体のリクエスト数も合計値として監視したいとき。
そのままでは以下のグラフ (サーバー 2 台の例) のようにサーバー別に表示されます。
f:id:nishikawasasaki:20181223141719p:plain
ケース的にロードバランサが入っていることが多いでしょうから
ELB などそれ自体に Mackerel が対応しているものを利用していれば
そちらで計測してしまうのもありですが、
式グラフを使うことでも合計値の監視ができます。

メトリックの合計を計算する式は、そのまま sum です。
これを利用してロールに属するすべてのサーバーの nginx リクエスト数の合計を表現するには

sum(
  role(serviceA:roleX, custom.nginx.requests.requests)
)

のように書くことができます。
グラフはこうなります。
f:id:nishikawasasaki:20181223141838p:plain

簡単に合計値のグラフを表示することができました。

いくつかのメトリックを 1 つのグラフに表示したいとき

合計値だけだとサーバーによってリクエスト数の偏りがあることを見逃してしまうかもしれません。
そんなときは式 group を使って

group(
  role(serviceA:roleX, custom.nginx.requests.requests),
  sum(role(serviceA:roleX, custom.nginx.requests.requests))
)

のように
role(serviceA:roleX, custom.nginx.requests.requests) でサーバー別のリクエスト数も表示してから、
group で 1 つのグラフにまとめてやると良いですね。
f:id:nishikawasasaki:20181223141936p:plain

簡単に 1 まとめにして表示することができました。

グラフに別名をつけたいとき

ここまでで作ったグラフ、オンマウスにしてある時点での数値をみようとすると
f:id:nishikawasasaki:20181223142428p:plain
のように式がそのまま表示されてしまって直感的ではありません。
そんなときは式 alias を使って表示名がカスタマイズできます。

group(
    role(serviceA:roleX, custom.nginx.requests.requests),
    alias(
      sum(role(serviceA:roleX,custom.nginx.requests.requests)),
      'sum'
    )
)

「sum」という名前にしました。 f:id:nishikawasasaki:20181223142904p:plain
グラフにも反映されていますね。

一定期間前の数値と比較したいとき

昨日の、先週の、先月の、去年の同じ時間帯と今の数値を比較したいことは多々あります。
去年の今頃のリクエスト数と比べてどうだろう?
定期的に受信しているテキストデータは増えているのか減っているのか?
いろいろなケースがありますよね。
そんなときは式 timeShift を使って

timeShift(
  role(serviceA:roleX, custom.nginx.requests.requests),
  1d
)

のようにあるメトリックの指定期間前の値を表示することができます。

でも過去分だけ表示してもわかりにくいので、
groupalias をつかって

group(
  alias(
    sum(
     role(serviceA:roleX, custom.nginx.requests.requests) 
    ), 
    'now'
  ),
  alias(
    timeShift(
      sum(role(serviceA:roleX, custom.nginx.requests.requests)),
      1d
    ),
    'past'
  )
)

のように組み合わせると、
f:id:nishikawasasaki:20181223144253p:plain
とグラフにすることができます。

一定期間前の数値と比較したいとき (差分編)

上では現在分・過去分をグラフにしてみましたが、
そうではなく変化量だけを監視したいときもあります。
普段は安定している値なんだけど
何かあると大きく変化するような値の監視に良いんじゃないでしょうか。

こういうときは先ほどの timeShiftdiff を組み合わせると表現できます。

diff(
  role(serviceA:roleY, custom.なにかの行数A.*),
  timeShift(role(serviceA:roleY, custom.なにかの行数A.*), 1m)
)

1 分前の値と今の値の差分をグラフにしてみています。

f:id:nishikawasasaki:20181223145258p:plain

どこで増えたり減ったりしたのか一目瞭然ですね。

他に

紹介しきれませんでしたが、
他にも式には

  • 平均値や最大値・最小値
  • メトリックどうしでの掛算や割算・定数倍や定数割
  • 移動平均や線形回帰

など用意されていて
監視する数値と使い方によって可能性は無限大 (?) です。
せっかくの楽しい機能なのでぜひ公式のドキュメントを読みながらいろいろ試してみてください!!

真打:式による監視

実はここまで式を使ってグラフにしていたのは前座でした。

mackerel.io

個人的には式の真価は監視によって発揮されると思っています。
というのもグラフを作ってそれ自体を見ることから発展して、
人がグラフを見ていくうちに発見した監視した方がよいパターンを式によって表現し
それを Mackerel の監視対象として設定することで
監視漏れの危険や監視コストを減らすことができるからです。
すべての監視を自動にできなくてもその少しでも Mackerel が頑張ってくれるなら助かることです。

「式による監視」は式グラフに慣れた方なら簡単で、
グラフの時と同じように式を使ってメトリックをもとに計算させて
アラートの発生条件等を設定するだけです。
(5 分間隔での監視となるなど、いくつか監視の制限がありますので公式をご確認ください。)

上で紹介した差分値に対して一定以上の変化があったらアラートしたり
これまでに計測値した値の最大値を更新したときにアラートしたりと、
とても便利な監視が実現できますね!

当機能は、有償オプションとなります。Freeプランでは利用できません。

いやーこれは課金待ったなし!
いますぐ Standard プランに入りましょう!!
(2018/12/24 現在)

おあとがよろしいようで

Pixela の更新で IFTTT 連携できるようになったので Google Home から飲酒記録できるようにした

前回

な記事を書いた際は

IFTTT が使えると Google Home から声でインクリメントしたりと
色々とトリガーの幅が広がって良さそうなのですが、
IFTTT の Web Hook はリクエストヘッダの指定ができないみたいでした。(ぱっと見)
このあたりは今後の機能追加や、工夫の仕方で回避ができそうです〜。

という感じでしたが、
なんと速攻でアップデートが入ってできるようになりました。

すごい!はやい!!
これで GAS 無しで IFTTT 連携できます!

飲酒していると Android 端末を手に取ってウィジェットボタンから飲酒インクリメントを
ほぼ 100% 忘れてしまう問題を抱えていたので、
Google Home でインクリメントできるように IFTTT 経由するようさっそく対応させてみました。

「Incoming Webhook 的なもの」はブログでも紹介されているように

curl -X POST https://pixe.la/v1/users/nishikawasasaki/webhooks -H 'X-USER-TOKEN:前回のトークン' -d '{"graphID":"drinking-graph","type":"increment"}'

としてインクリメントを実行する内容で取得します。
すると

{"message":"Success.","isSuccess":true,"webhookHash":"ハッシュ値"}

が取得できるので、
次からは POST で https://pixe.la/v1/users/nishikawasasaki/webhooks/ハッシュ値
呼び出すだけでインクリメントができるようになります。

IFTTT で「this」に Google Assistant を選んで、
「Say a simple phrase」に

f:id:nishikawasasaki:20181021221959p:plain

みたいに呼びかけを登録しておいて、
「Make a web request」側にはさきほど取得した URL を POST するように指定します。
なにも送信しないので「Body」は空っぽのままです。

f:id:nishikawasasaki:20181021222209p:plain

保存して Google Home に高らかに宣言しましょう

OK Google!お酒を飲んでいる!!!!

すると Pixela の草が更新されます!
もっとテンションの高いフレーズを登録して飲酒気分を高めても良いですね!!

OK Google!俺は!いま!!酒を飲んでいる!!!

いっそのこと

飲酒した人「OK Google いっしょに飲まないか?」
Google Home「お役に立てそうにありません」

なんてのも良いかもしれません (悲しい)

実際には、簡単に IFTTT 経由で Google Assistant から記録ができるようになったので、
Nature Remo でテレビやエアコンなど家電を操作した頻度を Pixela で可視化してみたり
日常の中で意識せずに草がはやせるようになった点に便利さがあるように思います。

さらにアイディアしだいでおもしろいことがたくさんできそうな Pixela 楽しいです!
id:a-know さんありがとうございます!!

Pixela で飲酒杯数を草を生やして記録する (Android のウィジェットボタンをタップして)

id:a-know さんが

というのを公開されていたので、
今日までの夏休みの最後 (?) に何か残したくて
自分にとって良い使い道がないか考えてみてました。

筋トレみたいな健康系は自分がアピールしても……だし、
自分らしい数値をと考えていたところで飲酒のことを思い出す。

ビールと日本酒では度数が違うけれど
そもそも草で可視化するのはある程度のアバウトさが許されると思って
「飲んだ杯数」をざっくりカウントしてみることにしてみました🍺

準備は上のリンク先でも説明されているとおりとても簡単。

規約とドキュメントを読んだら、
まずはどこかで自分用のトークンを作成しておきます。

それからユーザーを作成。
token には先ほど作ったトークンを指定し、
username を自身のユーザー名に、規約等読んで OK なら yes を。

curl -X POST https://pixe.la/v1/users -d '{"token":"作ったトークン", "username":"nishikawasasaki", "agreeTermsOfService":"yes", "notMinor":"yes"}'

↓正常終了を示すレスポンス

{"message":"Success.","isSuccess":true}

次は作ったユーザーでグラフを作成します。

  • id にはグラフの ID を
  • name にはグラフ名を
  • unit には単位を指定するので「杯」として「cup」を (cups の方が良かったかな?)
  • type には杯数を int で数えるので「int」を
  • color はテーマが色々あるみたいなのでまずは「shibafu」を

指定してみます。

curl -X POST https://pixe.la/v1/users/nishikawasasaki/graphs -H 'X-USER-TOKEN:作ったトークン' -d '{"id":"drinking-graph","name":"cups-graph","unit":"cup","type":"int","color":"shibafu"}'
{"message":"Success.","isSuccess":true}

ここまででグラフが完成しています!
簡単!すごい!!

まだ作ったばかりで草のない不毛の地なので、
試しに過去分を記録してみます。

昨日 (2018/10/14) は昼からビール (2 杯) と餃子を楽しんで、
夜は晩酌に日本酒を 3 杯味わったので計 5 杯でした。
これを送信するために

curl -X POST https://pixe.la/v1/users/nishikawasasaki/graphs/drinking-graph -H 'X-USER-TOKEN:作ったトークン' -d '{"date":"20181014","quantity":"5"}'

とすると、
正常に処理が完了して

{"message":"Success.","isSuccess":true}

とレスポンスを得られます。
この時点で草が生えて

f:id:nishikawasasaki:20181015170536p:plain

該当日分が (少し) 緑になって草が生えました!
過去分は覚えている限り (何も覚えていない) この形式で送信すれば記録できます。

さて、これからの分は飲んだら飲んだ分その場でインクリメントしていきたいですよね。
Pixel APIincrement を利用すれば可能です🍶
リクエスト方法はこれまでとほとんど変わらず

curl -X PUT https://pixe.la/v1/users/nishikawasasaki/graphs/drinking-graph/increment -H 'X-USER-TOKEN:作ったトークン' -H 'Content-Length:0'

のようにエンドポイントを変えるだけです。
単にインクリメントするだけなので値はなにも送信しなくて OK です。

これもリクエストが成功すると

{"message":"Success.","isSuccess":true}

とレスポンスがあります。

ただ、お酒を飲むときに毎回 curl コマンドを実行するのは
苦行ですしミスオペレーションの恐れが 400% です。
そこで、簡単にインクリメントができるように
Androidウィジェットを使ってボタンにしておきます。

ウィジェットボタンを作る方法は色々あると思いますが、
マナーモード解除・設定を自動化するために使っている MacroDroid を使いました。
Tasker など他の方法でも簡単にできると思います。

MacroDroid の場合は下記のキャプチャのように

  • トリガーをウィジェットボタン (カスタム)
  • アクション
    • シェルスクリプト: インクリメント用 API を実行した curl コマンドをそのまま貼り付け
    • ポップアップメッセージを表示: ボタンを押して動いたことがわかるように「🍺+1」をポップアップさせる

としました。
「カスタム」のウィジェットボタンにしたのはアイコン等を好きに設定したかったからなので、
MacroDroid の「トリガー」は他にボタンでも何でも大丈夫です。

f:id:nishikawasasaki:20181015171634p:plain

ウィジェットが完成したので、
Android のホーム画面にボタンとして設置しておきます。

f:id:nishikawasasaki:20181015172029p:plain

ちょっとすぐに良いアイコンが見つからなかったので
電池が充電されている状態のアイコンに「🍺」とラベルを付けておきました。
(良いフリーの🍺アイコンを探したい……)

設置したボタンをタップすると MacroDroid の「アクション」で設定したとおり
「🍺+1」とポップアップメッセージが表示されて Pixela がインクリメントされます!

f:id:nishikawasasaki:20181015172304p:plain

今日 (2018/10/15) 分に少し草が生えました!
あとは飲んだときに忘れずにこのボタンを押すタスクを
しっかり自分自身に実装してください!!

IFTTT が使えると Google Home から声でインクリメントしたりと
色々とトリガーの幅が広がって良さそうなのですが、
IFTTT の Web Hook はリクエストヘッダの指定ができないみたいでした。(ぱっと見)
このあたりは今後の機能追加や、工夫の仕方で回避ができそうです〜。
(2018/10/21 Pixela のアップデートでできるようになりました!)

ということで↓な感じに
Androidウィジェットを使って簡単に飲酒杯数を Pixela で記録できるようになったのでした🍶🍺🍷
(下記はキャプチャではなく実際に Pixela を表示しています。)

🍺草

アイディアしだいでおもしろいことがたくさんできそうな Pixela 楽しいです!
id:a-know さんありがとうございます!!

(夏休みの最後になにをしてるんだろう……)

その後……

  • 色を芝生よりビールっぽい黄色の ichou に変えてみた
  • はてなブログのヘッダに表示するようにしてみた

Reactive System Meetup in 大阪 で Akka HTTP の話をしてきました

少し時間が経ってしまっていますが忘れないうちに……。

2018/09/20 の 19 時からおこなわれた「Reactive System Meetup in 大阪」で
Akka HTTP の話をしてきました。

Reactive System Meetup in 大阪 - connpass

8 月の終わりに「突然ですが……」からはじまる DM を受け取ったことで発表を決めました。
それは折しも Scala関西 Summit2018 の CfP が 8 月末で
ちょうど良いかなーと考えていた時期だったので
ちょっとした打算もあり軽く乗っかったのでした。
(けっきょくいろいろあって CfP は出さず……。)

私の発表の前後に

  • Akka によるリアクティブシステムの概要
  • Spring WebFlux

があったので、
Akka シリーズの実例として Akka HTTP を取り上げて
ディレクティブや Streams との連携にフォーカスしてみました。
HTTP のリクエストを 1 つのメッセージとして見立てて (実際は少し違いますが)
Akka やアクターモデルを Akka HTTP からはじめるのも入り口に良いのかもと思います。

発表資料は以下です。

「Akka をどんなときに使えば良いの?」とう質問をいただきましたが、
Actor ならスレッドから解放されたいときや Remote Actor を使って楽したいとき、
Akka Streams であればメモリに乗り切らないようなデータを
リクエスト受付しだいさばいていきたいときでしょうか。
バッチを書くときなら処理の各フェーズを Actor や Streams の Flow にあてると
Akka の書き方に乗っかるだけである程度きれいな分割がされてすっきりしやすいと感じています。

また「Akka を使うと (エンジニアなど) いろいろリソース確保が難しいんじゃないの?」については
Akka に限らずなんにでも程度こそあれ当てはまるのかなと思います。
例えば冗長性や耐障害性に関して Akka ではなくインフラなどでカバーするのも一つの手で
そこは状況やチームしだいで組み合わせを変えていくのが最良だと思います。

でも「これが良さそう!使いたい!」と思ったら
信じたものと気持ちを大切にしても良いんじゃないかなとも思っています。
(要調査・要覚悟)

ブログ放置しすぎなので技術のことばかりじゃなくていいから
何か書くようにしたいなー