【问题标题】:How to write logfile in csv format using logback?如何使用 logback 以 csv 格式编写日志文件?
【发布时间】:2017-09-18 12:01:11
【问题描述】:

我有一个要求,我需要使用 logback 以 csv 格式编写日志。我找到了一个可以做到这一点的示例

    <appender name="csv" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.csv</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <!-- rollover daily -->
    <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.csv</fileNamePattern>
        <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
        <maxFileSize>100MB</maxFileSize>    
        <maxHistory>60</maxHistory>
        <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
       <encoder>
         <pattern>%msg%n</pattern>
        </encoder>
     </appender>

但是我还需要在每个文件中都有这样的标准标题:-

    Time,User,Param1,Param2

如何在每个滚动文件中添加标题

【问题讨论】:

  • 要将标题行写入每个文件,您可能必须扩展您的 appender 类。

标签: java csv logback


【解决方案1】:

你可以实现自己的Layout,扩展Logback的PatternLayout

public class LogFileHeaderPatternLayout extends PatternLayout {

    private String header;

    public void setHeader(String header) {
        this.header = header;
    }

    @Override
    public String getFileHeader() {
        return header;
    }
}

然后像这样引用它:

<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
    <layout class="x.y.z.LogFileHeaderPatternLayout">
        <header>a,b,c,d</header>
        <pattern>%msg%n</pattern>
    </layout>
</encoder>

如果 Logback 坚持在每次打开日志文件时(即每次应用程序启动时)都添加此标头,那么您可以像这样条件化 getFileHeader()

public String getFileHeader() {
    if (alreadyContainsHeader()) {
        return "";
    } else {
        return header;
    }
}

private boolean alreadyContainsHeader() {
    try(BufferedReader br = new BufferedReader(new FileReader(filePath))) {
        String line = null;
        while ((line = br.readLine()) != null) {
            if (line.contains(header)) {
                return true;
            } else {
                break;
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }
    return false;
}

【讨论】:

  • 嗨,这工作正常,但唯一的问题是每当我重新启动应用程序时,标题都会再次附加。我如何确保它不会发生?
  • @KaushikChakraborty 我已经更新了答案,为“多个文件头”问题提供了解决方案。
  • “alreadyContainsHeader”检查非常复杂,需要打开一个实时文件并读取其内容(第一行但仍然如此)。仅检查文件是否存在且不为空不是更好的解决方案吗?
  • Logback 中也有一个PatternLayout
  • 谢谢。你得到了我的支持!但是......你从哪里得到'filePath'(in alreadyContainsHeader())
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2011-12-11
  • 2021-03-11
  • 1970-01-01
  • 2015-03-19
  • 2011-11-29
  • 1970-01-01
相关资源
最近更新 更多