Package org.drools.core.audit

Source Code of org.drools.core.audit.WorkingMemoryFileLogger

/*
* Copyright 2005 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.drools.core.audit;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import org.drools.core.WorkingMemory;
import org.drools.core.audit.event.LogEvent;
import org.drools.core.util.IoUtils;
import org.kie.api.event.rule.AgendaGroupPoppedEvent;
import org.kie.api.event.rule.AgendaGroupPushedEvent;
import org.kie.api.event.rule.RuleFlowGroupActivatedEvent;
import org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent;
import org.kie.internal.event.KnowledgeRuntimeEventManager;

import com.thoughtworks.xstream.XStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A logger of events generated by a working memory. It stores its information
* in a file that can be specified. All the events logged are written to the
* file when the writeToDisk() method is invoked. The log will contain all the
* events logged serialized to XML using XStream. Every time a new logger is
* created, the old event log will be overwritten.
*
* TODO: make this class more scalable, for example - logging to several files
* if log becomes too large - automatically write updates to file at certain
* time intervals - ...
*/
public class WorkingMemoryFileLogger extends WorkingMemoryLogger {

    protected static final transient Logger logger = LoggerFactory.getLogger(WorkingMemoryFileLogger.class);

    private List<LogEvent> events            = new ArrayList<LogEvent>();
    private String         fileName          = "event";
    private int            maxEventsInMemory = 1000;
    private int            nbOfFile          = 0;
    private boolean        split             = true;
    private boolean        initialized       = false;
    protected boolean      terminate         = false;

    public WorkingMemoryFileLogger() {
    }

    /**
     * Creates a new WorkingMemoryFileLogger for the given working memory.
     */
    public WorkingMemoryFileLogger(final WorkingMemory workingMemory) {
        super( workingMemory );
    }

    public WorkingMemoryFileLogger(final KnowledgeRuntimeEventManager session) {
        super( session );
    }

    @SuppressWarnings("unchecked")
    public void readExternal(ObjectInput in) throws IOException,
                                            ClassNotFoundException {
        super.readExternal( in );
        events = (List<LogEvent>) in.readObject();
        fileName = (String) in.readObject();
        maxEventsInMemory = in.readInt();
        nbOfFile = in.readInt();
        split = in.readBoolean();
        initialized = in.readBoolean();
        terminate = in.readBoolean();
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        super.writeExternal( out );
        out.writeObject( events );
        out.writeObject( fileName );
        out.writeInt( maxEventsInMemory );
        out.writeInt( nbOfFile );
        out.writeBoolean( split );
        out.writeBoolean( initialized );
        out.writeBoolean( terminate );
    }

    /**
     * Sets the name of the file the events are logged in. No extensions should
     * be given since .log is automatically appended to the file name. The
     * default is an event.log file in the current working directory. This can
     * be a path relative to the current working directory (e.g.
     * "mydir/subDir/myLogFile"), or an absolute path (e.g. "C:/myLogFile").
     *
     * @param fileName
     *            The name of the file the events should be logged in.
     */
    public void setFileName(final String fileName) {
        this.fileName = fileName;
    }

    /**
     * All events in the log are written to file. The log is automatically
     * cleared afterwards.
     */
    public void writeToDisk() {
        if ( !initialized ) {
            initializeLog();
        }
        Writer writer = null;
        try {
            FileOutputStream fileOut = new FileOutputStream( this.fileName + (this.nbOfFile == 0 ? ".log" : this.nbOfFile + ".log" ),
                                                             true );
            writer = new OutputStreamWriter( fileOut,
                                             IoUtils.UTF8_CHARSET );
            final XStream xstream = new XStream();
            WorkingMemoryLog log = null;
            synchronized ( this.events ) {
                log = new WorkingMemoryLog(new ArrayList<LogEvent>( this.events ),
                                           isPhreak ? "PHREAK" : "RETEOO");
                clear();
            }
            writer.write( xstream.toXML( log ) + "\n" );
        } catch ( final FileNotFoundException exc ) {
            throw new RuntimeException( "Could not create the log file.  Please make sure that directory that the log file should be placed in does exist." );
        } catch ( final Throwable t ) {
            logger.error("error", t);
        } finally {
            if ( writer != null ) {
                try {
                    writer.close();
                } catch ( Exception e ) {
                }
            }
        }
        if ( terminate ) {
            closeLog();
            terminate = true;
        } else if ( split ) {
            closeLog();
            this.nbOfFile++;
            initialized = false;
        }
    }

    private void initializeLog() {
        try {
            FileOutputStream fileOut = new FileOutputStream( this.fileName + (this.nbOfFile == 0 ? ".log" : this.nbOfFile + ".log"),
                                                             false );
            Writer writer = new OutputStreamWriter( fileOut,
                                                    IoUtils.UTF8_CHARSET );
            writer.append( "<object-stream>\n" );
            writer.close();
            initialized = true;
        } catch ( final FileNotFoundException exc ) {
            throw new RuntimeException( "Could not create the log file.  Please make sure that directory that the log file should be placed in does exist." );
        } catch ( final Throwable t ) {
            logger.error("error", t);
        }
    }

    private void closeLog() {
        try {
            FileOutputStream fileOut = new FileOutputStream( this.fileName + (this.nbOfFile == 0 ? ".log" : this.nbOfFile + ".log"),
                                                             true);
            Writer writer = new OutputStreamWriter( fileOut,
                                                    IoUtils.UTF8_CHARSET);
            writer.append( "</object-stream>\n" );
            writer.close();
        } catch ( final FileNotFoundException exc ) {
            throw new RuntimeException( "Could not close the log file.  Please make sure that directory that the log file should be placed in does exist." );
        } catch ( final Throwable t ) {
            logger.error("error", t);
        }
    }

    /**
     * Clears all the events in the log.
     */
    private void clear() {
        synchronized ( this.events ) {
            this.events.clear();
        }
    }

    /**
     * Sets the maximum number of log events that are allowed in memory. If this
     * number is reached, all events are written to file. The default is 1000.
     *
     * @param maxEventsInMemory
     *            The maximum number of events in memory.
     */
    public void setMaxEventsInMemory(final int maxEventsInMemory) {
        this.maxEventsInMemory = maxEventsInMemory;
    }

    public void logEventCreated(final LogEvent logEvent) {
        synchronized ( this.events ) {
            this.events.add( logEvent );
            if ( this.events.size() > this.maxEventsInMemory ) {
                writeToDisk();
            }
        }
    }

    public void setSplit(boolean split) {
        this.split = split;
    }

    public void stop() {
        if ( !terminate ) {
            terminate = true;
            writeToDisk();
        }
    }
}
TOP

Related Classes of org.drools.core.audit.WorkingMemoryFileLogger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.