You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/12/10 12:15:55 UTC
(camel) 04/05: CAMEL-21468: camel-http - Allow to log request/repsonse HTTP raw data to see what is sent over the wire.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch hlog
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 2d5de4eb9e1a75a379eaf5b9d4a9f37ca22c4b39
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Dec 10 13:10:14 2024 +0100
CAMEL-21468: camel-http - Allow to log request/repsonse HTTP raw data to see what is sent over the wire.
---
.../catalog/beans/LoggingHttpActivityListener.json | 2 +-
.../LoggingHttpActivityListenerConfigurer.java | 6 ++
.../camel/bean/LoggingHttpActivityListener.json | 2 +-
.../apache/camel/component/http/HttpComponent.java | 1 +
.../apache/camel/component/http/HttpEndpoint.java | 2 +
.../apache/camel/component/http/HttpProducer.java | 22 ++++-
.../http/LoggingHttpActivityListener.java | 94 +++++++++++++++-------
7 files changed, 97 insertions(+), 32 deletions(-)
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LoggingHttpActivityListener.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LoggingHttpActivityListener.json
index 19ca316a584..9e6db510a8a 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LoggingHttpActivityListener.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LoggingHttpActivityListener.json
@@ -10,7 +10,7 @@
"groupId": "org.apache.camel",
"artifactId": "camel-http",
"version": "4.10.0-SNAPSHOT",
- "properties": { "showRouteId": { "index": 0, "kind": "property", "displayName": "Show Route Id", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Show route ID." }, "showRouteGroup": { "index": 1, "kind": "property", "displayName": "Show Route Group", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaul [...]
+ "properties": { "showRouteId": { "index": 0, "kind": "property", "displayName": "Show Route Id", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Show route ID." }, "showRouteGroup": { "index": 1, "kind": "property", "displayName": "Show Route Group", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaul [...]
}
}
diff --git a/components/camel-http/src/generated/java/org/apache/camel/component/http/LoggingHttpActivityListenerConfigurer.java b/components/camel-http/src/generated/java/org/apache/camel/component/http/LoggingHttpActivityListenerConfigurer.java
index 073035688d4..bdd0202c8d9 100644
--- a/components/camel-http/src/generated/java/org/apache/camel/component/http/LoggingHttpActivityListenerConfigurer.java
+++ b/components/camel-http/src/generated/java/org/apache/camel/component/http/LoggingHttpActivityListenerConfigurer.java
@@ -36,6 +36,8 @@ public class LoggingHttpActivityListenerConfigurer extends org.apache.camel.supp
case "showRouteGroup": target.setShowRouteGroup(property(camelContext, boolean.class, value)); return true;
case "showrouteid":
case "showRouteId": target.setShowRouteId(property(camelContext, boolean.class, value)); return true;
+ case "showstreams":
+ case "showStreams": target.setShowStreams(property(camelContext, boolean.class, value)); return true;
case "sourcelocationloggername":
case "sourceLocationLoggerName": target.setSourceLocationLoggerName(property(camelContext, boolean.class, value)); return true;
default: return false;
@@ -58,6 +60,8 @@ public class LoggingHttpActivityListenerConfigurer extends org.apache.camel.supp
case "showRouteGroup": return boolean.class;
case "showrouteid":
case "showRouteId": return boolean.class;
+ case "showstreams":
+ case "showStreams": return boolean.class;
case "sourcelocationloggername":
case "sourceLocationLoggerName": return boolean.class;
default: return null;
@@ -81,6 +85,8 @@ public class LoggingHttpActivityListenerConfigurer extends org.apache.camel.supp
case "showRouteGroup": return target.isShowRouteGroup();
case "showrouteid":
case "showRouteId": return target.isShowRouteId();
+ case "showstreams":
+ case "showStreams": return target.isShowStreams();
case "sourcelocationloggername":
case "sourceLocationLoggerName": return target.isSourceLocationLoggerName();
default: return null;
diff --git a/components/camel-http/src/generated/resources/META-INF/services/org/apache/camel/bean/LoggingHttpActivityListener.json b/components/camel-http/src/generated/resources/META-INF/services/org/apache/camel/bean/LoggingHttpActivityListener.json
index 19ca316a584..9e6db510a8a 100644
--- a/components/camel-http/src/generated/resources/META-INF/services/org/apache/camel/bean/LoggingHttpActivityListener.json
+++ b/components/camel-http/src/generated/resources/META-INF/services/org/apache/camel/bean/LoggingHttpActivityListener.json
@@ -10,7 +10,7 @@
"groupId": "org.apache.camel",
"artifactId": "camel-http",
"version": "4.10.0-SNAPSHOT",
- "properties": { "showRouteId": { "index": 0, "kind": "property", "displayName": "Show Route Id", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Show route ID." }, "showRouteGroup": { "index": 1, "kind": "property", "displayName": "Show Route Group", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaul [...]
+ "properties": { "showRouteId": { "index": 0, "kind": "property", "displayName": "Show Route Id", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Show route ID." }, "showRouteGroup": { "index": 1, "kind": "property", "displayName": "Show Route Group", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaul [...]
}
}
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
index 396cb4773da..218d316bf72 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
@@ -1068,6 +1068,7 @@ public class HttpComponent extends HttpCommonComponent implements RestProducerFa
clientConnectionManager.close();
clientConnectionManager = null;
}
+ ServiceHelper.stopService(httpActivityListener);
super.doStop();
}
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
index 7df8d469e07..3ca8bf6eef8 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
@@ -332,6 +332,8 @@ public class HttpEndpoint extends HttpCommonEndpoint implements LineNumberAware
if (httpClient instanceof Closeable closeable) {
IOHelper.close(closeable);
}
+ ServiceHelper.stopService(httpActivityListener);
+ super.doStop();
}
// Properties
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
index 93c550035a0..211c61ad244 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
@@ -37,6 +37,7 @@ import java.util.Map.Entry;
import org.apache.camel.CamelExchangeException;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePropertyKey;
+import org.apache.camel.LineNumberAware;
import org.apache.camel.Message;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.TypeConverter;
@@ -83,7 +84,7 @@ import org.apache.hc.core5.http.protocol.HttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class HttpProducer extends DefaultProducer {
+public class HttpProducer extends DefaultProducer implements LineNumberAware {
private static final Logger LOG = LoggerFactory.getLogger(HttpProducer.class);
@@ -813,4 +814,23 @@ public class HttpProducer extends DefaultProducer {
this.httpClient = httpClient;
}
+ @Override
+ public int getLineNumber() {
+ return getEndpoint().getLineNumber();
+ }
+
+ @Override
+ public void setLineNumber(int lineNumber) {
+ // noop
+ }
+
+ @Override
+ public String getLocation() {
+ return getEndpoint().getLocation();
+ }
+
+ @Override
+ public void setLocation(String location) {
+ // noop
+ }
}
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/LoggingHttpActivityListener.java b/components/camel-http/src/main/java/org/apache/camel/component/http/LoggingHttpActivityListener.java
index cda6dc06c85..1b96727b1d2 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/LoggingHttpActivityListener.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/LoggingHttpActivityListener.java
@@ -35,8 +35,10 @@ import org.apache.camel.support.processor.DefaultMaskingFormatter;
import org.apache.camel.support.service.ServiceSupport;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
import static org.apache.camel.support.LoggerHelper.getLineNumberLoggerName;
@@ -59,8 +61,13 @@ public class LoggingHttpActivityListener extends ServiceSupport implements Camel
private boolean showExchangeId = true;
@Metadata(defaultValue = "true", description = "Show the HTTP body.")
private boolean showBody = true;
+ @Metadata(defaultValue = "true",
+ description = "Whether to show HTTP body that are streaming based. Beware that Camel will have to read the content into memory to print to log, and will re-create the HttpEntity stored on the request/response object. If you have large payloads then this can impact performance.")
+ private boolean showStreams = true;
@Metadata(defaultValue = "true", label = "formatting", description = "Show the HTTP headers.")
private boolean showHeaders = true;
+ @Metadata(defaultValue = "50000", description = "Limits the number of characters logged from the HTTP body.")
+ private int maxChars = 50000;
@Metadata(description = "If true, mask sensitive information like password or passphrase in the log.")
private Boolean logMask;
@Metadata(defaultValue = "true", description = "If enabled then each information is outputted as separate LOG events.")
@@ -79,29 +86,6 @@ public class LoggingHttpActivityListener extends ServiceSupport implements Camel
}
}
- private CamelLogger getLogger(Object source, Exchange exchange) {
- String name = null;
- if (sourceLocationLoggerName) {
- name = getLineNumberLoggerName(source);
- }
- if (name == null) {
- name = LoggingHttpActivityListener.class.getName();
- }
- LoggingLevel level = LoggingLevel.INFO;
- if (loggingLevel != null && !loggingLevel.equals("INFO")) {
- level = LoggingLevel.valueOf(loggingLevel);
- }
- return new CamelLogger(name, level);
- }
-
- private String getValue(boolean sensitive, Object value) {
- String v = value != null ? value.toString() : null;
- if (v != null && (sensitive || logMask != null && logMask)) {
- v = maskingFormatter.format(v);
- }
- return v;
- }
-
@Override
public void onRequestSubmitted(Object source, Exchange exchange, HttpHost httpHost, ClassicHttpRequest request) {
CamelLogger logger = getLogger(source, exchange);
@@ -170,12 +154,33 @@ public class LoggingHttpActivityListener extends ServiceSupport implements Camel
lines.add(""); // empty line before body
try {
var e = request != null ? request.getEntity() : response.getEntity();
- if (e != null && e.isRepeatable()) {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- e.writeTo(bos);
- lines.add(getValue(false, bos.toString()));
- } else if (e != null) {
- lines.add("WARN: Cannot log HTTP body because the body is not repeatable");
+ if (e != null) {
+ if (e.isStreaming() && !showStreams) {
+ lines.add("WARN: Cannot log HTTP body because the body is streaming");
+ } else {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ e.writeTo(bos);
+ String data = bos.toString();
+ if (data.length() > maxChars) {
+ data = data.substring(0, maxChars) + " ... [Body clipped after " + maxChars
+ + " chars, total length is " + data.length() + "]";
+ }
+ lines.add(getValue(false, data));
+ if (!e.isRepeatable()) {
+ // need to re-create body as stream is EOL
+ byte[] arr = bos.toByteArray();
+ ContentType ct = null;
+ if (e.getContentType() != null) {
+ ct = ContentType.parse(e.getContentType());
+ }
+ e = new ByteArrayEntity(arr, ct);
+ if (request != null) {
+ request.setEntity(e);
+ } else {
+ response.setEntity(e);
+ }
+ }
+ }
}
} catch (Exception e) {
// ignore
@@ -193,6 +198,29 @@ public class LoggingHttpActivityListener extends ServiceSupport implements Camel
}
}
+ private CamelLogger getLogger(Object source, Exchange exchange) {
+ String name = null;
+ if (sourceLocationLoggerName) {
+ name = getLineNumberLoggerName(source);
+ }
+ if (name == null) {
+ name = LoggingHttpActivityListener.class.getName();
+ }
+ LoggingLevel level = LoggingLevel.INFO;
+ if (loggingLevel != null && !loggingLevel.equals("INFO")) {
+ level = LoggingLevel.valueOf(loggingLevel);
+ }
+ return new CamelLogger(name, level);
+ }
+
+ private String getValue(boolean sensitive, Object value) {
+ String v = value != null ? value.toString() : null;
+ if (v != null && (sensitive || logMask != null && logMask)) {
+ v = maskingFormatter.format(v);
+ }
+ return v;
+ }
+
@Override
public CamelContext getCamelContext() {
return camelContext;
@@ -243,6 +271,14 @@ public class LoggingHttpActivityListener extends ServiceSupport implements Camel
this.showBody = showBody;
}
+ public boolean isShowStreams() {
+ return showStreams;
+ }
+
+ public void setShowStreams(boolean showStreams) {
+ this.showStreams = showStreams;
+ }
+
public boolean isShowHeaders() {
return showHeaders;
}