2017-09-18 5 views
2

J'ai une exigence où j'ai besoin d'écrire un journal dans un format csv en utilisant le logback. J'ai trouvé un échantillon où je peux le faire queComment écrire un fichier journal au format csv en utilisant le logback?

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

Cependant je dois aussi avoir un en-tête standard comme celui-ci dans tous les fichiers: -

Time,User,Param1,Param2 

Comment puis-je ajouter l'en-tête dans chaque roulement fichier

+0

Pour écrire une ligne d'en-tête dans chaque fichier que vous devrez probablement étendre votre classe appender. – wallenborn

Répondre

1

Vous pouvez implémenter votre propre Layout:

public class LogFileHeaderPatternLayout extends PatternLayout { 

    private String header; 

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

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

Et puis référence comme ceci:

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

Si Logback insiste sur l'ajout de cet en-tête du temps de Evey il ouvre le fichier journal (à savoir chaque fois que l'application démarre), alors vous pouvez conditionalise getFileHeader() comme ceci:

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 { 
       return false; 
      } 
     } 
    } catch (Exception ex) { 
     ex.printStackTrace(System.err); 
     return false; 
    } 
} 
+0

Salut, cela fonctionne correctement mais le seul problème est que chaque fois que je redémarre l'application, l'en-tête est de nouveau ajouté. Comment puis-je m'assurer que cela n'arrive pas? –

+0

@KaushikChakraborty J'ai mis à jour la réponse pour offrir une solution au problème des 'en-têtes de fichiers multiples'. – glytching

+0

La vérification 'alreadyContainsHeader' est assez compliquée, nécessitant l'ouverture d'un fichier live et la lecture de son contenu (première ligne mais toujours). Une meilleure solution ne serait-elle pas de vérifier seulement si le fichier existe et n'est pas vide? – vacant78