如何在log4j中只转义信息而不是所有行?[英] How to escape only message instead of all row in log4j?

本文是小编为大家收集整理的关于如何在log4j中只转义信息而不是所有行?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有以下模式:

public class EscapedEnhancedPatternLayout extends EnhancedPatternLayout {
    @Override
    public String format(LoggingEvent event) {
        return StringEscapeUtils.escapeJava(super.format(event));
    }
}

但这逃脱了完整的记录行.

我想拥有这样的东西,但仅用于消息.

但是LoggingEvent类没有setMessage和setRenderedMessage方法.

我看不到LoggingEvent的复制构造函数.如果LoggingEvent有复制构造函数,我可以从LoggingEvent继承,并在下面提到的覆盖方法.

请告知我如何解决我的问题.

推荐答案

您是对的,没有LoggingEvent(LoggingEvent other)构造函数,但是您可以将事件的值传递给在您的format方法中:

@Override
public String format(LoggingEvent event) {
    Object msgObj = event.getMessage();

    LoggingEvent newEvent = new LoggingEvent(
        event.getFQNOfLoggerClass(),
        event.getLogger(), event.getTimeStamp(),
        event.getLevel(),
        StringEscapeUtils.escapeJava(msgObj != null ? msgObj.toString() : null),
        event.getThreadName(),
        event.getThrowableInformation(),
        event.getNDC(),
        event.getLocationInformation(),
        event.getProperties());

    return super.format(newEvent);
}

这将从旧值中创建一个新的LoggingEvent. StringEscapeUtils.escapeJava方法现在可以修改message而不会影响其他属性,您仍然可以使用super.format

其他推荐答案

另一种方法可能是创建自定义LogEventFactory. A LogEventFactory用于生成凸坑.应用程序可以通过将系统属性Log4jLogEventFactory的值设置为自定义LogeVentFactory类的名称来替换标准LogEventFactory.

创建LogEvent实例的方法如下:

LogEvent createEvent(String loggerName,
               org.apache.logging.log4j.Marker marker,
               String fqcn,
               org.apache.logging.log4j.Level level,
               org.apache.logging.log4j.message.Message data,
               List<Property> properties,
               Throwable t)

和DefaultLogEventFactory是log4j的基本实现.在您的情况下,您可以扩展基本实现并逃脱消息,然后拨打默认实现.它会成为这样的东西:

public class MyCustomLogEventFactory extends DefaultLogEventFactory {

    /**
     * Creates a log event.
     *
     * @param loggerName The name of the Logger.
     * @param marker An optional Marker.
     * @param fqcn The fully qualified class name of the caller.
     * @param level The event Level.
     * @param data The Message.
     * @param properties Properties to be added to the log event.
     * @param t An optional Throwable.
     * @return The LogEvent.
     */
     @Override
    public LogEvent createEvent(final String loggerName, final Marker marker,
                             final String fqcn, final Level level, final Message data,
                             final List<Property> properties, final Throwable t) {
        super.createEvent(loggerName, marker, fqcn, level, StringEscapeUtils.escapeJava(data != null ? data.toString() : null), properties, t);
    }
}

本文地址:https://www.itbaoku.cn/post/1575006.html

问题描述

I have the following PatternLayout:

public class EscapedEnhancedPatternLayout extends EnhancedPatternLayout {
    @Override
    public String format(LoggingEvent event) {
        return StringEscapeUtils.escapeJava(super.format(event));
    }
}

but this escapes full logging row.

I want to have something like this but only for message.

but LoggingEvent class has not setMessage and setRenderedMessage methods.

And I don't see copy constructor at LoggingEvent. If LoggingEvent had copy constructor I can inherited from LoggingEvent and override methods mentioned below.

Please advise me how to solve my issue.

推荐答案

You're right, there is no LoggingEvent(LoggingEvent other) constructor, but you can pass the event's values to the LoggingEvent constructor in your format method like this:

@Override
public String format(LoggingEvent event) {
    Object msgObj = event.getMessage();

    LoggingEvent newEvent = new LoggingEvent(
        event.getFQNOfLoggerClass(),
        event.getLogger(), event.getTimeStamp(),
        event.getLevel(),
        StringEscapeUtils.escapeJava(msgObj != null ? msgObj.toString() : null),
        event.getThreadName(),
        event.getThrowableInformation(),
        event.getNDC(),
        event.getLocationInformation(),
        event.getProperties());

    return super.format(newEvent);
}

This will create a new LoggingEvent from the old one with all values set. The StringEscapeUtils.escapeJava method can now modify the the message without affecting the other properties and you can still use super.format

其他推荐答案

An alternative approach could be to create a customized LogEventFactory. A LogEventFactory is used to generate LogEvents. Applications may replace the standard LogEventFactory by setting the value of the system property Log4jLogEventFactory to the name of the custom LogEventFactory class.

The method that will be called to create a instance of LogEvent is as follows:

LogEvent createEvent(String loggerName,
               org.apache.logging.log4j.Marker marker,
               String fqcn,
               org.apache.logging.log4j.Level level,
               org.apache.logging.log4j.message.Message data,
               List<Property> properties,
               Throwable t)

and DefaultLogEventFactory is the basic implementation for log4j. In your case you could extend the basic implementation and escape the message after which you call the default implementation. It would become something like this:

public class MyCustomLogEventFactory extends DefaultLogEventFactory {

    /**
     * Creates a log event.
     *
     * @param loggerName The name of the Logger.
     * @param marker An optional Marker.
     * @param fqcn The fully qualified class name of the caller.
     * @param level The event Level.
     * @param data The Message.
     * @param properties Properties to be added to the log event.
     * @param t An optional Throwable.
     * @return The LogEvent.
     */
     @Override
    public LogEvent createEvent(final String loggerName, final Marker marker,
                             final String fqcn, final Level level, final Message data,
                             final List<Property> properties, final Throwable t) {
        super.createEvent(loggerName, marker, fqcn, level, StringEscapeUtils.escapeJava(data != null ? data.toString() : null), properties, t);
    }
}