BufferedReader: Vom Logfile zur Datenbank

mramaze

Mitglied
Hi Leute,

ist mein erster Beitrag also bitte nicht böse sein, falls es schon was zu dem Thema gibt. Hab auch schon gesucht und was gefunden, aber nicht hundertprozentig passend.

Hab grad irgendwie ne Blockade bzw. einen Denkfehler und komm nicht weiter.

Folgendes Szenario:
Ich möchte (erstmal zur Vereinfachung) ein Logfile (später mehrere) auslesen. Es sollen alle Datenfelder des Common Logfile-Formats (also IP-Adresse, Datum etc....) in ein eigenes Datenfeld einer Tabelle einer Datenbank geschrieben werden. Das auslesen funktioniert wunderbar. Hier mal mein bisheriger Code:

Java:
 public void readLogfile(String name) throws IOException {
    	 
    	 		
    			 FileInputStream fstream = new FileInputStream(name);
    
    			 DataInputStream in = new DataInputStream(fstream);

    			 BufferedReader br = new BufferedReader(new InputStreamReader(in));

    			 String strLine;

    	 
    			 	//Read File Line By Line
    			 	while ((strLine = br.readLine()) != null)   {
    	
    			 		// System.out.println (strLine);
    			 		
    			 		List<String> logList = new ArrayList<String>();
    			 		logList.add(strLine);
 						
    			 		Iterator<String> it = logList.iterator();
    			 		
    			 			while (it.hasNext()) {
    			 				
    			 				System.out.println(it.next());
    			 			
    			 				StringTokenizer tokenizer = new StringTokenizer(strLine);
    	    
    			 					while (tokenizer.hasMoreTokens()) {

    			 						tokenList = new ArrayList<String>();
    			 						tokenList.add(tokenizer.nextToken());
    			 	

    			 						System.out.println(tokenList);

    			 					
    			 					}    	    	
    			 			}
    			 	}

    	  //Close the input stream
    	  in.close();
    	  }

Ich schreibe jede Zeile in eine ArrayList und gehe anschließend mit dem StringTokenizer drüber um die einzelnen Datenfelder des Logfiles zu bekommen. Nun möchte ich jedes Datenfeld in die einer Datenbank speichern, bekomme das aber irgendwie nicht hin. In der Konsole wird alles so ausgegeben wie ich es möchte. Jedoch weiß ich nicht, wie ich auf die einzelnen Tokens zugreifen kann, um sie abzuspeichern.

Ich kann irgendwie nicht auf die Indizes der ArrayList zugreifen, um beispielsweise die IP-Adresse zu extrahieren und abzuspeichern (IP-Adressen sind im Logfile immer an erster Stelle, also hatt ich mir das ungefähr so gedacht: String ip = tokenList.get(0); o.ä.). Ich denke mal das funktioniert wegen der "dynamischen" Befüllung der Liste in der while-Schleife nicht.

Ich hoffe ich habe mein Problem deutlich ausgedrückt und bedanke mich für konstruktive Vorschläge. Steh gerade voll auf dem Schlauch 😉.
 
Morgen.
Zunächst einmal kannst du dir den Block
Java:
                        List<String> logList = new ArrayList<String>();
                        logList.add(strLine);
                        
                        Iterator<String> it = logList.iterator();
                        
                            while (it.hasNext()) {
schenken, weil du immer nur eine Zeile liest und diese in eine temporäre Liste (logList) mit genau einen Eintrag zu schreiben ist unnötig. Du kannst also direkt mit dem Tokenizer anfangen.

Beim Tokenizer kannst du mitzählen welcher Index es ist, und die Werte entsprechend setzen, in etwa so:
Java:
while ((line = reader.readLine()) != null) {
    String ip = "";
    String timestamp = "";
    String message = "";
    //bzw. wasauchimmer

    int i = 0;
    StringTokenizer tokenzier = new StringTokenizer(line);
    while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken();

        switch (i) {
            case 0: ip = token;
                    break;
            case 1: timestamp = token;
                    break;
            case 2: message = token;
                    break;
            default:
                // huch?
        }

        i++;
    } //while    
} //while
 
