weblog of key_amb

主にIT関連の技術メモ

6/8 appengine ja night #33 に行ってきた #gcpja

後でブログ書こうと思って、土日にも書くのを忘れていた(汗)のですが、珍しく早起きして思い出したので、今更ブログを書いています。。

というわけで、掲題の通り、6/8 に appengine ja night #33 に行ってきました。

ご存知、GAE こと Google App Engine のユーザ向けイベントですね。

さて、今年はよく GAE の話題を見聞きするように思います。
今回も発表されていたメルカリアッテで採用されたという件と、GCP の年内東京リージョン開設が発表されたことがインパクトが大きかったですかね。

今回の発表資料(の一部)は Connpass の資料一覧ページ に上がっておりますので、そちらをご覧ください。

印象に残ったこと

「メルカリ アッテ」の発表

事前に 4/23 Go Conference の発表資料を見ていたこともあり、個人的に一番注目度が高い発表でした。

正確な月次コストについての言明は避けられましたが、DAU 100万あたり 200万円と、かなり具体的な数字が述べられました。
コスト試算するにあたって参考になりそうです。
また、GAE の費用内訳の紹介もありました。(詳しくは資料をご覧ください)

Standard Environment が強い

Standard Environment と Flexible Environment については公式の Google App Engine ドキュメントをご覧ください。

今回のイベントでは、Standard Environment 対応言語の中でも、Go 言語推しの方々が目立ったと思います。メルカリアッテさんも Go。

「メルカリ アッテ」の発表でも述べられていたように、急激なトラフィック変動にもロスなくシームレスにスケールできるのは、Standard Environment + Go言語の力によるところがあるようです。

逆に言うと、Flexible Environment だとインスタンスの起動が遅い(下の参考記事によれば分単位)ので、そこまで瞬間的にスケールはできないのだろうと思われます。

例えば、3月に GAE 対応が発表された Ruby や Node.js は Flexible Environment なので、これらの言語での GAE 利用を検討する場合、この点は念頭に置いておいた方がよさそうです。

この辺り、最近下の記事を読んで、参考になりました。

LT: a2cさん「GAEレスポンスの1桁ms化」

今の GAE は海外にしか拠点がなく、RTT が 300ms 以上はかかるので、それを短縮しましょうという話。
このトークでは CDN の Fastly を使って高速化した事例が紹介されました。

メモ:

  • Fastly について:
    • XHR のプリフライトリクエストをスキップできる
    • 全てのログを即時に取得可能
    • CDN なのに演算できる
    • パージなど API の使い勝手がよさそう
    • 価格についてはボリュームディスカウントが効く。詳しくは Fastly の営業さんに聞いて下さい、と。

その他

他にも色々おもしろい話があったので、興味があれば Togetter など見てみるとよいかもです。

所感

運用のないインフラは、インフラの理想だと思います。

GAE は、特有の制約も色々とあるようですが、レイテンシ要求の厳しくない、RDB を使わなくていいサービスであれば、有力な候補になりそうです。

なんとなく、今後スタートアップなどでの採用も増えそうだなと思いました。

Ubuntu + xkb で JISキーボードのキー配置入れ替え

はじめに

仕事で使っている Mac は、昔USキーボードがかっこいいと思っていた頃にUSキーボードにしたままなのですが、家ではJIS配置のキーボードを使っています。
JIS配置の場合、「変換」「無変換」キーが余ること、「半角/全角」「Esc」キーが遠いことから、昔から以下のように入れ替えて使っています。

  • 「変換」 ⇔ 「半角/全角」
  • 「無変換」 ⇔ 「Esc」

…で、最近 Ubuntu 16.04 LTS でこれのやり方を調べてやってみたので、本記事にメモしておきます。

TL;DR

