Skip to content

Instantly share code, notes, and snippets.

@kengelke
Created January 29, 2013 14:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kengelke/4664612 to your computer and use it in GitHub Desktop.
Save kengelke/4664612 to your computer and use it in GitHub Desktop.
A custom log appender for log4j that allows one to catch log messages generated by log4j from within the application.
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.log4j.spi.LoggingEvent;
public class CachingSingletonAppender {
private static final CachingSingletonAppender theInstance = new CachingSingletonAppender();
private List<LogEventListener> listeners;
private List<LogEvent> eventCache;
private CachingSingletonAppender() {
listeners = new ArrayList<>();
eventCache = new ArrayList<>();
}
public static CachingSingletonAppender getInstance() {
return theInstance;
}
public void append(LoggingEvent le) {
LogEvent event = new LogEvent(le.getLevel().toString(), le.getMessage().toString(), new Date(le.getTimeStamp()));
if (!listeners.isEmpty()) {
for (LogEventListener listener : listeners) {
listener.handle(event);
}
} else {
eventCache.add(event);
}
}
public void addLoggingEventListener(LogEventListener listener) {
listeners.add(listener);
if (listeners.size() == 1 && !eventCache.isEmpty()) {
sendAndClearCache();
}
}
public void removeLoggingEventListener(LogEventListener listener) {
listeners.remove(listener);
}
synchronized private void sendAndClearCache() {
for (LogEventListener listener : listeners) {
for (LogEvent event : eventCache) {
listener.handle(event);
}
}
eventCache.clear();
}
}
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class InternalAppenderWrapper extends AppenderSkeleton {
private CachingSingletonAppender appender = CachingSingletonAppender.getInstance();
@Override
protected void append(LoggingEvent le) {
appender.append(le);
}
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return false;
}
}
log4j.rootLogger=INFO, internal
log4j.appender.internal=InternalAppenderWrapper
import java.util.Date;
public class LogEvent {
private String level;
private String message;
private Date timestamp;
public LogEvent() {
}
public LogEvent(String level, String message, Date timestamp) {
this.level = level;
this.message = message;
this.timestamp = timestamp;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
}
public interface LogEventListener {
void handle(LogEvent event);
}
@gaurav9822
Copy link

is it designed for log4jv1 or log4j2?

@Nocarz
Copy link

Nocarz commented May 24, 2019

@gaurav9822
basing on package name "org.apache.log4j" it's log4jv1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment