
org.jwall.web.audit.io.ConcurrentAuditReader Maven / Gradle / Ivy
/*
* Copyright (C) 2007-2014 Christian Bockermann
*
* This file is part of the web-audit library.
*
* web-audit library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The web-audit library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
package org.jwall.web.audit.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import org.jwall.web.audit.AuditEvent;
import org.jwall.web.audit.util.ParserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* This class read the index-file of a concurrent auditlog and
* creates audit-events from the appopriate event-files, if
* available.
*
* @author Christian Bockermann <[email protected]>
*
*/
public class ConcurrentAuditReader
extends AbstractAuditEventReader
//implements AuditEventReader
{
/** A unique logger for this class */
private static Logger log = LoggerFactory.getLogger( ConcurrentAuditReader.class );
private File index;
/* The data-directory where all the event-files are stored (in subdirectories) */
private File dataDir;
private boolean finished = false;
private long bytesRead = 0L;
private boolean tail = true;
/**
* This constructor creates a new concurrent audit-reader that reads from the
* given index file and expects the audit data-files to exist relative to the
* given data-directory.
*
* @param dataDir The base directory of the data-files.
* @param indexFile The file containing the summary-lines for all events.
* @throws IOException In case any of the files cannot be read or does not exist.
*/
public ConcurrentAuditReader( File dataDir, File indexFile, boolean tail ) throws IOException {
super( new FileInputStream( indexFile ) );
this.dataDir = dataDir;
this.tail = tail;
index = indexFile;
if( ! ( index.exists() && index.canRead() ) )
throw new IOException("Cannot read index-file: "+index.toString() );
if( tail ){
log.debug( "Listening on tail of index-file (skipping " + index.length() + " bytes)..." );
reader.skip( index.length() );
} else
log.debug("Reading complete index-file...");
}
public ConcurrentAuditReader( InputStream index, File dataDir ) throws IOException {
super( index );
this.dataDir = dataDir;
log.debug( "Listening on tail of index-file..." );
}
public ConcurrentAuditReader( File data, File index ) throws IOException {
this( data, index, false );
}
/**
* This constructor creates a new concurrent audit-reader that
* listens on the index file in the given data-directory. The
* index-file is assumed to be called index
and
* has to exists in the given data-directory.
*
* @param dataDir The directory where all audit-data is stored.
* @throws IOException In case the index file does not exists or
* cannot be read.
*/
public ConcurrentAuditReader( File dataDir, boolean tail ) throws IOException {
this( dataDir, new File( dataDir.getAbsolutePath() + "/index" ), tail );
}
public ConcurrentAuditReader( File dataDir ) throws IOException {
this( dataDir, false );
}
/**
*
* This method read the next event from the file-system. If there
* is none available it waits and listens for another one to be
* appended to the index-file.
*
* @throws IOException
*/
public AuditEvent readNext()
throws IOException, ParseException
{
log.debug("ConcurrentAuditReader.readNext()");
String line = null;
do {
line = reader.readLine();
while( line == null && tail ){
try {
log.debug( "Waiting for next event..." );
Thread.sleep( 1000 );
line = reader.readLine();
} catch (Exception e) {
e.printStackTrace();
}
}
log.debug("line: "+line);
if( line == null ){
this.eofReached = true;
if( tail )
return null;
else {
log.debug( "End-of-file reached, not in \"continuous-reading\"-mode. Closing." );
finished = true;
}
} else {
return this.readEvent( line );
}
} while( !finished );
log.debug("index-line: "+line);
return null;
}
/**
* This method creates an audit-event instance from a file. The filename is
* extracted from the given index-entry line s
and the basic
* data directory that was specified at creation of this audit-reader.
*
* @param s The index entry line.
* @return An audit-event.
* @throws IOException In case the file cannot be read (due to non-existence
* or missing rights) an exception is thrown.
*/
public AuditEvent readEvent( String s ) throws IOException, ParseException {
String line = s.replaceFirst("\\[", "\"").replaceFirst("\\]", "\"");
String[] token = ParserUtils.splitQuotedString( line );
token = AccessLogAuditReader.splitAccessLine( line );
File evtFile = new File( dataDir.getAbsolutePath() + "/" + token[12] );
log.debug("Reading event from "+evtFile.getAbsoluteFile());
int retries = 3;
while(retries > 0 && ! (evtFile.exists() && evtFile.canRead() ) ) {
try {
log.debug("waiting for file {} to be created...", evtFile.getAbsolutePath() );
retries--;
Thread.sleep(200);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
if( ! evtFile.exists() )
throw new IOException("File not found: "+evtFile.getAbsolutePath());
if(! evtFile.canRead() )
throw new IOException("Cannot read event from file: "+evtFile.getAbsolutePath() );
try {
AbstractAuditEventReader ms2ar = new ModSecurity2AuditReader( evtFile );
AuditEvent evt = ms2ar.readNext();
ms2ar.close();
return evt;
} catch (Exception e){
throw new IOException( e.getMessage() );
}
}
public void finish(){
finished = true;
}
public void close() throws IOException {
reader.close();
}
public long bytesRead(){
return bytesRead;
}
public long bytesAvailable(){
if( index != null )
return index.length();
return Long.MAX_VALUE;
}
@Override
public Iterator iterator() {
try {
return new AuditEventIterator( this );
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy