Annotation of java/classes/org/w3c/tools/log/DNSResolver.java, revision 1.4
1.1 ylafon 1: // DNSResolver.java
1.4 ! ylafon 2: // $Id: DNSResolver.java,v 1.3 1999/03/18 10:22:43 ylafon Exp $
1.1 ylafon 3: // (c) COPYRIGHT MIT, INRIA and Keio, 1996-1999.
4: // Please first read the full copyright statement in file COPYRIGHT.html
5:
6: // a sample CLF/ELF log file name resolver post processing tool
7: // @author Yves Lafon <ylafon@w3.org>
8:
9: package org.w3c.tools.log;
10:
11: import java.lang.*;
12: import java.util.*;
13: import java.io.*;
14: import java.net.*;
15: import java.text.*;
16: import org.w3c.util.ThreadCache;
17:
18: public class DNSResolver {
19:
1.4 ! ylafon 20: /**
! 21: * the thread in charge of doing DNS resolution
! 22: * It works better if the getHostName() call is not blocking
! 23: * the whole JVM :)
! 24: */
! 25:
1.1 ylafon 26: private class ResolverThread implements Runnable {
27: String line;
28: DateFormat dfp; // date format parser
29:
30: public void run() {
31: boolean ok;
32: String host;
33: DNSEntry entry;
34: String res;
35: String ip_str = line.substring(0, line.indexOf(' '));
36: byte a[] = ip_str.getBytes();
1.4 ! ylafon 37:
! 38: if (resolve) {
! 39: ok = true;
! 40: for (int i=0; ok && i<a.length; i++) {
! 41: if (a[i] == '.')
! 42: continue;
! 43: if (a[i]< '0' || a[i]> '9')
! 44: ok = false;
! 45: }
! 46: } else
! 47: ok = false;
1.1 ylafon 48: if (!ok) {
1.4 ! ylafon 49: try {
! 50: // probably a resolved line, print and continue :)
! 51: if (dfp != null) {
! 52: String date_str = line.substring(line.indexOf('[')+1,
! 53: line.indexOf(']'));
! 54: long stamp = 0;
! 55: try {
! 56: stamp = dfp.parse(date_str).getTime();
! 57: } catch (Exception ex) {
! 58: // invalid date, should we skip? use 0 as a default...
! 59: }
! 60: // rewrite the log entry :)
! 61: synchronized (System.out) {
! 62: System.out.println(Long.toString(stamp) +
! 63: " " + line);
! 64: }
! 65: } else {
! 66: synchronized (System.out) {
! 67: System.out.println(line);
! 68: }
1.2 ylafon 69: }
1.4 ! ylafon 70: } catch (Exception parsex) {
! 71: // exit cleanly
1.1 ylafon 72: }
73: return;
74: }
75: // ok so it is a REAL ip string :)
76: host = (String) badHosts.get(ip_str);
77: if (host == null) {
78: entry = (DNSEntry) hosts.get(ip_str);
79:
80: if (entry == null || !entry.isResolved()) {
81: try {
82: host = InetAddress.getByName(ip_str).getHostName();
83: if (host.equals(ip_str)) {
84: badHosts.put(ip_str, ip_str);
85: if (entry != null)
86: entry.notFound();
87: else {
88: entry = new DNSEntry(ip_str, false);
89: hosts.put(ip_str, entry);
90: }
91: } else {
92: if (entry != null)
93: entry.setHost(host);
94: else {
95: entry = new DNSEntry(host);
96: hosts.put(ip_str, entry);
97: }
98: }
99: } catch (UnknownHostException uhe) {
100: host = ip_str;
101: badHosts.put(ip_str, ip_str);
102: if (entry != null)
103: entry.notFound();
104: else {
105: entry = new DNSEntry(ip_str, false);
106: hosts.put(ip_str, entry);
107: }
108: }
109: } else
110: host = entry.host;
111: }
112:
113: // ok, now we have the host :)
114: res = line.substring(line.indexOf(' '));
115: if (dfp != null) {
116: // and add the timestamp!
117: String date_str = res.substring(res.indexOf('[')+1,
118: res.indexOf(']'));
119: long stamp = 0;
120: try {
121: stamp = dfp.parse(date_str).getTime();
122: } catch (Exception ex) {
123: // invalid date, should we skip? use 0 as a default...
124: }
125: // rewrite the log entry :)
126: synchronized (System.out) {
127: System.out.println(Long.toString(stamp) +
128: " " + host + res);
129: }
130: } else {
131: // rewrite the log entry :)
132: synchronized (System.out) {
133: System.out.println(host + res);
134: }
135: }
136: }
1.4 ! ylafon 137: /**
! 138: * create a new resolver thread, with the full ECLF entry
! 139: */
1.1 ylafon 140: ResolverThread(String line, boolean timestamp) {
141: this.line = line;
142: dfp = (timestamp) ?
143: new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss z") :
144: null;
145: }
146: }
147:
148:
149: private BufferedReader bf;
150: private Hashtable hosts;
151: private Hashtable badHosts;
152: private ThreadCache threadCache;
153: private boolean timestamp;
1.4 ! ylafon 154: private boolean resolve;
1.2 ylafon 155: private int cacheSize;
1.1 ylafon 156:
1.4 ! ylafon 157: /**
! 158: * the main loop, works on the reader provided at initialization
! 159: */
! 160:
1.1 ylafon 161: public void readLog() {
162: String read;
163: boolean ok, done;
164: int pos, qpos;
165: String host;
166: String pass_date;
167: String request;
168: int resp_code;
169: int resp_size;
170: String referer = null;
171: String user_agent = null;
172: String res;
173: String tmp;
174: DNSEntry entry;
175:
176: try {
177: while ( (read = bf.readLine()) != null) {
178: done = false;
179: if (read.length() < 40) { // remove bad lines
180: continue;
181: }
182: ResolverThread rt = new ResolverThread(read, timestamp);
183: if ( ! threadCache.getThread(rt, true) ) {
184: System.err.println("*** unable to process :" + read);
185: }
186: }
1.3 ylafon 187: threadCache.waitForCompletion();
1.1 ylafon 188: // save the hashtable in a file
189: FileOutputStream fileOut = null;
190: try {
191: fileOut = new FileOutputStream("dns.oj");
192: ObjectOutputStream out = null;
193: try {
194: out = new ObjectOutputStream(fileOut);
195: out.writeObject(hosts);
196: } catch (Exception e) {
197: } finally {
198: try {
199: out.close();
200: } catch (Exception e) {}
201: }
202: } catch (Exception e) {
203: } finally {
204: try {
205: fileOut.close();
206: } catch (Exception e) {}
207: }
208:
209: } catch (IOException ex) {
210: }
211: }
212:
1.4 ! ylafon 213: /**
! 214: * create a new Resovler engine
! 215: * @param bf, a buffered reader, the log source
! 216: * @param cacheSize the number of threads used to do resolution
! 217: * @param timestamp if set, the resolver will add a numeric timestamp
! 218: * useful to sort mixed entries
! 219: * @param resolve if set, it will do DNS resolution of the entry
! 220: */
! 221:
! 222: public DNSResolver(BufferedReader bf, int cacheSize,
! 223: boolean timestamp, boolean resolve) {
1.1 ylafon 224: this.bf = bf;
1.4 ! ylafon 225: this.resolve = resolve;
1.1 ylafon 226: this.badHosts = new Hashtable(201);
227: this.timestamp = timestamp;
1.2 ylafon 228: this.cacheSize = cacheSize;
1.1 ylafon 229:
230: // load the hashtable from a file.
231: FileInputStream fileIn = null;
232: try {
233: fileIn = new FileInputStream("dns.oj");
234: ObjectInputStream in = null;
235: try {
236: in = new ObjectInputStream(fileIn);
237: hosts = (Hashtable) in.readObject();
238: } catch (Exception e) {
239: hosts = new Hashtable(1001);
240: } finally {
241: try {
242: in.close();
243: } catch (Exception e) {}
244: }
245: } catch (Exception e) {
246: hosts = new Hashtable(1001);
247: } finally {
248: try {
249: fileIn.close();
250: } catch (Exception e) {}
251: }
252: threadCache = new ThreadCache("resolver");
253: threadCache.setThreadPriority(5);
254: threadCache.setCachesize(cacheSize);
255: threadCache.initialize();
256: }
257:
258: public DNSResolver(BufferedReader bf, int cacheSize) {
1.4 ! ylafon 259: this(bf, cacheSize, false, true);
1.1 ylafon 260: }
261:
1.4 ! ylafon 262: public DNSResolver(BufferedReader bf, boolean timestamp, boolean resolve) {
! 263: this(bf, 50, timestamp, resolve);
1.1 ylafon 264: }
265:
266: public DNSResolver(BufferedReader bf) {
1.4 ! ylafon 267: this(bf, 50, false, true);
1.1 ylafon 268: }
269: }
Webmaster