如何在 log4net 中将级别记录为单个字母?

How to log the level as a single letter in log4net?

有没有办法改变这个配置:

<appender name="appender" type="log4net.Appender.RollingFileAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] [%-5level] %logger - %message%newline" />
  </layout>
</appender>

... 将日志级别记录为单个字母,如下所示:

DEBUG -> D
INFO  -> I
WARN  -> W
ERROR -> E
FATAL -> F

我试过%-1level,但数字只控制要用空格填充的字符数。 ([%-5level] 意味着 [INFO ] 而不是 [INFO])所以 [%-1level] 给了我 [INFO] 而不是预期的 [I].

目前我的想法:

变量 1

我可以为每个级别配置一个单独的附加程序,其中为每个级别设置固定的级别字母,所有日志记录到同一个文件:

<appender name="info-appender" type="log4net.Appender.RollingFileAppender">
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
  <file value="logfile.log" />
  <filter type="log4net.Filter.LevelMatchFilter">
    <levelToMatch value="INFO" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] [I] %logger - %message%newline" />
  </layout>
</appender>
<appender name="warn-appender" type="log4net.Appender.RollingFileAppender">
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
  <file value="logfile.log" />
  <filter type="log4net.Filter.LevelMatchFilter">
    <levelToMatch value="WARN" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] [W] %logger - %message%newline" />
  </layout>
</appender>
.
.
<root>
  <level value="ALL" />
  <appender-ref ref="debug-appender" />
  <appender-ref ref="info-appender" />
  <appender-ref ref="warn-appender" />
  <appender-ref ref="error-appender" />
  <appender-ref ref="fatal-appender" />
</root>

变量 2

我想可以扩展 log4net.Appender.RollingFileAppender 并覆盖渲染方法,或者如果可能的话,可以覆盖一些其他渲染关卡的内部方法。 (还没有检查这是否真的可能)

问题:

有没有更简单的方法来实现这个目标? (仅配置)

最简单的解决方案,使用截断格式:%.1level 而不是 %-5level 应该截断输出,如图 here

唉,没来得及现场测试。如果它不起作用,请在下面查看我的初始答案。

编辑:我没有正确阅读截断的描述:

If the data item is longer than the maximum field, then the extra characters are removed from the beginning of the data item and not from the end

这与您的需要不符。请查看编写自定义 PatternLayoutConverter


每个模式元素都根据 PatternLayoutConverter 的集合进行解析,这些元素用于处理用户所需的模式。您最好的选择是创建一个特定的 PatternLayoutConverter 来记录您希望格式化的级别。 Here 是一个示例,我在其中解释了使用特定日期时间格式的相同原则。

在你的情况下,它可以像这样简单:

public class MyLevelPatternConverter : PatternLayoutConverter
{
    protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        writer.Write(loggingEvent.Level.DisplayName.Substring(0, 1));
    }
}

查看文档:https://logback.qos.ch/manual/layouts.html

您可以通过格式化程序轻松完成:

%.-1level

不过,负数在这里的用法很奇怪。