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