格式化登录中的链接 [英] Format links in logback

查看:84
本文介绍了格式化登录中的链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Groovy配置与Logback一起使用.有时,我会记录一个目录或文件位置,我希望它作为链接出现在我的HTML日志中.这是我当前的配置.

I am using groovy configuration with logback. Occasionally, I will log a directory or file location, and I'd like it to come up in my HTML log as a link. Here is what my configuration looks like currently.

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" 
    }
  }
}

有人对我如何获得这个想法有想法吗?

Anyone have a thought as to how I could get this?

推荐答案

在表中生成锚标记或任何其他HTML有两个障碍.我正在尝试注销1.2.3

There are two obstacles to generating anchor tags or any other HTML within the table. I'm working against logback 1.2.3

首先,您需要一种转换消息,查找路径并将其替换为锚点的方法.创建可从该模式使用的自定义转换器非常简单,并且在此处记录.我的粗略实现看起来像这样,您可能需要修改路径检测以适合您:

First you need a way to convert your message, looking for paths and replacing them with anchors. Creating custom converters that you can use from the pattern is straightforward and documented here. My crude implementation looks like this, you'll probably want to modify the path detection to suit you:

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 之类的字符串.

This is attempting to escape any suspicious characters before replacing strings like /path/to/thing with an anchor tag.

其次,HTMLLayout

Secondly, the HTMLLayout escapes everything, this is so it doesn't generate a malformed table and improves security (scripts can't be injected etc). So even with your new converter wired up and referenced correctly HTMLLayout will escape the anchor.

要解决此问题,我扩展了HTMLLayout,不幸的是,您必须重写类的内胆并将其放在同一包中以访问包私有字段.

To get around this I extended HTMLLayout, unfortunately you have to override the guts of the class and put it in the same package to access package private fields.

您要更改的只是转义行,我将其更改为 String s = c.getClass().equals(LinkConverter.class)吗?c.convert(event):Transform.escapeTags(c.convert(event)); 尝试将影响降到最低.

All you want to change is the escaping line, I changed it to String s = c.getClass().equals(LinkConverter.class) ? c.convert(event): Transform.escapeTags(c.convert(event)); to try and minimise the impact.

这是完整的实现:

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);
    }
}

我的最终登录配置如下:

My final logback configuration looks like this:

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"])

这是我使用此代码的存储库.

这篇关于格式化登录中的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