Skip to content

Commit dd2e833

Browse files
pcornishmsavy
authored andcommitted
Adds the ability to log the HTTP response status code to the log plugin.
1 parent 3291ef8 commit dd2e833

File tree

5 files changed

+75
-27
lines changed

5 files changed

+75
-27
lines changed
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"frameworkVersion" : 1.0,
33
"name" : "Log Policy Plugin",
4-
"description" : "This plugin has policies for logging to std out.",
4+
"description" : "This plugin has policies for logging HTTP headers.",
55
"version" : "${project.version}"
66
}

log-policy/src/main/apiman/policyDefs/schemas/log-policyDef.schema

+12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@
88
"title": "Direction",
99
"description": "You may choose to log either the Request headers, Response headers, or both.",
1010
"enum": [ "request", "response", "both" ]
11+
},
12+
"logHeaders": {
13+
"title": "Log Headers",
14+
"description": "Whether to log the HTTP headers.",
15+
"type": "boolean",
16+
"default": true
17+
},
18+
"logStatusCode": {
19+
"title": "Log Status Code",
20+
"description": "Whether to log the HTTP response status code.",
21+
"type": "boolean",
22+
"default": false
1123
}
1224
}
1325
}

log-policy/src/main/java/io/apiman/plugins/log_policy/LogHeadersPolicy.java

+14-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.apiman.plugins.log_policy.beans.LogHeadersDirectionType;
2727

2828
import java.util.Map.Entry;
29+
import java.util.Set;
2930
import java.util.TreeSet;
3031

3132
/**
@@ -75,7 +76,7 @@ protected void doApply(ApiRequest request, IPolicyContext context, LogHeadersCon
7576
IApimanLogger logger = context.getLogger(getClass());
7677
String endpoint = request.getApi().getEndpoint();
7778
context.setAttribute(ENDPOINT_ATTRIBUTE, endpoint);
78-
if (config.getDirection() != LogHeadersDirectionType.response) {
79+
if (config.isLogHeaders() && config.getDirection() != LogHeadersDirectionType.response) {
7980
logHeaders(logger, request.getHeaders(), HttpDirection.REQUEST, endpoint);
8081
}
8182
chain.doApply(request);
@@ -90,26 +91,32 @@ protected void doApply(ApiResponse response, IPolicyContext context, LogHeadersC
9091
IApimanLogger logger = context.getLogger(getClass());
9192
if (config.getDirection() != LogHeadersDirectionType.request) {
9293
String endpoint = context.getAttribute(ENDPOINT_ATTRIBUTE, ""); //$NON-NLS-1$
93-
logHeaders(logger, response.getHeaders(), HttpDirection.RESPONSE, endpoint);
94+
if (config.isLogStatusCode()) {
95+
logger.info(String.format("Status code %d for %s", response.getCode(), endpoint));
96+
}
97+
if (config.isLogHeaders()) {
98+
logHeaders(logger, response.getHeaders(), HttpDirection.RESPONSE, endpoint);
99+
}
94100
}
95101
chain.doApply(response);
96102
}
97103

98-
/**
104+
/**
99105
* Logs the given headers to standard output.
100106
* @param logger
101107
* @param headers
102108
* @param direction
103109
* @param endpoint
104110
*/
105111
private void logHeaders(IApimanLogger logger, final HeaderMap headers, final HttpDirection direction, final String endpoint) {
106-
logger.info(String.format("Logging %d %s headers for %s", headers.size(), direction.getDescription(), endpoint)); //$NON-NLS-1$
107-
TreeSet<String> sortedKeys = new TreeSet<>(headers.keySet());
112+
final StringBuilder sb = new StringBuilder();
113+
sb.append(String.format("Logging %d %s headers for %s", headers.size(), direction.getDescription(), endpoint)); //$NON-NLS-1$
114+
final Set<String> sortedKeys = new TreeSet<>(headers.keySet());
108115
for (String key : sortedKeys) {
109116
for (Entry<String, String> pair : headers.getAllEntries(key)) {
110-
logger.info(String.format("Key : %s, Value : %s", pair.getKey(), pair.getValue())); //$NON-NLS-1$
117+
sb.append(String.format("\r\nKey : %s, Value : %s", pair.getKey(), pair.getValue())); //$NON-NLS-1$
111118
}
112119
}
120+
logger.info(sb.toString());
113121
}
114-
115122
}

