Java 로그

Codren·2021년 6월 6일

Section 1. 로그 (log)

1. 로그 (log)

시스템 운영 및 활동에 대한 기록

  • 오류가 발생 했을 때 log 를 참고하여 디버깅을 용이하게 함
  • 너무 적은 로그 : 정확한 시스템의 상황을 파악하기 어려움
  • 너무 많은 로그 : 빈번한 file I/O의 오버헤드와 로그 파일의 백업 문제등...




2. 로깅 (logging)

log 를 기록하는 활동

  • 로그 파일에 해당 상황을 기록하는 코드를 추가하여 필요한 정보를 남김




3. java.util.logging

  • 자바에서 기본적으로 제공되는 log package
  • 파일이나 콘솔에 로그 내용을 출력할 수 있음
  • jre/lib/logging.properties 파일을 편집하여 로그의 출력방식, 로그 레벨을 변경 할 수 있음
  • logging 패키지에서 제공하는 로그 레벨 - severe, warning, info, config, fine, finer, finest
  • 오픈소스 log4j를 많이 사용하고 있음




4. logging 시나리오

    ① Logger 인스턴스를 생성 (singleton pattern)
    ② 로그를 남기기 위한 FileHandler를 생성
    ③ FileHandler의 level을 지정
    ④ Logger 의 addHandler 메서드로 FileHandler 를 추가
    ⑤ 로그를 기록하고 싶은 부분에 Logger 인스턴스의 메서드 구현

	logger.finest(msg);
        logger.finer(msg);
        logger.fine(msg);
        logger.config(msg);
        logger.info(msg);
        logger.warning(msg);
        logger.severe(msg);




5. Logger 클래스

  • 전체에 대한 logger 의 level 과 특정 핸들러의 level 중에 높은 레벨이 지정됨
import java.util.logging.*;
import java.io.IOException;


public class MyLogger {
	
    Logger logger = Logger.getLogger("mylogger");		# 'mylogger' 라는 이름으로 Logger 클래스 생성 
    private static MyLogger instance = new MyLogger();		# MyLogger 클래스 singleton pattern 적용 

    private FileHandler logFile = null;				
    private FileHandler warningFile = null;
    private FileHandler fineFile = null;
    
    private MyLogger(){						# private 생성자 
	
            try {
                logFile = new FileHandler("log.txt", true); 		# 파일 핸들러 생성
                warningFile = new FileHandler("warning.txt", true); 	# 파일 핸들러 생성
                fineFile = new FileHandler("fine.txt", true);		# 파일 핸들러 생성

            } catch (SecurityException e) {			# 파일 핸들러 관련 exception
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            logFile.setFormatter(new SimpleFormatter());	# 로그를 기록하는 형식 지정 
            warningFile.setFormatter(new SimpleFormatter()); 	# 로그를 기록하는 형식 지정 
            fineFile.setFormatter(new SimpleFormatter()); 	# 로그를 기록하는 형식 지정 

            logger.setLevel(Level.ALL);				# 전체에 대한 logger의 level 지정
            fineFile.setLevel(Level.FINE);			# fineFile 핸들러의 level 지정	
            warningFile.setLevel(Level.WARNING);		# warningFile 핸들러의 level 지정	
	
            logger.addHandler(logFile);				# 핸들러 객체 등록
            logger.addHandler(warningFile);			# 핸들러 객체 등록
            logger.addHandler(fineFile);			# 핸들러 객체 등록
        }	

        public static MyLogger getLogger(){			# singleton pattern
        return instance;
        }


        public void log(String msg){				# log 메서드가 불리면 
								# msg 문자열을 모든 레벨 log 파일에 기록
        logger.finest(msg);
        logger.finer(msg);
        logger.fine(msg);
        logger.config(msg);
        logger.info(msg);
        logger.warning(msg);
        logger.severe(msg);

        }

        public void fine(String msg){				# fine 메서드가 불리면
        logger.fine(msg);					# fine 레벨 이상의 로그파일에 msg 문자열 기록
        }	

        public void warning(String msg){			# warning 메서드가 불리면
        logger.warning(msg);					# warning 레벨 이상의 로그파일에 msg 문자열 기록
        }
}




6. 나머지 클래스 파일

public class StudentNameFormatException extends IllegalArgumentException{

	public StudentNameFormatException(String message){
		super(message);
	}
}

  • Student 클래스
  • 발생하는 예외를 Student 클래스를 생성한 클래스에서 처리하도록 throw
public class Student {

	private String studentName;
	MyLogger myLogger = MyLogger.getLogger();	# 로그를 기록하기 위해 MyLogger 불러옴
	
	public Student(String studentName){

		if(studentName == null){
		
			throw new StudentNameFormatException("name must not be null");
		}
		if( studentName.split(" ").length > 3)
        
			throw new StudentNameFormatException("이름이 너무 길어요");
		
		this.studentName = studentName;
	}

	
	public String getStudentName() {
		
		myLogger.fine("begin getStudentName()");	# 특정 메서드 수행된 것을 기록
		
		return studentName;
	}
}

  • Main 부분
public class StudentTest {
	
	public static void main(String[] args) {
	
		MyLogger myLogger = MyLogger.getLogger();	# 로그를 기록하기 위해 MyLogger 불러옴
		
		String name = null;
		try{
			Student student = new Student(name);
			
		}catch( StudentNameFormatException e ){
			myLogger.warning(e.getMessage());
		}
		
		try{
			Student student = new Student("Edward Jon Kim Test");
		}catch ( StudentNameFormatException e){
			myLogger.warning(e.getMessage());
		}
		
		Student student = new Student("James");
	}
	
}




5. logging 동작 원리

    ① Main 에서 MyLogger 인스턴스 불러온 뒤 Student 인스턴스 생성
    ② Student 생성자 블럭에서 throw StudentNameFormatException (super(message))
    ③ Student 인스턴스를 생성하려 했던 Main 으로 돌아와서 catch 문으로 빠짐
    ④ catch 문에서 logger.level("e.getMessage()"); 수행




6. logging 결과

  • log 를 콘솔에 출력함
  • jre/lib/logging.properties 파일을 편집하여 로그의 출력 방식을 변경할 수 있음

  • log, fine, warning 로그 파일 생성됨 ( warning.txt 로그 파일)

0개의 댓글