Skip to content

Commit 564451b

Browse files
committed
Add source for blog
1 parent 34e25a0 commit 564451b

File tree

6 files changed

+236
-0
lines changed

6 files changed

+236
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Extending Log4j2 Demo
2+
This project code accompanies a blog found at
3+
4+
https://andrew-flower.com/blog/Create_Custom_Log4j_Plugins
5+
6+
It demos a method of extending Log4j2 using Converters as well as a
7+
method for testing the converter
8+
9+
## Running the test
10+
Type the following command to run the tests using Maven.
11+
You will need Maven installed of course
12+
```
13+
mvn install
14+
```

pom.xml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.andrew_flower.demo</groupId>
8+
<artifactId>blog-extending-log4j2</artifactId>
9+
<version>1.0.0</version>
10+
11+
<dependencies>
12+
<dependency>
13+
<groupId>org.apache.logging.log4j</groupId>
14+
<artifactId>log4j-api</artifactId>
15+
<version>2.1</version>
16+
</dependency>
17+
<dependency>
18+
<groupId>org.apache.logging.log4j</groupId>
19+
<artifactId>log4j-core</artifactId>
20+
<version>2.1</version>
21+
</dependency>
22+
<dependency>
23+
<groupId>junit</groupId>
24+
<artifactId>junit</artifactId>
25+
<version>4.9</version>
26+
<scope>test</scope>
27+
</dependency>
28+
</dependencies>
29+
30+
<repositories>
31+
<repository>
32+
<id>central</id>
33+
<url>http://repo1.maven.org/maven2/</url>
34+
</repository>
35+
</repositories>
36+
</project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.andrew_flower.example;
2+
3+
/**
4+
* Created on 15/2/20.
5+
*
6+
* @author rewolf
7+
*/
8+
public class MythicalApplicationRequestHandler {
9+
private static MythicalApplicationRequestHandler instance = null;
10+
11+
public synchronized static MythicalApplicationRequestHandler getInstance() {
12+
if (instance == null) {
13+
instance = new MythicalApplicationRequestHandler();
14+
}
15+
return instance;
16+
}
17+
18+
public synchronized static void setInstance(MythicalApplicationRequestHandler instance) {
19+
MythicalApplicationRequestHandler.instance = instance;
20+
}
21+
22+
public String getCurrentRequestId() {
23+
return "abcd-efgh-1234-5678";
24+
}
25+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.andrew_flower.example;
2+
3+
import org.apache.logging.log4j.core.LogEvent;
4+
import org.apache.logging.log4j.core.config.plugins.Plugin;
5+
import org.apache.logging.log4j.core.pattern.*;
6+
7+
/**
8+
* @author rewolf
9+
*/
10+
@Plugin(name = "ReqIdConverter", category = "Converter")
11+
@ConverterKeys({"reqId"})
12+
public class ReqIdConverter extends LogEventPatternConverter {
13+
protected ReqIdConverter(String name, String style) {
14+
super(name, style);
15+
}
16+
17+
public static ReqIdConverter newInstance(String[] options) {
18+
return new ReqIdConverter("reqId", "reqId");
19+
}
20+
21+
@Override
22+
public void format(LogEvent event, StringBuilder toAppendTo) {
23+
toAppendTo.append(getReqId());
24+
}
25+
26+
protected String getReqId() {
27+
String reqId = MythicalApplicationRequestHandler.getInstance().getCurrentRequestId();
28+
if (reqId == null) {
29+
reqId = "-";
30+
}
31+
return reqId;
32+
}
33+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.andrew_flower.example;
2+
3+
import org.apache.logging.log4j.*;
4+
import org.apache.logging.log4j.core.*;
5+
import org.apache.logging.log4j.core.appender.*;
6+
import org.apache.logging.log4j.core.config.*;
7+
import org.apache.logging.log4j.core.layout.PatternLayout;
8+
9+
import java.io.*;
10+
11+
/**
12+
* @author rewolf
13+
*/
14+
public class StringAppender extends AbstractOutputStreamAppender<StringAppender.StringOutputStreamManager> {
15+
static LoggerContext context = (LoggerContext) LogManager.getContext(false);
16+
static Configuration configuration = context.getConfiguration();
17+
StringOutputStreamManager manager;
18+
19+
private StringAppender(String name, Layout<? extends Serializable> layout, Filter filter, StringOutputStreamManager manager, boolean ignoreExceptions, boolean immediateFlush) {
20+
super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
21+
this.manager = manager;
22+
}
23+
24+
public static StringAppender createStringAppender(String nullablePatternString) {
25+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
26+
PatternLayout layout;
27+
if (nullablePatternString == null) {
28+
layout = PatternLayout.createDefaultLayout();
29+
} else {
30+
layout = PatternLayout.createLayout(nullablePatternString, configuration, null, null, true, false, null, null);
31+
}
32+
33+
return new StringAppender(
34+
"StringAppender",
35+
layout,
36+
null,
37+
new StringOutputStreamManager(outputStream, "StringStream", layout),
38+
false,
39+
true);
40+
}
41+
42+
public void addToLogger(String loggerName, Level level) {
43+
LoggerConfig loggerConfig = configuration.getLoggerConfig(loggerName);
44+
loggerConfig.addAppender(this, level, null);
45+
context.updateLoggers();
46+
}
47+
48+
public void removeFromLogger(String loggerName) {
49+
LoggerConfig loggerConfig = configuration.getLoggerConfig(loggerName);
50+
loggerConfig.removeAppender("StringAppender");
51+
context.updateLoggers();
52+
}
53+
54+
public String getOutput() {
55+
manager.flush();
56+
return new String(manager.getStream().toByteArray());
57+
}
58+
59+
/**
60+
* StringOutputStreamManager to manage an in memory byte-stream representing our stream
61+
*/
62+
protected static class StringOutputStreamManager extends OutputStreamManager {
63+
ByteArrayOutputStream stream;
64+
65+
protected StringOutputStreamManager(ByteArrayOutputStream os, String streamName, Layout<?> layout) {
66+
super(os, streamName, layout);
67+
stream = os;
68+
}
69+
70+
public ByteArrayOutputStream getStream() {
71+
return stream;
72+
}
73+
}
74+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.andrew_flower.example;
2+
3+
4+
import org.apache.logging.log4j.Level;
5+
import org.apache.logging.log4j.LogManager;
6+
import org.apache.logging.log4j.Logger;
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
10+
import static org.junit.Assert.assertEquals;
11+
12+
/**
13+
* @author rewolf
14+
*/
15+
public class LogConverterTest {
16+
private final static String STUB_REQ_ID = "Haro-I-Id";
17+
18+
@Before
19+
public void setup() {
20+
MythicalApplicationRequestHandler stub = new MythicalApplicationRequestHandler() {
21+
@Override
22+
public String getCurrentRequestId() {
23+
return STUB_REQ_ID;
24+
}
25+
};
26+
MythicalApplicationRequestHandler.setInstance(stub);
27+
}
28+
29+
@Test
30+
public void formatAppendsRequestId() throws Exception {
31+
ReqIdConverter converter = ReqIdConverter.newInstance(new String[]{});
32+
StringBuilder message = new StringBuilder().append("BEFORE_");
33+
34+
converter.format(null, message);
35+
36+
assertEquals("BEFORE_" + STUB_REQ_ID, message.toString());
37+
}
38+
39+
@Test
40+
public void logReplacesKeyWithReqId() throws Exception {
41+
// Get the RootLogger which, if you don't have log4j2-test.xml defined, will only log ERRORs
42+
Logger logger = LogManager.getRootLogger();
43+
// Create a String Appender to capture log output
44+
StringAppender appender = StringAppender.createStringAppender("[%reqId] %m");
45+
appender.addToLogger(logger.getName(), Level.INFO);
46+
appender.start();
47+
48+
// Log to the string appender
49+
logger.error("Test");
50+
51+
assertEquals("[" + STUB_REQ_ID + "] Test", appender.getOutput());
52+
appender.removeFromLogger(LogManager.getRootLogger().getName());
53+
}
54+
}

0 commit comments

Comments
 (0)