Skip to content

Commit e198b5a

Browse files
committed
Better support for nested calls in Jersey.
Bumped version to 2.0.8.
1 parent f06d5d0 commit e198b5a

File tree

19 files changed

+174
-71
lines changed

19 files changed

+174
-71
lines changed

cf-java-logging-support-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<parent>
2525
<groupId>com.sap.hcp.cf.logging</groupId>
2626
<artifactId>cf-java-logging-support-parent</artifactId>
27-
<version>2.0.7</version>
27+
<version>2.0.8</version>
2828
<relativePath>../pom.xml</relativePath>
2929
</parent>
3030
<profiles>

cf-java-logging-support-core/src/main/java/com/sap/hcp/cf/logging/common/RequestRecord.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public RequestRecord(String layerKey, Direction direction) {
8888
addTag(Fields.DIRECTION, direction.toString());
8989
setDefaults();
9090
start();
91+
RequestRecordHolder.add(this);
9192
}
9293

9394
/**
@@ -181,6 +182,10 @@ public long stop() {
181182

182183
return endMs;
183184
}
185+
186+
public void close() {
187+
RequestRecordHolder.remove(this);
188+
}
184189

185190
@Override
186191
public String toString() {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.sap.hcp.cf.logging.common;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
/**
7+
* As we need to keep track of nested calls we use thread local storage to
8+
* manage a set of RequestRecord instances that are "in flight" for individual
9+
* thread.
10+
*
11+
* Upon removal of a record, we check whether that one is the last one so that
12+
* we can clear context information.
13+
*
14+
*/
15+
public class RequestRecordHolder {
16+
17+
private static final ThreadLocal<Set<RequestRecord>> RECORD_SETS = new ThreadLocal<Set<RequestRecord>>();
18+
19+
public static void add(RequestRecord rr) {
20+
if (rr == null) {
21+
return;
22+
}
23+
Set<RequestRecord> recSet = RECORD_SETS.get();
24+
if (recSet == null) {
25+
recSet = new HashSet<RequestRecord>();
26+
RECORD_SETS.set(recSet);
27+
}
28+
recSet.add(rr);
29+
}
30+
31+
public static void remove(RequestRecord rr) {
32+
if (rr == null) {
33+
return;
34+
}
35+
Set<RequestRecord> recSet = RECORD_SETS.get();
36+
if (recSet.remove(rr)) {
37+
/*
38+
* -- time to clean up if this was the last
39+
*/
40+
if (recSet.isEmpty()) {
41+
rr.resetContext();
42+
}
43+
}
44+
}
45+
}

cf-java-logging-support-jersey/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<relativePath>../pom.xml</relativePath>
1010
<groupId>com.sap.hcp.cf.logging</groupId>
1111
<artifactId>cf-java-logging-support-parent</artifactId>
12-
<version>2.0.7</version>
12+
<version>2.0.8</version>
1313
</parent>
1414

1515
<name>cf-java-logging-support-jersey</name>

cf-java-logging-support-jersey/src/main/java/com/sap/hcp/cf/logging/jersey/filter/ClientRequestContextAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public Direction getDirection() {
3939

4040
public void setHeader(String headerName, String headerValue) {
4141
if (headerName != null && headerValue != null) {
42-
MultivaluedMap<String, String > headers = ctx.getStringHeaders();
42+
MultivaluedMap<String, Object > headers = ctx.getHeaders();
4343
headers.add(headerName, headerValue);
4444
}
4545
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.sap.hcp.cf.logging.jersey.filter;
2+
3+
import javax.ws.rs.client.Invocation;
4+
5+
import org.glassfish.jersey.server.ContainerRequest;
6+
7+
import com.sap.hcp.cf.logging.common.HttpHeaders;
8+
import com.sap.hcp.cf.logging.common.LogContext;
9+
10+
public class ClientRequestUtils {
11+
12+
public static Invocation.Builder propagate(Invocation.Builder builder, ContainerRequest req) {
13+
String correlationId = LogContext.getCorrelationId();
14+
if (correlationId == null) {
15+
correlationId = req.getHeaderString(HttpHeaders.CORRELATION_ID);
16+
}
17+
if (correlationId != null) {
18+
builder.header(HttpHeaders.CORRELATION_ID, correlationId);
19+
}
20+
return builder;
21+
}
22+
23+
}

cf-java-logging-support-jersey/src/main/java/com/sap/hcp/cf/logging/jersey/filter/RequestHandler.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.sap.hcp.cf.logging.jersey.filter;
22

3+
import java.net.URI;
4+
35
import com.sap.hcp.cf.logging.common.Defaults;
46
import com.sap.hcp.cf.logging.common.Fields;
57
import com.sap.hcp.cf.logging.common.HttpHeaders;
@@ -10,7 +12,22 @@
1012
public class RequestHandler {
1113

1214
public RequestRecord handle(RequestContextAdapter adapter) {
13-
LogContext.initializeContext(getCorrelationIdFromHeader(adapter));
15+
16+
/*
17+
* -- This might be an outgoing call and we may already have a correlation
18+
* -- id in the LogContext
19+
*/
20+
String correlationId = LogContext.getCorrelationId();
21+
if (correlationId == null) {
22+
correlationId = getCorrelationIdFromHeader(adapter);
23+
LogContext.initializeContext(correlationId);
24+
/*
25+
* -- it was not in the header, then propagate
26+
*/
27+
if (correlationId == null) {
28+
adapter.setHeader(HttpHeaders.CORRELATION_ID, LogContext.getCorrelationId());
29+
}
30+
}
1431

1532
RequestRecord lrec = new RequestRecord(adapter.getName(), adapter.getDirection());
1633
lrec.start();
@@ -20,8 +37,9 @@ public RequestRecord handle(RequestContextAdapter adapter) {
2037
return lrec;
2138

2239
}
40+
2341
private void addHeaders(RequestContextAdapter adapter, RequestRecord lrec) {
24-
lrec.addTag(Fields.REQUEST, getValue(adapter.getUri().getPath()));
42+
lrec.addTag(Fields.REQUEST, getValue(getRequestUri(adapter)));
2543
lrec.addTag(Fields.METHOD, getValue(adapter.getMethod()));
2644
lrec.addTag(Fields.REMOTE_IP, getValue(adapter.getUri().getAuthority()));
2745
lrec.addTag(Fields.REMOTE_HOST, getValue(adapter.getUri().getHost()));
@@ -51,4 +69,13 @@ private String getCorrelationIdFromHeader(RequestContextAdapter adapter) {
5169
private String getHeader(RequestContextAdapter adapter, String headerName) {
5270
return getValue(adapter.getHeader(headerName));
5371
}
72+
73+
private String getRequestUri(RequestContextAdapter adapter) {
74+
URI uri = adapter.getUri();
75+
StringBuilder sb = new StringBuilder(uri.getPath());
76+
if (uri.getQuery() != null) {
77+
sb.append("?").append(uri.getQuery());
78+
}
79+
return sb.toString();
80+
}
5481
}

cf-java-logging-support-jersey/src/main/java/com/sap/hcp/cf/logging/jersey/filter/ResponseHandler.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ public class ResponseHandler {
1313

1414
private static final Logger LOGGER = LoggerFactory.getLogger(ResponseHandler.class);
1515

16-
public void handle(ResponseContextAdapter responseContext, RequestRecord logRecord) {
17-
if (logRecord != null) {
18-
logRecord.addValue(Fields.RESPONSE_SIZE_B, new LongValue(responseContext.getLength()));
19-
logRecord.addTag(Fields.RESPONSE_CONTENT_TYPE, responseContext.getHeader(HttpHeaders.CONTENT_TYPE));
20-
logRecord.addValue(Fields.RESPONSE_STATUS, new LongValue(responseContext.getStatus()));
21-
logRecord.stop();
22-
LOGGER.info(Markers.REQUEST_MARKER, logRecord.toString());
23-
logRecord.resetContext();
16+
public void handle(ResponseContextAdapter responseContext, RequestRecord rr) {
17+
if (rr != null) {
18+
rr.addValue(Fields.RESPONSE_SIZE_B, new LongValue(responseContext.getLength()));
19+
rr.addTag(Fields.RESPONSE_CONTENT_TYPE, responseContext.getHeader(HttpHeaders.CONTENT_TYPE));
20+
rr.addValue(Fields.RESPONSE_STATUS, new LongValue(responseContext.getStatus()));
21+
rr.stop();
22+
LOGGER.info(Markers.REQUEST_MARKER, rr.toString());
23+
/*
24+
* -- close this instance
25+
*/
26+
rr.close();
27+
}
28+
else {
29+
LOGGER.error("No record found to handle response {}", responseContext);
2430
}
2531
}
2632
}

cf-java-logging-support-jersey/src/test/java/com/sap/hcp/cf/logging/jersey/filter/AbstractFilterTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ protected String getField(String fieldName) {
3737
}
3838
}
3939

40+
protected String getField(String fieldName, int i) {
41+
try {
42+
return JSON.std.mapFrom(getLine(i)).get(fieldName).toString();
43+
} catch (Exception ex) {
44+
ex.printStackTrace();
45+
return null;
46+
}
47+
}
48+
4049
protected int getLogSize() {
4150
return this.outContent.toString().split("\n").length;
4251
}
@@ -45,4 +54,9 @@ private String getLastLine() {
4554
String[] lines = this.outContent.toString().split("\n");
4655
return lines[lines.length-1];
4756
}
57+
58+
public String getLine(int i) {
59+
String[] lines = this.outContent.toString().split("\n");
60+
return lines[i];
61+
}
4862
}

cf-java-logging-support-jersey/src/test/java/com/sap/hcp/cf/logging/jersey/filter/RequestMetricsClientFilterTest.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import static org.hamcrest.core.IsNull.nullValue;
88
import static org.junit.Assert.assertThat;
99

10+
import javax.ws.rs.client.Invocation;
1011
import javax.ws.rs.core.Application;
1112
import javax.ws.rs.core.Response;
1213

@@ -16,6 +17,7 @@
1617

1718
import com.sap.hcp.cf.logging.common.Defaults;
1819
import com.sap.hcp.cf.logging.common.Fields;
20+
import com.sap.hcp.cf.logging.common.HttpHeaders;
1921
import com.sap.hcp.cf.logging.common.RequestRecord.Direction;
2022

2123

@@ -47,17 +49,20 @@ protected Application configure() {
4749

4850
@Test
4951
public void ChainedResourcePerformanceLogTest() {
50-
/*
51-
* -- this is requesting a resource that itself issues another request
52-
* -- thus, we should see two log entries
53-
*/
54-
final Response response = target("testchainedresource").request().get();
52+
final String CORRELATION_ID = "test-1234-5678";
53+
final Response response = target("testchainedresource").request().header(HttpHeaders.CORRELATION_ID, CORRELATION_ID).get();
5554
if (response.hasEntity()) {
5655
String res = response.readEntity(String.class);
5756
res.length();
5857
}
59-
assertThat(getLogSize(), is(4));
58+
assertThat(getLogSize(), is(2));
6059
assertThat(response.getStatus(), is(200));
60+
/*
61+
* -- correlation id should have been propagated
62+
*/
63+
for (int i = 0; i < getLogSize(); i++) {
64+
assertThat(getField(Fields.CORRELATION_ID, i), is(CORRELATION_ID));
65+
}
6166
}
6267

6368
@Test

0 commit comments

Comments
 (0)