"아, 여기구나! 오늘 또 수업이 있는 거 기억나?"

"아니, 난 그냥 당신을 찾고 있었다. 거의..."

"좋아요, 그럼 시작하겠습니다. 오늘은 로깅에 대해 말씀 드리고 싶습니다."

"로그는 발생한 이벤트의 목록입니다. 거의 배의 일지나 일기와 비슷합니다. 또는 Twitter와 더 관련이 있을 수 있습니다. 당연히 로거는 로깅에 사용하는 개체입니다."

"프로그래밍에서는 거의 모든 것을 기록하는 것이 관례입니다. 그리고 Java에서는 모든 것을 기록하고 그 이상도 기록합니다."

"사실 Java 프로그램은 UI, 콘솔 등이 없는 대형 서버 애플리케이션인 경우가 매우 많습니다. 수천 건의 사용자 요청을 동시에 처리하고 다양한 오류가 발생하는 경우가 많습니다. 특히 서로 다른 스레드가 서로 간섭하기 시작할 때."

"사실 이러한 상황에서 거의 재현되지 않는 버그와 오류를 검색하는 유일한 방법은 각 스레드에서 발생하는 모든 일을 기록하는 것입니다."

"대부분 로그에는 메서드 인수, 포착된 오류 및 많은 중간 정보에 대한 정보가 포함되어 있습니다."

"로그가 완전할수록 일련의 이벤트를 재현하고 오류나 버그의 원인을 추적하기가 더 쉬워집니다."

"때로는 로그가 하루에 몇 기가바이트에 도달합니다. 이것은 정상입니다."

"몇 기가바이트? O_o"

"예. 대부분의 경우 로그 파일은 관련 날짜 표시와 함께 자동으로 보관됩니다."

"워."

"어허. 처음에 Java에는 자체 로거가 없었습니다. 결과적으로 여러 개의 독립적인 로거가 작성되었습니다. 그 중 가장 일반적인 것은 log4j였습니다."

"몇 년 후 Java는 자체 로거를 얻었지만 그 기능은 훨씬 열등했고 널리 사용되지 않았습니다."

"Java에 공식 로거가 있는 것은 사실 이지만 전체 Java 프로그래머 커뮤니티는 다른 로거를 사용하는 것을 선호합니다. "

"나중에 log4j를 기반으로 여러 로거가 작성되었습니다."

"그럼 지금 널리 사용되는 특수 범용 로거 slf4j가 모두를 위해 작성되었습니다. log4j와 매우 유사하므로 로깅을 설명할 때 예로 사용하겠습니다."

"전체 로깅 프로세스는 세 부분으로 구성됩니다."

" 먼저 정보를 수집하라."

" 둘째 , 수집된 정보를 필터링합니다."

" 셋째 , 선택한 정보를 기록합니다."

"수집부터 시작하겠습니다. 다음은 기록하는 클래스의 일반적인 예입니다."

로깅이 있는 클래스
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"빨간색으로 강조 표시된 단어에 주의하세요."

" 3행  – 로거 객체를 생성합니다. 이러한 정적 객체는 거의 모든 클래스에서 생성됩니다! 음, 데이터를 저장하는 것 외에는 아무것도 하지 않는 클래스를 제외하고 말입니다."

" LoggerFactory 는 로거를 생성하기 위한 특수 클래스이고 getLogger는 정적 메서드 중 하나입니다. 현재 객체는 일반적으로 전달되지만 다양한 옵션이 가능합니다."

" 7행 – 메소드 호출에 대한 정보가 로거에 기록됩니다. 이것이 메소드의 첫 번째 행임을 참고하십시오. 메소드가 호출되는 즉시 로그에 정보를 기록합니다."

"우리는 정보의 중요성이 DEBUG 수준임을 의미하는 디버그 방법을 호출합니다. 이것은 필터링에 사용됩니다. 몇 분 후에 이에 대해 말씀드리겠습니다."

" 17행 – 예외를 포착하고... 즉시 로그에 기록합니다! 이것이 바로 수행해야 할 작업입니다."

"이번에는 정보가 ERROR 수준임을 즉시 나타내는 오류 메서드를 호출합니다."

로거 - 1

"지금은 모든 것이 명확해 보입니다. 글쎄요, 우리 대화 중에 명확할 수 있는 한 말입니다."

"좋습니다. 그럼 메시지 필터링으로 넘어가겠습니다."

"일반적으로 각 로그 메시지에는 고유한 중요도 수준이 있으며 이를 사용하여 일부 메시지를 삭제할 수 있습니다. 내가 언급한 중요도 수준은 다음과 같습니다."

중요도 수준 설명
모두 모든 메시지
추적하다 세분화된 디버그 메시지
디버그 중요한 디버그 메시지
정보 정보 메시지
경고하다 경고
오류 오류
치명적인 치명적인 오류
끄다 메시지 없음

