ちょっと使って見ようかな?と思ったので、使いかたメモ。
設定ファイルの書き方がlog4jと同じなのがうれしいかも。
Ubuntu環境だったら、apt-getで一発インストール可能。
$ sudo apt-get install liblog4cxx9c2a liblog4cxx9-dev liblog4cxx9-doc
$ cat log4cxxtest.cpp
//
// log4cxxtest - log4cxx sample program
//
// compile
// g++ -llog4cxx -o log4cxxtest log4cxxtest.cpp
//
// see also...
// http://logging.apache.org/log4cxx/manual.html
//
#include <string>
#include "log4cxx/logger.h"
#include "log4cxx/basicconfigurator.h"
#include "log4cxx/propertyconfigurator.h"
#include "log4cxx/helpers/exception.h"
using namespace std;
using namespace log4cxx;
int
main(int argc, char *argv[])
{
// 初期化
try {
// 設定ファイルを読み込み
PropertyConfigurator::configure("log4cxx.conf");
}
catch(const log4cxx::helpers::Exception &e) {
// もし設定ファイルが読めなかったら、BasicConfiguratorを使って初期化
BasicConfigurator::configure();
}
// ロガーの生成
LoggerPtr log(Logger::getLogger(""));
// ログの出力
LOG4CXX_FATAL(log, "fatal output...");
LOG4CXX_ERROR(log, "error output...");
LOG4CXX_WARN (log, "warn output...");
LOG4CXX_INFO (log, "info output...");
LOG4CXX_DEBUG(log, "debug output...");
return 0;
}
$ cat log4cxx.conf
# root logger setting
log4j.rootLogger=DEBUG, C, R
# using console appender
log4j.appender.C=org.apache.log4j.ConsoleAppender
log4j.appender.C.layout=org.apache.log4j.PatternLayout
log4j.appender.C.layout.ConversionPattern=%d [%t] %-5p %c(%F:%L) - %m%n
# using rolling file appender
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=log.txt
log4j.appender.R.layout.ConversionPattern=%d [%t] %-5p %c(%F:%L) - %m%n
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=3
$ g++ -llog4cxx -o log4cxxtest log4cxxtest.cpp
$ ./log4cxxtest
2008-04-02 10:18:46,888 [3081643712] FATAL (log4cxxtest.cpp:37) - fatal output...
2008-04-02 10:18:46,889 [3081643712] ERROR (log4cxxtest.cpp:38) - error output...
2008-04-02 10:18:46,889 [3081643712] WARN (log4cxxtest.cpp:39) - warn output...
2008-04-02 10:18:46,889 [3081643712] INFO (log4cxxtest.cpp:40) - info output...
2008-04-02 10:18:46,889 [3081643712] DEBUG (log4cxxtest.cpp:41) - debug output...
ログ出力するメッセージがstd::stringで、文字列を作るのが面倒いと思ったので、
#define __LOG4CXX_WRAPPER(level, log, ...) \
{ \
if (log->isEnabledFor(level) ) { \
char msg[1024]; \
snprintf(msg, 1024, __VA_ARGS__); \
LOG4CXX_LOG(log, level, msg) \
} \
}
#define LOGGER_FATAL(log, ...) \
__LOG4CXX_WRAPPER(log4cxx::Level::FATAL, log, __VA_ARGS__)
#define LOGGER_ERROR(log, ...) \
__LOG4CXX_WRAPPER(log4cxx::Level::ERROR, log, __VA_ARGS__)
#define LOGGER_WARN(log, ...) \
__LOG4CXX_WRAPPER(log4cxx::Level::WARN, log, __VA_ARGS__)
#define LOGGER_INFO(log, ...) \
__LOG4CXX_WRAPPER(log4cxx::Level::INFO, log, __VA_ARGS__)
#define LOGGER_DEBUG(log, ...) \
__LOG4CXX_WRAPPER(log4cxx::Level::DEBUG, log, __VA_ARGS__)
みたいなマクロを作って
// ログの出力 LOGGER_FATAL(log, "fatal output...%s,%d,%f", "hoge", 123, 456.78); LOGGER_ERROR(log, "error output...%s,%d,%f", "hoge", 123, 456.78); LOGGER_WARN (log, "warn output...%s,%d,%f", "hoge", 123, 456.78); LOGGER_INFO (log, "info output...%s,%d,%f", "hoge", 123, 456.78); LOGGER_DEBUG(log, "debug output...%s,%d,%f", "hoge", 123, 456.78);
と、printf風味に使うと便利なのかな…?
最近すっかりUbuntuばかり使っている今日この頃なのですが、なにげにapt-cache searchしたらRTカーネル版が用意されていることにびっくり。
RTカーネルってデフォルトで用意されるほど需要あるのかな?
$ apt-cache search linux-image-2.6.22 virtualbox-ose-modules-2.6.22-14-generic - virtualbox-ose modules for linux-image-2.6.22-14-generic virtualbox-ose-modules-2.6.22-14-server - virtualbox-ose modules for linux-image-2.6.22-14-server linux-image-2.6.22-14-386 - Linux kernel image for version 2.6.22 on i386 linux-image-2.6.22-14-generic - Linux kernel image for version 2.6.22 on x86/x86_64 linux-image-2.6.22-14-server - Linux kernel image for version 2.6.22 on x86/x86_64 linux-image-2.6.22-14-virtual - Linux kernel image for version 2.6.22 on x86 linux-image-2.6.22-14-rt - Linux kernel image for version 2.6.22 on RT kernel linux-image-2.6.22-14-ume - Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded linux-image-2.6.22-14-xen - Linux kernel image for version 2.6.22 on This kernel can be used for Xen dom0 and domU linux-image-2.6.22-14-ccs - Linux kernel image for version 2.6.22 on Linux Kernel with TOMOYO Linux 1.5.2 patch linux-image-2.6.22-14-tomoyo1.5.2 - Linux kernel image for version 2.6.22 on Linux Kernel with TOMOYO Linux 1.5.2 patch
TOMOYO Linuxなカーネルも用意されてるのね。
Mac環境ではQuickSilver、Windows環境ではbluewindを使っているのですが、最近、Ubuntu環境でも似たようなGNOME Launch Boxを使いはじめました。
$ sudo apt-get install gnome-launch-box
「システム」->「設定」->「セッション」あたりでログイン時に起動するように設定しておいて、デフォルトではAlt+spaceで呼び出すことができます。
個人的には、
$ gconftool -s /apps/gnome-launch-box/bindings/activate -t string Muhenkan
を設定しておいて、無変換キーで呼び出せるように設定しています。
GNOME Launch Boxはアプリケーションの起動以外にも、Firefoxのブックマークも候補に表示されるので非常に便利です。

