システム・PC

Rails3.2でデフォルトのログの場所を変更する方法

検索しても情報が錯綜しているようですが、ソースを見るかぎりproduction.rbあたりに、このように書くのが作者の意図に沿っていると思われます。
 config.paths['log'] = ["/var/log/rails/production.log"]
もちろん自前や別のLoggerを使うという手もあります。例えば、
 config.logger = Logger.new(/"/var/log/rails/production.log")
とかやってもいいわけですが(多くはこれがヒットする)、これだとログのデバッグレベルが既定のデフォルト(つまりDEBUG)になり、かなりログが賑やかです。

ソースを読むと分かるのですが、config.loggerにLoggerが設定されていると、config.log_levelを見に行きそうで行かないので、config.log_levelは効きません。

しかるにLoggerクラスはインスタンスを生成するときに、log_levelを変更できないので、newした後設定してやればOKなんですが、path変えるだけならちょっと煩わしいかなと。例えば次のようにすればよいようです。
 config.logger = Logger.new("/var/log/rails/production.log")
 config.logger.level = Logger::INFO
rails3.2.12で確認。 ソースは

railties-3.2.12/lib/rails/application/bootstrap.rb

あたり

このサイトを passenger + nginx に置き換えた

apache22だったのを置き換え。
特に問題なく動いている模様。

gem関連はportsで管理をしないというポリシーなんで、アプデート管理がちょっと面倒そうだなぁ。

Vistaと7のUDFドライバはちょっとおかしい?

という結論に達しました。 XPで読めてもVistaや7で読めないものがあるようです。

具体的にはパケットライトでUDF2.01で書いたもの。技術的にはVirtual Partition Mapというのを使います。これは上書きできないDVD-Rなどのwrite onceのメディアにあたかも上書きされているかのように記録していくという複雑なファイルシステムです。

で、弊社には(自作の)UDFのツールがいくつかあるので、ディスクの全データを調べてみました。ファイナライズしてないと普通には吸い出せないのでATAPIコマンド発行でセコセコ吸いだし。

データ自体にはどこにも問題があるように思えません。念のため Philipsが出してるチェッカにかけてもちゃんと読めるし、問題は無い模様。

しかし、このOSはとても普及しているので、一応それなりにちゃんと調べないといけません。エラーログとかないので、一体どこが気に入らなくて読めないのかWindowsの気持ちになって調べることに。

こういうのは、読めるデータから読めないデータにちょっとづつ近づけていくのが早い。

そこで、Vista, 7で読めるデータを作成(具体的にはVistaで作る)。それをツールを使ってセコセコと崩していってみました。CRCとかcheck sumとか手動で計算してられないんで、こういうのはツールが大活躍。

で、その結果、ディレクトリのデータがVirtual Partition Map 上にあると読めないようです。これをVirtualじゃない方(普通のpartition Map)に配置すると読めます。

これはバグじゃないかなぁ?ディレクトリのデータはどっちに置いてもいい(と思われる)ので、Virtual Partition Map上あっても読めるようにしてほしかった。実際XPやMacOSでは実際読めます。というか、XPで読めてたのに、Vistaで読めなくなるって・・・

ちなみにXPにSonic UDF Readerというのを入れると同じ挙動をしめすから、どっかのやつを買ってきてVista以降に入れてるのかな?

Node.jsで 80番ポートをListenするWebサーバを作る

簡単にWebサーバが作れますとかいって、よく、以下のようなコードが紹介されています。(余談ながら、私個人としてはコードが短いことがどうしていいことなのかは理解に苦しみます。ある特定の、かつ、まったく現実的に役に立たないコードが短いことにどんな利点があるのでしょうか???)
var http = require('http');
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(3000, '127.0.0.1');
これを実行したあと、ブラウザで

http://127.0.0.1:3000

を開くとHello Worldというページが見れます。3000番ポートをhttp標準の80番ポートにして動かそうと単純に以下のようにすると
var http = require('http');
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(80, '127.0.0.1');
と修正すると
node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: listen EACCES
    at errnoException (net.js:640:11)
    at Array.0 (net.js:726:28)
    at EventEmitter._tickCallback (node.js:192:40)
みたいな例外が発生して動きません。1023番までは一般ユーザではlistenできないからです。rootでなら動きますが、それじゃprocessがrootで動いちゃいます。なんかあったときに(セキュリティの問題とか)全部システムがのっとられてしまうかもしれない。

これは、以下のようにsetuidでlistenしたあとに、プロセスのオーナを変更するのが「よい実装」でしょう。一度でも listenしちゃえばプロセスのオーナを誰に変えても問題ないのです(この例では80番にしている)

