Skip to content

Commit 35d7f43

Browse files
Fix escaping of thread and logger
1 parent 55485ae commit 35d7f43

File tree

3 files changed

+64
-77
lines changed

3 files changed

+64
-77
lines changed

cf-java-logging-support-log4j2/src/main/java/com/sap/hcp/cf/log4j2/layout/LayoutPatternBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public LayoutPatternBuilder addRequestMetrics() {
4040

4141
public LayoutPatternBuilder addBasicApplicationLogs() {
4242
appendQuoted(Fields.TYPE, Defaults.TYPE_LOG).append(",");
43-
appendQuoted(Fields.LOGGER, "%logger").append(",");
44-
appendQuoted(Fields.THREAD, "%thread").append(",");
43+
appendQuoted(Fields.LOGGER, "%replace{%logger}{\"}{\\\\\"}").append(",");
44+
appendQuoted(Fields.THREAD, "%replace{%thread}{\"}{\\\\\"}").append(",");
4545
appendQuoted(Fields.LEVEL, "%p").append(",");
4646
appendUnquoted(Fields.CATEGORIES, "%categories").append(",");
4747
appendUnquoted(Fields.MSG, "%jsonmsg{escape}").append(",");

cf-java-logging-support-log4j2/src/test/java/com/sap/hcp/cf/log4j2/layout/LayoutPatternBuilderTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void basicApplicationLogs() throws Exception {
3737
String pattern = new LayoutPatternBuilder().addBasicApplicationLogs().build();
3838

3939
assertThat(pattern, specificPart(is(
40-
",\"type\":\"log\",\"logger\":\"%logger\",\"thread\":\"%thread\",\"level\":\"%p\",\"categories\":%categories,\"msg\":%jsonmsg{escape}")));
40+
",\"type\":\"log\",\"logger\":\"%replace{%logger}{\"}{\\\\\"}\",\"thread\":\"%replace{%thread}{\"}{\\\\\"}\",\"level\":\"%p\",\"categories\":%categories,\"msg\":%jsonmsg{escape}")));
4141
}
4242

4343
@Test
@@ -83,7 +83,7 @@ public void applicationScenario() throws Exception {
8383
.suppressExceptions().build();
8484

8585
assertThat(pattern, specificPart(is(
86-
",\"type\":\"log\",\"logger\":\"%logger\",\"thread\":\"%thread\",\"level\":\"%p\",\"categories\":%categories,\"msg\":%jsonmsg{escape},%ctxp{excluded-field},\"custom_fields\":{%cf{custom-field}}%ex{0} ")));
86+
",\"type\":\"log\",\"logger\":\"%replace{%logger}{\"}{\\\\\"}\",\"thread\":\"%replace{%thread}{\"}{\\\\\"}\",\"level\":\"%p\",\"categories\":%categories,\"msg\":%jsonmsg{escape},%ctxp{excluded-field},\"custom_fields\":{%cf{custom-field}}%ex{0} ")));
8787
}
8888

8989
@Test
@@ -93,7 +93,7 @@ public void exceptionScenario() throws Exception {
9393
.build();
9494

9595
assertThat(pattern, specificPart(is(
96-
",\"type\":\"log\",\"logger\":\"%logger\",\"thread\":\"%thread\",\"level\":\"%p\",\"categories\":%categories,\"msg\":%jsonmsg{escape},%ctxp{excluded-field},\"custom_fields\":{%cf{custom-field}},\"stacktrace\":%stacktrace")));
96+
",\"type\":\"log\",\"logger\":\"%replace{%logger}{\"}{\\\\\"}\",\"thread\":\"%replace{%thread}{\"}{\\\\\"}\",\"level\":\"%p\",\"categories\":%categories,\"msg\":%jsonmsg{escape},%ctxp{excluded-field},\"custom_fields\":{%cf{custom-field}},\"stacktrace\":%stacktrace")));
9797
}
9898

