머리말
프로젝트의 규모가 점점 커질수록 새로운 모듈이 지속적으로 도입되고, 각 모듈마다 자체 로그가 출력되므로 결국에는 로그를 전혀 볼 수 없게 됩니다. 프로젝트에는 다음과 같은 로그가 있습니다.
외부 메시지 수신 로그 및 외부 메시지 전송 로그
백그라운드 상주 스레드 로그 처리; 외부 인터페이스 액세스 매개변수 및 반환 결과와 같은 인터페이스 로그
서비스가 데이터베이스에 액세스하여 생성된 SQL 로그
그 중 메시지 로그 및 백그라운드 스레드의 로그 데이터 양이 매우 많습니다. 모든 로그가 하나로 인쇄되는 경우 파일에서 tail -f log.log 파일을 사용하면 로그가 빠르게 스크롤되어 특정 SQL 또는 서비스 액세스 로그를 보거나 찾을 수 없습니다. .
해법은 로그가 서로 영향을 미치지 않도록 서로 다른 로그를 분류하여 출력하는 것입니다. 특히 중요한 인터페이스 액세스 로그는 문제를 쉽게 찾아 해결할 수 있습니다.
1단계: log4j.properties에서 구성
먼저 내 log4j.properties 구성을 모두 게시합니다.
log4j.rootLogger=INFO, console, file log4j.appender.console=net.czt.log.AsyncConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p crazyant-web %-17c{2} (%13F:%L) %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} - %m%n log4j.appender.console.bufferSize=10000 log4j.appender.console.encoding=UTF-8 log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.file=/home/work/apache-tomcat-6.0.39/logs/crazyant.log log4j.appender.file.MaxBackupIndex=5 log4j.appender.file.MaxFileSize=1GB log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%-5p] crazyant-web %d{yyyy-MM-dd HH:mm:ss,SSS} %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} method:%l%n%m%n log4j.appender.file.bufferSize=10000 log4j.appender.file.encoding=UTF-8 log4j.logger.net.czt.crazyant.msg=DEBUG, message log4j.additivity.net.czt.crazyant.msg=false log4j.appender.message=org.apache.log4j.RollingFileAppender log4j.appender.message.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_message.log log4j.appender.message.Append=true log4j.appender.message.MaxFileSize=1GB log4j.appender.message.MaxBackupIndex=5 log4j.appender.message.layout=org.apache.log4j.PatternLayout log4j.appender.message.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n log4j.appender.message.encoding=UTF-8 log4j.logger.net.czt.crazyant.async.service=DEBUG, async log4j.additivity.net.czt.crazyant.async.service=false log4j.appender.async=org.apache.log4j.RollingFileAppender log4j.appender.async.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_async.log log4j.appender.async.Append=true log4j.appender.async.MaxFileSize=1GB log4j.appender.async.MaxBackupIndex=5 log4j.appender.async.layout=org.apache.log4j.PatternLayout log4j.appender.async.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n log4j.appender.async.encoding=UTF-8 log4j.logger.net.czt.orm.mybatis.SqlMonitorManager=DEBUG, showsql log4j.additivity.net.czt.orm.mybatis.SqlMonitorManager=false log4j.logger.net.czt.transaction.interceptor.SmartTransactionInterceptor=DEBUG, showsql log4j.additivity.net.czt.transaction.interceptor.SmartTransactionInterceptor=false log4j.appender.showsql=org.apache.log4j.RollingFileAppender log4j.appender.showsql.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_sql.log log4j.appender.showsql.Append=true log4j.appender.showsql.MaxFileSize=1GB log4j.appender.showsql.MaxBackupIndex=5 log4j.appender.showsql.layout=org.apache.log4j.PatternLayout log4j.appender.showsql.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n log4j.appender.showsql.encoding=UTF-8 log4j.logger.net.czt.crazyant.service=DEBUG, service log4j.additivity.net.czt.crazyant.service=false log4j.appender.service=org.apache.log4j.RollingFileAppender log4j.appender.service.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_service.log log4j.appender.service.Append=true log4j.appender.service.MaxFileSize=1GB log4j.appender.service.MaxBackupIndex=5 log4j.appender.service.layout=org.apache.log4j.PatternLayout log4j.appender.service.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n log4j.appender.service.encoding=UTF-8
구성 파일 아래에서 쉽게 볼 수 있습니다. 예, 메시지(message), async(백엔드 스레드), showsql(데이터베이스 로그), 서비스(인터페이스 호출)를 각각 다른 로그 파일에 출력합니다.
몇 가지 설명:
log4j.rootLogger=INFO, console, file
log4j에는 rootLogger 및 일반 Logger 개념이 기본적으로 하나만 필요합니다. 즉, 모든 로그는 이 로그 파일에만 출력됩니다.
공통 로거 구성 보기(인터페이스 로그 서비스를 예로 들어):
1. log4j.logger.net.czt.crazyant.service=DEBUG, service
이 문장의 "net.czt.crazyant.service"는 공통 로거 로그 구성이 적용되는 패키지의 전체 경로를 나타냅니다.
컬러 서비스는 공통 로거의 이름
2. log4j.additivity.net.czt.crazyant.service=false
"net.czt.crazyant.service"는 위와 동일하게 구성 항목
을 대상으로 하는 패키지임을 나타냅니다. 이 구성의 의미는 패키지의 로그를 rootLogger 로그에 출력하는 것이 아니라, 직접 구성한 로그에만 출력한다는 의미입니다. ;
3. log4j.appender.service=org.apache.log4j.RollingFileAppender 및 이 구성 섹션 아래의 구성 항목
여기서는 "service" 문자열입니다. 위의 첫 번째 구성 항목의 "서비스"는 동일하며 일반 Logger의 구성을 나타냅니다.
아래 구성 항목은 rootLogger와 동일하며 일일 출력 파일, 인코딩을 나타냅니다. UTF8, 조각화 규칙, 각 줄의 출력 모드 등
제가 직접 겪은 문제는 위의 log4j.properties를 구성한 후 각 로그 파일이 생성되었지만 아무 것도 없다는 것을 발견했습니다. 내용이 왜 들어있어요? 아래 두 번째 주의사항을 살펴보겠습니다.
Step 2. 로그 출력 시, 로그 객체에 해당하는 특정 클래스를 설정해야 합니다.
은 무엇을 의미하나요? 위의 구성 항목 중에 "net.czt.crazyant.service"라는 패키지 문자열이 있는데, log4j가 어떻게 다른 패키지의 로거 로그를 다른 파일로 출력하는지 생각해 볼까요? 방법:
1. 인터셉터 또는 aop를 사용하여 log4j가 로그 출력을 자체적으로 감지하고, 로그가 어떤 패키지에서 생성되었는지 감지하여 해당 파일에 출력합니다. , 사용자는 Class 매개변수를 전달하고, log4j는 클래스에 해당하는 패키지를 획득하고 이를 표준으로 사용하여 다른 로그 파일을 찾습니다.
코드를 보면 log4j가 다음을 사용하는 것이 분명합니다. 후자의 간단한 방법 직접적인 방법:
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class MyClassImpl implements MyClass { /** * loger */ private static final Log logger = LogFactory.getLog(MyClassImpl.class); /** * my func */ public void myfunc() { logger.info("call method myfunc."); } }
logger = LogFactory.getLog(MyClassImpl.class)에서는 로거를 사용하는 Class 매개변수가 전달되고, 반영된 Class의 패키지 주소는 log4j에서 사용됩니다. 출력 로그 패키지 주소.