From e4efd0f634036b4cdd565544b5cc1ab0d8f3da22 Mon Sep 17 00:00:00 2001 From: zheliu2 <770120041@qq.com> Date: Mon, 9 Mar 2026 12:10:51 -0400 Subject: [PATCH 1/2] Fix JSON escaping in task details log metadata (#8528) Wrap OpenSearchMessageField values with %enc{...}{JSON} in the OpenSearchJsonLayout pattern to ensure proper JSON escaping of field values that may contain quotes or other special characters. Signed-off-by: zheliu2 <770120041@qq.com> --- .../logging/OpenSearchJsonLayoutTests.java | 6 +++--- .../common/logging/OpenSearchJsonLayout.java | 2 +- .../SearchShardTaskDetailsLogMessageTests.java | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/qa/logging-config/src/test/java/org/opensearch/common/logging/OpenSearchJsonLayoutTests.java b/qa/logging-config/src/test/java/org/opensearch/common/logging/OpenSearchJsonLayoutTests.java index 0a8bd46ac96f3..b5d820329d30a 100644 --- a/qa/logging-config/src/test/java/org/opensearch/common/logging/OpenSearchJsonLayoutTests.java +++ b/qa/logging-config/src/test/java/org/opensearch/common/logging/OpenSearchJsonLayoutTests.java @@ -122,8 +122,8 @@ public void testLayoutWithAdditionalFields() { "\"cluster.name\": \"${sys:opensearch.logs.cluster_name}\", " + "\"node.name\": \"%node_name\", " + "\"message\": \"%notEmpty{%enc{%marker}{JSON} }%enc{%.-10000m}{JSON}\"" + - "%notEmpty{, \"x-opaque-id\": \"%OpenSearchMessageField{x-opaque-id}\"}" + - "%notEmpty{, \"someOtherField\": \"%OpenSearchMessageField{someOtherField}\"}" + + "%notEmpty{, \"x-opaque-id\": \"%enc{%OpenSearchMessageField{x-opaque-id}}{JSON}\"}" + + "%notEmpty{, \"someOtherField\": \"%enc{%OpenSearchMessageField{someOtherField}}{JSON}\"}" + "%notEmpty{, %node_and_cluster_id }" + "%exceptionAsJson }" + System.lineSeparator())); } @@ -143,7 +143,7 @@ public void testLayoutWithAdditionalFieldOverride() { "\"component\": \"%c{1.}\", " + "\"cluster.name\": \"${sys:opensearch.logs.cluster_name}\", " + "\"node.name\": \"%node_name\"" + - "%notEmpty{, \"message\": \"%OpenSearchMessageField{message}\"}" + + "%notEmpty{, \"message\": \"%enc{%OpenSearchMessageField{message}}{JSON}\"}" + "%notEmpty{, %node_and_cluster_id }" + "%exceptionAsJson }" + System.lineSeparator())); } diff --git a/server/src/main/java/org/opensearch/common/logging/OpenSearchJsonLayout.java b/server/src/main/java/org/opensearch/common/logging/OpenSearchJsonLayout.java index 60df94036cc6b..a902a9dfc1d82 100644 --- a/server/src/main/java/org/opensearch/common/logging/OpenSearchJsonLayout.java +++ b/server/src/main/java/org/opensearch/common/logging/OpenSearchJsonLayout.java @@ -133,7 +133,7 @@ private String pattern(String type, String[] opensearchMessageFields, int maxMes map.put("message", inQuotes("%notEmpty{%enc{%marker}{JSON} }%enc{" + messageFormat + "}{JSON}")); for (String key : opensearchMessageFields) { - map.put(key, inQuotes("%OpenSearchMessageField{" + key + "}")); + map.put(key, inQuotes("%enc{%OpenSearchMessageField{" + key + "}}{JSON}")); } return createPattern(map, Stream.of(opensearchMessageFields).collect(Collectors.toSet())); } diff --git a/server/src/test/java/org/opensearch/tasks/consumer/SearchShardTaskDetailsLogMessageTests.java b/server/src/test/java/org/opensearch/tasks/consumer/SearchShardTaskDetailsLogMessageTests.java index 099f70a3b14d3..bc0a0297bb4b5 100644 --- a/server/src/test/java/org/opensearch/tasks/consumer/SearchShardTaskDetailsLogMessageTests.java +++ b/server/src/test/java/org/opensearch/tasks/consumer/SearchShardTaskDetailsLogMessageTests.java @@ -58,4 +58,21 @@ public void testTaskDetailsLogHasJsonFields() { equalTo("{0=[{cpu_time_in_nanos=100, memory_in_bytes=100}, stats_type=worker_stats, is_active=true, threadId=0]}") ); } + + public void testTaskDetailsLogWithJsonMetadata() { + String jsonMetadata = "{\"query\":{\"match_all\":{}},\"size\":10}"; + SearchShardTask task = new SearchShardTask( + 1, + "transport", + "indices:data/read/search[phase/query]", + "test", + null, + Collections.singletonMap(Task.X_OPAQUE_ID, "my_id"), + () -> jsonMetadata + ); + SearchShardTaskDetailsLogMessage p = new SearchShardTaskDetailsLogMessage(task); + + // Verify that metadata with JSON content is stored correctly + assertThat(p.getValueFor("metadata"), equalTo(jsonMetadata)); + } } From a5bbbfd424f658b8a375831defc54adaefb71998 Mon Sep 17 00:00:00 2001 From: zheliu2 <770120041@qq.com> Date: Tue, 10 Mar 2026 11:45:43 -0400 Subject: [PATCH 2/2] Add CHANGELOG entry for #20802 Signed-off-by: zheliu2 <770120041@qq.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 420e0fa3bdf3d..494feaaf1bbe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Fix ShardSearchFailure in transport-grpc ([#20641](https://github.com/opensearch-project/OpenSearch/pull/20641)) - Fix TLS cert hot-reload for Arrow Flight transport ([#20732](https://github.com/opensearch-project/OpenSearch/pull/20732)) - Fix misleading heap usage cancellation message in SearchBackpressureService ([#20779](https://github.com/opensearch-project/OpenSearch/pull/20779)) +- Fix JSON escaping in task details log metadata ([#20802](https://github.com/opensearch-project/OpenSearch/pull/20802)) ### Dependencies - Bump shadow-gradle-plugin from 8.3.9 to 9.3.1 ([#20569](https://github.com/opensearch-project/OpenSearch/pull/20569))