listenのコールバックに置いておくのは listenを読んだ直後にsetuidをすると、listenが完了する前にsetuidをしてしまう可能性があるから。このあたりイベント駆動型の言語はめんどくさいよなぁ。
var http = require('http');
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(80, '0.0.0.0', function(){process.setuid(80)});


このあたり、昔のUNIXの人には常識なんだろうけど、rootで動かせばいいじゃんみたいなページが沢山あるので老婆心ながらブログに書いておきます。ま、Apacheとかを前段に置いて、reverse proxyというのが、さらなる正解なのかもですが。

HP ProLiant Micro Server のunixbenchの結果

モノはこれ。送料合わせて35k。

HP ProLiant Micro Server

プロセッサー	AMD Athlon™ II NEO N36L
メモリ	1GB PC3-10600E DDR3メモリ
ストレージ	250GB ノンホットプラグ 3.5インチ型 SATA ハードディスクドライブ
電源	150W ノンホットプラグ、ノンリダンダントパワーサプライ
標準構成にほぼ同じロットのhynixのメモリを1Gだけ買ってきて刺した状態。 OSはFreeBSD 8.2-RC1 amd64 です。

HDDは交換簡単だけど、メモリはケーブルガンガン外したりでめんどくさい。マイクロサーバの宿命ですな。

ファンはケースファンしかないので、かなり静かだと思われます。会社はうるさいから家で使えるレベルかどうかはわからないけど。

ちなみにオイラが今会社で使用しているPCのスコアは179ですw
  BYTE UNIX Benchmarks (Version 4.1.0)
  System -- XXXXX.XXXXX
  Start Benchmark Run: Fri Dec  3 14:53:23 JST 2010
   2 interactive users.
   2:53PM  up  1:17, 2 users, load averages: 0.00, 0.08, 0.65
  -r-xr-xr-x  1 root  wheel  136696 Dec 23 02:12 /bin/sh
  /bin/sh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.2, stripped
  /dev/ad4s1e   229399220 1130388 209916896     1%    /usr
Dhrystone 2 using register variables     7149283.2 lps   (10.0 secs, 10 samples)
Double-Precision Whetstone                 1268.9 MWIPS (10.0 secs, 10 samples)
System Call Overhead                     575940.8 lps   (10.0 secs, 10 samples)
Pipe Throughput                          818763.9 lps   (10.0 secs, 10 samples)
Pipe-based Context Switching             131706.4 lps   (10.0 secs, 10 samples)
Process Creation                           2705.4 lps   (30.0 secs, 3 samples)
Execl Throughput                           1560.8 lps   (29.9 secs, 3 samples)
File Read 1024 bufsize 2000 maxblocks    608269.0 KBps  (30.0 secs, 3 samples)
File Write 1024 bufsize 2000 maxblocks   108110.0 KBps  (30.0 secs, 3 samples)
File Copy 1024 bufsize 2000 maxblocks    104892.0 KBps  (30.0 secs, 3 samples)
File Read 256 bufsize 500 maxblocks      190746.0 KBps  (30.0 secs, 3 samples)
File Write 256 bufsize 500 maxblocks     106123.0 KBps  (30.0 secs, 3 samples)
File Copy 256 bufsize 500 maxblocks       64822.0 KBps  (30.0 secs, 3 samples)
File Read 4096 bufsize 8000 maxblocks    1425772.0 KBps  (30.0 secs, 3 samples)
File Write 4096 bufsize 8000 maxblocks   102577.0 KBps  (30.0 secs, 3 samples)
File Copy 4096 bufsize 8000 maxblocks     84410.0 KBps  (30.0 secs, 3 samples)
Shell Scripts (1 concurrent)               3444.7 lpm   (60.0 secs, 3 samples)
Shell Scripts (8 concurrent)                708.0 lpm   (60.0 secs, 3 samples)
Shell Scripts (16 concurrent)               361.0 lpm   (60.0 secs, 3 samples)
Arithmetic Test (type = short)           328733.0 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = int)             312902.1 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = long)            328613.0 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = float)           710422.1 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = double)          740003.9 lps   (10.0 secs, 3 samples)
Arithoh                                  185015597.5 lps   (10.0 secs, 3 samples)
C Compiler Throughput                      1042.3 lpm   (60.0 secs, 3 samples)
Dc: sqrt(2) to 99 decimal places          91266.0 lpm   (30.0 secs, 3 samples)
Recursion Test--Tower of Hanoi            98742.1 lps   (20.0 secs, 3 samples)





INDEX VALUES TEST BASELINE RESULT INDEX

