2013-05-07 17 views
6

Qualcuno ha provato a scrittura log4j file di log direttamente -Hadoop Distributed File System?Write Log4j uscita per HDFS

In caso affermativo, si prega di rispondere come ottenere ciò. Penso che dovrò creare un Appender per questo.

È questo il modo? La mia necessità è di scrivere registri su un file a intervalli particolari e interrogare quei dati in una fase successiva.

+0

due anni dopo qualcuno ha notizie su come farlo senza usare il canale? Nel mio caso i registri non sono neanche lontanamente abbastanza lunghi da averne bisogno – Irene

risposta

8

Si consiglia di utilizzare Apache Flume per questa attività. C'è Flume appender for Log4j. In questo modo, si inviano i log su Flume e si scrive su HDFS. La cosa buona di questo approccio è che Flume diventa un unico punto di comunicazione con HDFS. Flume semplifica l'aggiunta di nuove fonti di dati senza scrivere serie di codice per l'interazione con HDFS ancora e ancora.

1

lo standard log4j (1.x) non supporta la scrittura su HDFS. ma fortunato, log4j è molto facile da estendere. Ho scritto un HDFS FileAppender per scrivere il log su MapRFS (compatibile con Hadoop). il nome del file può essere qualcosa come "maprfs: ///projects/example/root.log". Funziona bene nei nostri progetti. Estrao la parte del codice dell'appender e la incollo qui sotto. i frammenti di codice potrebbero non essere in grado di essere eseguiti. ma questo ti darà l'idea di come scriverti appender. In realtà, è sufficiente estendere org.apache.log4j.AppenderSkeleton e implementare append(), close(), requireLayout(). per ulteriori informazioni, è anche possibile scaricare il codice sorgente di log4j 1.2.17 e vedere come è definito l'AppenderSkeleton, vi darà tutte le informazioni lì. in bocca al lupo!

nota: il metodo alternativo per scrivere su HDFS consiste nel montare l'HDFS su tutti i nodi, in modo da poter scrivere i registri proprio come scrivere nella directory locale. forse questo è un modo migliore in pratica.

import org.apache.log4j.AppenderSkeleton; 
import org.apache.log4j.spi.LoggingEvent; 
import org.apache.log4j.Layout; 
import org.apache.hadoop.conf.Configuration; 

import java.io.*; 

public class HDFSFileAppender { 
    private String filepath = null; 
    private Layout layout = null; 

    public HDFSFileAppender(String filePath, Layout layout){ 
     this.filepath = filePath; 
     this.layout = layout; 
    } 

    @Override 
    protected void append(LoggingEvent event) { 
     String log = this.layout.format(event); 
     try { 
      InputStream logStream = new ByteArrayInputStream(log.getBytes()); 
      writeToFile(filepath, logStream, false); 
      logStream.close(); 
     }catch (IOException e){ 
      System.err.println("Exception when append log to log file: " + e.getMessage()); 
     } 
    } 

    @Override 
    public void close() {} 

    @Override 
    public boolean requiresLayout() { 
     return true; 
    } 

    //here write to HDFS 
    //filePathStr: the file path in MapR, like 'maprfs:///projects/aibot/1.log' 
    private boolean writeToFile(String filePathStr, InputStream inputStream, boolean overwrite) throws IOException { 
     boolean success = false; 
     int bytesRead = -1; 
     byte[] buffer = new byte[64 * 1024 * 1024]; 
     try { 
      Configuration conf = new Configuration(); 
      org.apache.hadoop.fs.FileSystem fs = org.apache.hadoop.fs.FileSystem.get(conf); 
      org.apache.hadoop.fs.Path filePath = new org.apache.hadoop.fs.Path(filePathStr); 
      org.apache.hadoop.fs.FSDataOutputStream fsDataOutputStream = null; 

      if(overwrite || !fs.exists(filePath)) { 
       fsDataOutputStream = fs.create(filePath, overwrite, 512, 3, 64*1024*1024); 
      }else{ //append to existing file. 
       fsDataOutputStream = fs.append(filePath, 512); 
      } 

      while ((bytesRead = inputStream.read(buffer)) != -1) { 
       fsDataOutputStream.write(buffer, 0, bytesRead); 
      } 

      fsDataOutputStream.close(); 
      success = true; 
     } catch (IOException e) { 
      throw e; 
     } 
     return success; 
    } 

}