Skip to content

Commit 91441cd

Browse files
authored
feat: add http logging for Java (#606)
1 parent 441e17c commit 91441cd

File tree

6 files changed

+151
-3
lines changed

6 files changed

+151
-3
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ Twilio.setEdge("sydney");
9292

9393
This will result in the `hostname` transforming from `api.twilio.com` to `api.sydney.au1.twilio.com`.
9494

95+
### Enable Debug Logging
96+
In order to enable debug logging, create a configuration file named log4j2.xml that defines the logger at the root level to at least 'debug'. An example of the configuration file can be found [here](src/main/java/com/twilio/example/log4j2.xml). For more configuration options please see the log4j configuration [documentation](https://logging.apache.org/log4j/2.x/manual/configuration.html).
97+
```java
98+
Twilio.init(accountSid, authToken);
99+
Twilio.setLoggerConfiguration("path/to/log4j2.xml");
100+
```
101+
95102
### Environment Variables
96103

97104
`twilio-java` supports the credentials, region, and edge values stored in the following environment variables:
@@ -139,7 +146,7 @@ try {
139146
new PhoneNumber("+15559994321"), // From number
140147
"Hello world!" // SMS body
141148
).create();
142-
149+
143150
System.out.println(message.getSid());
144151
} catch (final ApiException e) {
145152
System.err.println(e);

pom.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,16 @@
238238
<version>3.4.1</version>
239239
<scope>test</scope>
240240
</dependency>
241+
<dependency>
242+
<groupId>org.apache.logging.log4j</groupId>
243+
<artifactId>log4j-api</artifactId>
244+
<version>2.14.0</version>
245+
</dependency>
246+
<dependency>
247+
<groupId>org.apache.logging.log4j</groupId>
248+
<artifactId>log4j-core</artifactId>
249+
<version>2.14.0</version>
250+
</dependency>
241251
</dependencies>
242252
<build>
243253
<plugins>
@@ -382,4 +392,4 @@
382392
<artifactId>oss-parent</artifactId>
383393
<version>7</version>
384394
</parent>
385-
</project>
395+
</project>

src/main/java/com/twilio/Twilio.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
import java.util.Objects;
1313
import java.util.concurrent.ExecutorService;
1414
import java.util.concurrent.Executors;
15+
import java.io.File;
16+
17+
import org.apache.logging.log4j.core.LoggerContext;
18+
import org.apache.logging.log4j.LogManager;
1519

1620
/**
1721
* Singleton class to initialize Twilio environment.
@@ -150,6 +154,19 @@ public static synchronized void setEdge(final String edge) {
150154
Twilio.edge = edge;
151155
}
152156

157+
/**
158+
* Set the logger configuration file path.
159+
*
160+
* @param filePath path to logging configuration file
161+
* @param loggerContext defaults to false to get the appropriate logger context for the caller.
162+
*/
163+
public static synchronized void setLoggerConfiguration(final String filePath, final boolean... loggerContext) {
164+
boolean logContext = (loggerContext.length >= 1) ? loggerContext[0] : false;
165+
LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(logContext);
166+
File file = new File(filePath);
167+
context.setConfigLocation(file.toURI());
168+
}
169+
153170
/**
154171
* Returns (and initializes if not initialized) the Twilio Rest Client.
155172
*
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--logging configuration file example-->
3+
<Configuration status="warn" name="MyApp" packages="">
4+
<Appenders>
5+
<Console name="STDOUT" target="SYSTEM_OUT">
6+
<PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
7+
</Console>
8+
</Appenders>
9+
<Loggers>
10+
<Root level="debug">
11+
<AppenderRef ref="STDOUT"/>
12+
</Root>
13+
</Loggers>
14+
</Configuration>

src/main/java/com/twilio/http/TwilioRestClient.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
55

66
import java.util.function.Predicate;
7+
import java.util.Map;
8+
import java.util.List;
9+
10+
import org.apache.logging.log4j.LogManager;
11+
import org.apache.logging.log4j.Logger;
12+
import org.apache.logging.log4j.core.LoggerContext;
713

814
public class TwilioRestClient {
915

@@ -19,6 +25,7 @@ public class TwilioRestClient {
1925
private final String region;
2026
private final String edge;
2127
private final HttpClient httpClient;
28+
private static final Logger logger = LogManager.getLogger();
2229

2330
private TwilioRestClient(Builder b) {
2431
this.username = b.username;
@@ -50,7 +57,16 @@ public Response request(final Request request) {
5057
if (edge != null)
5158
request.setEdge(edge);
5259

53-
return httpClient.reliableRequest(request);
60+
logRequest(request);
61+
Response response = httpClient.reliableRequest(request);
62+
logger.debug("status code: " + response.getStatusCode());
63+
org.apache.http.Header[] responseHeaders = response.getHeaders();
64+
logger.debug("response headers:");
65+
for (int i = 0; i < responseHeaders.length; i++) {
66+
logger.debug(responseHeaders[i]);
67+
}
68+
69+
return response;
5470
}
5571

5672
public String getAccountSid() {
@@ -126,4 +142,29 @@ public TwilioRestClient build() {
126142
}
127143
}
128144

145+
/**
146+
* Logging debug information about HTTP request.
147+
*/
148+
public void logRequest(final Request request) {
149+
logger.debug("-- BEGIN Twilio API Request --");
150+
logger.debug("request method: " + request.getMethod());
151+
logger.debug("request URL: " + request.getUrl());
152+
final Map<String, List<String>> queryParams = request.getQueryParams();
153+
final Map<String, List<String>> headerParams = request.getHeaderParams();
154+
155+
if (!queryParams.isEmpty()) {
156+
logger.debug("query parameters: " + queryParams);
157+
}
158+
159+
if (!headerParams.isEmpty()) {
160+
logger.debug("header parameters: ");
161+
for (String key : headerParams.keySet()) {
162+
if (!key.toLowerCase().contains("authorization")) {
163+
logger.debug(key + ": " + headerParams.get(key));
164+
}
165+
}
166+
}
167+
logger.debug("-- END Twilio API Request --");
168+
}
169+
129170
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.twilio.http;
2+
3+
import com.twilio.Twilio;
4+
import com.twilio.rest.Domains;
5+
import com.twilio.rest.api.v2010.account.Message;
6+
import org.junit.Before;
7+
import org.junit.Test;
8+
import org.junit.Assert;
9+
10+
import java.io.ByteArrayOutputStream;
11+
import java.io.PrintStream;
12+
13+
public class LoggingTest {
14+
private ByteArrayOutputStream output;
15+
private PrintStream originalStream;
16+
17+
@Before
18+
public void setUp() throws Exception {
19+
Twilio.init("AC123", "AUTH TOKEN");
20+
}
21+
22+
public void logCapturingSetup() {
23+
output = new ByteArrayOutputStream();
24+
PrintStream outputStream = new PrintStream(output);
25+
originalStream = System.out;
26+
System.setOut(outputStream);
27+
}
28+
29+
public void finishLogCapturingSetup(Request request) {
30+
TwilioRestClient twilioRestClient = Twilio.getRestClient();
31+
twilioRestClient.logRequest(request);
32+
System.out.flush();
33+
System.setOut(originalStream);
34+
}
35+
36+
@Test
37+
public void testDebugLogging() {
38+
logCapturingSetup();
39+
Twilio.setLoggerConfiguration("src/main/java/com/twilio/example/log4j2.xml");
40+
final Request request = new Request(HttpMethod.GET, Domains.API.toString(),
41+
"/2010-04-01/Accounts/AC123/Messages/MM123.json");
42+
request.addHeaderParam("Authorization", "authorization value");
43+
request.addHeaderParam("Test Header", "test value");
44+
finishLogCapturingSetup(request);
45+
Assert.assertTrue(output.toString().contains("GET"));
46+
Assert.assertFalse(output.toString().contains("Authorization"));
47+
}
48+
49+
@Test
50+
public void testUsingDefaultConfigurationFileDebugLogging() {
51+
logCapturingSetup();
52+
final Request request = new Request(HttpMethod.GET, Domains.API.toString(),
53+
"/2010-04-01/Accounts/AC123/Messages/MM123.json");
54+
request.addHeaderParam("Authorization", "authorization value");
55+
request.addHeaderParam("Test Header", "test value");
56+
finishLogCapturingSetup(request);
57+
Assert.assertTrue(output.toString().isEmpty());
58+
}
59+
}

0 commit comments

Comments
 (0)