log-policy/src/main/java/io/apiman/plugins/log_policy/beans/LogHeadersConfigBean.java

+26
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ public class LogHeadersConfigBean {
2727
@JsonProperty
2828
private LogHeadersDirectionType direction;
2929

30+
/**
31+
* Whether to log the request/response headers.
32+
* Defaults to {@code true} for backwards compatibility.
33+
*/
34+
@JsonProperty
35+
private boolean logHeaders = true;
36+
37+
/**
38+
* Whether to log the response status code.
39+
*/
40+
@JsonProperty
41+
private boolean logStatusCode;
42+
3043
/**
3144
* Constructor.
3245
*/
@@ -47,4 +60,17 @@ public void setDirection(LogHeadersDirectionType direction) {
4760
this.direction = direction;
4861
}
4962

63+
/**
64+
* @return whether to log the headers
65+
*/
66+
public boolean isLogHeaders() {
67+
return logHeaders;
68+
}
69+
70+
/**
71+
* @return whether to log the status code
72+
*/
73+
public boolean isLogStatusCode() {
74+
return logStatusCode;
75+
}
5076
}

log-policy/src/test/java/io/apiman/plugins/log_policy/LogHeadersPolicyTest.java

+22-19
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class LogHeadersPolicyTest extends ApimanPolicyTest {
2323
* A simple happy flow test to verify the policy does not blow up in our face.
2424
*/
2525
@Test
26-
@Configuration("{ \"direction\" : \"both\" }")
26+
@Configuration("{ \"direction\" : \"both\", \"logStatusCode\" : true }")
2727
public void testLogHeadersWithoutAnyRequestHeaders() throws PolicyFailureError, Throwable {
2828
PrintStream out = System.out;
2929
ByteArrayOutputStream testOutput = new ByteArrayOutputStream();
@@ -35,11 +35,12 @@ public void testLogHeadersWithoutAnyRequestHeaders() throws PolicyFailureError,
3535
output = redactDates(output);
3636
output = normalize(output);
3737
String expected = "INFO: Logging 0 HTTP Request headers for io.apiman.test.policies.EchoBackEndApi\n" +
38-
"INFO: Logging 4 HTTP Response headers for io.apiman.test.policies.EchoBackEndApi\n" +
39-
"INFO: Key : Content-Length, Value : 167\n" +
40-
"INFO: Key : Content-Type, Value : application/json\n" +
41-
"INFO: Key : Date, Value : XXX\n" +
42-
"INFO: Key : Server, Value : apiman.policy-test\n" +
38+
"INFO: Status code 200 for io.apiman.test.policies.EchoBackEndApi\n" +
39+
"INFO: Logging 4 HTTP Response headers for io.apiman.test.policies.EchoBackEndApi\n" +
40+
"Key : Content-Length, Value : 167\n" +
41+
"Key : Content-Type, Value : application/json\n" +
42+
"Key : Date, Value : XXX\n" +
43+
"Key : Server, Value : apiman.policy-test\n" +
4344
"";
4445
Assert.assertEquals(expected, output);
4546
} finally {
@@ -51,7 +52,7 @@ public void testLogHeadersWithoutAnyRequestHeaders() throws PolicyFailureError,
5152
* A simple happy flow test to verify the policy does not blow up in our face.
5253
*/
5354
@Test
54-
@Configuration("{ \"direction\" : \"both\" }")
55+
@Configuration("{ \"direction\" : \"both\", \"logStatusCode\" : true }")
5556
public void testLogHeadersHappyFlow() throws PolicyFailureError, Throwable {
5657
PrintStream out = System.out;
5758
ByteArrayOutputStream testOutput = new ByteArrayOutputStream();
@@ -66,12 +67,13 @@ public void testLogHeadersHappyFlow() throws PolicyFailureError, Throwable {
6667
output = redactDates(output);
6768
output = normalize(output);
6869
String expected = "INFO: Logging 1 HTTP Request headers for io.apiman.test.policies.EchoBackEndApi\n" +
69-
"INFO: Key : X-Test-Name, Value : testGet\n" +
70+
"Key : X-Test-Name, Value : testGet\n" +
71+
"INFO: Status code 200 for io.apiman.test.policies.EchoBackEndApi\n" +
7072
"INFO: Logging 4 HTTP Response headers for io.apiman.test.policies.EchoBackEndApi\n" +
71-
"INFO: Key : Content-Length, Value : 199\n" +
72-
"INFO: Key : Content-Type, Value : application/json\n" +
73-
"INFO: Key : Date, Value : XXX\n" +
74-
"INFO: Key : Server, Value : apiman.policy-test\n" +
73+
"Key : Content-Length, Value : 199\n" +
74+
"Key : Content-Type, Value : application/json\n" +
75+
"Key : Date, Value : XXX\n" +
76+
"Key : Server, Value : apiman.policy-test\n" +
7577
"";
7678
Assert.assertEquals(expected, output);
7779
} finally {
@@ -98,7 +100,7 @@ public void testLogHeadersHappyFlowRequestOnly() throws PolicyFailureError, Thro
98100
output = redactDates(output);
99101
output = normalize(output);
100102
String expected = "INFO: Logging 1 HTTP Request headers for io.apiman.test.policies.EchoBackEndApi\n" +
101-
"INFO: Key : X-Test-Name, Value : testGet\n" +
103+
"Key : X-Test-Name, Value : testGet\n" +
102104
"";
103105
Assert.assertEquals(expected, output);
104106
} finally {
@@ -110,7 +112,7 @@ public void testLogHeadersHappyFlowRequestOnly() throws PolicyFailureError, Thro
110112
* A simple happy flow test to verify the policy does not blow up in our face.
111113
*/
112114
@Test
113-
@Configuration("{ \"direction\" : \"response\" }")
115+
@Configuration("{ \"direction\" : \"response\", \"logStatusCode\" : true }")
114116
public void testLogHeadersHappyFlowResponseOnly() throws PolicyFailureError, Throwable {
115117
PrintStream out = System.out;
116118
ByteArrayOutputStream testOutput = new ByteArrayOutputStream();
@@ -124,11 +126,12 @@ public void testLogHeadersHappyFlowResponseOnly() throws PolicyFailureError, Thr
124126
String output = testOutput.toString("UTF-8");
125127
output = redactDates(output);
126128
output = normalize(output);
127-
String expected = "INFO: Logging 4 HTTP Response headers for io.apiman.test.policies.EchoBackEndApi\n" +
128-
"INFO: Key : Content-Length, Value : 199\n" +
129-
"INFO: Key : Content-Type, Value : application/json\n" +
130-
"INFO: Key : Date, Value : XXX\n" +
131-
"INFO: Key : Server, Value : apiman.policy-test\n" +
129+
String expected = "INFO: Status code 200 for io.apiman.test.policies.EchoBackEndApi\n" +
130+
"INFO: Logging 4 HTTP Response headers for io.apiman.test.policies.EchoBackEndApi\n" +
131+
"Key : Content-Length, Value : 199\n" +
132+
"Key : Content-Type, Value : application/json\n" +
133+
"Key : Date, Value : XXX\n" +
134+
"Key : Server, Value : apiman.policy-test\n" +
132135
"";
133136
Assert.assertEquals(expected, output);
134137
} finally {

0 commit comments

Comments
 (0)