アクセスログのIPアドレスを逆引き
Posted feedbacks - diff
そうか、デーモンスレッドでなければ、それが終了するまでメインスレッドは終了しないから、joinする必要はないはず・・・。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | --- prev.py Mon Aug 6 23:55:36 2007
+++ main.py Mon Aug 6 23:56:02 2007
@@ -55,7 +55,6 @@
lines.pop().output()
queue = Queue.Queue()
count = 10 # hint: configure thread count here
- threads = []
for _ in xrange(count):
def resolve():
while 1:
@@ -65,7 +64,6 @@
line.resolve()
thread = threading.Thread(target=resolve)
thread.start()
- threads.append(thread)
for line in read():
lines.appendleft(line)
queue.put(line)
@@ -73,8 +71,6 @@
output(0)
for _ in xrange(count):
queue.put(None) # terminator
- for thread in threads:
- thread.join()
if __name__ == '__main__':
main()
|
他の人にコメントして気づいたんだけど、Matcher に複数スレッドからロックなしにアクセスしてます ね・・・。変更せず取得しているだけだから安全だと 思ってたけど、メソッド内で例えば計算結果を キャッシュするなどして、メンバ変数を変更して いたら・・・安全とは言えない気がしてきました。 というわけで、別スレッドからアクセスするのは bytes と addr だけにするパッチです。addr は 参照を返してるだけだし、bytes はスレッド 開始以降変更してないので、これで完全に スレッドセーフなはず。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | --- MeApp.java.orig Tue Aug 7 17:12:58 2007
+++ MeApp.java Tue Aug 7 17:14:36 2007
@@ -40,37 +40,39 @@
throw new RuntimeException("line should start with IP a
ddress");
}
+ final String addr = m.group(0);
+
final Future<String> future;
- if (_map.containsKey(m.group(0)))
+ if (_map.containsKey(addr))
{
- future = _map.get(m.group(0));
+ future = _map.get(addr);
}
else
{
+ final byte[] bytes = new byte[m.groupCount()];
+
+ for (int i = 0; i < bytes.length; ++i)
+ {
+ bytes[i] = (byte)Integer.parseInt(m.group(i + 1));
+ }
+
future = service.submit(new Callable<String>()
{
public String call() throws Exception
{
- final byte[] bytes = new byte[m.groupCount()];
-
- for (int i = 0; i < bytes.length; ++i)
- {
- bytes[i] = (byte)Integer.parseInt(m.group(i
+ 1));
- }
-
try
{
return InetAddress.getByAddress(bytes).getH
ostName();
}
catch (UnknownHostException e)
{
- return m.group(0);
+ return addr;
}
}
});
- _map.put(m.group(0), future);
+ _map.put(addr, future);
}
_queue.offer(new Callable<String>()
|



沢渡 みかげ
#3395()
Rating1/1=1.00
アクセスログの各行の先頭にIPアドレスがあります.そのIPアドレスを逆引き結果のFQDNで置き換えてください.
逆引きが出来なかった場合は,IPアドレスのまま残します. IPアドレス以外の部分は,そのまま加工せずに残してください.
----
例)192.168.7.1 が逆引きできない場合
210.166.209.71 - - [26/Jul/2007:22:32:47 +0900] "GET / HTTP/1.1" 403 283 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.5) Gecko/20070713 Firefox/2.0.0.5"
192.168.7.1 - - [26/Jul/2007:22:32:48 +0900] "GET /favicon.ico HTTP/1.1" 404 290 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.5) Gecko/20070713 Firefox/2.0.0.5"
↓
mikage.to - - [26/Jul/2007:22:32:47 +0900] "GET / HTTP/1.1" 403 283 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.5) Gecko/20070713 Firefox/2.0.0.5"
192.168.7.1 - - [26/Jul/2007:22:32:48 +0900] "GET /favicon.ico HTTP/1.1" 404 290 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.5) Gecko/20070713 Firefox/2.0.0.5"
----
アクセスログは膨大な量があるため,現実的な時間で処理できるよう,以下の条件をつけます.
・メモリに入りきらないような巨大なログも処理できるようにしてください.(ファイル全体をメモリに読み込むのはNG)
・十分な速度で処理できるよう,並列化する等の工夫をしてください.
・DNSサーバに大量のリクエストが行かないよう,結果をキャッシュしてDNSサーバへのアクセスを削減してください. なお,DNSのTTLは無視して結果をキャッシュしてかまいません. (ログの記録された時間の逆引きするタイミングがずれているため,正確な逆引きは元々無理なので)
名前解決はgethostbyaddrを利用しても良いですし,再帰的に名前解決が出来るDNSサーバと直接通信してもかまいません.
ログを順次読み取り処理する部分を,データを共有しつついかに並列化するか,という部分を問うのが目的です.
このお題は沢渡みかげさんの投稿です。ご投稿ありがとうございます。
[ reply ]