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 java.io.ByteArrayOutputStream;
020 import java.io.IOException;
021 import java.io.ObjectOutputStream;
022 import java.io.OutputStream;
023
024 import org.apache.logging.log4j.core.Layout;
025 import org.apache.logging.log4j.core.LogEvent;
026 import org.apache.logging.log4j.core.config.Node;
027 import org.apache.logging.log4j.core.config.plugins.Plugin;
028 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
029
030 /**
031 * Formats a {@link LogEvent} in its Java serialized form.
032 */
033 @Plugin(name = "SerializedLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
034 public final class SerializedLayout extends AbstractLayout<LogEvent> {
035
036 private static final long serialVersionUID = 1L;
037
038 private static byte[] serializedHeader;
039
040 static {
041 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
042 try {
043 final ObjectOutputStream oos = new ObjectOutputStream(baos);
044 oos.close();
045 serializedHeader = baos.toByteArray();
046 } catch (final Exception ex) {
047 LOGGER.error("Unable to generate Object stream header", ex);
048 }
049 }
050
051 private SerializedLayout() {
052 super(null, null);
053 }
054
055 /**
056 * Formats a {@link org.apache.logging.log4j.core.LogEvent} as a serialized byte array of the LogEvent object.
057 *
058 * @param event The LogEvent.
059 * @return the formatted LogEvent.
060 */
061 @Override
062 public byte[] toByteArray(final LogEvent event) {
063 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
064 try {
065 final ObjectOutputStream oos = new PrivateObjectOutputStream(baos);
066 try {
067 oos.writeObject(event);
068 oos.reset();
069 } finally {
070 oos.close();
071 }
072 } catch (final IOException ioe) {
073 LOGGER.error("Serialization of LogEvent failed.", ioe);
074 }
075 return baos.toByteArray();
076 }
077
078 /**
079 * Returns the LogEvent.
080 *
081 * @param event The Logging Event.
082 * @return The LogEvent.
083 */
084 @Override
085 public LogEvent toSerializable(final LogEvent event) {
086 return event;
087 }
088
089 /**
090 * Creates a SerializedLayout.
091 * @return A SerializedLayout.
092 */
093 @PluginFactory
094 public static SerializedLayout createLayout() {
095 return new SerializedLayout();
096 }
097
098 @Override
099 public byte[] getHeader() {
100 return serializedHeader;
101 }
102
103 /**
104 * SerializedLayout returns a binary stream.
105 * @return The content type.
106 */
107 @Override
108 public String getContentType() {
109 return "application/octet-stream";
110 }
111
112 /**
113 * The stream header will be written in the Manager so skip it here.
114 */
115 private class PrivateObjectOutputStream extends ObjectOutputStream {
116
117 public PrivateObjectOutputStream(final OutputStream os) throws IOException {
118 super(os);
119 }
120
121 @Override
122 protected void writeStreamHeader() {
123 }
124 }
125 }