9999
private static Matcher<String> specificPart(Matcher<String> expected) {

cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/encoder/LayoutPatterns.java

Lines changed: 59 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,85 +11,72 @@
1111
*/
1212
public final class LayoutPatterns {
1313

14-
public static enum PATTERN_KEY {
15-
APPLICATION, EXCEPTION, REQUEST
16-
}
14+
public static enum PATTERN_KEY {
15+
APPLICATION, EXCEPTION, REQUEST
16+
}
1717

18-
/*
19-
* -- this is the common prefix to all variants. -- the final line will add
20-
* non-predefined context parameters from the MDC -- as this list may be
21-
* empty, we use "replace" to at a colon if it's not
22-
*/
23-
private static final String COMMON_PREFIX_PATTERN = "{ " + JSON_FIELD(Fields.WRITTEN_AT,
24-
"%d{yyyy-MM-dd'T'HH:mm:ss.SSSX,UTC}", true,
25-
true) + JSON_FIELD(Fields.WRITTEN_TS,
26-
"%tstamp", false, false) +
27-
"%replace(%ctxp){'(.+)', ',$1'},";
18+
/*
19+
* -- this is the common prefix to all variants. -- the final line will add
20+
* non-predefined context parameters from the MDC -- as this list may be empty,
21+
* we use "replace" to at a colon if it's not
22+
*/
23+
private static final String COMMON_PREFIX_PATTERN = "{ "
24+
+ JSON_FIELD(Fields.WRITTEN_AT, "%d{yyyy-MM-dd'T'HH:mm:ss.SSSX,UTC}", true, true)
25+
+ JSON_FIELD(Fields.WRITTEN_TS, "%tstamp", false, false) + "%replace(%ctxp){'(.+)', ',$1'},";
2826

29-
/*
30-
* -- all layout patterns end like this
31-
*/
32-
private static final String COMMON_POSTFIX_PATTERN = "}%n";
27+
/*
28+
* -- all layout patterns end like this
29+
*/
30+
private static final String COMMON_POSTFIX_PATTERN = "}%n";
3331

34-
/*
35-
* -- for standard application log messages we always add these fields. --
36-
* note the last line where we make sure that the original message string --
37-
* is quoted and properly escaped and that "custom fields" are added
38-
*/
39-
private static final String APP_PREFIX_PATTERN = JSON_FIELD(Fields.TYPE, Defaults.TYPE_LOG, true, true) +
40-
JSON_FIELD(Fields.LOGGER, "%logger", true, true) + JSON_FIELD(
41-
Fields.THREAD, "%thread", true, true) +
42-
JSON_FIELD(Fields.LEVEL, "%p", true, true) + JSON_FIELD(
43-
Fields.CATEGORIES,
44-
"%categories",
45-
false,
46-
true) +
47-
JSON_FIELD(Fields.MSG,
48-
"%jsonmsg{escape}%replace(%args{custom_fields}){'(.+)', ',$1'}",
49-
false, false);
32+
/*
33+
* -- for standard application log messages we always add these fields. -- note
34+
* the last line where we make sure that the original message string -- is
35+
* quoted and properly escaped and that "custom fields" are added
36+
*/
37+
private static final String APP_PREFIX_PATTERN = JSON_FIELD(Fields.TYPE, Defaults.TYPE_LOG, true, true)
38+
+ JSON_FIELD(Fields.LOGGER, "%replace(%logger){'\"','\\\\\"'}", true, true)
39+
+ JSON_FIELD(Fields.THREAD, "%replace(%thread){'\"','\\\\\"'}", true, true)
40+
+ JSON_FIELD(Fields.LEVEL, "%p", true, true) + JSON_FIELD(Fields.CATEGORIES, "%categories", false, true)
41+
+ JSON_FIELD(Fields.MSG, "%jsonmsg{escape}%replace(%args{custom_fields}){'(.+)', ',$1'}", false, false);
5042

51-
/*
52-
* -- a simple application log message does not include exception/stack
53-
* trace info
54-
*/
55-
private static final String APP_LOG_PATTERN = COMMON_PREFIX_PATTERN + APP_PREFIX_PATTERN + "%nopex " +
56-
COMMON_POSTFIX_PATTERN;
43+
/*
44+
* -- a simple application log message does not include exception/stack trace
45+
* info
46+
*/
47+
private static final String APP_LOG_PATTERN = COMMON_PREFIX_PATTERN + APP_PREFIX_PATTERN + "%nopex "
48+
+ COMMON_POSTFIX_PATTERN;
5749

58-
/*
59-
* -- if the application log was written including stack trace info, write
60-
* it out! -- to avoid any trouble with our event processing pipeline that
61-
* expect a single -- line message, make sure newlines and tabs are escaped.
62-
* -- newlines are actually escaped with additional surrounding spaces to
63-
* make the -- standard ES tokenizer work
64-
*/
65-
private static final String APP_EX_LOG_PATTERN = COMMON_PREFIX_PATTERN + APP_PREFIX_PATTERN + "," + JSON_FIELD(
66-
Fields.STACKTRACE,
67-
"%stacktrace",
68-
false,
69-
false) +
70-
"%nopex " + COMMON_POSTFIX_PATTERN;
50+
/*
51+
* -- if the application log was written including stack trace info, write it
52+
* out! -- to avoid any trouble with our event processing pipeline that expect a
53+
* single -- line message, make sure newlines and tabs are escaped. -- newlines
54+
* are actually escaped with additional surrounding spaces to make the --
55+
* standard ES tokenizer work
56+
*/
57+
private static final String APP_EX_LOG_PATTERN = COMMON_PREFIX_PATTERN + APP_PREFIX_PATTERN + ","
58+
+ JSON_FIELD(Fields.STACKTRACE, "%stacktrace", false, false) + "%nopex " + COMMON_POSTFIX_PATTERN;
7159

72-
/*
73-
* -- if we write a request log/"beat" all we want/need is already in the
74-
* message (object), but -- we need to flatten it as we don't want nested
75-
* JSON objects.
76-
*/
77-
private static final String REQUEST_METRICS_PATTERN = COMMON_PREFIX_PATTERN + JSON_FIELD(Fields.TYPE,
78-
Defaults.TYPE_REQUEST,
79-
true, true) +
80-
"%jsonmsg{flatten}%nopex" + COMMON_POSTFIX_PATTERN;
60+
/*
61+
* -- if we write a request log/"beat" all we want/need is already in the
62+
* message (object), but -- we need to flatten it as we don't want nested JSON
63+
* objects.
64+
*/
65+
private static final String REQUEST_METRICS_PATTERN = COMMON_PREFIX_PATTERN
66+
+ JSON_FIELD(Fields.TYPE, Defaults.TYPE_REQUEST, true, true) + "%jsonmsg{flatten}%nopex"
67+
+ COMMON_POSTFIX_PATTERN;
8168

82-
public static String getPattern(PATTERN_KEY key) {
83-
switch (key) {
84-
case REQUEST:
85-
return REQUEST_METRICS_PATTERN;
69+
public static String getPattern(PATTERN_KEY key) {
70+
switch (key) {
71+
case REQUEST:
72+
return REQUEST_METRICS_PATTERN;
8673

87-
case EXCEPTION:
88-
return APP_EX_LOG_PATTERN;
74+
case EXCEPTION:
75+
return APP_EX_LOG_PATTERN;
8976

90-
case APPLICATION:
91-
default:
92-
return APP_LOG_PATTERN;
93-
}
94-
}
77+
case APPLICATION:
78+
default:
79+
return APP_LOG_PATTERN;
80+
}
81+
}
9582
}

0 commit comments

Comments
 (0)