Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write logfile in csv format using logback?

Tags:

java

csv

logback

I have a requirement where I need to write a log in a csv format using logback. I have found a sample where I can do just that

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

However I also need to have a standard header like this in every file:-

    Time,User,Param1,Param2

How do I add the header in every rolling file

like image 816
Kaushik Chakraborty Avatar asked Sep 18 '17 12:09

Kaushik Chakraborty


People also ask

How do I change the Logback configuration file?

Setting the location of the configuration file via a system property. You may specify the location of the default configuration file with a system property named "logback. configurationFile" . The value of this property can be a URL, a resource on the class path or a path to a file external to the application.

What is Appender in Logback?

Appenders place log messages in their final destinations. A Logger can have more than one Appender. We generally think of Appenders as being attached to text files, but Logback is much more potent than that. Layout prepares messages for outputting.

What is totalSizeCap in Logback?

The lastest version of logback.qos.ch (1.1. 7) supports the property "totalSizeCap". This property can be used to limit the total size of archived log files. Currently, the top level nifi pom. xml specifies version 1.1.


1 Answers

You can implement your own Layout, extending Logback's PatternLayout:

public class LogFileHeaderPatternLayout extends PatternLayout {

    private String header;

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

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

And then reference it like so:

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

If Logback insists on adding this header evey time it opens the log file (i.e. every time the application starts) then you could conditionalise getFileHeader() like so:

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;
}
like image 98
glytching Avatar answered Sep 29 '22 12:09

glytching