fluentdをインストールしてみる

fluentdはいろんなところからログを集約してどこかに吐き出すというものらしい。

http://fluentd.org/doc/install.html

これを見ながら、fluentdをインストールしてみる。OSによらないインストールの仕方をしてみたいので、Binary Package によるインストールはやめて、RubyGemsでやってみよう。

Ruby >= 1.9.2 が必要らしいが、

$ ruby --version
ruby 1.8.7 (2010-06-23 patchlevel 299) [x86_64-linux]

apt-get で探しても 1.9.1 までしかないようで、Rubyからインストールし直すのは面倒なので、RubyGems はあきらめて、.tar.gz を試してみる。

$ wget https://github.com/downloads/fluent/fluentd/fluentd-0.10.6.tar.gz
$ tar xvzf fluentd-0.10.6.tar.gz
$ cd fluentd-0.10.6
$ ./configure
configure: error: find openssl header not found
$ sudo apt-get install libssl-dev
$ ./configure
$ make
$ sudo make install
Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it.

途中で configure でエラーが出たので、足りないファイルを apt-get でインストールした。

しかし make install でまたエラーが出てしまった。Rubyの知識がまったくないので、原因がよくわからず、

https://github.com/fluent/fluentd/pull/7

これに関係あるかどうかよくわからないが、戻って、.tar.gz によるインストールをやめて、Git Repository からインストールしてみようにも、ここでも Ruby >= 1.9.2 らしいので、あきらめて Ruby >= 1.9.2 をインストールしてみることからやってみる。

$ wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p0.tar.gz
$ tar xvzf ruby-1.9.3-p0.tar.gz
$ cd ruby-1.9.3-p0/
$ ./configure
$ make
$ sudo make install
$ ruby --version
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]

Ruby 1.9.3 をインストールできたので、RubyGemsでのfluentdインストールを試みる。

$ sudo gem install fluentd
$ which fluentd
/usr/local/bin/fluentd

インストールできた。

$ fluentd --setup ./fluentd
$ fluentd -c ./fluentd/fluent.conf -vv &
$ echo '{"json":"message"}' | fluent-cat debug.test

できたみたい。

javax.net.ssl.SSLSocket を使ってHTTPSにアクセスする

java.net.URLConnection を使えば簡単なのだが、あえて javax.net.ssl.SSLSocket を使ってHTTPSにアクセスしてみるサンプル。

このサンプルはScalaだがJavaでも同じようなもんだろう。

// SunのJavaであれば、$JAVA_HOME/jre/lib/security/cacerts というパスに
// 必要なファイルがあるらしいのだが、
// 私の環境ではSunのではなかったらしく、みつからなかった。
// $ locate cacerts
// としたらいくつかあり、そのうちの /etc/ssl/certs/java/cacerts というパスを使ってみた。
// このファイルがなにものかあまり理解していないが、
// このファイルを読み込むにはパスワードが必要で、
// Sunのものや、上記パスのものは "changeit" というパスワードが設定されているらしい。
val keyStore = java.security.KeyStore.getInstance("JKS");
keyStore.load(new java.io.FileInputStream("/etc/ssl/certs/java/cacerts"), "changeit".toCharArray);

val tmf = javax.net.ssl.TrustManagerFactory.getInstance("PKIX");
tmf.init(keyStore);

val context = javax.net.ssl.SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);

val sf = context.getSocketFactory();

// https://twitter.com/ にアクセスしてみる。
val socket = sf.createSocket("twitter.com", 443).asInstanceOf[javax.net.ssl.SSLSocket];

socket.startHandshake();

// ここで指定している文字コードはなんでもいいと思う。
val op = new java.io.OutputStreamWriter(socket.getOutputStream(), "UTF-8");

// https://twitter.com/ へのリクエストを投げる
op.write("GET / HTTP/1.1\r\nHost: twitter.com\r\n\r\n");
op.flush();

// ここで指定している文字コードはなんでもいいと思う。
val ip = new java.io.InputStreamReader(socket.getInputStream(), "UTF-8");

// ループはソケットからの入力を標準出力にそのまま出しているだけ。
// HTTPSのレスポンスが出力される。
while({
  val c = ip.read();
  if(c < 0){
    false;
  } else {
    print(c.asInstanceOf[Char]);
    true;
  }
}){}
socket.close();

