| /* |
| * 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.logging.log4j.core.layout; |
| |
| import java.io.Serializable; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.logging.log4j.Logger; |
| import org.apache.logging.log4j.core.Layout; |
| import org.apache.logging.log4j.core.LogEvent; |
| import org.apache.logging.log4j.core.config.Configuration; |
| import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; |
| import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; |
| import org.apache.logging.log4j.status.StatusLogger; |
| |
| /** |
| * Abstract base class for Layouts. |
| * |
| * @param <T> |
| * The Class that the Layout will format the LogEvent into. |
| */ |
| public abstract class AbstractLayout<T extends Serializable> implements Layout<T> { |
| |
| /** |
| * Subclasses can extend this abstract Builder. |
| * |
| * @param <B> The type to build. |
| */ |
| public abstract static class Builder<B extends Builder<B>> { |
| |
| @PluginConfiguration |
| private Configuration configuration; |
| |
| @PluginBuilderAttribute |
| private byte[] footer; |
| |
| @PluginBuilderAttribute |
| private byte[] header; |
| |
| @SuppressWarnings("unchecked") |
| public B asBuilder() { |
| return (B) this; |
| } |
| |
| public Configuration getConfiguration() { |
| return configuration; |
| } |
| |
| public byte[] getFooter() { |
| return footer; |
| } |
| |
| public byte[] getHeader() { |
| return header; |
| } |
| |
| public B setConfiguration(final Configuration configuration) { |
| this.configuration = configuration; |
| return asBuilder(); |
| } |
| |
| public B setFooter(final byte[] footer) { |
| this.footer = footer; |
| return asBuilder(); |
| } |
| |
| public B setHeader(final byte[] header) { |
| this.header = header; |
| return asBuilder(); |
| } |
| |
| } |
| |
| /** |
| * Allow subclasses access to the status logger without creating another instance. |
| */ |
| protected static final Logger LOGGER = StatusLogger.getLogger(); |
| |
| /** |
| * The current Configuration. |
| */ |
| protected final Configuration configuration; |
| |
| /** |
| * The number of events successfully processed by this layout. |
| */ |
| protected long eventCount; |
| |
| /** |
| * The footer to add when the stream is closed. May be null. |
| */ |
| protected final byte[] footer; |
| |
| /** |
| * The header to include when the stream is opened. May be null. |
| */ |
| protected final byte[] header; |
| |
| /** |
| * Constructs a layout with an optional header and footer. |
| * |
| * @param header |
| * The header to include when the stream is opened. May be null. |
| * @param footer |
| * The footer to add when the stream is closed. May be null. |
| * @deprecated Use {@link #AbstractLayout(Configuration, byte[], byte[])} |
| */ |
| @Deprecated |
| public AbstractLayout(final byte[] header, final byte[] footer) { |
| this(null, header, footer); |
| } |
| |
| /** |
| * Constructs a layout with an optional header and footer. |
| * |
| * @param configuration |
| * The configuration |
| * @param header |
| * The header to include when the stream is opened. May be null. |
| * @param footer |
| * The footer to add when the stream is closed. May be null. |
| */ |
| public AbstractLayout(final Configuration configuration, final byte[] header, final byte[] footer) { |
| super(); |
| this.configuration = configuration; |
| this.header = header; |
| this.footer = footer; |
| } |
| |
| public Configuration getConfiguration() { |
| return configuration; |
| } |
| |
| @Override |
| public Map<String, String> getContentFormat() { |
| return new HashMap<>(); |
| } |
| |
| /** |
| * Returns the footer, if one is available. |
| * |
| * @return A byte array containing the footer. |
| */ |
| @Override |
| public byte[] getFooter() { |
| return footer; |
| } |
| |
| /** |
| * Returns the header, if one is available. |
| * |
| * @return A byte array containing the header. |
| */ |
| @Override |
| public byte[] getHeader() { |
| return header; |
| } |
| |
| protected void markEvent() { |
| eventCount++; |
| } |
| |
| /** |
| * Encodes the specified source LogEvent to some binary representation and writes the result to the specified |
| * destination. |
| * <p> |
| * The default implementation of this method delegates to the {@link #toByteArray(LogEvent)} method which allocates |
| * temporary objects. |
| * </p><p> |
| * Subclasses can override this method to provide a garbage-free implementation. For text-based layouts, |
| * {@code AbstractStringLayout} provides various convenience methods to help with this: |
| * </p> |
| * <pre>@Plugin(name = "MyLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true) |
| * public final class MyLayout extends AbstractStringLayout { |
| * @Override |
| * public void encode(LogEvent event, ByteBufferDestination destination) { |
| * StringBuilder text = getStringBuilder(); |
| * convertLogEventToText(event, text); |
| * getStringBuilderEncoder().encode(text, destination); |
| * } |
| * |
| * private void convertLogEventToText(LogEvent event, StringBuilder destination) { |
| * ... // append a text representation of the log event to the StringBuilder |
| * } |
| * } |
| * </pre> |
| * |
| * @param event the LogEvent to encode. |
| * @param destination holds the ByteBuffer to write into. |
| * @see AbstractStringLayout#getStringBuilder() |
| * @see AbstractStringLayout#getStringBuilderEncoder() |
| */ |
| @Override |
| public void encode(final LogEvent event, final ByteBufferDestination destination) { |
| final byte[] data = toByteArray(event); |
| destination.writeBytes(data, 0, data.length); |
| } |
| } |