/*
*
* Copyright (c) void.fm
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name void.fm nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package etm.contrib.aggregation.log;
import etm.contrib.aggregation.filter.RegexEtmFilter;
import etm.core.aggregation.Aggregator;
import etm.core.aggregation.EtmFilter;
import etm.core.monitor.EtmException;
import etm.core.monitor.EtmMonitorContext;
import etm.core.monitor.EtmPoint;
import etm.core.renderer.MeasurementRenderer;
/**
* Sometimes it is important to have access to raw measurement results. This
* base class wrap an existing aggregator and dumps all EtmPoints to a
* certain logging implementation using a common log format. Before dumping
* the measurement poin the nested aggregator {@link Aggregator#add} method is
* called.
* <p/>
* Logger implementations will use the default logger name {@link #DEFAULT_LOG_NAME}
* unless this name was altered using {@link #setLogName(String)}.
* <p/>
* A EtmPoint will logged using the {@link DefaultOutputFormatter}. You may override
* the default implementation by using {@link #setFormatter}.
* <p/>
* Due to the direct performance impact this aggregator
* should be used in conjunction with a time based buffered aggregator,
* such as {@link etm.core.aggregation.BufferedTimedAggregator}. Therefore a logging aggregator
* chain should look like this: <code>BufferedTimedAggregator -> Implementation of
* AbstractLogAggregator -> (Flat/Nested)Aggregator</code>. Be aware that
* log timestamps and measurement timestamps may be out of synch due to buffering.
*
* @author void.fm
* @version $Revision$
*/
public abstract class AbstractLogAggregator implements Aggregator {
protected static final String DEFAULT_LOG_NAME = "etm-raw-data";
protected Aggregator delegate;
protected String logName = DEFAULT_LOG_NAME;
protected LogOutputFormatter formatter;
protected EtmFilter filter;
protected EtmMonitorContext ctx;
protected AbstractLogAggregator(Aggregator aAggregator) {
delegate = aAggregator;
}
/**
* Overrides the default logger name. Make sure to call this method
* before starting the EtmMonitor, otherwhise changes will be unaffected.
*
* @param aLogName The new name of the logger.
*/
public void setLogName(String aLogName) {
logName = aLogName;
}
/**
* Overrides the default log output formatter. Make sure to call this method
* before starting the EtmMonitor, otherwhise changes will be unaffected.
*
* @param aFormatter A new formatter.
*/
public void setFormatter(LogOutputFormatter aFormatter) {
formatter = aFormatter;
}
public void setFormatterClass(Class aFormatterClazz) {
try {
formatter = (LogOutputFormatter) aFormatterClazz.newInstance();
} catch (Exception e) {
throw new EtmException(e);
}
}
/**
* Adds a filter for symbolic EtmPoint names that
* should be logged. Uses {@link java.util.regex.Pattern}
* for pattern matching. Multiple pattern may be supplied
* separated by a ";". Requires JDK 1.4 or higher.
*
* @param matchingPattern One or more pattern, separated by ;
* @see etm.contrib.aggregation.filter.RegexEtmFilter
*/
public void setFilterPattern(String matchingPattern) {
filter = new RegexEtmFilter(matchingPattern);
}
public void add(EtmPoint point) {
delegate.add(point);
if (filter == null || filter.matches(point)) {
logMeasurement(point);
}
}
public void flush() {
delegate.flush();
}
public void reset() {
delegate.reset();
}
public void reset(final String symbolicName) {
delegate.reset(symbolicName);
}
public void render(MeasurementRenderer renderer) {
delegate.render(renderer);
}
public void init(EtmMonitorContext aCtx) {
ctx = aCtx;
delegate.init(aCtx);
}
public void start() {
if (formatter == null) {
formatter = new DefaultOutputFormatter();
}
delegate.start();
}
public void stop() {
delegate.stop();
}
/**
* Logs a raw measurement result.
*
* @param aPoint The point to be logged.
*/
protected abstract void logMeasurement(EtmPoint aPoint);
/**
* Get the current monitor context.
*
* @since 1.3.0
* @return Returns the current monitor context.
*/
public EtmMonitorContext getCtx() {
return ctx;
}
}