scalaでシェルスクリプトを書く その2

Scalaスクリプトを書いて気軽に実行したくても、コンパイルに非常に時間がかかるので、コンパイル結果を保存しておいて、繰り返し同じスクリプトを実行するときにはコンパイル結果をJavaコマンドだけで実行できるようにした。

このファイルをパスの通ったディレクトリに scalash として保存しておいて、実行権限を与えておくと、以下のようなスクリプトを実行できる。

#!/path/to/scalash

args.foreach { a => println(a); }

scalaでシェルスクリプトを書く

Scalaにオプションを渡す必要がない場合。

#!/usr/bin/env scala
!#

println("abc");

Scalaにクラスパスなどのオプションを渡す必要がある場合、シェルスクリプトの1行目(シェバング)にScalaの引数を渡せなかったので、しかたなく以下のように書いた。

#!/bin/sh
# -*- scala -*-

TMP_FILE=`mktemp /tmp/scala.XXXX.scala`
cat <<EOF > $TMP_FILE

println("abc");

EOF

scala -cp クラスパス $TMP_FILE
rm $TMP_FILE

2行目はEmacsで開いたときにScalaモードにするためのおまじない。mktempコマンドは安全に一時ファイルを生成するためのコマンド。

しかしScalaの起動に時間がかかりすぎるのがなんとかならないか。

diffとpatchの使い方

複数ファイルがある可能性のある2つのディレクトリaとbがあったとして、そのdiffをする方法。

diff -urN a b > diff.diff

aが編集前、bが編集後のディレクトリとして、編集内容を表すdiff.diffがとれる。拡張子をdiffにすると、Emacsでカラーで表示されるようだ。オプションrはディレクトリの中にディレクトリがある場合に対応。オプションNは追加したファイルの内容もdiff.diffに記録するため。


このdiff.diffをcというディレクトリに適用する方法。

patch -u -p1 -d c < diff.diff

cd c としなくてもいいように -d で適用するディレクトリを指定する。


diffのときにオプションNをつけないと、bにあった新規ファイルがcに追加されない。

ディレクトリの中にあるたくさんのファイルの文字列を全置換する方法

いまのディレクトリにある全てのテキストファイルにあるテキスト ABC を検索してそれをすべて DEF に置換するコマンド。

find . -name "*.txt" -exec sed -i 's/ABC/DEF/g' {} \;

Ubuntu に vserver をインストールする。

いま使っている Ubuntu 10.04 に vserver をインストールしてみた。

http://linux-vserver.org/Installation_on_Ubuntu
ここを参考に
/etc/apt/source.list
deb... deb-src... の2行を追記する。その後、

sudo apt-get update
sudo apt-get install linux-image-vserver linux-headers-vserver util-vserver vserver-debiantools
sudo shutdown -r now

これでvserver関連のツールとvserverに対応したカーネルがインストールされるので、カーネルアップデートを反映するためにマシン再起動する。

再起動後以下のコマンドで仮想Linuxを構築する。testvserver というのは仮想Linuxの名前で、たぶん何でもいい。IPアドレスは適切なものにする。lucid は Ubuntu 10.04 のことだと思う。このコマンドはだらだらとファイルをネットからダウンロードして仮想Linuxを構築する。

sudo vserver testvserver build -m debootstrap --hostname testvserver --interface eth0:192.168.99.99 -- -d lucid -m http://us.archive.ubuntu.com/ubuntu/

完了したら、以下のコマンドで仮想Linux動する。

sudo vserver testvserver start

以下のコマンドで仮想Linuxに入ることができる。仮想Linux内でrootになっている。exitで仮想Linuxから抜ける。

sudo vserver testvserver enter

仮想Linux終了のコマンド。

sudo vserver testvserver stop


以前、VMwareの中の仮想マシンの中にVMwareをインストールして、孫仮想マシンを入れてみようとしたが、孫は起動しなかった。vserverならVMwareの中の仮想マシンの中で動かせるようだ。

しかし、仮想Linuxに設定したIPで外部から接続しようとしてもホストLinuxのほうにつながってしまうようだ。なぜだ?