Skip to content

Commit 2668d4e

Browse files
committed
improved logger serialization by removing cruft
1 parent 4011670 commit 2668d4e

File tree

6 files changed

+108
-43
lines changed

6 files changed

+108
-43
lines changed

logback-classic/src/main/java/ch/qos/logback/classic/Logger.java

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Iterator;
2121
import java.util.List;
2222

23+
import ch.qos.logback.classic.spi.LoggerContextVO;
2324
import ch.qos.logback.classic.util.LoggerNameUtil;
2425
import org.slf4j.LoggerFactory;
2526
import org.slf4j.Marker;
@@ -55,22 +56,22 @@ public final class Logger implements org.slf4j.Logger, LocationAwareLogger,
5556
private String name;
5657

5758
// The assigned levelInt of this logger. Can be null.
58-
private Level level;
59+
transient private Level level;
5960

6061
// The effective levelInt is the assigned levelInt and if null, a levelInt is
6162
// inherited form a parent.
62-
private int effectiveLevelInt;
63+
transient private int effectiveLevelInt;
6364

6465
/**
6566
* The parent of this category. All categories have at least one ancestor
6667
* which is the root category.
6768
*/
68-
private Logger parent;
69+
transient private Logger parent;
6970

7071
/**
7172
* The children of this logger. A logger may have zero or more children.
7273
*/
73-
private List<Logger> childrenList;
74+
transient private List<Logger> childrenList;
7475

7576
/**
7677
* It is assumed that once the 'aai' variable is set to a non-null value, it
@@ -92,7 +93,7 @@ public final class Logger implements org.slf4j.Logger, LocationAwareLogger,
9293
* <p>
9394
* 4) AppenderAttachableImpl is thread safe
9495
*/
95-
private transient AppenderAttachableImpl<ILoggingEvent> aai;
96+
transient private AppenderAttachableImpl<ILoggingEvent> aai;
9697
/**
9798
* Additivity is set to true by default, that is children inherit the
9899
* appenders of their ancestors by default. If this variable is set to
@@ -101,18 +102,14 @@ public final class Logger implements org.slf4j.Logger, LocationAwareLogger,
101102
* its appenders, unless the children have their additivity flag set to
102103
* <code>false</code> too. See the user manual for more details.
103104
*/
104-
private boolean additive = true;
105+
transient private boolean additive = true;
105106

106107
final transient LoggerContext loggerContext;
107-
// loggerRemoteView cannot be final because it may change as a consequence
108-
// of changes in LoggerContext
109-
LoggerRemoteView loggerRemoteView;
110108

111109
Logger(String name, Logger parent, LoggerContext loggerContext) {
112110
this.name = name;
113111
this.parent = parent;
114112
this.loggerContext = loggerContext;
115-
buildRemoteView();
116113
}
117114

