在表格中生成錨標記或任何其他HTML有兩個障礙。我正在對抗logback 1.2.3
首先,您需要一種方法來轉換您的消息,尋找路徑並將其替換爲錨點。創建可以在模式中使用的自定義轉換器非常簡單,並且可以使用documented here。我的原油實現看起來是這樣,你可能要修改的路徑檢測,以滿足您:
package ch.qos.logback.classic.html;
import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.helpers.Transform;
public class LinkConverter extends ClassicConverter {
public String convert(ILoggingEvent iLoggingEvent) {
String message = iLoggingEvent.getMessage();
message = Transform.escapeTags(message);
message = message.replaceAll(" (/\\S+)", " <a href=\"$1\">file://$1</a>");
return message;
}
}
這是試圖用一個錨標記替換像/path/to/thing
字符串之前轉義任何可疑人物。
其次,HTMLLayout escapes everything,這是因爲它不會生成格式不正確的表並提高安全性(腳本不能被注入等)。所以,即使您的新轉換器連線並正確引用,HTMLLayout也會逃離主播。
爲了解決這個問題,我擴展了HTMLLayout,但不幸的是,您必須重寫該類的內涵並將其放在同一個包中以訪問包專用字段。
所有你想改變的是逃跑線,我改變它爲String s = c.getClass().equals(LinkConverter.class) ? c.convert(event): Transform.escapeTags(c.convert(event));
試圖儘量減少影響。
這裏是全面實施:
package ch.qos.logback.classic.html;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.helpers.Transform;
import ch.qos.logback.core.pattern.Converter;
public class UnsafeHTMLLayout extends HTMLLayout{
public String doLayout(ILoggingEvent event) {
StringBuilder buf = new StringBuilder();
this.startNewTableIfLimitReached(buf);
boolean odd = true;
if((this.counter++ & 1L) == 0L) {
odd = false;
}
String level = event.getLevel().toString().toLowerCase();
buf.append(CoreConstants.LINE_SEPARATOR);
buf.append("<tr class=\"");
buf.append(level);
if(odd) {
buf.append(" odd\">");
} else {
buf.append(" even\">");
}
buf.append(CoreConstants.LINE_SEPARATOR);
for(Converter c = this.head; c != null; c = c.getNext()) {
this.appendEventToBuffer(buf, c, event);
}
buf.append("</tr>");
buf.append(CoreConstants.LINE_SEPARATOR);
if(event.getThrowableProxy() != null) {
this.throwableRenderer.render(buf, event);
}
return buf.toString();
}
private void appendEventToBuffer(StringBuilder buf, Converter<ILoggingEvent> c, ILoggingEvent event) {
buf.append("<td class=\"");
buf.append(this.computeConverterName(c));
buf.append("\">");
String s = c.getClass().equals(LinkConverter.class) ? c.convert(event): Transform.escapeTags(c.convert(event));
buf.append(s);
buf.append("</td>");
buf.append(CoreConstants.LINE_SEPARATOR);
}
}
我最後的logback的配置是這樣的:
import ch.qos.logback.classic.html.LinkConverter
conversionRule("linkEscaper", LinkConverter.class)
appender("htmlLog", FileAppender) {
file = "/tmp/out.html"
append = false
encoder(LayoutWrappingEncoder) {
layout("ch.qos.logback.classic.html.UnsafeHTMLLayout"){
pattern = "%d{yyyy/MM/dd HH:mm:ss}%-5p%logger{0}%linkEscaper"
}
}
}
root(INFO, ["htmlLog"])
這裏是my repo with this code。
這是一個激烈的,不錯的工作!你有沒有這個,或者你是否只是爲了這個問題而構建它? – Steve
我正確的說%linkEscaper取代了模式中的%m嗎?我的問題是,log.info(「blahblah {}」,var)不會替代 layout(「ch.qos.logback.classic.html.CustomHTMLLayout」){pattern =「%d {yyyy/MM/dd HH:mm:ss}% - 5p%logger {0}%linkEscaper「} – Steve
@Steve是它代替'%m'。我使用'conversionRule(「linkEscaper」,LinkConverter.class)''在logback配置的頂部附近註冊它。爲此問題構建它。 – roby