xkb の設定ファイル /usr/share/X11/xkb/symbols/inet を以下のように直接編集しました。

  // Evdev Standardized Keycodes
  partial alphanumeric_keys
  xkb_symbols "evdev" {
      :
-     key <HENK>   {      [ Henkan                ]       };
-     key <MUHE>   {      [ Muhenkan              ]       };
+     //key <HENK>   {      [ Henkan                ]       };
+     //key <MUHE>   {      [ Muhenkan              ]       };
+     key <HENK>   {      [ Zenkaku_Hankaku       ]       };
+     key <MUHE>   {      [ Escape                ]       };
+     key <ESC>    {      [ Muhenkan              ]       };
+     key <TLDE>   {      [ Henkan                ]       };
      :

ざっくり解説

xkbX Window System の一部で、キーボードを制御するもののようです。

この xkb の設定は下のコマンドで確認することができます。

setxkbmap -print

自分の環境では次の出力が得られました。

xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete"  };
    xkb_compat    { include "complete"  };
    xkb_symbols   { include "pc+jp+us:2+inet(evdev)"    };
    xkb_geometry  { include "pc(pc105)" };
};

設定ファイル /usr/share/X11/xkb/symbols/inetxkb_symbols の行で読み込まれています。
これには、キーボードのシンボル(キーに対するエイリアスのようなものと理解している)とその振る舞いの対応が記述されているようです。

そのマッピングを上のように書き換えた、というわけです。

なぜグローバルな設定ファイルを書き換えたか

後掲する参考記事では ~/.xkb/symbols/ 以下に独自のキーシンボル設定ファイルを作り、xkb_symbols のブロックで include するやり方が記載されています。
自分も最初、それでやろうと思ったのですが、入力モードを 日本語 ⇔ 英語 と切り替えると、設定がリセットされてしまうようで、しばらくこれにハマりました。
おそらく、xkb のグローバルな設定で、 xkb_symbols が再読み込みされるのだろうと想像しました。

その設定をログインユーザについて書き換える方がベターと思いますが、そこまで調べずに今回はこういうやり方にしてしまいました。

入力モードの切り替えは「Ctrl + Space」でもできる

冒頭で「半角/全角」キーが遠いと述べましたが、入力モードのトグルだけであれば、「Ctrl + Space」でもできます。
これは下の記事にある Fcitx の機能で、Ubuntu 16.04 LTS では、最初から有効になっているようでした。

また、下の記事もこの Fcitx の機能を使った Tips のようです。

参考記事

"clenv" というシェルスクリプトのパッケージ管理ツールのようなものを作った

主に先月、開発していました。
いまバージョンは 0.1.12 です。

最近、久しぶりにやりかけだった機能拡張を進めようかと思ったのですが、拡張した機能を今後、自分自身でもあまり使うイメージが持てなくて、現状をひとまずこの記事にまとめておくことにしました。

目次:

clenv とは

シェルスクリプトのパッケージ管理システムがあったら、流行るんじゃないかという妄想があって、試しにちょっと作ってみた、という感じです。

今のところ、シェルスクリプトに限らず、コマンドラインで実行可能なファイルをまとめる用途には使えるかな、というぐらいのもので、実際に自分でも使っています。

できること:

  • $CLENV_ROOT/shims/ というパス配下にモジュールの実行ファイルの symlink を貼る
  • $CLENV_ROOT/environments/ に任意の名前で「環境」を作り、モジュール群をその「環境」にインストール

お察しかと思いますが、clenv という名前は rbenvplenv の類推です。

clam モジュール

clenv で利用されるモジュールを clam モジュールと呼ぶことにしました。

モジュールの形式としては「Git リポジトリ」か、「ローカル環境からアクセスできるファイルシステム内の特定ディレクトリ」のみサポートされています。
いずれの場合も、clam.spec というファイルをトップ階層に持つ必要があります。

拙作のシェルスクリプトテストツールである shove も、実はこの clam モジュール形式に対応しておりまして、その clam.spec は下のようになっています。

