Skip to content
This repository was archived by the owner on Feb 5, 2026. It is now read-only.

Commit b08c34f

Browse files
Added support for multiple Logentries Handler configurations (java.util.logging)
* [LOG-13064] iops java util library issue * [LOG-13064] iops java util library issue * [LOG-13064] iops java util library issue * [LOG-13064] iops java util library issue
1 parent 78a2502 commit b08c34f

File tree

7 files changed

+260
-9
lines changed

7 files changed

+260
-9
lines changed

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,49 @@ Currently logs which exceed 65536 characters in length, including any patterns a
2121

2222
-------
2323

24+
Configure Java Util Logging with multiple handlers
25+
==================
26+
This library allows you to set up different loggers (java.util.logging.Logger) each of them with a different
27+
Logentries handler configuration (e.g. to support different tokens).
28+
29+
1. Add to logging.properties the following props:
30+
- Log configuration class:
31+
```
32+
config=com.rapid7.jul.MultipleLogentriesHandlerConfig
33+
```
34+
35+
- List all the handler names you need:
36+
```
37+
logentries.handler.names=logger1,logger2
38+
```
39+
40+
- Configure each handler using the handler name specified before as prefix:
41+
42+
```
43+
logger1.com.rapid7.jul.LogentriesHandler.token=4ff1cb0a-beea-4616-b647-1c113de8e7bb
44+
logger1.com.rapid7.jul.LogentriesHandler.region=eu
45+
logger1.com.rapid7.jul.LogentriesHandler.port=10000
46+
logger1.com.rapid7.jul.LogentriesHandler.formatter=java.util.logging.SimpleFormatter
47+
48+
logger2.com.rapid7.jul.LogentriesHandler.token=a70d9089-576c-4668-9641-14995d493a62
49+
logger2.com.rapid7.jul.LogentriesHandler.region=eu
50+
logger2.com.rapid7.jul.LogentriesHandler.port=10000
51+
logger2.com.rapid7.jul.LogentriesHandler.formatter=java.util.logging.SimpleFormatter
52+
```
53+
54+
2. Get the LogManager and configure it with the property file:
55+
```
56+
LogManager logManager = LogManager.getLogManager();
57+
InputStream is = new FileInputStream("src/main/resources/logging.properties");
58+
logManager.readConfiguration(is);
59+
```
60+
61+
3. Get the loggers:
62+
```
63+
Logger logger1 = Logger.getLogger("logger1");
64+
Logger logger2 = Logger.getLogger("logger2");
65+
```
66+
-------
2467
2568
Contact Support
2669
===============

