復活!!!!
ひさびさにブログに復活!なんか書く。多分なんか書く。
mod_proxy_ajpの使い方
何のことはない。
mod_proxyでの必須の手続きをすれば良いだけなのだが、下のサイトのお陰で2時間嵌まった。
http://www.adminweb.jp/apache/tomcat/index.html
この手順では一切触れられていないが、一つ重要な設定が洩れている。
mod_proxyの動作モードが書かれていない。
# 普通ReverseProxyで設定するよね? ProxyRequest Off <Proxy *> Order deny,allow Allow from all </Proxy> <Location tomcat/> ProxyPass ajp://host1.underthetree.jp:8009/ ProxyPassReverse ajp://host1.underthetree.jp:8009/ </Location>
もし他で嵌まっている人がいたらと思って、ご参考までに。
変なプログラマ勉強会(違)#12
どうも、変なプログラマの作り方勉強会#12に参加しました。
今回のお題目はバックアップということで、久々にプレゼンをさせて頂きました。
とhatenadiary見てみたら、半年位参加してなかったんですねぇ。
たまたま家のサーバでLVMを使っていたので、そのスナップショットが使えるかどうかためしてみるという内容でのプレゼンをしました。
あ、前まで使ってたファイルリンク機能が使えない。。。
http://underthetree.jp/henPG.pdf
途中に「実装」と「ためしてみた」が有りますが、32個のスナップショットの親ボリュームに10GBの変更を加えると、320GBの変更が発生しました。合掌
実装でちょっとだけ流した動く保証の無いシェルスクリプト
mksnap.sh
#!/bin/sh . ./lvconfig.ini LIFE=$1 SECS=$(date '+%s') TSTAMP=$(date '+%Y,%m,%d_%H.%M') LVNAME=${LVDIR}/${SNAP_PREFIX}${SECS}${LIFE} MNTPATH=${MNTPNT}/${MNT_PREFIX}${TSTAMP} SLP=30 if ! [ lvcreate --size 100m --snapshot --name "${LVNAME}" "${TARGET}" ]; then echo lvcreate failed. exit 1; fi for (( A=60; $A > 0; A--)); do if [ mount /dev/vg00/${LVNAME} ${MNTPATH} ]; then echo mount successful. echo ${SECS} ${LVNAME} ${MNTPATH} > $LOCKDIR/lock_${SECS} exit 0; else echo mount failed. \ Waiting for next mount after sleeping ${SLP} seconds. \ Left $A times... sleep $SLP fi done echo timed out, cleaning up files... umount ${MNTPATH} 2>&1 rmdir -r ${MNTPATH} 2>&1 lvremove "${LVNAME}" 2>&1 exit 1;
cleansnap.sh
#!/bin/sh . ./lvconfig.ini NOW=$(date '+%s') DEL_L=$(($NOW - $LIFE_L)) DEL_M=$(($NOW - $LIFE_M)) DEL_S=$(($NOW - $LIFE_S)) for LC in $(ls -1 ${LVDIR}); do SNP=$(cat ${LC}) typeset -a ARY=$SNP TSTAMP=$ARY[0] LVNAME=$ARY[1] MNTPATH=$ARY[2] case $LC in *_L) OUTDATE=$DEL_L; ;; *_M) OUTDATE=$DEL_M; ;; *_S) OUTDATE=$DEL_S; ;; esac if [ $TSTAMP -le $OUTDATE] ]; then echo removing ${SNP} ... [ umount "$MNTPATH" 2>&1 ] || \ echo ERROR unmounting volume $MNTPATH && continue; [ lvremove "$LVNAME" 2>&1 ] || \ echo ERROR removing snapshot $LVNAME && continue; [ rmdir $MNTPATH ] || \ echo ERROR removing directory $MNTPATH && continue; echo remove successful! fi done
lvconfig.ini
LIFE_S=43200 LIFE_M=345600 LIFE_L=864000 SNAP_PREFIX=snap_ MNT_PREFIX=backup_ LOCKDIR=/var/local/lock/snaps LVDIR=/dev/vg1 MNTPNT=/mnt/snaps TARGET=/dev/vg1/home
変なプログラマ#5
またまた恥をかきに参加しますた。変なプログラマ第5回。
今回は「地図」でのプレゼンターということで、以前http://tomoshibi.mozilla.jp/とかで使われて不思議だったIPからだいたいどの辺からのアクセスがあったのかというのを解析して表示するスクリプトを書きました。
まあ、例によってロジックの間違いの為に「実家のページを見ているユーザがなぜか全て海外からのアクセスであった。」という恥ずかしい結果になりました。
過去3年間のアクセス元(笑)
http://maps.google.com/maps?q=37.8113,-122.3008
http://maps.google.com/maps?q=45.5184,-122.6554
http://maps.google.com/maps?q=36.5412,-121.3956
http://maps.google.com/maps?q=41.8822,-87.6309
http://maps.google.com/maps?q=37.4192,-122.0574
http://maps.google.com/maps?q=37.5155,-121.8962
http://maps.google.com/maps?q=38.6164,-121.4962
http://maps.google.com/maps?q=40.7619,-73.9763
http://maps.google.com/maps?q=17.7452,-64.7072
http://maps.google.com/maps?q=34.0530,-118.2642
http://maps.google.com/maps?q=33.9415,-118.1307
http://maps.google.com/maps?q=47.5839,-122.2995
http://maps.google.com/maps?q=37.4249,-122.0074
http://maps.google.com/maps?q=38.6312,-90.1922
http://maps.google.com/maps?q=26.2794,50.2083
http://maps.google.com/maps?q=45.6868,-122.5756
http://maps.google.com/maps?q=40.6290,-80.0793
http://maps.google.com/maps?q=45.5000,-73.5833
http://maps.google.com/maps?q=34.1738,-118.1702
http://maps.google.com/maps?q=49.2500,-122.9500
http://maps.google.com/maps?q=37.3042,-122.0946
http://maps.google.com/maps?q=37.8091,-122.2702
http://maps.google.com/maps?q=29.7523,-95.3670
http://maps.google.com/maps?q=38.0000,-97.0000
#!/usr/bin/perl # IPから発信地を推測するスクリプト(IPのDBが要るよ) use strict; use warnings; open GINDEX, "<", './????1.csv' or die $!; my @ipmap; # ここのロジックが怪しい? while (<GINDEX>) { next if ! m/^"(\d+)","(\d+)","(\d+)"/; my ($saddr, $eaddr, $code) = ($1, $2, $3); my $range = ($eaddr - $saddr + 1) / 2; my $caddr = $range + $saddr; push @ipmap, [$caddr, $range, $code]; } @ipmap = sort(@ipmap); my %codeMap; #一般的なApacheログを読み、IPデータベースとつきあわせる while (<>) { next if ! m/\d+\.\d+\.\d+\.\d+/; my $ip = &getIpSerial($&); #print "$ip\n"; my $blockCode = &findCode(\@ipmap, $ip); $codeMap{$blockCode} ++; } print map { "$_:$codeMap{$_}\n" } keys(%codeMap); sub findCode ($$) { my $list = shift; my $ip = shift; my $len = int($#{$list} / 2 + 0.5); my $i = $len; while ($len > 0) { my $delta = $ip - $$list[$i][0]; return $$list[$i][2] if abs($delta) <= $$list[$i][1]; $len = int($len / 2); $i += $len * ($delta < 0 ? -1 : 1); } return -1; } sub getIpSerial($) { return -1 if ! m/(\d+)\.(\d+)\.(\d+)\.(\d+)/; my ($a,$b,$c,$d) = ($1, $2, $3, $4); return ($a<<24) + ($b<<16) + ($c<<8) +$d; }
#!/usr/bin/env perl #さっき作ったリストを地名DBとつきあわせて、GoogleMapsのリンクを生成するスクリプト open GCITY, '<', './????2.csv' or die $!; my %maps; while (<GCITY>) { next if ! m/^\d/; my ($code, $country, undef, $city, undef, $ido, $keido) = split(",", $_); $maps{$code} = { 'country' => $country, 'city' => $city, 'ido' => $ido, 'keido' => $keido, }; } while (<>) { my ($code, $count) = split(":", $_); next if $code == -1 || !exists($maps{$code}); print "http://maps.google.com/maps?q="; print $maps{$code}->{ido}.",".$maps{$code}->{keido}; print "\n"; }
ちなみに、GeoIPというサイトで入手出来る????.csvをスクリプトにかけると動きます。使い方はそれぞれ短いソースなので、適当に推察してください。
GeoIPが提供する.pmモジュールAPIで対応していない(?)機能を実現(ちゃんと動かないけどね)しているので、規約違反だ!とか、間違いだらけやんけ!臭っ!などなにか問題があればご連絡願います。m(__)m
第二回変なプログラマの作り方勉強会
いやはや、1週間放ってしまいました。
総評はだいたい皆さんが書いてらっしゃるので、今回は自分が発表した途中までのプレの続きを書きたいと思います。
「ありきたりな人が贈る、アリキタリなソート」
なるタイトルで本当にアリキタリな実装のソートを作りました。
#!/usr/bin/perl use strict; use Getopt::Long; my $null = ''; my @fields; my ($in, $out, $fs) = ('-', '-', "\t"); GetOptions( '--input=s' => \$in, '--output=s' => \$out, '--field-separator|s=s' => \$fs, '--fields|f=i' => \@fields, ); open IN, "<$in" or die "Error in opening input stream : $in ".$!; our $comp; if ($fields[0] =~ m/\d/) { $comp = sub (@@) { my $a = $_[0]; my $b = $_[1]; foreach (@fields) { my $ret = ($$a[$_-1] cmp $$b[$_-1]); return $ret if $ret != 0; } return join($fs, @$a) cmp join($fs, @$b); }; } else { $comp = sub (@@) { my $a = shift; my $b = shift; return join($fs, @$a) cmp join($fs, @$b); }; } my $head = {}; foreach (<IN>) { my @indata = split($fs, $_); my $leaf = $head; for ( ;$leaf->{data}; ) { my $ret = &$comp(\@indata, $leaf->{data}); if ($ret < 0) { $leaf->{lessNode}={} if !$leaf->{lessNode}; $leaf = $leaf->{lessNode}; } else { $leaf->{greatNode}={} if !$leaf->{greatNode}; $leaf = $leaf->{greatNode}; } } $leaf->{data} = \@indata; } close IN; open OUT, ">$out" or die "Error in opening output stream : ".$!; print &printNodes($head); close OUT; sub printNodes { my $leaf = $_[0]; my $left = ''; my $right = ''; if ($leaf->{lessNode}) { $left = &printNodes($leaf->{lessNode}); } if ($leaf->{greatNode}) { $right = &printNodes($leaf->{greatNode}); } return $left.join($fs, @{$leaf->{data}}).$right; }
とりあえず。 続きは夜を待たれい。
第二回変なプログラマの作り方勉強会(つづき)
続き
標準入力またはファイルから、テキストデータを読み込み1行を1単位としてヒープソートします。入力行が\tまたは-sに指定した文字で複数のフィールドに区切られている場合、-fで優先フィールドを指定することが出来ます。
↓むちゃくちゃ横着な例
sh-3.2$ perl sortbase.pl -s ',' -f 2 1 3,5 4,4 5,3 ^D 5,3 4,4 3,5 sh-3.2$
このままではさすがに何の変哲もないので、せっかく作ったソートをなんかの役に立てようということを考えた。
ちょっと考えて、サザンのベスト盤をmp3にしたら、何回も「希望の轍」とか「勝手にシンドバット」とか流れてきてちょっと飽きが来るので、ソートを使って重複を抽出するということを思いついた。(ここで「ライブコーディングします」などと言いながら全く出来ずに撃沈、プレ終了・・・)
端末はLinuxなのでmp3のID3タグを抽出するコマンドをパイプでつないでタイトル毎にソートをかけることで重複している曲が分かるという格好。
この作業をする前に以下のツールをインストールしてください。
eyeD3 (参考:http://packages.debian.org/lenny/eyeD3)
ちなみにこのコマンド、実行すると以下のような感じになる。
sh-3.2$ eyeD3 --no-color mp3x/サザンオールスターズ/Ballad_3_\(The_Album_Of_Love\)_Disc_1/01.真夏の果実.mp3 01.真夏の果実.mp3 [ 7.75 MB ] ------------------------------------------------------------------------------- Time: 04:37 MPEG1, Layer III [ ~233 kb/s @ 44100 Hz - Joint stereo ] ------------------------------------------------------------------------------- ID3 v2.4: title: 真夏の果実 artist: サザンオールスターズ album: Ballad 3 (The Album Of Love) Disc 1 year: 2000 track: 1
アーティスト「サザンオールスターズ」のフォルダ以下すべてのmp3にeyeD3を実行し、ソートするワンライナー
find mp3x/サザンオールスターズ/ -name *.mp3 -exec eyeD3 --no-color {} \; | perl -e 'my ($a, $t); foreach (<>) { $a = $1 if $_=~/album: ([^\t]+)/; $t = $1 if $_=~/title: ([^\t]+)/; if ("$a" ne "" && "$t" ne "") { print "$a\t$t\n"; $a=""; $t=""; }}' | perl sortbase.pl -f 2 1
ソートしない出力
海のYeah!! [Disc 2] 恋のジャック・ナイフ 海のYeah!! [Disc 2] そんなヒロシに騙されて 海のYeah!! [Disc 2] YOU 海のYeah!! [Disc 2] 涙のキッス 海のYeah!! [Disc 2] あなただけを 〜Summer Heartbreak〜 海のYeah!! [Disc 2] 素敵なバーティー (NO NO BIRDY) 海のYeah!! [Disc 2] さよならベイビー 海のYeah!! [Disc 2] 平和の琉歌 海のYeah!! [Disc 2] 愛の言霊 〜Spiritual Message〜 海のYeah!! [Disc 2] マンピーのG★SPOT 海のYeah!! [Disc 2] MOON LIGHT LOVER 海のYeah!! [Disc 2] エロティカ・セブン 海のYeah!! [Disc 2] 太陽は罪な奴 海のYeah!! [Disc 2] シュラバ★ラ★バンバ 海のYeah!! [Disc 2] 真夏の果実 海のYeah!! DISC-1 SEA SIDE チャコの海岸物語 海のYeah!! DISC-1 SEA SIDE いとしのエリー 海のYeah!! DISC-1 SEA SIDE 鎌倉物語 海のYeah!! DISC-1 SEA SIDE ミス・ブランニュー・デイ (MISS BRAND-NEW DAY) 海のYeah!! DISC-1 SEA SIDE BYE BYE MY LOVE (U are the one) 海のYeah!! DISC-1 SEA SIDE 海 海のYeah!! DISC-1 SEA SIDE 勝手にシンドバッド 海のYeah!! DISC-1 SEA SIDE 匂艶 THE NIGHT CLUB 海のYeah!! DISC-1 SEA SIDE 忘れられた BIG WAVE 海のYeah!! DISC-1 SEA SIDE 栞のテーマ 海のYeah!! DISC-1 SEA SIDE 夏をあきらめて 海のYeah!! DISC-1 SEA SIDE 希望の轍 海のYeah!! DISC-1 SEA SIDE みんなのうた 海のYeah!! DISC-1 SEA SIDE いなせなロコモーション 海のYeah!! DISC-1 SEA SIDE C調言葉に御用心 Ballad 3 (The Album Of Love) Disc 1 希望の轍 Ballad 3 (The Album Of Love) Disc 1 素敵なバーディー(NO NO BIRDY) Ballad 3 (The Album Of Love) Disc 1 クリスマス・ラブ 〜涙のあとには白い雪が降る〜 Ballad 3 (The Album Of Love) Disc 1 OH, GIRL (悲しい胸のスクリーン) Ballad 3 (The Album Of Love) Disc 1 冷たい夏 Ballad 3 (The Album Of Love) Disc 1 慕情 Ballad 3 (The Album Of Love) Disc 1 涙のキッス Ballad 3 (The Album Of Love) Disc 1 BLUE HEAVEN Ballad 3 (The Album Of Love) Disc 1 忘れられたBIG WAVE Ballad 3 (The Album Of Love) Disc 1 さよならベイビー Ballad 3 (The Album Of Love) Disc 1 せつない胸に風が吹いてた Ballad 3 (The Album Of Love) Disc 1 HAIR Ballad 3 (The Album Of Love) Disc 1 逢いたくなった時に君はここにいない Ballad 3 (The Album Of Love) Disc 1 真夏の果実 Ballad 3 (The Album Of Love) Disc 2 Saudade〜真冬の蜃気楼〜 Ballad 3 (The Album Of Love) Disc 2 あなただけを〜Summer Heartbreak〜 Ballad 3 (The Album Of Love) Disc 2 SEA SIDE WOMAN BLUES Ballad 3 (The Album Of Love) Disc 2 Love Affair〜秘密のデート Ballad 3 (The Album Of Love) Disc 2 心を込めて花束を Ballad 3 (The Album Of Love) Disc 2 Moon Light Lover Ballad 3 (The Album Of Love) Disc 2 愛の言霊〜Spiritual Message〜 Ballad 3 (The Album Of Love) Disc 2 Tsunami Ballad 3 (The Album Of Love) Disc 2 夏の日のドラマ Ballad 3 (The Album Of Love) Disc 2 BLUE HEAVEN Ballad 3 (The Album Of Love) Disc 2 湘南 SEPTEMBER Ballad 3 (The Album Of Love) Disc 2 愛無き愛児〜Before the Storm〜 Ballad 3 (The Album Of Love) Disc 2 素敵な夢を叶えましょう Ballad 3 (The Album Of Love) Disc 2 唐人物語 (ラシャメンのうた)
ソート後の出力
Ballad 3 (The Album Of Love) Disc 1 BLUE HEAVEN Ballad 3 (The Album Of Love) Disc 2 BLUE HEAVEN 海のYeah!! DISC-1 SEA SIDE BYE BYE MY LOVE (U are the one) 海のYeah!! DISC-1 SEA SIDE C調言葉に御用心 Ballad 3 (The Album Of Love) Disc 1 HAIR Ballad 3 (The Album Of Love) Disc 2 Love Affair〜秘密のデート 海のYeah!! [Disc 2] MOON LIGHT LOVER Ballad 3 (The Album Of Love) Disc 2 Moon Light Lover Ballad 3 (The Album Of Love) Disc 1 OH, GIRL (悲しい胸のスクリーン) Ballad 3 (The Album Of Love) Disc 2 SEA SIDE WOMAN BLUES Ballad 3 (The Album Of Love) Disc 2 Saudade〜真冬の蜃気楼〜 Ballad 3 (The Album Of Love) Disc 2 Tsunami 海のYeah!! [Disc 2] YOU 海のYeah!! [Disc 2] あなただけを 〜Summer Heartbreak〜 Ballad 3 (The Album Of Love) Disc 2 あなただけを〜Summer Heartbreak〜 海のYeah!! DISC-1 SEA SIDE いとしのエリー 海のYeah!! DISC-1 SEA SIDE いなせなロコモーション Ballad 3 (The Album Of Love) Disc 1 さよならベイビー 海のYeah!! [Disc 2] さよならベイビー Ballad 3 (The Album Of Love) Disc 1 せつない胸に風が吹いてた 海のYeah!! [Disc 2] そんなヒロシに騙されて 海のYeah!! DISC-1 SEA SIDE みんなのうた 海のYeah!! [Disc 2] エロティカ・セブン Ballad 3 (The Album Of Love) Disc 1 クリスマス・ラブ 〜涙のあとには白い雪が降る〜 海のYeah!! [Disc 2] シュラバ★ラ★バンバ 海のYeah!! DISC-1 SEA SIDE チャコの海岸物語 海のYeah!! [Disc 2] マンピーのG★SPOT 海のYeah!! DISC-1 SEA SIDE ミス・ブランニュー・デイ (MISS BRAND-NEW DAY) Ballad 3 (The Album Of Love) Disc 1 冷たい夏 海のYeah!! DISC-1 SEA SIDE 勝手にシンドバッド 海のYeah!! DISC-1 SEA SIDE 匂艶 THE NIGHT CLUB Ballad 3 (The Album Of Love) Disc 2 唐人物語 (ラシャメンのうた) Ballad 3 (The Album Of Love) Disc 2 夏の日のドラマ 海のYeah!! DISC-1 SEA SIDE 夏をあきらめて 海のYeah!! [Disc 2] 太陽は罪な奴 Ballad 3 (The Album Of Love) Disc 1 希望の轍 海のYeah!! DISC-1 SEA SIDE 希望の轍 海のYeah!! [Disc 2] 平和の琉歌 Ballad 3 (The Album Of Love) Disc 2 心を込めて花束を 海のYeah!! DISC-1 SEA SIDE 忘れられた BIG WAVE Ballad 3 (The Album Of Love) Disc 1 忘れられたBIG WAVE 海のYeah!! [Disc 2] 恋のジャック・ナイフ 海のYeah!! [Disc 2] 愛の言霊 〜Spiritual Message〜 Ballad 3 (The Album Of Love) Disc 2 愛の言霊〜Spiritual Message〜 Ballad 3 (The Album Of Love) Disc 2 愛無き愛児〜Before the Storm〜 Ballad 3 (The Album Of Love) Disc 1 慕情 海のYeah!! DISC-1 SEA SIDE 栞のテーマ 海のYeah!! DISC-1 SEA SIDE 海 Ballad 3 (The Album Of Love) Disc 1 涙のキッス 海のYeah!! [Disc 2] 涙のキッス Ballad 3 (The Album Of Love) Disc 2 湘南 SEPTEMBER Ballad 3 (The Album Of Love) Disc 1 真夏の果実 海のYeah!! [Disc 2] 真夏の果実 海のYeah!! [Disc 2] 素敵なバーティー (NO NO BIRDY) Ballad 3 (The Album Of Love) Disc 1 素敵なバーディー(NO NO BIRDY) Ballad 3 (The Album Of Love) Disc 2 素敵な夢を叶えましょう Ballad 3 (The Album Of Love) Disc 1 逢いたくなった時に君はここにいない 海のYeah!! DISC-1 SEA SIDE 鎌倉物語
ってことで、勝手にシンドバットは一回しかでなかったですね。
コレを使えばとりあえず余分なMP3の整理にはなると思います。
眠いので続きはまた気が向けば後日っ!
変なプログラマーの作り方勉強会
半年ぶりのブログ更新(笑)
11月14日金曜日、変なプログラマーの作り方というちょっとキャッチーなタイトル(失礼)の勉強会に参加してきた。
19時まで仕事だったのでちょっと遅れての参加だったが、内容はこんな感じ
- カップラーメンより早く掲示板を作る id:fujioka0729さん(同時解説id:guccyonさん)
ライブコーディングで3分以内に掲示板を作るというテーマ。
遅れた分で残念ながら最初の掲示板のベース作成が見られなかったが、後から聞いたところホントに掲示板はカップラーメンより早く出来たらしい。
一人に割り当てられた15分のセッションの残り時間はjavascript(Prototype.js)で画面エフェクトを作成するところに使われ、タイプミスとシンタックスエラー、null対策に苦しめられつつも最後には見栄えする掲示板ができた。ちなみに解説者が居なかったら、あー間違えた、こーでもないと独り言を聞きつつ淡々とかかれるviの画面を見ていることになったと思う。(それはそれでカオスな空気がおもしろそうだけど)
ライブコーディングに使うエディタがviというところにある意味感動したり、たかだか十数分でコードを作ることができるフレームワークの凄さを感じた。
- Flexでつくるゆるふわ掲示板 id:obanettyさん
FlexでTweener(モジュール?忘れた)を使い、ユルくてフワーな感じの、綺麗なFlashベース掲示板の披露された。仕込み済みの実装が結構でかかったのと、独創的でも普通のプログラマの書くようなコードだった都合なのか、なぜかプレゼンで自分の過去の経歴を紹介していた。
文章で説明するのが面倒なくらい、綺麗なエフェクトが掛かっていて凄いなぁと感じた。こうやって振り返るとへぇ終わってしまうのが残念な感じだった。いや、他の2人が凄かったからかも。
- バッチファイルで掲示板作りに挑戦してみた 崎さん(idわからず)
HTTPのCGIにバッチファイルを使い、掲示板を実装するというテーマ。
プレゼンではトライアンドエラーの流れまで説明され、バッチファイルで掲示板を作るというナンセンスなテーマながら、ちゃんとした掲示板を作っていた。作り込めば掲示板ぐらいなら実装できるということを示された点に色々な意味で感心した。
...
これらのプレゼンを見て、最後に「自分が感じた一番良かったもの」を出すというコンペを行った。
僕は崎さんに1票をいれた。
キャッチーでありながら、タイトル通りに良い変なプログラマーが集まったと思うし、確かにおもしろい勉強会となった。
次回はソートを行うそうで、今度はプレゼンターで参加しようと思う。というか抜き差しならなくなって参加する訳ですが・・・