
org.apache.log.output.MemoryTarget Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of avalon-logkit Show documentation
Show all versions of avalon-logkit Show documentation
Excalibur's Logkit package
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.log.output;
import org.apache.log.LogEvent;
import org.apache.log.LogTarget;
import org.apache.log.Priority;
/**
* Output LogEvents into an buffer in memory.
* At a later stage these LogEvents can be forwarded or
* pushed to another target. This pushing is triggered
* when buffer is full, the priority of a LogEvent reaches a threshold
* or when another class calls the push method.
*
* This is based on specification of MemoryHandler in Logging JSR47.
*
* @author Avalon Development Team
* @author Peter Donald
*/
public class MemoryTarget
extends AbstractTarget
{
///Buffer for all the LogEvents
private final LogEvent[] m_buffer;
///Priority at which to push LogEvents to next LogTarget
private Priority m_threshold;
///Target to push LogEvents to
private LogTarget m_target;
///Count of used events
private int m_used;
///Position of last element inserted
private int m_index;
///Flag indicating whether it is possible to overite elements in array
private boolean m_overwrite;
/**
* Creation of a new instance of the memory target.
* @param target the target to push LogEvents to
* @param size the event buffer size
* @param threshold the priority at which to push LogEvents to next LogTarget
*/
public MemoryTarget( final LogTarget target,
final int size,
final Priority threshold )
{
m_target = target;
m_buffer = new LogEvent[ size ];
m_threshold = threshold;
open();
}
/**
* Set flag indicating whether it is valid to overwrite memory buffer.
*
* @param overwrite true if buffer should overwrite logevents in buffer, false otherwise
*/
protected synchronized void setOverwrite( final boolean overwrite )
{
m_overwrite = overwrite;
}
/**
* Process a log event, via formatting and outputting it.
*
* @param event the log event
*/
protected synchronized void doProcessEvent( final LogEvent event )
{
//Check if it is full
if( isFull() )
{
if( m_overwrite )
{
m_used--;
}
else
{
getErrorHandler().error( "Memory buffer is full", null, event );
return;
}
}
if( 0 == m_used )
{
m_index = 0;
}
else
{
m_index = ( m_index + 1 ) % m_buffer.length;
}
m_buffer[ m_index ] = event;
m_used++;
if( shouldPush( event ) )
{
push();
}
}
/**
* Check if memory buffer is full.
*
* @return true if buffer is full, false otherwise
*/
public final synchronized boolean isFull()
{
return m_buffer.length == m_used;
}
/**
* Determine if LogEvent should initiate a push to target.
* Subclasses can overide this method to change the conditions
* under which a push occurs.
*
* @param event the incoming LogEvent
* @return true if should push, false otherwise
*/
protected synchronized boolean shouldPush( final LogEvent event )
{
return ( m_threshold.isLowerOrEqual( event.getPriority() ) || isFull() );
}
/**
* Push log events to target.
*/
public synchronized void push()
{
if( null == m_target )
{
getErrorHandler().error( "Can not push events to a null target", null, null );
return;
}
try
{
final int size = m_used;
int base = m_index - m_used + 1;
if( base < 0 )
{
base += m_buffer.length;
}
for( int i = 0; i < size; i++ )
{
final int index = ( base + i ) % m_buffer.length;
//process event in buffer
m_target.processEvent( m_buffer[ index ] );
//help GC
m_buffer[ index ] = null;
m_used--;
}
}
catch( final Throwable throwable )
{
getErrorHandler().error( "Unknown error pushing events.", throwable, null );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy