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