klingt ziemlich ähnlich zu
http://www.java-forum.org/datenbankprogrammierung/130772-csv-datei-einlesen-datenbank.html
in dem Sinne dass zu DB-Code bisher alles fehlt,
da kann man auch hier kaum mehr als auf Tutorials verlinken, oder jemand schreibt zufällig eine Komplettlösung dazu

----

ansonsten:
> Ich kann irgendwie nicht auf die Indizes der ArrayList zugreifen, um beispielsweise die IP-Adresse zu extrahieren

kannst du das auch näher erläutern? was geht denn an list.get(0) nicht?
welchen Code hast du mit welchen Fehlermeldungen oder sonstigen Problemen?

----

ein Konstrukt a la
Java:
                    //Read File Line By Line
                    while ((strLine = br.readLine()) != null)   {
        
                        // System.out.println (strLine);
                        
                        List<String> logList = new ArrayList<String>();
                        logList.add(strLine);
                        
                        Iterator<String> it = logList.iterator();
                        
                            while (it.hasNext()) {
macht natürlich auch für sich schon wenig Sinn,
nach Standard wird jede Zeile aus der Datei eingelesen, dann aber jeweils eine neue Liste erstellt,
der eine String eingefügt und die Liste in einer neuen Schleife durchlaufen,
wozu?
das könnte man sich sparen und gleich mit strLine weiterarbeiten,
bzw. wird ja auch gemacht, das it.next() aus der Liste wird nur einmal ausgegeben, sonst passiert nichts damit,

das ist unsinniger Code,
wenn das schon schwierig ist, dann wird komplexere DB natürlich noch viel schwieriger
 
Ich würde da gar nicht lange frickeln um eine eigene, suboptimale Lösung zu erstellen, sondern gleich log4j oder besser logback nutzen, die bieten beide Appender für RDBMS.
 
@KrokoDiehl: Danke für den Vorschlag. Ich werds mal veruschen so umzusetzen. Ich hab mir schon gedacht, dass das mit der Liste irgendwie unnötig ist. Aber ich hab mal mit nem Prof. darüber geredet und der hat mir diese Vorgehensweise vorgeschlagen und ich hab mich dann auf diese Variante festgefahren gehabt.

@SlaterB: DB-Code fehlt, weil ich ihn bisher noch nicht eingefügt habe. Aber der sollte dann das kleinere Übel sein.
Wenn der Index 0 ist, funktioniert das ganze, er gibt mir allerdings dann die gesamte Zeile in Tokens aus.

Java:
StringTokenizer tokenizer = new StringTokenizer(strLine);
    	    
    while (tokenizer.hasMoreTokens()) {

    	 tokenList = new ArrayList<String>();
         tokenList.add(tokenizer.nextToken());
    			 	

          System.out.println(tokenList.get(1));
    			 						

    	}

Das die erste Liste (logList) keinen Sin macht stimmt. Aber bei der TokenList wollt ich halt dann über die Indize auf die einzelnen Tokens zugreifen. Bei Index >= 1 bekomm ich ne IndexOutOfBoundException.

@maki:Ich will das LogFile eines Webservers auswerten (ich weiß es gibt unzählige LogFileAnalyzer, aber das ist erst der erste Schritt). Log4j bzw. Logback sind doch dazu da, um den eigenen Code mitzuloggen oder täusch ich mich da?
 
bei der tokenList gilt bisher praktisch dasselbe wie bei der logList, hatte ich noch nicht angeschaut:
wenn du INNERHALB der Schleife ständig eine neue Liste erzeugst und nur das aktuelle Element einfügst,
dann ist die Liste sinnlos

erzeuge die Liste nur VOR der tokenizer-Schleife und füge alle Elemente ein,
NACH der Schleife hast du dann hoffentlich mehrere Einträge und kannst mit verschiedenen Indexen, auch > 0, zugreifen
 
Da hast du natürlich recht. Die Liste muss ich vor der Schleife erzeugen. Bei sowas bin ich immer viel zu leichtsinnig und pass nicht auf 😉.

Aber KrokoDiehls Lösung funktioniert wunderbar.

Danke für eure Hilfe.
 

Zurück
Oben