# bash
name=shove
version=0.7.2
executables=bin/shove
resources=lib/*

このファイルは clam という bash スクリプト内で評価されます。

clam スクリプトRubygem, Perlcpan コマンド相当です。

clam https://github.com/key-amb/shove.git を実行すると shoveclenv の環境下にインストールします。
デフォルトの default environment を使っている場合、$CLENV_ROOT/environments/ 以下のディレクトリ構成は以下のようになります。

~/.clenv/environments
└── default
    ├── Clamdb.txt
    ├── bin
    │   └── shove -> ~/.clenv/environments/default/modules/shove/bin/shove
    ├── lib
    │   ├── shove.bashrc -> ~/.clenv/environments/default/modules/shove/lib/shove.bashrc
    │   └── t.shrc -> ~/.clenv/environments/default/modules/shove/lib/t.shrc
    └── modules
        └── shove/ # モジュールのディレクトリが丸っとコピーされる

で、 ~/.clenv/environments/default/bin~/.clenv/shims に symlink されるので、 ~/.clenv/shims に PATH を通しておけば shove をパスなしで実行できる、というわけです。

clam を使う前に 〜 clenv セットアップ

順番が前後したのですが、上の clam の機能を使う前に clenv のセットアップが必要です。
README.md にも書いている通りですが、転記しておきます。

インストール:

git clone https://github.com/key-amb/clenv.git ~/.clenv

シェルの設定:

export CLENV_ROOT=$HOME/.clenv
export PATH="$HOME/.clenv/bin:$PATH"
export PATH="$HOME/.clenv/shims:$PATH"
. ${CLENV_ROOT}/shrc.d/clenv.shrc

初回はこれを .bashrc ないし .zshenv に書いて exec $SHELL -l を実行して下さい。
最後の . clenv.shrcclenv_switchclenv_use という2つのシェル関数をロードします。

環境の作成には clenv init-env [ENV] を実行します。(ENV のデフォルトは default)
これは $CLENV_ROOT/environments/ 以下に所定のディレクトリを作るだけです。

clenv_switch ENV で、~/.clenv/environments/ENV/bin~/.clenv/shims に symlink されます。
clenv_use ENV だと更に ~/.clenv/environments/ENV/lib/*シェルスクリプトとして現在のシェルに読み込みます。(が、この機能は要らないかなと思っていたりします。)

その他便利かもしれない使い方

Clamfile

RubyGemfile, Perlcpanfile 相当です。

モジュールをこのファイルに記述して clam -r Clamfile でまとめてインストールできます。
気になる方は README.md をご覧ください。

任意の実行ファイルを勝手に clam 化してインストール

「この実行ファイルに PATH を通したいから clenv 下に入れておきたい」というときに便利な使い方です。
単純にソースをローカルにダウンロードして clam.spec を記述すればいいです。

wget https://example.com/any-program.zip
unzip any-program.zip
cd any-program
cat <<EOS > clam.spec
name=any-program
version=0.x
executables=bin/*
EOS
clam . # インストール

こんな感じで any-program/bin/* 以下の実行ファイルに PATH を通せます。

clenv を作ってよかったこと

自分は割とリポジトリを細かく分ける性格で、小さな CLI を含むリポジトリがちらほらあります。
clenv 以前は、それらを submodule にまとめて管理していました。 その管理や、各環境で PATH を通す作業がやや面倒だったのですが、clenv + clam に移行して Clamfile だけの管理になったので、ちょっと楽になった気がします。

clam は消すのも簡単なので、ツールを試しに使うようなときに、とりあえず PATH を通しておくことも気軽にできます。

あれ、シェルスクリプトあんまり関係ない…?

そうなんです。
一応シェル・リソースをロードする機能もあるにはあるのですが、今のところ、「任意の実行ファイルをまとめる君」になっており、「シェルスクリプトのパッケージ管理ツール」としては不完全かな、と思います。

最初に考えていた構想では、シェル関数などを再利用しやすいようにしようなどの企てもあったのですが、今は手が止まってる感じです。
Bash でライブラリ関数的なものを作る気になったら、この構想も進めたい気持ちが高まるかもしれません。

Zsh だとけっこうプラグインがたくさんあって、プラグインの管理ツールもあるようなので、ひょっとしたらここで考えているようなことは実現されているかもしれませんね。

(そもそもシェル関数にしたいケースってけっこう限られそうだと最近思いました。その話はまた機会があれば。)

他に似たようなものないの?

シェルスクリプトのパッケージ管理システムとして見つけたのは下の2つです。

それぞれ、各々のフレームワークの中でモジュール化して再利用できそうな雰囲気ですが、さらっと眺めたところ、各々の形式に合わせてモジュール/パッケージを作らないといけなさそうな感じ。
自分が妄想しているものとは少し違うかなー、と思いました。

余談 〜 shove との関係

下の記事でもちらっと言及していましたが、shove を作ったのは、この clenv のテストを書くためでした。

おわりに

…というわけで、かなり個人用途な感じのツールですが、GitHub で公開していますので、ご利用・ツッコミなどご自由にどうぞ。

また、他に「こういうのあるよ」という情報をいただけましたら幸いに思います。

Enjoy!

アラートをまとめるシステム "poloxy" の v0.2 をリリースしました

前回の記事で紹介した poloxy をその後リリースして、本稿の執筆時点で v0.2.1 までバージョンが進みました。

※5/8 v0.3.1 になったので追記しました。

目次:

"poloxy" とは

繰り返しになるので詳しい説明は割愛しますが、スライドや README に載せている図を再掲しておきます。

f:id:key_amb:20160503224310p:plain

こんな感じで、アラートをまとめて通知してくれるものです。
まとめられたアラートの内容は Web Dashboard で確認できます。

Motivation

サーバサイドアプリケーションの開発・運用従事者の方は何かやらかしてアラートを大量に飛ばした経験はあるでしょうか。

私は、あります^^;

アラートがたくさん届くと心臓に悪いですね。
たくさんアラートが発火したとしても、1通にまとまって届いてくれたら安心ですね。

…というわけで、それをやってくれるものを作ってみた、というものです。

4/28 の西日暮里.rb で、発表スライドの3ページ目に「1時間に1000件以上アラートを受信したことがある人」という質問を入れていました。
発表中に聞いてみたところ、若干名いらっしゃったので、多少はニーズがあるかなと思っています。

Current Status (※5/8 追記アリ)

できた:

  • Web Dashboard
  • HTTP API
  • Worker
  • 送信
  • まとめる
    • 単位時間(1分程度。configで変更可能)に受信したアラートの品目単位
    • 単位時間に受信したアラートのグループ単位
    • 単位時間に受信したアラートの宛先(と送信タイプ)単位
  • (5/8 追加) アラートのスヌーズ ... 単位時間じゃなくて一定時間アラートを飛ばさなくする
    • 該当アラートと同じ (品目、グループ、深刻度) のアラートを message.default_snooze で設定した秒数(デフォルト30分)スヌーズします。

まだできてない:

  • SMTP 受信/中継
  • 古いデータのパージ機能
  • WebUI でのページング等

その他スライド発表時点から変更した点:

  • Redis キューを使わなくして、DB に統合しました

ドキュメントは今のところ README にざっと書いています。
config や curl のサンプルも載せているので、一応お試しいただけるかな、と思います。

Milestone

上の「まだできてない」に挙げていることは v1.0 リリースまでにはやろうと思っていることです。

趣味でやっていることもあり、いついつまでというのは特に決めてませんが。

試してみて「困った」など、何かフィードバックがありましたら、GitHub 等でお知らせ頂ければ幸いです。

(余談) Another Approach 〜 Fluentd との相似について

受信はさておき、送信は今後種類が増えるかもしれないので、Pluggable にしておいた方がよさそうです。
一応、それを見越して動的に各送信タイプの class をロードするようにしています。
そんなことを考えていたら、ふと「あれ、送信と受信があってなんだか Fluentd っぽい」と思った瞬間がありました。

ひょっとしたら、Daioikachan *1みたいに Fluentd の仕組みに乗っかった方が筋がよかっただろうか、とちょっと悩んでいたりします。

Fluentd の既存のプラグインでも、ログを間引いたり*2、suppression を入れたりできるもの*3はあるようなので、そっちのアプローチもアリだったかもしれません。

とはいえ、"poloxy" には Dashboard や DB が付いていたり、アラートのグルーピングなど独自な概念もあるので、Fluentd プラグイン化はやりすぎですかね。。

5/8 追記: AdminLTE という UI テンプレートについて

追記ついでに、AdminLTE について触れておきます。

自分にはフロントエンドをイチから作り込めるほどスキルも余裕もないので、Bootstrap ベースのテンプレートを使って、必要な部分だけカスタマイズする、という方針にしています。

"poloxy" の WebUI では、管理画面向けで多機能なテンプレートである AdminLTE を使ってみました。

その豊富な機能を使いこなすところまでは全然至っていませんが、作りたかった UI を割といい感じに整えることができたかなと思います。
いろいろパーツも揃っているので、便利です。

以前、はてブで上がっていた Gentellela *4でもいいかなと思いましたが、色調の好みでこちらにしました。

ドキュメンテーション用の Hugo のテーマ "bootie-docs" を改善しました #gohugo

Bootie Docs はちょうど一年前ぐらいにドキュメンテーション用の静的サイトジェネレータがほしくて作った Hugo*1 の Theme (テンプレート)です。
当時の記事はこちら:

色々イケてないところがあったので、GW 連休中にがっつり手を入れて、機能追加もしましたので、お知らせします。

ほとんど CHANGELOG に書いた内容に相当します。

※5/7 更に変更点有り、追記しました。

デフォルトアイコンがかっこ悪い

見るたびに気持ちが萎えていたので、パワーポイントでちょっと図形をいじって、こんな感じ になりました。
雰囲気おしゃれになったかなと。

依存コンポーネントを最新版にアップデートし、シンタックスハイライトのスタイルを選択可能に

Bootstrap と jQuery (v1系) と highlight.js を最新化しました。
highlight.js については、config.toml の params.highlightStyle という設定値で好みのスタイルを選べるようにしました。
どんなスタイルがあるかは こちら に highlight.js のデモページがありますので、ご参考まで。

サイトマップ的なページを作った

/index/ というパスで全ページリストを表示できるようにしました。
Hugo は自由にディレクトリを切ってページを階層化できるのですが、2段階までは階層表示できます。
やり方は Bootie Docs の マニュアルサイト をアップデートしていますので、こちらをご確認下さい。

サイドバーをスクロールに追従するようにした

久しぶりに JavaScript を書きました。
Chrome, Firefox, Safari では動作確認しました。
※もっといい書き方があったら教えてほしい^^;

5/7 追記:

  • ケータイなど幅の狭いブラウザで表示が崩れてしまっていたのを修正し、元通りのレスポンシブな表示になるようにしました。

Google のサイト検索機能を使った検索フォームを付けられるようにした

config で params.searchDomain を設定した場合のみ、有効になります。

(5/7 追記)メニューのテキストを変更可能に、任意ページをメニューに追加可能に

今までは content/ 直下のページ or section しかメニューに足せなかったのですが、v1.1.0 で任意ページを足せるようにしました。
これにより config の書き方が変わりましたので、ご注意下さい。

Before v1.0.x:

[params]
  mainMenu = ["about", "usage"]

After v1.1.0:

[[params.mainMenu]]
  name = "About"
  link = "about"

[[params.mainMenu]]
  name = "Usage"
  link = "usage"

TOML の Array of Tables という記法を使っています。
下の書き方も試したのですが、たぶん Hugo 内部で使われているパーサが inline table 記法に未対応で、エラーになってしまいました。

[params]
  mainMenu = [
    { name = "About", link = "about" },
    { name = "Usage", link = "usage" },
  ]

(5/7 追記) カテゴリ > ページの一覧をサイドバーやTOPページで表示するようにした

これにより、上述のサイトマップ的ページを設置する意義は薄れました^^;
まあ、お好みでどうぞ。

その他、細かいスタイルの改善

  • table にスタイルが付いてなかったので、bootstrap の .table-striped, .table-bordered 相当のスタイルを付けて GitHub っぽく見えるようにした。
  • コードブロック内が折り返しされていたので、折り返さないように。*2
  • ページ幅が最大 970px だったが、1200px に変更

自分のプロダクトのドキュメントサイトも更新しました

見本としてご参考にどうぞ。

fireap は GitHub Wiki から引っ越しました。
Markdown 形式なので引越しそのものは簡単でした。
(※その過程で色々スタイルのイケてないところを見つけたので v1.0.1 => v1.0.2 になりましたが。)

終わりに

ドキュメント用のテーマとして、より使いやすくなったと思います。
Markdown でドキュメントを管理したいときに、選択肢としてご一考いただければ幸いです。

既にお使いの方は、ぜひアップデートしてみてください。*3

Enjoy!

*1:Golang 製の静的サイトジェネレータ

*2:参考: Bootstrapを使った場合にpreタグを改行させたくない

*3:5/8 本家 hugoThemes にも最新版が取り込まれました :D https://github.com/spf13/hugoThemes/pull/133