복붙노트

[HADOOP] Log4j 출력을 HDFS에 씁니다.

HADOOP

Log4j 출력을 HDFS에 씁니다.

Log4j 로그 파일을 Hadoop Distributed File System에 직접 작성하려고 시도한 사람이 있습니까?

그렇다면이를 달성하는 방법에 회신 해주십시오. 나는 그것을 위해 Appender를 만들어야한다고 생각합니다.

이게 방법인가요? 내 필요성은 특정 간격으로 파일에 로그를 작성하고 나중에 해당 데이터를 쿼리하는 것입니다.

해결법

  1. ==============================

    1.이 작업을 위해 Apache Flume을 사용하는 것이 좋습니다. Log4j 용 Flume appender가 있습니다. 이렇게하면 Flume에 로그를 보내고 HDFS에 기록합니다. 이 접근법에 대한 좋은 점은 Flume이 HDFS와의 단일 통신 지점이된다는 것입니다. Flume을 사용하면 HDFS와 상호 작용할 코드를 여러 번 쓰지 않고도 새로운 데이터 소스를 쉽게 추가 할 수 있습니다.

    이 작업을 위해 Apache Flume을 사용하는 것이 좋습니다. Log4j 용 Flume appender가 있습니다. 이렇게하면 Flume에 로그를 보내고 HDFS에 기록합니다. 이 접근법에 대한 좋은 점은 Flume이 HDFS와의 단일 통신 지점이된다는 것입니다. Flume을 사용하면 HDFS와 상호 작용할 코드를 여러 번 쓰지 않고도 새로운 데이터 소스를 쉽게 추가 할 수 있습니다.

  2. ==============================

    2.표준 log4j (1.x)는 HDFS에 대한 쓰기를 지원하지 않습니다. 운 좋게도 log4j는 확장하기가 쉽습니다. 필자는 HDFS FileAppender를 작성하여 MapRFS에 로그를 기록했습니다 (Hadoop과 호환 가능). 파일 이름은 "maprfs : ///projects/example/root.log"와 같을 수 있습니다. 그것은 우리 프로젝트에서 잘 작동합니다. appender 부분을 추출하여 아래에 붙여 넣습니다. 코드 스 니펫을 실행하지 못할 수 있습니다. 그러나 이것은 appender를 작성하는 방법에 대한 아이디어를 줄 것입니다. 사실, org.apache.log4j.AppenderSkeleton을 확장하고 append (), close (), requiresLayout ()을 구현하기 만하면됩니다. 자세한 정보는 log4j 1.2.17 소스 코드를 다운로드하고 AppenderSkeleton이 정의 된 방법을 참조하십시오. 모든 정보가 제공됩니다. 행운을 빕니다!

    표준 log4j (1.x)는 HDFS에 대한 쓰기를 지원하지 않습니다. 운 좋게도 log4j는 확장하기가 쉽습니다. 필자는 HDFS FileAppender를 작성하여 MapRFS에 로그를 기록했습니다 (Hadoop과 호환 가능). 파일 이름은 "maprfs : ///projects/example/root.log"와 같을 수 있습니다. 그것은 우리 프로젝트에서 잘 작동합니다. appender 부분을 추출하여 아래에 붙여 넣습니다. 코드 스 니펫을 실행하지 못할 수 있습니다. 그러나 이것은 appender를 작성하는 방법에 대한 아이디어를 줄 것입니다. 사실, org.apache.log4j.AppenderSkeleton을 확장하고 append (), close (), requiresLayout ()을 구현하기 만하면됩니다. 자세한 정보는 log4j 1.2.17 소스 코드를 다운로드하고 AppenderSkeleton이 정의 된 방법을 참조하십시오. 모든 정보가 제공됩니다. 행운을 빕니다!

    참고 : HDFS에 쓰기위한 다른 방법은 모든 노드에 HDFS를 마운트하는 것입니다. 따라서 로컬 디렉토리에 쓰기와 마찬가지로 로그를 쓸 수 있습니다. 어쩌면 이것은 실제로 더 좋은 방법 일 것입니다.

    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;
        }
    
    }
    
  3. from https://stackoverflow.com/questions/16420170/write-log4j-output-to-hdfs by cc-by-sa and MIT license