Newer
Older
/*
* Copyright 2007 ETH Zuerich, CISD
*
* Licensed 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 ch.systemsx.cisd.common.logging;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.WriterAppender;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
* A <code>WriterAppender</code> extension that buffers its output in a <code>ByteArrayOutputStream</code> until you ask for it by using
* {@link #getLogContent()}.
* <p>
* It internally uses a <code>ByteArrayOutputStream</code> which collect the log output and can return it using {@link #getLogContent()}. It is a good
* idea to reset the log recorder by calling {@link #resetLogContent()} before calling a unit test method.
* </p>
*
* @author Christian Ribeaud
*/
public final class BufferedAppender extends WriterAppender
{
private final ByteArrayOutputStream logRecorder;
private final List<Pattern> patternOfSuppressedLogEvents = new LinkedList<Pattern>();
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
* Constructor with default pattern layout (which is {@link PatternLayout#DEFAULT_CONVERSION_PATTERN}) and {@link Level#DEBUG} as log level.
*/
public BufferedAppender()
{
this(Level.DEBUG);
}
/**
* Constructor with default pattern layout (which is {@link PatternLayout#DEFAULT_CONVERSION_PATTERN}).
*
* @param logLevel
*/
public BufferedAppender(final Level logLevel)
{
this(null, logLevel);
}
public BufferedAppender(final String pattern, final Level logLevel)
{
this(pattern, logLevel, null);
}
/**
* Creates an instance for specified optional layout pattern, log level and regex of the logger name onto which log entries are filtered.
*/
public BufferedAppender(final String patternOrNull, final Level logLevel, final String loggerNameRegex)
{
logRecorder = new ByteArrayOutputStream();
if (loggerNameRegex != null)
{
final Pattern pattern = Pattern.compile(loggerNameRegex);
this.addFilter(new Filter()
{
@Override
public int decide(LoggingEvent event)
{
String loggerName = event.getLoggerName();
return pattern.matcher(loggerName).matches() ? Filter.ACCEPT : Filter.DENY;
}
});
}
setWriter(createWriter(logRecorder));
setLayout(createLayout(patternOrNull));
configureRootLogger();
setThreshold(logLevel);
}
public void addRegexForLoggingEventsToBeDropped(String loggerNameRegex)
{
final Pattern pattern = Pattern.compile(loggerNameRegex);
this.addFilter(new Filter()
{
@Override
public int decide(LoggingEvent event)
{
String loggerName = event.getLoggerName();
return pattern.matcher(loggerName).matches() ? Filter.DENY : Filter.ACCEPT;
}
});
patternOfSuppressedLogEvents.add(Pattern.compile(".*" + loggerNameRegex + ".*"));
}
private final void configureRootLogger()
{
Logger.getRootLogger().addAppender(this);
}
protected Layout createLayout(final String pattern)
{
return new PatternLayout(pattern);
}
/**
* Returns the content of this log appender.
* <p>
* Never returns <code>null</code> but could return an empty string.
* </p>
*/
public final String getLogContent()
{
String content = new String(logRecorder.toByteArray()).trim();
String[] split = content.split("\n");
StringBuilder builder = new StringBuilder();
for (String line : split)
{
if (shouldBeSuppressed(line) == false)
{
builder.append(line).append("\n");
}
}
return builder.toString().trim();
}
private boolean shouldBeSuppressed(String line)
{
for (Pattern pattern : patternOfSuppressedLogEvents)
{
if (pattern.matcher(line).matches())
{
return true;
}
}
return false;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
}
public List<String> getLogLines()
{
return Arrays.asList(getLogContent().split("\n"));
}
public final void resetLogContent()
{
logRecorder.reset();
}
//
// WriterAppender
//
@Override
public final void reset()
{
Logger.getRootLogger().removeAppender(this);
super.reset();
}
//
// Object
//
@Override
public final String toString()
{
return getEncoding();
}
}