首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >logback:异常堆栈跟踪之前的newline,而不是其他?

logback:异常堆栈跟踪之前的newline,而不是其他?
EN

Stack Overflow用户
提问于 2015-05-27 10:43:54
回答 1查看 1.5K关注 0票数 5

如果我在日志模式中的异常堆栈跟踪之前放置了一个换行符:

代码语言:javascript
运行
复制
<Pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} %msg %n %rEx{short} %n</Pattern>

然后打印一个额外的换行符,这样普通的日志语句之间就会出现空行。

如果我删除额外的换行符:

代码语言:javascript
运行
复制
<Pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} %msg %rEx{short} %n</Pattern>

然后,堆栈跟踪不会从新行开始,这使得它们很难阅读。

谁能想到一种方法,让登录回只打印额外的换行符时,有一个堆栈跟踪,而不是其他?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-15 20:05:51

我有一个可行的解决方案,但我不喜欢它,因为它被过度设计,应该更优雅。

这是一个更一般问题的具体情况:只有当某个评估器(检查异常是否存在)匹配时,才输出模式。我很久以前就从这里得到了实现。

需要janino。如果有比我更有登录经验的人可以将其缩减到更合理的代码量,请这样做。

IfPresentConverter.java

代码语言:javascript
运行
复制
public class IfPresentConverter extends CompositeConverter<ILoggingEvent> {
    private final List<EventEvaluator<ILoggingEvent>> evaluatorList = new ArrayList<>();
    private int errorCount = 0;

    @Override
    @SuppressWarnings("unchecked")
    public void start() {
        final List<String> optionList = getOptionList();
        final Map<?, ?> evaluatorMap = (Map<?, ?>) getContext().getObject(CoreConstants.EVALUATOR_MAP);

        for (final String evaluatorStr : optionList) {
            final EventEvaluator<ILoggingEvent> ee = (EventEvaluator<ILoggingEvent>) evaluatorMap.get(evaluatorStr);
            if (ee != null) {
                evaluatorList.add(ee);
            }
        }

        if (evaluatorList.isEmpty()) {
            addError("At least one evaluator is expected, but you have declared none.");
            return;
        }

        super.start();
    }

    @Override
    public String convert(final ILoggingEvent event) {
        boolean evalResult = true;
        for (final EventEvaluator<ILoggingEvent> ee : evaluatorList) {
            try {
                if (!ee.evaluate(event)) {
                    evalResult = false;
                    break;
                }
            } catch (final EvaluationException eex) {
                evalResult = false;

                errorCount++;
                if (errorCount < CoreConstants.MAX_ERROR_COUNT) {
                    addError("Exception thrown for evaluator named [" + ee.getName() + "].", eex);
                } else {
                    final ErrorStatus errorStatus = new ErrorStatus("Exception thrown for evaluator named [" + ee.getName() + "].", this, eex);
                    errorStatus.add(new ErrorStatus("This was the last warning about this evaluator's errors. " + "We don't want the StatusManager to get flooded.", this));
                    addStatus(errorStatus);
                }
            }
        }

        if (evalResult) {
            return super.convert(event);
        } else {
            return CoreConstants.EMPTY_STRING;
        }
    }

    @Override
    protected String transform(final ILoggingEvent event, final String in) {
        return in;
    }
}

logback.xml

代码语言:javascript
运行
复制
<configuration>
    <conversionRule conversionWord="ifPresent" converterClass="org.example.IfPresentConverter"/>

    <evaluator name="has_ex">
        <expression>return throwableProxy != null;</expression>
    </evaluator>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>lorem ipsum %msg{}%ifPresent(\n%ex{full}){has_ex}%n</pattern>
        </encoder>
    </appender>

    <root>
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30480213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档