JAVA : Rediriger Sytem.out et System.err

Une vielle application ? Pas de logger en place ou pas utilisé partout ?
Le refactoring pour supprimer tous les appels à System.out et System.err peut etre long et fastidieu.

Plusieurs solutions existent :

1) Redéfinir System.out et System.err (1ere version)

La solution la plus simple consiste à redéfinir les deux flux a l’aide de setOut et setErr pour rediriger la sortie vers un fichier.

  1. final StringBuilder sb = new StringBuilder();
  2. sb.append("LOG-");
  3. SimpleDateFormat str = new SimpleDateFormat(
  4.   "yyyy-MM-dd-HH-mm-ss-");
  5. sb.append(str.format(new Date()));
  6. final File file = File.createTempFile(sb.toString(), ".log");
  7. final PrintStream printStream = new PrintStream(file);
  8. System.setOut(printStream);
  9. System.setErr(printStream);

2) Redéfinir System.out et System.err (2eme version)

Et si on doit garder les deux ? Si on veut conserver l’affichage dans la console et avoir également le résultat inscrit dans un fichier de log ?

Pour cela, nous devons définir une classe utilitaire qui va à la fois écrire dans un fichier et dans la console.

  1. public class PrintStreamWrapper extends PrintStream {
  2.  private final PrintStream parent;
  3.  
  4.  public PrintStreamWrapper(PrintStream parent, File file)
  5.    throws IOException {
  6.   super(file);
  7.   this.parent = parent;
  8.  }
  9.  
  10.  @Override
  11.  public boolean checkError() {
  12.   return parent.checkError() || super.checkError();
  13.  }
  14.  
  15.  @Override
  16.  public void write(int x) {
  17.   parent.write(x); // "write once;
  18.   super.write(x); // write somewhere else."
  19.  }
  20.  
  21.  @Override
  22.  public void write(byte[] x, int o, int l) {
  23.   parent.write(x, o, l); // "write once;
  24.   super.write(x, o, l); // write somewhere else."
  25.  }
  26.  
  27.  @Override
  28.  public void close() {
  29.   parent.close();
  30.   super.close();
  31.  }
  32.  
  33.  @Override
  34.  public void flush() {
  35.   parent.flush();
  36.   super.flush();
  37.  }
  38. }

Il suffit de l’utiliser comme suit :

  1. try {
  2.  final StringBuilder sb = new StringBuilder();
  3.  sb.append("LOG-");
  4.  SimpleDateFormat str = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-");
  5.  sb.append(str.format(new Date()));
  6.  final File file = File.createTempFile(sb.toString(), ".log");
  7.  final PrintStream outWrapper = new PrintStreamWrapper(System.out,
  8.    file);
  9.  final PrintStream errWrapper = new PrintStreamWrapper(System.err,
  10.    file);
  11.  System.setOut(outWrapper);
  12.  System.setErr(errWrapper);
  13. } catch (final IOException e) {
  14.  e.printStackTrace();
  15. }

3) Redirection vers log4j

C’est bien beau de rediriger vers un fichier mais ça serait bien d’utiliser notre bon Log4j afin que les nouveaux log et les anciens soient dans le même fichier.

  1. //redirection de System.out et err vers log4j
  2. System.setOut(new PrintStream(new LoggingOutputStream(logger,Level.INFO),true));
  3. System.setErr(new PrintStream(new LoggingOutputStream(logger,Level.ERROR),true));

Le commentaires sont fermés.