2017-06-19 32 views
0

我正在使用groovy配置和logback。偶爾,我會記錄一個目錄或文件位置,並且我希望它作爲鏈接出現在我的HTML日誌中。這是我的配置目前的樣子。logback中的格式鏈接

appender("htmlLog", FileAppender) { 
    file = "${logPath}/${logName}.html" 
    append = false 
    encoder(LayoutWrappingEncoder) { 
    layout("ch.qos.logback.classic.html.HTMLLayout"){ 
     pattern = "%d{yyyy/MM/dd HH:mm:ss}%-5p%logger{0}%m" 
    } 
    } 
} 

任何人都有一個想法,我怎麼能得到這個?

回答

1

在表格中生成錨標記或任何其他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

+0

這是一個激烈的,不錯的工作!你有沒有這個,或者你是否只是爲了這個問題而構建它? – Steve

+0

我正確的說%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

+0

@Steve是它代替'%m'。我使用'conversionRule(「linkEscaper」,LinkConverter.class)''在logback配置的頂部附近註冊它。爲此問題構建它。 – roby