ポート番号が22以外だったらどうやって使うのかな?と思ってたら、FAQに載っていたのでメモ。
$ /Applications/sshfs.app/Contents/Resources/sshfs-static -p 10022 user@example.com:/foo/bar/ ~/mount
CUIから-pオプションで指定するみたい。
機会があってちょっと使ってみたけど、"自分が歩くホットスポット"という感覚に衝撃を受けた。
ちなみに、WMWifiRouterを使うときはad-hoc接続を使用する。 Eye-Fiで撮影した写真をその場でFlickrにアップロードできたら面白いのになーと思っていたら、Eye-Fiはad-hoc接続では使えない様子。残念。

このあたりを見ていて、なんとなくアホになる割合って50%ぐらいなのかな?と思って検証したくなったのがきっかけ。
アホっぽく以下のコードを走らせ続けてみた。
#!/usr/bin/ruby
include Math
puts "n,aho_count,aho_percent"
aho_count = 0
n = 0
prec = 10
loop {
n+=1
aho_count +=1 if n%3 == 0 || n.to_s =~ /3/
if n % prec == 0
aho_percent = aho_count / n.to_f * 100.0;
puts "#{n},#{aho_count},#{aho_percent}"
$stdout.flush
prec = 10**((log10(n)).to_i)
end
}
Intel Core 2 Duo E8400(3GHz)のPCで12時間ぐらい走らせ続けて、100億オーバーぐらいまでカウント。ちょっとこれ以上は現実的ではなさそうかも…
以下は実行結果のファイル
これをグラフにしてみるとこんな感じ。x軸は対数です。

グラフを見ていると、意外と80%ぐらいで収束しそうな感じなのね。
あと、30とか300とかの連続してアホになるゾーンで急激に割合が高くなるのがグラフからわかります。
よく考えたら、桁数が増えてくると3を含まない数字は逆に少なくなってくるような気が。限りなく100%に近づくのかな?
さらに考えてみた検証結果はこちら
ひょっとしたら限りなく100%に近づくのが正解?と思ったので、もう少し考えてみることに。
アホみたいに1つづつ数を調べていると手持ちのCPUパワーだと100億ぐらいが限界そうなので、 下記のようなアホになる数の近似値を求める関数を考えてみました。
#!/usr/bin/ruby
# 問題を簡単にするため、このプログラムではp = log10(n)というpを定義し、
# pが1以上の整数の場合のみ調べています。
# 要するに、n=10,100,1000,...というケースのみ調べています。
# 0〜(10**p)-1までの間に3を含む数がいくつあるかを返す関数
def h3(p)
return 0 if p == 0
return 1 if p == 1
# (0~29, 40〜99のような普通ゾーン) + (30〜39のような3が連続するゾーン)
h3(p-1) * 9 + 10 ** (p - 1)
end
# 0〜(10**p)-1までの間で何回アホになるかを返す関数
def calc_aho(p)
n = 10 ** p
# (3の倍数) + (3を含む数) - (3の倍数でかつ3を含む数)
# n / 3 + h3(p) - (h3(p) / 3)
(n + 2 * h3(p)) / 3
end
puts "n,aho_count,aho_percent"
# 10**1〜10**100までのケースについて調べてみる
(1..100).each {|p|
n = 10**p
aho_count = calc_aho(p)
aho_percent = aho_count / n.to_f * 100
puts "#{n},#{aho_count},#{aho_percent}"
}
前に求めた結果とこの関数の結果を比較すると、かなりいい感じに近似値を求めることができていると思われます。
| n | 力づくで数えたアホになる数の総数 | 上記プログラムを使って求めた近似値 |
| 10 | 3 | 4 |
| 100 | 45 | 46 |
| 1000 | 513 | 514 |
| 10000 | 5625 | 5626 |
| 100000 | 60633 | 60634 |
| 1000000 | 645705 | 645706 |
| 10000000 | 6811353 | 6811354 |
| 100000000 | 71302185 | 71302186 |
| 1000000000 | 741719673 | 741719674 |
| 10000000000 | 7675477065 | 7675477066 |
以下は10〜10**100までの数を求めた結果です。

まず、アホになる数の総数は下記の式を満たしていると考えられます。
アホになる数の総数 = 3の倍数の総数 + 3を含む数の総数 - 3の倍数かつ3を含む数の総数

プログラムでは、それぞれの項を次のようにして求めています。
| 3の倍数の総数 | nが与えられたとき、単純にn/3としています。 |
| 3を含む数の総数 | 再帰を使って求めています。求め方はプログラムの方を参照してください |
| 3の倍数かつ3を含む数の総数 | 3を含む数の総数の1/3と仮定しています。 |
3を含む数の中には1/3ぐらい3の倍数が含まれているだろうとかなり適当に仮定しているのですが、 適当な割にはなぜか100億ぐらいまで結果とほぼ一致していてかなり不思議な感じがします。
この式がどこまで正確にアホになる数を求めることができるのか、時間があればさらに追求してみたいと思いますw
◆ ykato [ナベアツ問題、別アプローチ?でやってみました。 http://d.hatena.ne.jp/comiken/2008..]
◆ シラハマ [お久しぶりです。おもしろいっすね。 n桁の整数が3を含む確率は 1-0.9^n n->∞のとき、1に収束するので..]