001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache license, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License. You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the license for the specific language governing permissions and
015     * limitations under the license.
016     */
017    package org.apache.logging.log4j.core.layout;
018    
019    import org.apache.logging.log4j.core.LogEvent;
020    import org.apache.logging.log4j.core.config.plugins.Plugin;
021    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
022    
023    import java.io.ByteArrayOutputStream;
024    import java.io.IOException;
025    import java.io.ObjectOutputStream;
026    import java.io.OutputStream;
027    
028    /**
029     * Format a LogEvent in its serialized form.
030     */
031    @Plugin(name = "SerializedLayout", type = "Core", elementType = "layout", printObject = true)
032    public final class SerializedLayout extends AbstractLayout<LogEvent> {
033    
034        private static byte[] header;
035    
036        static {
037            ByteArrayOutputStream baos = new ByteArrayOutputStream();
038            try {
039                ObjectOutputStream oos = new ObjectOutputStream(baos);
040                oos.close();
041                header = baos.toByteArray();
042            } catch (Exception ex) {
043                LOGGER.error("Unable to generate Object stream header", ex);
044            }
045        }
046    
047        private SerializedLayout() {
048        }
049    
050        /**
051         * Formats a {@link org.apache.logging.log4j.core.LogEvent} in conformance with the log4j.dtd.
052         *
053         * @param event The LogEvent.
054         * @return the formatted LogEvent.
055         */
056        public byte[] toByteArray(final LogEvent event) {
057            ByteArrayOutputStream baos = new ByteArrayOutputStream();
058            try {
059                ObjectOutputStream oos = new PrivateObjectOutputStream(baos);
060                try {
061                    oos.writeObject(event);
062                } finally {
063                    oos.close();
064                }
065            } catch (IOException ioe) {
066                LOGGER.error("Serialization of LogEvent failed.", ioe);
067            }
068            return baos.toByteArray();
069        }
070    
071        /**
072         * Returns the LogEvent.
073         *
074         * @param event The Logging Event.
075         * @return The LogEvent.
076         */
077        public LogEvent toSerializable(final LogEvent event) {
078            return event;
079        }
080    
081        /**
082         * Create a SerializedLayout.
083         * @return A SerializedLayout.
084         */
085        @PluginFactory
086        public static SerializedLayout createLayout() {
087    
088            return new SerializedLayout();
089        }
090    
091        @Override
092        public byte[] getHeader() {
093            return header;
094        }
095    
096        /**
097         * The stream header will be written in the Manager so skip it here.
098         */
099        private class PrivateObjectOutputStream extends ObjectOutputStream {
100    
101            public PrivateObjectOutputStream(OutputStream os) throws IOException {
102                super(os);
103            }
104    
105            @Override
106            protected void writeStreamHeader() {
107            }
108        }
109    }