이러한 수준은 메시지를 필터링할 때도 사용됩니다.

로깅 수준을 WARN으로 설정했다고 가정합니다. 그러면 WARN보다 덜 중요한 모든 메시지(TRACE, DEBUG, INFO)가 삭제됩니다.

필터링 수준을 FATAL로 설정하면 ERROR 메시지도 무시됩니다.

"필터링할 때 사용되는 중요도 수준에는 두 가지가 더 있습니다. OFF는 모든 메시지를 삭제하고 ALL은 모든 메시지를 표시합니다(아무것도 삭제되지 않음)."

"필터링은 어디서 어떻게 설정합니까?"

"더 고민하지 않고 말씀드리겠습니다."

"일반적으로 log4j 로거 설정은 log4j.properties 파일에 지정됩니다."

이 파일에서 여러 appender 개체를 지정할 수 있습니다. 데이터는 이러한 개체에 기록됩니다. 데이터 소스가 있고 목적이 반대인 개체인 어펜더가 있습니다. 데이터가 물처럼 흘러드는 객체.

"여기 몇 가지 예가 있어요:"

콘솔에 로그인
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

1행과 4행 - 주석입니다.

2행 – 원하는 로깅 수준을 나타냅니다. 덜 중요한 모든 레벨(DEBUG, TRACE)은 폐기됩니다.

같은 위치에 쉼표를 추가한 다음 로그가 기록될 개체의 이름(우리가 생각해낸 이름)을 표시합니다. 5-9행에는 해당 설정이 포함되어 있습니다.

5행 – appender 유형( ConsoleAppender )을 지정합니다.

6행 – 우리는 작성하고 있는 위치를 정확히 나타냅니다( System.out. ).

7행 - 전환 패턴을 관리할 클래스를 설정합니다(PatternLayout).

8행 – 쓰기에 사용할 변환 패턴을 설정합니다. 위의 예에서는 날짜와 시간입니다.

"파일에 쓰는 방법은 다음과 같습니다."

파일에 로깅
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

"2행은 메시지 필터링 수준과 어펜더 개체(싱크)의 이름을 설정합니다."

"5행 – 파일 추가기 유형( RollingFileAppender )을 지정합니다."

"6행 – 로그가 기록될 파일의 ​​이름을 지정합니다."

"7행 – 최대 로그 크기를 지정합니다. 이 크기 제한을 초과하면 새 파일이 생성됩니다."

"8행 - 저장할 이전 로그 파일의 수를 지정합니다."

"9-10행 - 변환 패턴을 설정합니다."

"여기서 무슨 일이 일어나고 있는지는 모르겠지만 추측할 수는 있습니다. 고무적입니다."

"훌륭합니다. 그러면 다음은 파일과 콘솔에 로그를 작성하는 방법의 예입니다."

콘솔 및 파일에 로깅
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

"아, 그렇게 할 수 있구나? 대단해!"

"예. 원하는 만큼 추가자를 선언하고 각각을 사용자 정의할 수 있습니다."

또한 각 어펜더는 메시지 필터링을 위한 매우 유연한 설정을 가질 수 있습니다. 각 어펜더에 개별 메시지 필터링 수준을 할당할 수 있을 뿐만 아니라 패키지별로 메시지를 필터링할 수도 있습니다! 그렇기 때문에 로거를 만들 때 클래스를 지정해야 합니다( LoggerFactory.getLogger 에 대해 이야기하고 있습니다 ).

"예를 들어:"

콘솔 및 파일에 로깅
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

"6행과 15행 - 각 어펜더에 대해 자체 필터링 수준을 설정했습니다."

"20-23행 – 메시지에 대한 패키지 이름과 필터링 수준을 지정합니다. Log4j.logger는 접두사입니다. 패키지 이름은 주황색으로 강조 표시됩니다."

"정말요? 그렇게도 할 수 있어요. 좋아요!"

"그런데 log4j와 slf4j는 모두 JDK에 포함되어 있지 않습니다. 별도로 다운로드해야 합니다. 여기에서 다운로드할 수 있습니다 . 하지만 다른 방법이 있습니다."

" 1단계. 클래스에 가져오기 추가:"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" 2단계 . 이 줄에 커서를 놓고 IntelliJ IDEA에서 Alt+Enter를 누릅니다."

" 3단계 . '웹에서 파일 jar» 메뉴 항목'을 선택합니다.

" 4단계 . 'slf4j-log4j13.jar' 선택"

" 5단계 . 라이브러리(jar)를 다운로드할 위치 지정"

" Step 6 . 필요한 클래스를 사용하십시오."

"우와! 정말 멋진 하루였어. 너무 새롭고 너무 멋져!"

"여기 에 로깅에 대한 또 다른 좋은 기사가 있습니다 .

"좋아, 충분해. 가서 진정해, 프로그래머."