在表格中生成锚标记或任何其他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