118115
public Level getEffectiveLevel() {
@@ -789,14 +786,6 @@ public LoggerContext getLoggerContext() {
789786
return loggerContext;
790787
}
791788

792-
public LoggerRemoteView getLoggerRemoteView() {
793-
return loggerRemoteView;
794-
}
795-
796-
void buildRemoteView() {
797-
this.loggerRemoteView = new LoggerRemoteView(name, loggerContext);
798-
}
799-
800789
public void log(Marker marker, String fqcn, int levelInt, String message,
801790
Object[] argArray, Throwable t) {
802791
Level level = Level.fromLocationAwareLoggerInteger(levelInt);

logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,20 @@ void initEvaluatorMap() {
8484
* A new instance of LoggerContextRemoteView needs to be created each time the
8585
* name or propertyMap (including keys or values) changes.
8686
*/
87-
private void syncRemoteView() {
87+
private void updateLoggerContextVO() {
8888
loggerContextRemoteView = new LoggerContextVO(this);
89-
for (Logger logger : loggerCache.values()) {
90-
logger.buildRemoteView();
91-
}
9289
}
9390

9491
@Override
9592
public void putProperty(String key, String val) {
9693
super.putProperty(key, val);
97-
syncRemoteView();
94+
updateLoggerContextVO();
9895
}
9996

10097
@Override
10198
public void setName(String name) {
10299
super.setName(name);
103-
syncRemoteView();
100+
updateLoggerContextVO();
104101
}
105102

106103
public final Logger getLogger(final Class clazz) {

logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextVO.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public LoggerContextVO(LoggerContext lc) {
4545
this.name = lc.getName();
4646
this.propertyMap = lc.getCopyOfPropertyMap();
4747
this.birthTime = lc.getBirthTime();
48-
4948
}
5049

5150
public LoggerContextVO(String name, Map<String,String> propertyMap, long birthTime) {
@@ -94,6 +93,9 @@ public int hashCode() {
9493
int result = name != null ? name.hashCode() : 0;
9594
result = 31 * result + (propertyMap != null ? propertyMap.hashCode() : 0);
9695
result = 31 * result + (int) (birthTime ^ (birthTime >>> 32));
96+
97+
System.out.println("LoggerContextVO"+System.identityHashCode(this)+" hashcode:"+result);
98+
9799
return result;
98100
}
99101
}

logback-classic/src/test/java/ch/qos/logback/classic/LoggerSerializationTest.java

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,15 @@
1313
*/
1414
package ch.qos.logback.classic;
1515

16-
import java.io.ByteArrayInputStream;
17-
import java.io.ByteArrayOutputStream;
18-
import java.io.IOException;
19-
import java.io.ObjectInputStream;
20-
import java.io.ObjectOutputStream;
16+
import java.io.*;
2117

2218
import org.junit.After;
2319
import org.junit.Before;
2420
import org.junit.Test;
2521
import org.slf4j.LoggerFactory;
2622

23+
import static org.junit.Assert.assertTrue;
24+
2725
public class LoggerSerializationTest {
2826

2927
// force SLF4J initialization for subsequent Logger readResolce ooperaiton
@@ -50,25 +48,103 @@ public void tearDown() throws Exception {
5048
lc = null;
5149
logger = null;
5250
}
53-
51+
5452
@Test
55-
public void serialization() throws IOException, ClassNotFoundException {
53+
public void basicSerialization() throws IOException, ClassNotFoundException {
5654
Foo foo = new Foo(logger);
5755
foo.doFoo();
5856
Foo fooBack = writeAndRead(foo);
5957
fooBack.doFoo();
6058
}
6159

62-
private Foo writeAndRead(Foo foo) throws IOException,
63-
ClassNotFoundException {
64-
oos.writeObject(foo);
60+
@Test
61+
public void deepTreeSerialization() throws IOException {
62+
// crate a tree of loggers under "aaaaaaaa"
63+
Logger a = lc.getLogger("aaaaaaaa");
64+
lc.getLogger("aaaaaaaa.a");
65+
lc.getLogger("aaaaaaaa.a.a");
66+
lc.getLogger("aaaaaaaa.a.b");
67+
lc.getLogger("aaaaaaaa.a.c");
68+
lc.getLogger("aaaaaaaa.a.d");
69+
70+
lc.getLogger("aaaaaaaa.b");
71+
lc.getLogger("aaaaaaaa.b.a");
72+
lc.getLogger("aaaaaaaa.b.b");
73+
lc.getLogger("aaaaaaaa.b.c");
74+
lc.getLogger("aaaaaaaa.b.d");
75+
76+
lc.getLogger("aaaaaaaa.c");
77+
lc.getLogger("aaaaaaaa.c.a");
78+
lc.getLogger("aaaaaaaa.c.b");
79+
lc.getLogger("aaaaaaaa.c.c");
80+
lc.getLogger("aaaaaaaa.c.d");
81+
82+
lc.getLogger("aaaaaaaa.d");
83+
lc.getLogger("aaaaaaaa.d.a");
84+
lc.getLogger("aaaaaaaa.d.b");
85+
lc.getLogger("aaaaaaaa.d.c");
86+
lc.getLogger("aaaaaaaa.d.d");
87+
88+
Logger b = lc.getLogger("b");
89+
90+
writeObject(oos, a);
91+
oos.close();
92+
int sizeA = bos.size();
93+
94+
bos = new ByteArrayOutputStream();
95+
oos = new ObjectOutputStream(bos);
96+
97+
writeObject(oos, b);
98+
oos.close();
99+
int sizeB = bos.size();
100+
101+
assertTrue("serialized logger should be less than 100 bytes", sizeA < 100);
102+
// logger tree should not influnce serialization
103+
assertTrue("serialized loggers should be nearly the same size a:" + sizeA + ", sizeB:" + sizeB, (sizeA - sizeB) < 10);
104+
}
105+
106+
@Test
107+
public void secondObjectShouldAddLittleToLength() throws IOException {
108+
Logger a = lc.getLogger("a");
109+
Logger b = lc.getLogger("b");
110+
111+
writeObject(oos, a);
112+
int sizeA = bos.size();
65113
oos.flush();
114+
writeObject(oos,b);
115+
int sizeAB = bos.size();
66116
oos.close();
117+
118+
System.out.println("sizeA:"+sizeA);
119+
System.out.println("sizeAB:"+sizeAB);
120+
System.out.println("diff:"+(sizeAB-sizeA));
121+
122+
FileOutputStream fos = new FileOutputStream("/tmp/a.ser");
123+
fos.write(bos.toByteArray());
124+
fos.close();
125+
126+
}
127+
128+
private Foo writeAndRead(Foo foo) throws IOException,
129+
ClassNotFoundException {
130+
writeObject(oos, foo);
67131
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
68132
inputStream = new ObjectInputStream(bis);
69-
70-
Foo fooBack = (Foo) inputStream.readObject();
133+
Foo fooBack = readFooObject(inputStream);
71134
inputStream.close();
72135
return fooBack;
73136
}
137+
138+
Foo readFooObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
139+
return (Foo) readObject(inputStream);
140+
}
141+
private Object readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
142+
return inputStream.readObject();
143+
}
144+
145+
private void writeObject(ObjectOutputStream oos, Object o) throws IOException {
146+
oos.writeObject(o);
147+
oos.flush();
148+
oos.close();
149+
}
74150
}

logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventWithParametersBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public class LoggingEventWithParametersBuilder implements Builder<LoggingEvent>
2222

2323
final String MSG = "aaaaabbbbbcccc {} cdddddaaaaabbbbbcccccdddddaaaa {}";
2424

25-
private Logger logger = new LoggerContext()
26-
.getLogger(Logger.ROOT_LOGGER_NAME);
25+
LoggerContext loggerContext = new LoggerContext();
26+
private Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
2727

2828
public LoggingEvent build(int i) {
2929

@@ -42,7 +42,7 @@ public LoggingEvent build(int i) {
4242
le.getFormattedMessage();
4343
le.setLevel(Level.DEBUG);
4444
le.setLoggerName(logger.getName());
45-
le.setLoggerContextRemoteView(logger.getLoggerRemoteView().getLoggerContextView());
45+
le.setLoggerContextRemoteView(loggerContext.getLoggerContextRemoteView());
4646
le.setThreadName("threadName");
4747
return le;
4848
}

logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventBuilder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@
2020

2121
public class TrivialLoggingEventBuilder implements Builder {
2222

23-
private Logger logger = new LoggerContext()
24-
.getLogger(Logger.ROOT_LOGGER_NAME);
23+
LoggerContext loggerContext = new LoggerContext();
24+
25+
private Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
2526

2627
public Object build(int i) {
2728
LoggingEvent le = new LoggingEvent();
2829
le.setTimeStamp(System.currentTimeMillis());
2930
le.setLevel(Level.DEBUG);
3031
le.setLoggerName(logger.getName());
31-
le.setLoggerContextRemoteView(logger.getLoggerRemoteView().getLoggerContextView());
32+
le.setLoggerContextRemoteView(loggerContext.getLoggerContextRemoteView());
3233
le.setMessage(MSG_PREFIX);
3334
le.setThreadName("threadName");
3435
return le;

0 commit comments

Comments
 (0)