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