001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.spi; 015 016import static org.junit.Assert.assertEquals; 017import static org.junit.Assert.assertNotNull; 018import static org.junit.Assert.assertNull; 019 020import java.io.ByteArrayInputStream; 021import java.io.ByteArrayOutputStream; 022import java.io.IOException; 023import java.io.ObjectInputStream; 024import java.io.ObjectOutputStream; 025import java.io.Serializable; 026import java.util.Map; 027 028import org.junit.After; 029import org.junit.Before; 030import org.junit.Test; 031import org.slf4j.MDC; 032import org.slf4j.Marker; 033import org.slf4j.MarkerFactory; 034 035import ch.qos.logback.classic.Level; 036import ch.qos.logback.classic.Logger; 037import ch.qos.logback.classic.LoggerContext; 038import ch.qos.logback.classic.net.LoggingEventPreSerializationTransformer; 039import ch.qos.logback.classic.net.server.HardenedLoggingEventInputStream; 040import ch.qos.logback.core.spi.PreSerializationTransformer; 041 042public class LoggingEventSerializationTest { 043 044 LoggerContext loggerContext; 045 Logger logger; 046 047 ByteArrayOutputStream bos; 048 ObjectOutputStream oos; 049 ObjectInputStream inputStream; 050 PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer(); 051 052 @Before 053 public void setUp() throws Exception { 054 loggerContext = new LoggerContext(); 055 loggerContext.setName("testContext"); 056 logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME); 057 // create the byte output stream 058 bos = new ByteArrayOutputStream(); 059 oos = new ObjectOutputStream(bos); 060 } 061 062 @After 063 public void tearDown() throws Exception { 064 loggerContext = null; 065 logger = null; 066 oos.close(); 067 } 068 069 @Test 070 public void smoke() throws Exception { 071 ILoggingEvent event = createLoggingEvent(); 072 ILoggingEvent remoteEvent = writeAndRead(event); 073 checkForEquality(event, remoteEvent); 074 } 075 076 @Test 077 public void context() throws Exception { 078 loggerContext.putProperty("testKey", "testValue"); 079 ILoggingEvent event = createLoggingEvent(); 080 ILoggingEvent remoteEvent = writeAndRead(event); 081 checkForEquality(event, remoteEvent); 082 083 assertNotNull(remoteEvent.getLoggerName()); 084 assertEquals(Logger.ROOT_LOGGER_NAME, remoteEvent.getLoggerName()); 085 086 LoggerContextVO loggerContextRemoteView = remoteEvent.getLoggerContextVO(); 087 assertNotNull(loggerContextRemoteView); 088 assertEquals("testContext", loggerContextRemoteView.getName()); 089 Map<String, String> props = loggerContextRemoteView.getPropertyMap(); 090 assertNotNull(props); 091 assertEquals("testValue", props.get("testKey")); 092 } 093 094 @Test 095 public void MDC() throws Exception { 096 MDC.put("key", "testValue"); 097 ILoggingEvent event = createLoggingEvent(); 098 ILoggingEvent remoteEvent = writeAndRead(event); 099 checkForEquality(event, remoteEvent); 100 Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap(); 101 assertEquals("testValue", MDCPropertyMap.get("key")); 102 } 103 104 @Test 105 public void updatedMDC() throws Exception { 106 MDC.put("key", "testValue"); 107 ILoggingEvent event1 = createLoggingEvent(); 108 Serializable s1 = pst.transform(event1); 109 oos.writeObject(s1); 110 111 MDC.put("key", "updatedTestValue"); 112 ILoggingEvent event2 = createLoggingEvent(); 113 Serializable s2 = pst.transform(event2); 114 oos.writeObject(s2); 115 116 // create the input stream based on the ouput stream 117 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 118 inputStream = new ObjectInputStream(bis); 119 120 // skip over one object 121 inputStream.readObject(); 122 ILoggingEvent remoteEvent2 = (ILoggingEvent) inputStream.readObject(); 123 124 // We observe the second logging event. It should provide us with 125 // the updated MDC property. 126 Map<String, String> MDCPropertyMap = remoteEvent2.getMDCPropertyMap(); 127 assertEquals("updatedTestValue", MDCPropertyMap.get("key")); 128 } 129 130 @Test 131 public void nonSerializableParameters() throws Exception { 132 LoggingEvent event = createLoggingEvent(); 133 LuckyCharms lucky0 = new LuckyCharms(0); 134 event.setArgumentArray(new Object[] { lucky0, null }); 135 ILoggingEvent remoteEvent = writeAndRead(event); 136 checkForEquality(event, remoteEvent); 137 138 Object[] aa = remoteEvent.getArgumentArray(); 139 assertNotNull(aa); 140 assertEquals(2, aa.length); 141 assertEquals("LC(0)", aa[0]); 142 assertNull(aa[1]); 143 } 144 145 @Test 146 public void testWithThrowable() throws Exception { 147 Throwable throwable = new Throwable("just testing"); 148 LoggingEvent event = createLoggingEventWithThrowable(throwable); 149 ILoggingEvent remoteEvent = writeAndRead(event); 150 checkForEquality(event, remoteEvent); 151 } 152 153 154 @Test 155 public void testWithMarker() throws Exception { 156 Marker marker = MarkerFactory.getMarker("A_MARKER"); 157 LoggingEvent event = createLoggingEvent(); 158 159 160 event.setMarker(marker); 161 assertNotNull(event.getMarker()); 162 163 ILoggingEvent remoteEvent = writeAndRead(event); 164 checkForEquality(event, remoteEvent); 165 166 assertNotNull(remoteEvent.getMarker()); 167 assertEquals(marker, remoteEvent.getMarker()); 168 } 169 170 @Test 171 public void testWithTwoMarkers() throws Exception { 172 Marker marker = MarkerFactory.getMarker("A_MARKER"); 173 Marker marker2 = MarkerFactory.getMarker("B_MARKER"); 174 marker.add(marker2); 175 LoggingEvent event = createLoggingEvent(); 176 177 event.setMarker(marker); 178 assertNotNull(event.getMarker()); 179 180 ILoggingEvent remoteEvent = writeAndRead(event); 181 checkForEquality(event, remoteEvent); 182 183 assertNotNull(remoteEvent.getMarker()); 184 assertEquals(marker, remoteEvent.getMarker()); 185 } 186 187 @Test 188 public void testWithCallerData() throws Exception { 189 LoggingEvent event = createLoggingEvent(); 190 event.getCallerData(); 191 ILoggingEvent remoteEvent = writeAndRead(event); 192 checkForEquality(event, remoteEvent); 193 } 194 195 @Test 196 public void extendendeThrowable() throws Exception { 197 LoggingEvent event = createLoggingEvent(); 198 Throwable throwable = new Throwable("just testing"); 199 ThrowableProxy tp = new ThrowableProxy(throwable); 200 event.setThrowableProxy(tp); 201 tp.calculatePackagingData(); 202 ILoggingEvent remoteEvent = writeAndRead(event); 203 checkForEquality(event, remoteEvent); 204 } 205 206 @Test 207 public void serializeLargeArgs() throws Exception { 208 209 StringBuilder buffer = new StringBuilder(); 210 for (int i = 0; i < 100000; i++) { 211 buffer.append("X"); 212 } 213 String largeString = buffer.toString(); 214 Object[] argArray = new Object[] { new LuckyCharms(2), largeString }; 215 216 LoggingEvent event = createLoggingEvent(); 217 event.setArgumentArray(argArray); 218 219 ILoggingEvent remoteEvent = writeAndRead(event); 220 checkForEquality(event, remoteEvent); 221 Object[] aa = remoteEvent.getArgumentArray(); 222 assertNotNull(aa); 223 assertEquals(2, aa.length); 224 String stringBack = (String) aa[1]; 225 assertEquals(largeString, stringBack); 226 } 227 228 private LoggingEvent createLoggingEvent() { 229 return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, "test message", null, null); 230 } 231 232 private LoggingEvent createLoggingEventWithThrowable(Throwable t) { 233 return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, "test message", t, null); 234 } 235 236 private void checkForEquality(ILoggingEvent original, ILoggingEvent afterSerialization) { 237 assertEquals(original.getLevel(), afterSerialization.getLevel()); 238 assertEquals(original.getFormattedMessage(), afterSerialization.getFormattedMessage()); 239 assertEquals(original.getMessage(), afterSerialization.getMessage()); 240 241 System.out.println(); 242 243 ThrowableProxyVO witness = ThrowableProxyVO.build(original.getThrowableProxy()); 244 assertEquals(witness, afterSerialization.getThrowableProxy()); 245 246 } 247 248 private ILoggingEvent writeAndRead(ILoggingEvent event) throws IOException, ClassNotFoundException { 249 Serializable ser = pst.transform(event); 250 oos.writeObject(ser); 251 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 252 inputStream = new HardenedLoggingEventInputStream(bis); 253 254 return (ILoggingEvent) inputStream.readObject(); 255 } 256 257}