src/main/java/com/rapid7/jul/LogentriesHandler.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ public final class LogentriesHandler extends Handler {
4141
private ByteBuffer buffer;
4242

4343
public LogentriesHandler() {
44-
configure();
44+
this(null);
45+
}
46+
47+
public LogentriesHandler(String prefix) {
48+
configure(prefix);
4549
connect();
4650
buffer = ByteBuffer.allocate(4096);
4751
}
@@ -145,21 +149,22 @@ boolean drain() {
145149
return true;
146150
}
147151

148-
void configure() {
152+
void configure(String prefix) {
149153
String cname = getClass().getName();
150-
setLevel(getLevelProperty(cname + ".level", Level.INFO));
151-
setFormatter(getFormatterProperty(cname + ".formatter", new SimpleFormatter()));
152-
setRegion(getStringProperty(cname + ".region", ""));
154+
String propsPrefix = prefix == null ? cname : prefix + "." + cname;
155+
setLevel(getLevelProperty(propsPrefix + ".level", Level.INFO));
156+
setFormatter(getFormatterProperty(propsPrefix + ".formatter", new SimpleFormatter()));
157+
setRegion(getStringProperty(propsPrefix + ".region", ""));
153158

154-
String hostProperty = getStringProperty(cname + ".host", null);
159+
String hostProperty = getStringProperty(propsPrefix + ".host", null);
155160
if (isNullOrEmpty(hostProperty)) {
156161
setHost(String.format(DATA_ENDPOINT_TEMPLATE, region));
157162
} else {
158163
setHost(hostProperty);
159164
}
160165

161-
setPort(getIntProperty(cname + ".port", 514));
162-
setToken(getBytesProperty(cname + ".token", ""));
166+
setPort(getIntProperty(propsPrefix + ".port", 514));
167+
setToken(getBytesProperty(propsPrefix + ".token", ""));
163168
}
164169

165170
void connect() {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.rapid7.jul;
2+
3+
import java.util.logging.LogManager;
4+
import java.util.logging.Logger;
5+
6+
/**
7+
* <code>MultipleLogentriesHandlerConfig</code>: Configuration class to set up multiple Logentries Handlers with different token or host.
8+
*/
9+
public class MultipleLogentriesHandlerConfig {
10+
private static final String LOGENTRIES_HANDLER_NAMES_PROPERTY_KEY = "logentries.handler.names";
11+
12+
public MultipleLogentriesHandlerConfig() {
13+
String handlerNamesPropertyValue = LogManager.getLogManager().getProperty(LOGENTRIES_HANDLER_NAMES_PROPERTY_KEY);
14+
if (handlerNamesPropertyValue != null) {
15+
String[] handlerNames = handlerNamesPropertyValue.split(",");
16+
for (String handlerName : handlerNames) {
17+
Logger logger = Logger.getLogger(handlerName);
18+
logger.addHandler(new LogentriesHandler(handlerName));
19+
logger.setUseParentHandlers(false);
20+
}
21+
}
22+
}
23+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.rapid7.jul;
2+
3+
4+
import org.junit.After;
5+
import org.junit.Test;
6+
7+
import java.util.logging.LogManager;
8+
import java.util.logging.Logger;
9+
10+
import static junit.framework.TestCase.assertEquals;
11+
import static junit.framework.TestCase.assertTrue;
12+
13+
public class LogentriesHandlerTest {
14+
15+
@After
16+
public void resetLogger() {
17+
LogManager.getLogManager().reset();
18+
}
19+
20+
@Test
21+
public void singleLogger() throws Exception {
22+
final String message = "a message to log";
23+
final String token = "0c7407d4-fd0d-4436-bb50-44f1266b4490";
24+
SocketChannelReceiver receiver = null;
25+
try {
26+
receiver = SocketChannelReceiver.createAndStartReceiver(10000);
27+
LogManager.getLogManager().readConfiguration(getClass()
28+
.getClassLoader().getResourceAsStream("logging_single_handler.properties"));
29+
Logger logger = Logger.getLogger("logger");
30+
logger.info(message);
31+
validateLogMessage(token, message, receiver.pollMessage());
32+
} finally {
33+
receiver.close();
34+
}
35+
}
36+
37+
@Test
38+
public void multipleLoggers() throws Exception {
39+
final String tokenLogger1 = "4ff1cb0a-beea-4616-b647-1c113de8e7bb";
40+
final String tokenLogger2 = "a70d9089-576c-4668-9641-14995d493a62";
41+
final String messageLogger1 = "test message for logger_1";
42+
final String messageLogger2 = "test message for logger_2";
43+
SocketChannelReceiver receiverLogger1 = null;
44+
SocketChannelReceiver receiverLogger2 = null;
45+
try {
46+
receiverLogger1 = SocketChannelReceiver.createAndStartReceiver(10000);
47+
receiverLogger2 = SocketChannelReceiver.createAndStartReceiver(10001);
48+
LogManager.getLogManager().readConfiguration(getClass()
49+
.getClassLoader().getResourceAsStream("logging_multiple_handlers.properties"));
50+
Logger log1 = Logger.getLogger("logger1");
51+
Logger log2 = Logger.getLogger("logger2");
52+
log1.info(messageLogger1);
53+
validateLogMessage(tokenLogger1, messageLogger1, receiverLogger1.pollMessage());
54+
log2.info(messageLogger2);
55+
validateLogMessage(tokenLogger2, messageLogger2, receiverLogger2.pollMessage());
56+
} finally {
57+
receiverLogger1.close();
58+
receiverLogger2.close();
59+
}
60+
}
61+
62+
private void validateLogMessage(String token, String message, String logLine) {
63+
assertTrue( "Log line length verification" , logLine.length() > token.length() + message.length());
64+
assertEquals("Token verification", token, logLine.split(" ")[0]);
65+
assertEquals("Log Message verification", message, logLine.substring(logLine.length() - message.length() - 1, logLine.length() - 1));
66+
}
67+
68+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.rapid7.jul;
2+
3+
import java.io.IOException;
4+
import java.net.InetSocketAddress;
5+
import java.nio.ByteBuffer;
6+
import java.nio.channels.ServerSocketChannel;
7+
import java.nio.channels.SocketChannel;
8+
import java.util.Collections;
9+
import java.util.concurrent.ArrayBlockingQueue;
10+
import java.util.concurrent.BlockingQueue;
11+
import java.util.concurrent.TimeUnit;
12+
13+
/**
14+
* Stub of logentries server
15+
*/
16+
public class SocketChannelReceiver {
17+
18+
private BlockingQueue<String> messagesReceived = new ArrayBlockingQueue<String>(10);
19+
private final int port;
20+
private ServerSocketChannel serverSocket;
21+
private boolean isReady = false;
22+
23+
private SocketChannelReceiver(int port) {
24+
this.port = port;
25+
}
26+
27+
public static SocketChannelReceiver createAndStartReceiver(int port) throws Exception {
28+
final SocketChannelReceiver receiver = new SocketChannelReceiver(port);
29+
Thread receiverThread = new Thread(new Runnable() {
30+
@Override
31+
public void run() {
32+
receiver.start();
33+
}
34+
});
35+
receiverThread.start();
36+
receiver.waitUntilReady();
37+
return receiver;
38+
}
39+
40+
private void start() {
41+
try {
42+
init();
43+
System.out.println("SocketChannelReceiver, waiting for client ...");
44+
SocketChannel clientSocketChannel = serverSocket.accept();
45+
System.out.println("Connection Established.");
46+
listenForMessages(clientSocketChannel);
47+
} catch (IOException e) {
48+
System.out.println("Error running SocketChannelReceiver!");
49+
e.printStackTrace();
50+
}
51+
}
52+
53+
public String pollMessage() throws Exception {
54+
return messagesReceived.poll(3, TimeUnit.SECONDS);
55+
}
56+
57+
public void close() {
58+
try {
59+
serverSocket.close();
60+
} catch (Exception e) {
61+
System.out.println("Error closing server socket!");
62+
e.printStackTrace();
63+
}
64+
}
65+
66+
private synchronized void init() throws IOException {
67+
serverSocket = ServerSocketChannel.open();
68+
serverSocket.socket().bind(new InetSocketAddress(port));
69+
isReady = true;
70+
notifyAll();
71+
}
72+
73+
private synchronized void waitUntilReady() throws InterruptedException {
74+
if (!isReady) {
75+
wait(5000);
76+
}
77+
}
78+
79+
private void listenForMessages(SocketChannel clientSocketChannel) throws IOException{
80+
ByteBuffer buffer = ByteBuffer.allocate(1024);
81+
while (serverSocket.isOpen()) { // listening for messages
82+
int messageLength = clientSocketChannel.read(buffer);
83+
if (messageLength == 0) {
84+
continue;
85+
}
86+
buffer.flip();
87+
byte[] bytes = new byte[buffer.remaining()];
88+
buffer.get(bytes);
89+
String[] messages = new String(bytes).split("\\r?\\n");
90+
Collections.addAll(messagesReceived, messages);
91+
buffer.clear();
92+
}
93+
}
94+
95+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
config=com.rapid7.jul.MultipleLogentriesHandlerConfig
2+
logentries.handler.names=logger1,logger2
3+
4+
logger1.com.rapid7.jul.LogentriesHandler.token=4ff1cb0a-beea-4616-b647-1c113de8e7bb
5+
logger1.com.rapid7.jul.LogentriesHandler.region=eu
6+
logger1.com.rapid7.jul.LogentriesHandler.port=10000
7+
logger1.com.rapid7.jul.LogentriesHandler.formatter=java.util.logging.SimpleFormatter
8+
logger1.com.rapid7.jul.LogentriesHandler.host=localhost
9+
10+
logger2.com.rapid7.jul.LogentriesHandler.token=a70d9089-576c-4668-9641-14995d493a62
11+
logger2.com.rapid7.jul.LogentriesHandler.region=eu
12+
logger2.com.rapid7.jul.LogentriesHandler.port=10001
13+
logger2.com.rapid7.jul.LogentriesHandler.formatter=java.util.logging.SimpleFormatter
14+
logger2.com.rapid7.jul.LogentriesHandler.host=localhost
15+
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
handlers=com.rapid7.jul.LogentriesHandler
22
.handlers=com.rapid7.jul.LogentriesHandler
3-
com.rapid7.jul.LogentriesHandler.token=f2ff093a-54c7-4305-9449-1dccda748347
3+
4+
com.rapid7.jul.LogentriesHandler.token=0c7407d4-fd0d-4436-bb50-44f1266b4490
45
com.rapid7.jul.LogentriesHandler.region=eu
56
com.rapid7.jul.LogentriesHandler.port=10000
67
com.rapid7.jul.LogentriesHandler.formatter=java.util.logging.SimpleFormatter
8+
com.rapid7.jul.LogentriesHandler.host=localhost

0 commit comments

Comments
 (0)