Dhrystone 2 using register variables 116700.0 7149283.2 612.6 Double-Precision Whetstone 55.0 1268.9 230.7 Execl Throughput 43.0 1560.8 363.0 File Copy 1024 bufsize 2000 maxblocks 3960.0 104892.0 264.9 File Copy 256 bufsize 500 maxblocks 1655.0 64822.0 391.7 File Copy 4096 bufsize 8000 maxblocks 5800.0 84410.0 145.5 Pipe Throughput 12440.0 818763.9 658.2 Pipe-based Context Switching 4000.0 131706.4 329.3 Process Creation 126.0 2705.4 214.7 Shell Scripts (8 concurrent) 6.0 708.0 1180.0 System Call Overhead 15000.0 575940.8 384.0 ========= FINAL SCORE 367.1

jailの中でsysinstall

FreeBSDのjailの中からsysinstallでパッケージを追加しようとすると networkが見つからんぞ。ゴルゥァ(死語?)みたいなことを言われる。

んーめんどくせーなぁ。

とおもってたら、オプションで rootを指定できるではないか。 こりゃ便利だわい。とrootをjailのrootにしてホスト側で実行してみたら、 パッケージはそちらを見ないという。もろホスト側にインストールされてしまいました。」

んー。どうすりゃいいのか?

と考えていたらひらめいた。

単純にホストのほうで chrootすりゃいいだけでした。 もちろん、rootが変わっただけだし、ディレクトリ的にはjailの中に いるとはいえ、この下にはすべて一式そろっている。

あまりに単純すぎてこの気がつくのが遅れましたわ

Passenger

最近はmongrelじゃなく、Passengerで運用するのがトレンドらしい。

ググると設定が超簡単。とかばっかり引っかかり。

そんな美味い話があるわけない。

とは思いつつも、Passengerを入れてみたところ、あっさり動きました。

しかしこれは一体何?

rubygemでインストールすると勝手にCのソースが展開されモジュールがコンパイルされる。
でもって「設定ファイルにこれを書け」と出て終了。

その通り書いて見ると、確かに動く、しかもなぜか setuidもされている。(ディレクトリのユーザになるのか?)

あまりに自動で動きすぎて、怖いくらいです。

んまぁそれでも動いているからいいや~

と思って、2日ほど動かしてみたら、マシンがめっちゃおもくなりました。

load averageが40とかどんだけ~

psでプロセステーブルを見てみると、HTTPプロセスが大量に作られててもうわけわからん。

やっぱ簡単にできるというものほど怪しいものはない。

というわけでmongrelに戻しました。こっちのほうがよっぽど簡単だ。

FreeBSD7.0で DVD を焼く

みんなどうやって焼いてるのかなー。
いろいろな焼き方があるようだけど、kernel作り直したりでめんどくさい

ということで焼くプログラム。FreeBSD5時代から愛用してたんだけど、
このたび7用に書き直してみました。

直接ATAPIコマンド発行してますので、
ちょっと改良すればファイナライズしてないディスクからデータを吸い出すのも可能。
あと、RZONEとかも調べられる。

そんなための余計なコードもあるけどあまりきにしないように。

気が向いたらもうちょっとまともにしよう。

あと、CD-Rでは仕えないので念のため。そもそも物理的構造がまったくちがうし。

http://www.guru.gr.jp/issei/~ata.c

コマンドは適当に compileしたのち、 rootで

# ata /dev/acd0 hogehoge.iso

とかすべし。

copyする

ファイルをディレクトリ単位でガツンとコピーしたいときのメモ。

今まではtarを使ってたんですが、ちょっと問題があるんですよね。 というのも昨今のBSDのファイルシステムでは「まばらなファイル」というのがあって、 これは、全部0x00の部分を記録しないという構造になっています。

具体的にこういうファイルを作るにはcreat(open)して1Tあたりまでseekして、1バイトwriteすればおk。

弊社は仕事柄DVDやBDのイメージファイルがたくさんあり、試験向けに1Tのファイルとかも あるんですがこれも実際のディスク上に占めるサイズはホンのチョビット(データは99.9%以上0x00なので)。

しかし、これをtarでコピーするとまじめに全部0x00で記録していくようで、HDDが何ペタあっても足りない。

これをなんとかしてくれる方法はないのかなーとソースを探ってたら cpioにて全部x00なら書かずに飛ばすという素的なオプションがあることが判明。

find . | cpio -p -adm --sparse /destination

こんな感じかな?

cpioってhard linkはちゃんと張ってくれるんでしたっけ?

思い立ってIMAPのコードを書く

完全趣味ですが、訳あって、サーバ側のプログラムを書き始めました。2日で出来ると思いきや思いの外複雑で、未だ日の目を見ていません。orz

このプロトコルは大変なプロトコルやねぇ。

サーバ側の負荷高杉。

これを作った当時は、こんなにサーバにパワーが要求される世の中がやってくるなんて 信じられなかったんだろうなぁ。