Created
May 29, 2016 12:28
-
-
Save remkop/715fcd6035c4f798c264e21450106399 to your computer and use it in GitHub Desktop.
Example layout for logging ByteBuffers straight to disk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.ByteBuffer; | |
import org.apache.logging.log4j.core.Layout; | |
import org.apache.logging.log4j.core.LogEvent; | |
import org.apache.logging.log4j.core.config.Node; | |
import org.apache.logging.log4j.core.config.plugins.Plugin; | |
import org.apache.logging.log4j.core.config.plugins.PluginFactory; | |
/** | |
* Layout for writing ObjectMessages containing a ByteBuffer to the appender. | |
* The ByteBuffer is expected to be ready for reading, with its current position at the start of the data, | |
* and its limit at the end of the data. | |
*/ | |
@Plugin(name = "ByteBufferMessageLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true) | |
public final class ByteBufferMessageLayout extends AbstractLayout<byte[]> { | |
private ByteBufferMessageLayout() { | |
super(null, null, null); | |
} | |
/** | |
* Creates a ByteBufferMessageLayout. | |
* @return A ByteBufferMessageLayout. | |
*/ | |
@PluginFactory | |
public static ByteBufferMessageLayout createLayout() { | |
return new ByteBufferMessageLayout(); | |
} | |
/** | |
* Extracts and logs the ByteBuffer from the LogEvent message. | |
* Does nothing if the message payload is not a ByteBuffer. | |
* <p> | |
* The ByteBuffer is expected to be ready for reading, with its current | |
* position at the start of the data, and its limit at the end of the data. | |
* </p> | |
* | |
* @param event The LogEvent. | |
* @param destination the destination to write the data to | |
*/ | |
@Override | |
public void encode(final LogEvent event, final ByteBufferDestination destination) { | |
final ByteBuffer src = extractByteBuffer(event); | |
if (src != null) { | |
ByteBuffer dest = destination.getByteBuffer(); | |
int todo = src.remaining(); | |
int pos = src.position(); | |
while (todo > 0) { | |
if (dest.remaining() < todo) { | |
dest = destination.drain(dest); | |
} | |
final int count = Math.min(dest.remaining(), src.remaining()); | |
src.position(pos); | |
src.limit(pos + count); | |
dest.put(src); | |
todo -= count; | |
pos += count; | |
} | |
} | |
} | |
private ByteBuffer extractByteBuffer(final LogEvent logEvent) { | |
final Object[] params = logEvent.getMessage().getParameters(); | |
if (params[0] instanceof ByteBuffer) { | |
return (ByteBuffer) params[0]; | |
} | |
return null; | |
} | |
/** | |
* Fallback layout method used by appenders if | |
* {@link org.apache.logging.log4j.core.util.Constants#ENABLE_DIRECT_ENCODERS} is set to false. | |
* | |
* @param event The Logging Event. | |
* @return the data to write to the appender | |
*/ | |
@Override | |
public byte[] toByteArray(final LogEvent event) { | |
final ByteBuffer byteBuffer = extractByteBuffer(event); | |
if (byteBuffer == null) { | |
return new byte[0]; | |
} | |
if (byteBuffer.hasArray() && byteBuffer.remaining() == byteBuffer.capacity()) { | |
return byteBuffer.array(); | |
} | |
final byte[] result = new byte[byteBuffer.remaining()]; | |
byteBuffer.get(result); | |
return result; | |
} | |
// not called | |
@Override | |
public byte[] toSerializable(final LogEvent event) { | |
return toByteArray(event); | |
} | |
/** | |
* ByteBufferMessageLayout returns a binary stream. | |
* @return The content type. | |
*/ | |
@Override | |
public String getContentType() { | |
return "application/octet-stream"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment