コミケ告知

サークル networkmaniacs.net(旧:浜風もっこす) 2017.02.17 デブサミ内 DevBooksに出展します。
詳細は circle タグの記事へ。
2013年3月31日日曜日

Fluentdの出力をWebSocketに流すoutput pluginを書いた

Fluentdの出力をWebSocketに流すだけのoutput pluginを書いてみました。Rubyが全然わからないので、使い方をぐぐりながら。
普通はモニタリングしたければログなり標準出力なりに出せばいいので、広く一般に使えるものではないでしょう。リモートで動いているFluentdが吐くデータを、ちょっと手元のブラウザに出してみたかったんじゃよ。

いわゆる自分用プラグインです。インストールは「pluginディレクトリに置いてくれ」「em-websocketに依存してるからあれ入れてね」というバルクな仕様。他に使う人がいれば、Gemにした方が良いのかもしれません。

はじめてのRuby雑感

何かの勉強会でサンプルがRubyだったため、1回書いたことがあるような気がしますが、何も覚えていませんでした。変数の種類とかifの書き方とかを検索するレベル。
Rubyでは、変数に関数を直接代入は出来ないという理解であってますかね?検索したら proc というのが出てきたので、とりあえずそれを使ってみました。変数に直接関数入れられる言語と比べると、めんどくせーなーという印象です。

はじめてのWebSocket (クライアント側) 雑感

WebSocketってきっと面倒で、専用のライブラリがあってそれを使うのかな…と想像していましたが、生のWebScoketオブジェクトを使ってちょろっと送受信するだけなら簡単でした。
websocket.orgにechoのサンプルがあるので見ると、WebSocketのオブジェクトをnewして、あとはハンドラ(onXXX)に必要なものをセットするだけです。サンプルをここに書きおこす必要は感じられない程度に、シンプル。
最初はサーバーを自前で立てなくても、サンプルで使っているws://echo.websocket.orgで試せるのも有難いです。サーバーの動作を疑わなくてもよい点で。

はじめてのWebSocket (サーバー側) 雑感

FluentdのプラグインはRubyである必要があるため、em-websocketを使いました。作者が作者だけにrev-websocketで…とまず思ったけど、3年間更新されてませんね。動きませんでした。
exampleの中にあるmulticastのサンプルを見ながら動かしたら、意外とあっさり複数接続も出来ているようです。

FluentdはMessagePackフォーマットで出すのも簡単なため、受信側にmsgpack.jsを組み込んで、バイナリ送信にも対応しました。その際、いつものsendメソッドで送ろうとしたら接続が切れてしまうので何かと思ったら、どうやらsend_binaryという別のメソッドがあったようです。pull requestの履歴の中にありました。READMEの範囲では、そんなのわからなかったよ…
2013年3月19日火曜日

g++ -std=c++11で色々と"not declared"が発生する場合

状況

  • g++でコンパイル
  • -stdの指定をしなければ万事うまくいく
  • -std=c++11を指定すると、not declaredになる関数がたくさん出る
    • snprintf, strdup, fileno等 
例:
hoge.cpp:20:21: error: ‘strdup’ was not declared in this scope

解決方法

-std=c++11ではなく、-std=gnu++11を使用する。

参考にしたのは、2年ほど前のstackoverflowの記事でした。
acceptされた解答にあるように、厳密に標準のC++の関数ではなくてGNU拡張であるため、こういうことが起きるようです。

使用したg++はCygwin上の4.7.2でした。
2013年3月12日火曜日

BOOST_FOREACHは参照で受けないとコピーされる

C++でループを回てコレクションを巡回するときに時折役に立つ、BOOST_FOREACH。(boost/foreach.hpp)
便利なんですが、巡回先のコレクションから受け側の変数に代入されるだけなので、参照で受けないとコピーされます。

以下のような、テスト用にコンストラクタ・デストラクタでprintfするだけの適当なクラスがあるとして。
class Hoge {
  public:
    Hoge() { printf("ctor %p\n", this); }
    Hoge(const Hoge& h) { printf("copy %p\n", this); }
    ~Hoge() { printf("dtor %p\n", this); }
};
気を使わずに単に変数で受けて巡回すると…
vector<hoge> hoge_vector(3);
BOOST_FOREACH(Hoge x, hoge_vector) { ; }
ctor 0x20010210
ctor 0x20010211
ctor 0x20010212
copy 0x28ac26
dtor 0x28ac26
copy 0x28ac26
dtor 0x28ac26
copy 0x28ac26
dtor 0x28ac26
dtor 0x20010210
dtor 0x20010211
dtor 0x20010212
ですよねー。参照(&x)で受けないと、スタック上にコピーして破棄してを繰り返しています。関数の引数でオブジェクトを値渡し、みたいな話でちょっと恥ずかしい。 boost.org公式のドキュメントにも、"Iterate over a sequence by reference, and modify the underlying sequence" という例が書いてあります。

参考:公式ドキュメント

参照で受ければ、もちろんコピーされずに済みます。
BOOST_FOREACH(Hoge &x, hoge_vector) { ; }
ctor 0x20010210
ctor 0x20010210
ctor 0x20010211
ctor 0x20010212
dtor 0x20010210
dtor 0x20010211
dtor 0x20010212
こんなくだらない話ですが、autoを使おうとするときって、型に対する意識が散漫になりませんか?
BOOST_FOREACH(auto x, hoge_vector) { ; }  // コピーされるよ
BOOST_FOREACH(auto &x, hoge_vector) { ; }
このループで変更を加えようとしている場合には、一時的に複製されたものを触っても何もおきなくて気づきます。しかし、読むだけの場合にはロジック上の不都合は起きないので、うっかりこのようなコードを埋め込んでしまうかも。
# boost 1.48.0にて確認
2013年3月9日土曜日

Chrome「プロフィールを開くことができませんでした」の解消

症状

起動時に「プロフィールを開くことができませんでした」というポップアップが毎回出る。

解決方法

C:\Users\ログインユーザー名\AppData\Local\Google\Chrome
の下の、Web Dataから始まる名前のファイルを削除。

雑感


こんな事をしようとした原因は、Chromeの開発版を最近アップデートしたら、アドレスバーの右に出るタイプの拡張機能が全滅したことでした。はてなブックマーク拡張とか、Adblockとか、クリックしてもpopupが出なくなってしまって、快適なWeb徘徊に支障をきたしていました。
どうしてこんな重大なバグを含むリリースがされてしまったのか…。とりあえず直ったので良かったですが。

開発版を使いたい場合、Google Chrome Canaryをインストールするべきですね。今回困ってあちこち検索するまで、存在を知りませんでした。通常のChromeとは別物として、同じ環境に同時にインストールできます。