Skip to content

Commit 491da9d

Browse files
authored
JMS - some more enhancements (#911)
1 parent 3081315 commit 491da9d

File tree

49 files changed

+1089
-416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1089
-416
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
# (Next)
22

33
## Features
4+
* JMS Enhancements (#911):
5+
* Add special handling for temporary queues/topics
6+
* Capture message bodies of text Messages
7+
* Rely on the existing `ELASTIC_APM_CAPTURE_BODY` agent config option (off by default).
8+
* Send as `context.message.body`
9+
* Limit size to 10000 characters. If longer than this size, trim to 9999 and append with ellipsis
10+
* Introduce the `ignore_message_queues` configuration to disable instrumentation (message tagging) for specific
11+
queues/topics as suggested in #710
12+
* Capture predefined message headers and all properties
13+
* Rely on the existing `ELASTIC_APM_CAPTURE_HEADERS` agent config option.
14+
* Send as `context.message.headers`
15+
* Sanitize sensitive headers/properties based on the `sanitize_field_names` config option
416

517
## Bug Fixes
618
* JDBC regression- `PreparedStatement#executeUpdate()` and `PreparedStatement#executeLargeUpdate()` are not traced (#918)

apm-agent-benchmarks/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</dependency>
3434
<!--
3535
we can't add elastic-apm-agent as it causes shading problems:
36-
java.util.ServiceConfigurationError: org.stagemonitor.configuration.ConfigurationOptionProvider: co.elastic.apm.agent.web.WebConfiguration not a subtype
36+
java.util.ServiceConfigurationError: org.stagemonitor.configuration.ConfigurationOptionProvider: co.elastic.apm.agent.impl.context.web.WebConfiguration not a subtype
3737
-->
3838
<dependency>
3939
<groupId>${project.groupId}</groupId>

apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,38 @@ public class CoreConfiguration extends ConfigurationOptionProvider {
267267
.dynamic(true)
268268
.buildWithDefault(Collections.<WildcardMatcher>emptyList());
269269

270+
private final ConfigurationOption<EventType> captureBody = ConfigurationOption.enumOption(EventType.class)
271+
.key("capture_body")
272+
.configurationCategory(CORE_CATEGORY)
273+
.tags("performance")
274+
.description("For transactions that are HTTP requests, the Java agent can optionally capture the request body (e.g. POST \n" +
275+
"variables). For transactions that are initiated by receiving a JMS text message, the agent can capture the \n" +
276+
"textual message body.\n" +
277+
"\n" +
278+
"If the HTTP request or the JMS message has a body and this setting is disabled, the body will be shown as [REDACTED].\n" +
279+
"\n" +
280+
"This option is case-insensitive.\n" +
281+
"\n" +
282+
"NOTE: Currently, only UTF-8 encoded plain text HTTP content types are supported.\n" +
283+
"The option <<config-capture-body-content-types>> determines which content types are captured.\n" +
284+
"\n" +
285+
"WARNING: Request bodies often contain sensitive values like passwords, credit card numbers etc.\n" +
286+
"If your service handles data like this, we advise to only enable this feature with care.\n" +
287+
"Turning on body capturing can also significantly increase the overhead in terms of heap usage,\n" +
288+
"network utilisation and Elasticsearch index size.")
289+
.dynamic(true)
290+
.buildWithDefault(EventType.OFF);
291+
292+
private final ConfigurationOption<Boolean> captureHeaders = ConfigurationOption.booleanOption()
293+
.key("capture_headers")
294+
.configurationCategory(CORE_CATEGORY)
295+
.tags("performance")
296+
.description("If set to `true`, the agent will capture request and response headers, including cookies.\n" +
297+
"\n" +
298+
"NOTE: Setting this to `false` reduces network bandwidth, disk space and object allocations.")
299+
.dynamic(true)
300+
.buildWithDefault(true);
301+
270302
private final ConfigurationOption<Map<String, String>> globalLabels = ConfigurationOption
271303
.builder(new MapValueConverter<String, String>(StringValueConverter.INSTANCE, StringValueConverter.INSTANCE, "=", ","), Map.class)
272304
.key("global_labels")
@@ -514,6 +546,14 @@ public List<WildcardMatcher> getIgnoreExceptions(){
514546
return ignoreExceptions.get();
515547
}
516548

549+
public EventType getCaptureBody() {
550+
return captureBody.get();
551+
}
552+
553+
public boolean isCaptureHeaders() {
554+
return captureHeaders.get();
555+
}
556+
517557
public boolean isTypePoolCacheEnabled() {
518558
return typePoolCache.get();
519559
}
@@ -589,4 +629,28 @@ public static String getConfigFileLocation(List<ConfigurationSource> configurati
589629
return configFileLocation;
590630
}
591631
}
632+
633+
public enum EventType {
634+
/**
635+
* Request bodies will never be reported
636+
*/
637+
OFF,
638+
/**
639+
* Request bodies will only be reported with errors
640+
*/
641+
ERRORS,
642+
/**
643+
* Request bodies will only be reported with request transactions
644+
*/
645+
TRANSACTIONS,
646+
/**
647+
* Request bodies will be reported with both errors and request transactions
648+
*/
649+
ALL;
650+
651+
@Override
652+
public String toString() {
653+
return name().toLowerCase();
654+
}
655+
}
592656
}

apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/AbstractContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
import java.util.concurrent.ConcurrentHashMap;
3232

3333
public abstract class AbstractContext implements Recyclable {
34+
35+
public static final String REDACTED_CONTEXT_STRING = "[REDACTED]";
36+
3437
/**
3538
* A flat mapping of user-defined labels with {@link String} keys and {@link String}, {@link Number} or {@link Boolean} values
3639
* (formerly known as tags).
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -22,28 +22,29 @@
2222
* under the License.
2323
* #L%
2424
*/
25-
package co.elastic.apm.agent.web;
25+
package co.elastic.apm.agent.impl.context;
2626

27-
import co.elastic.apm.agent.impl.context.TransactionContext;
28-
import co.elastic.apm.agent.impl.context.Request;
2927
import co.elastic.apm.agent.impl.error.ErrorCapture;
3028
import co.elastic.apm.agent.impl.transaction.Transaction;
3129
import co.elastic.apm.agent.report.processor.Processor;
30+
import co.elastic.apm.agent.configuration.CoreConfiguration;
3231
import org.stagemonitor.configuration.ConfigurationRegistry;
3332

34-
import static co.elastic.apm.agent.web.WebConfiguration.EventType.ALL;
35-
import static co.elastic.apm.agent.web.WebConfiguration.EventType.ERRORS;
36-
import static co.elastic.apm.agent.web.WebConfiguration.EventType.TRANSACTIONS;
33+
import static co.elastic.apm.agent.configuration.CoreConfiguration.EventType.ALL;
34+
import static co.elastic.apm.agent.configuration.CoreConfiguration.EventType.ERRORS;
35+
import static co.elastic.apm.agent.configuration.CoreConfiguration.EventType.TRANSACTIONS;
3736

3837
/**
39-
* This processor redacts the body according to the {@link WebConfiguration#captureBody} configuration option
38+
* This processor redacts the body according to the {@link co.elastic.apm.agent.configuration.CoreConfiguration#captureBody}
39+
* configuration option
4040
*/
41+
@SuppressWarnings("JavadocReference")
4142
public class BodyProcessor implements Processor {
4243

43-
private final WebConfiguration webConfiguration;
44+
private final CoreConfiguration coreConfiguration;
4445

4546
public BodyProcessor(ConfigurationRegistry configurationRegistry) {
46-
webConfiguration = configurationRegistry.getConfig(WebConfiguration.class);
47+
coreConfiguration = configurationRegistry.getConfig(CoreConfiguration.class);
4748
}
4849

4950
@Override
@@ -56,14 +57,15 @@ public void processBeforeReport(ErrorCapture error) {
5657
redactBodyIfNecessary(error.getContext(), ERRORS);
5758
}
5859

59-
private void redactBodyIfNecessary(TransactionContext context, WebConfiguration.EventType eventType) {
60-
final WebConfiguration.EventType eventTypeConfig = webConfiguration.getCaptureBody();
61-
if (hasBody(context.getRequest()) && eventTypeConfig != eventType && eventTypeConfig != ALL) {
62-
context.getRequest().redactBody();
60+
private void redactBodyIfNecessary(TransactionContext context, CoreConfiguration.EventType eventType) {
61+
final CoreConfiguration.EventType eventTypeConfig = coreConfiguration.getCaptureBody();
62+
if (eventTypeConfig != eventType && eventTypeConfig != ALL) {
63+
if (context.getRequest().getBody() != null) {
64+
context.getRequest().redactBody();
65+
}
66+
if (context.getMessage().getBody() != null) {
67+
context.getMessage().redactBody();
68+
}
6369
}
6470
}
65-
66-
private boolean hasBody(Request request) {
67-
return request.getBody() != null;
68-
}
6971
}

apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Message.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525
package co.elastic.apm.agent.impl.context;
2626

2727
import co.elastic.apm.agent.objectpool.Recyclable;
28+
import co.elastic.apm.agent.util.NoRandomAccessMap;
2829

2930
import javax.annotation.Nullable;
3031

32+
import static co.elastic.apm.agent.impl.context.AbstractContext.REDACTED_CONTEXT_STRING;
33+
3134
public class Message implements Recyclable {
3235

3336
@Nullable
@@ -36,6 +39,14 @@ public class Message implements Recyclable {
3639
@Nullable
3740
private String topicName;
3841

42+
@Nullable
43+
private String body;
44+
45+
/**
46+
* A mapping of message headers (in JMS includes properties as well)
47+
*/
48+
private final NoRandomAccessMap<String, String> headers = new NoRandomAccessMap<>();
49+
3950
@Nullable
4051
public String getQueueName() {
4152
return queueName;
@@ -56,18 +67,45 @@ public Message withTopic(String topicName) {
5667
return this;
5768
}
5869

70+
@Nullable
71+
public String getBody() {
72+
return body;
73+
}
74+
75+
public Message withBody(@Nullable String body) {
76+
this.body = body;
77+
return this;
78+
}
79+
80+
public void redactBody() {
81+
body = REDACTED_CONTEXT_STRING;
82+
}
83+
84+
public Message addHeader(String key, String value) {
85+
headers.add(key, value);
86+
return this;
87+
}
88+
89+
public NoRandomAccessMap<String, String> getHeaders() {
90+
return headers;
91+
}
92+
5993
public boolean hasContent() {
60-
return queueName != null || topicName != null;
94+
return queueName != null || topicName != null || body != null || headers.size() > 0;
6195
}
6296

6397
@Override
6498
public void resetState() {
6599
queueName = null;
66100
topicName = null;
101+
body = null;
102+
headers.resetState();
67103
}
68104

69105
public void copyFrom(Message other) {
70106
this.queueName = other.getQueueName();
71107
this.topicName = other.getTopicName();
108+
this.body = other.body;
109+
this.headers.copyFrom(other.getHeaders());
72110
}
73111
}

apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Request.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import java.nio.CharBuffer;
3939
import java.util.Enumeration;
4040

41+
import static co.elastic.apm.agent.impl.context.AbstractContext.REDACTED_CONTEXT_STRING;
42+
4143

4244
/**
4345
* Request
@@ -130,7 +132,7 @@ public void setRawBody(String rawBody) {
130132
}
131133

132134
public void redactBody() {
133-
setRawBody("[REDACTED]");
135+
setRawBody(REDACTED_CONTEXT_STRING);
134136
}
135137

136138
public Request addFormUrlEncodedParameter(String key, String value) {
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -22,7 +22,7 @@
2222
* under the License.
2323
* #L%
2424
*/
25-
package co.elastic.apm.agent.web;
25+
package co.elastic.apm.agent.impl.context;
2626

2727
import co.elastic.apm.agent.configuration.CoreConfiguration;
2828
import co.elastic.apm.agent.impl.context.Request;
@@ -34,12 +34,13 @@
3434
import co.elastic.apm.agent.util.PotentiallyMultiValuedMap;
3535
import org.stagemonitor.configuration.ConfigurationRegistry;
3636

37+
import static co.elastic.apm.agent.impl.context.AbstractContext.REDACTED_CONTEXT_STRING;
38+
3739
/**
3840
* Sanitizes web-related fields according to the {@link CoreConfiguration#sanitizeFieldNames} setting
3941
*/
4042
public class SanitizingWebProcessor implements Processor {
4143

42-
static final String REDACTED = "[REDACTED]";
4344
private final CoreConfiguration config;
4445

4546
public SanitizingWebProcessor(ConfigurationRegistry configurationRegistry) {
@@ -75,7 +76,7 @@ private void sanitizeRequest(Request request) {
7576
private void sanitizeMap(PotentiallyMultiValuedMap map) {
7677
for (int i = 0; i < map.size(); i++) {
7778
if (isSensitive(map.getKey(i))) {
78-
map.set(i, REDACTED);
79+
map.set(i, REDACTED_CONTEXT_STRING);
7980
}
8081
}
8182
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -22,7 +22,7 @@
2222
* under the License.
2323
* #L%
2424
*/
25-
package co.elastic.apm.agent.web;
25+
package co.elastic.apm.agent.impl.context.web;
2626

2727
import javax.annotation.Nullable;
2828

0 commit comments

Comments
 (0)