[logback-dev] [JIRA] (LOGBACK-1505) HTMLLayout - Performance Issue
QOS.CH (JIRA)
noreply-jira at qos.ch
Fri Feb 14 23:25:00 CET 2020
Kapil Patil created LOGBACK-1505:
------------------------------------
Summary: HTMLLayout - Performance Issue
Key: LOGBACK-1505
URL: https://jira.qos.ch/browse/LOGBACK-1505
Project: logback
Issue Type: Improvement
Components: logback-core
Affects Versions: 1.3.0-alpha5, 1.1.8
Environment: Issue is not limited to any OS & hardware combination.
Reporter: Kapil Patil
Assignee: Logback dev list
I observed this performance issue in 1.1.8 onward and even in latest 1.3.0-alpha5, same issue is present.
=============================================
Problem statement:
=============================================
We had configured SMTPAppender to generate error emails using HTMLLayout using default pattern.
In production env, our process end up generating logger.error with 27MB of message which also had data (I know that at first place our system should not have generated 27MB of error message but that want happened and we observed this performance issue.)
Here logback HTMLLayout was running for 70mins just to process that 27MB of data.
I know you might think I am stupid, but was able to trace root cause.
Performance issue is present in
ch.qos.logback.core.helpers.Transformer::escapeTags(final StringBuffer buf) method.
They way it is replacing and encoding html characters is not efficient, each replace is doing System.arraycopy which was issue.
Much better and correct way can be found in Log4j implementation of escapeTags
as shown below. this only taken approx 280millis to process same 27MB vs 70mins taken by logback implementation.
public static String escapeHtmlTags(String input) \{
if (Strings.isEmpty(input) || input.indexOf(34) == -1 && input.indexOf(38) == -1 && input.indexOf(60) == -1 && input.indexOf(62) == -1 && input.indexOf(39) == -1 ) \{
return input;
} else \{
StringBuilder buf = new StringBuilder(input.length() + 6);
int len = input.length();
for (int i = 0; i < len; ++i) \{
char ch = input.charAt(i);
if (ch > '>') \{
buf.append(ch);
} else if (ch == '<') \{
buf.append("<");
} else if (ch == '>') \{
buf.append(">");
} else if (ch == '&') \{
buf.append("&");
} else if (ch == '"') \{
buf.append(""");
} else if (ch == '\'') \{
buf.append("'");
} else \{
buf.append(ch);
}
}
return buf.toString();
}
}
--
This message was sent by Atlassian JIRA
(v7.3.1#73012)
More information about the logback-dev
mailing list