Log4j 란?

Apache에서 만든 로깅용 자바기반의 오픈소스 라이브러리이다. 디버깅용이나 로그 적재에 주로사용한다.

Log for java라는 뜻을 줄여서 Log4j 라고 하며 Jakarta-project에서 Java를 위한 프로젝트 중 하나이다.

간단히 말해 로그를 출력하기 위한 라이브러리이다.

 

log4j 가 없어도 로그는 출력할 수 있지만 각 소스마다 sysout을 이용해 로그를 출력한다면 디버깅 로그가 필요 없을 경우에는 모두 추적하여 삭제하는 번거러움이 있고 sysout은 호출하면 할 수록 성능이 저하된다. 

(궁금한 경우 루프문을 작성하여 sysout을 계속 출력해 보면 알 수 있다.)

 


취약점

최근 log4j에 대한 취약점으로 큰 이슈가 발생하였다.  JNDI Injection 취약점을 이용하여 서버에서 악성 코드를 실행할 수 있다.  아래와 같은 위험이 있다고 한다.

  • 대상 컴퓨터(서버)의 모든 권한 취득 가능
  • 비밀번호 없이 내부망 접근 가능
  • 악성 프로그램(랜섬웨어 등) 실행 가능
  • 기업의 중요한 자료 삭제 등

 


취약점 조치

버전 업그레이드를 위해 공홈에서 사용중인 JDK 버전에 맞는 라이브러리를 다운로드 받는다. 

https://logging.apache.org/log4j/2.x/download.html#

 

Log4j – Download Apache Log4j 2

<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apa

logging.apache.org

파일을 다운로드 받은 후 압축파일의 내용을 보면 필요한 파일보다 더 많은 파일이 있다. 

지금 우리가 수행할 작업은 1.x 버전에서 2.x 버전으로 변경하는 작업이므로 해당 작업을 중점으로 설명하겠다. 

( log4j2-2.x.x 버전 업그레이드는 라이브러리만 교체하면 되는것으로 알고 있음)

 

 

 

<라이브러리 교체>

프로젝트의 상황에 따라 일부 라이브러리는 차이가 있을 수 있다. 

(예를 들면 remix / jdbc가 붙은 log4j 관련 라이브러리)

그러나 버전 업그레이드에 반드시 필요한 파일은 3개가 있으며 slf4j를 사용하는 경우 1개의 교체해야하는 파일이 있다.

log4j-core-2.x.x.jar log4j-api-2.x.x.jar log4j-web-2.x.x.jar log4j-slf4j-impl-2.x.x.jar
추가 Slf4j 사용시 추가
( 교체 : slf4j-log4j12-1.x.x.jar)

 

기존 프로젝트에 삭제되어야하는 라이브러리는 다음과 같다.

  • log4j-1.x.x.jar
  • slf4j-log4j12-1.x.x.jar  (slf4j를 사용하지 않는 경우에는 해당 파일이 없을 수 있으나 대부분의 프로젝트에는 있다.)

추가되어야 하는 라이브러리 

  • log4j-core-2.x.x.jar
  • log4j-api-2.x.x.jar
  • log4j-web-2.x.x.jar
  • log4j-slf4j-impl-2.x.x.jar  / log4j2-2.x.x용 바인딩 파일 (slf4j를 사용하지 않는 경우 제외)

slf4j를 사용하며 기존에 존재하는 라이브러리 중 유지해야하는 라이브러리

  • slf4j-api-1.x.x.jar    /  기존 소스에서 API를 사용하고 있으므로 삭제하지 않음

 

 

<설정 변경 : WEB.XML>

log4j2.xml 경로설정 - log4j-2.x 버전에서는 web.xml에서 경로나 파일명을 명시하지 않으면 기본값으로 classpath: 경로에서 log4j2-test.xml 또는 log4j2.xml 파일을 찾는다고 한다. (log4j 에서도 동일했던 것 같은데..) 

하지만 명확하게 하기 위해 별도의 설정을 하도록한다.

<!-- 대상파일 web.xml -->

<!-- AS-IS  : 변경 전-->
<context-param>
	<param-name>log4jConfigLocation</param-name>
    <param-value>classpath:/log4j.xml</param-value>
</context-param>

<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

<!-- To-be : 변경 후-->
<context-param>
	<param-name>log4jConfiguration</param-name>
    <param-value>classpath:/log4j2.xml</param-value>
</context-param>
<listener>
	<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>

web.xml에 해당 코드가 없는경우 추가하도록 한다.

경험으로는 spring 3.1 버전에서는 해당 코드가 없는 프로젝트가 있었으며 spring 3.2 이후부터는 해당 코드가 있었다.

 

 

 

<설정 변경 : LOG4J2.XML>

log4j2.xml 파일에 대한 작성법은 여기서 다루지 않도록 한다.
     관련링크 :   https://logging.apache.org/log4j/2.x/manual/configuration.html

 

Log4j – Configuring Log4j 2

Configuration Inserting log requests into the application code requires a fair amount of planning and effort. Observation shows that approximately 4 percent of code is dedicated to logging. Consequently, even moderately sized applications will have thousan

logging.apache.org

 

사용중인 설정파일의 내용은 아래와 같다. 

<!-- 신규작성 파일 : log4j2.xml -->
<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="DEBUG">
	<Properties>
		<Property name="logNm">log_pattern_Layout</Property>
		<Property name="layoutPattern">[%d{ISO8601}][%5p] [%c{4}]: %m%n</Property>
	</Properties>
			
	<Appenders>
		<Console name="console" target="SYSTEM_OUT">
		    <PatternLayout pattern="${layoutPattern}" />
		</Console>
		<RollingRandomAccessFile
			name="rolling_log"
			fileName="./logs/file.log"
			filePattern="./logs/pjt/pjt-%d{yyyy-MM-dd_HH}_%i.log"
			immediateFlush="false"
			append="true"
			ignoreExceptions="false">
			<PatternLayout pattern="${layoutPattern}" />
			<Policies>
				<!-- 30MB 용량이 초과시 DefaultRolloverStrategy 정책만큼 넘버링 -->
				<SizeBasedTriggeringPolicy size="30 MB" />
				<!-- 일별 로그 파일 생성-->
				<TimeBasedTriggeringPolicy interval="1" modulate="true" />
			</Policies>
			<!-- 롤링 파일 1000개 까지 생성 -->
			<DefaultRolloverStrategy max="1000" />
		</RollingRandomAccessFile>
		
		<Async name="async_log" includeLocation="true">
			<AppenderRef ref="rolling_log" />
		</Async>

		
	</Appenders>

	

	<Loggers>
		<!-- 스프링 프레임워크에서 찍는건 level을 info로 설정 -->
		<logger name="org.springframework" level="info" additivity="false" >
			<AppenderRef ref="console" />
			<AppenderRef ref="async_log" />
		</logger>
		<Logger name="jdbc.connection" level="info" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		<Logger name="jdbc.audit" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		<Logger name="jdbc.resultset" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		<Logger name="jdbc.resultsettable" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		
		<Logger name="jdbc.sqltiming" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		<Logger name="com.ibatis" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		<Logger name="java.sql" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		<Logger name="com.kpmg.kr" level="error" additivity="false">
			<AppenderRef ref="async_log" />
		</Logger>
		

		<Root level="debug">
			<AppenderRef ref="async_log" />
			<AppenderRef ref="console" />
		</Root>
	</Loggers>

</Configuration>

 

 

<설정 변경 : JAVA CODE내 사용>

slf4j를 사용했다면 과거 1.X 버전을 사용할때랑 동일하므로 변경할 내용이 없으나. 사용하지 않는 다면 아래 예제를 참조하여 수정하도록 한다.( 보통은 slf4j를 상당수 사용하기 때문에 ....)

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

// logger name이 현재 클래스 경로인 것을 찾는다. 
private static Logger logger = LogManager.getLogger(this.getClass()); 

prvate static void write(String s){
	logger.info(s);
}

 

작업을 완료하고 콘솔(예를 들면 이클립스)에서 Was 기동시 붉은색 로그가 아닌 검정색 로그가 주르륵 올라간다면 적용이 완료되었다고 볼 수 있다. 

설정오류(설정에 오류는 있으나 컴파일 오류가 안나는 상태)의 경우 Was 기동시 붉은색 로그만 나타나게 된다면

즉, 스프링 관련 로그같은 별도의 검정색 텍스트가 보이지 않는다면 설정이 잘못되었다고 볼 수 있다. 

 

<오류 발생 Case>

모두 적용을 완료한 후 톰켓 기준 WAS 기동시 에러메세지가 나타나는 경우가 있다. 

 org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19

해당 현상은 톰켓 버그로 이 문제가 해결된 버전은 Tomcat을 사용함으로써 해결이 가능하다.

  • Tomcat 9.0.x : 9.0.0.M18 이후
  • Tomcat 8.5.x : 8.5.12 이상 
  • Tomcat 8.0.x : 8.0.42 이상
  • Tomcat 7.0.x : 7.0.76 이상

해당내용 관련 StackOverflow

https://stackoverflow.com/questions/23541532/org-apache-tomcat-util-bcel-classfile-classformatexception-invalid-byte-tag-in

 

org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 15

I'm porting a webapp from Tomcat 7 to another server with Tomcat 7 but with Java 8. Tomcat starts successfully but in log catalina.out I get: org.apache.tomcat.util.bcel.classfile.ClassFormatExce...

stackoverflow.com

 

개요

Apache HTTP Server에서 입력값 검증이 미흡하여 발생하는 버퍼오버플로우 취약점(CVE-2021-44790)
공격자가 조작된 요청을 mod_lua*모듈로 처리 할 때 버퍼 오버플로가 가능한 취약점

 

영향받는 버전

Apache HTTP Server 2.4.51 및 이전 버전

 

해결방안

1. 취약점 업데이트 (패치 적용 前 업무시스템의 서비스 영향 검토 후 적용할 것)
    -   2.4.51 및 이전 버전의 경우, 최신 버전(2.4.52) 업그레이드 적용[2]
 
2. 임시 조치방안
    - mod_lua 모듈 非활성화 (디폴트로 비활성화 되어있음)
    ※ 모듈 확인방법 : 소스 트리의 httpd.conf 내 "LoadModule lua_module modules/mod_lua.so" 검색 > 주석 처리

개요

Logback에서 발생하는 원격코드 실행 취약점 (CVE-2021-42550)[2]
-   공격자가 Logback구성파일인 logback.xml을 조작할 경우, 해당파일을 참조하는 과정에서 삽입된 JNDI*쿼리문을 실행 해 임의의 원격코드를 실행할 수 있는 취약점
※ 공격 전제조건
- Logback구성파일 logback.xml에 대한 쓰기 권한이나 해당파일을 수정/덮어쓰기 가능할 경우
- 수정된 구성파일 logback.xml을 환경에 적용(reload)할 수 있는 권한
 
* JNDI : 디렉토리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고하기 위한 Java API
(Java Naming and Directory Interface의 약어)

 

영향받는버전

- 1.2.8 이하 모든버전
- 1.3.0-alpha10 이하 모든버전

 

해결방안

취약점 업데이트 (패치 적용 前 업무시스템의 서비스 영향 검토 후 적용할 것)
-   1.2.8이하 버전의 경우, 최신 버전(1.2.9) 업그레이드 적용 [3]
-   1.3.0-alpha10이하 버전의 경우, 1.3.0-alpha11로 업그레이드 적용[3]
※   1.3.x시리즈의 경우, 기본적으로 JAVA9 모듈화 되어 있으며 slf4j-api 버전 2.0.x 필요
(runtime에는 Java8이상이면 되지만, 소스에서 Logback을 빌드하려면 Java9 필요)

 

임시 조치방안 (패치 즉시적용 불가할 경우)

1)    구성파일 logback.xml파일의 권한을 read-only로 변경
※ logback.xml 파일 위치 : /src/main/resources/

 

 

참고사이트

[1]    https://nvd.nist.gov/vuln/detail/CVE-2021-42550
[2]    http://logback.qos.ch/news.html
[3]    https://repo1.maven.org/maven2/ch/qos/logback/

log4j는 현재 2.16까지 나온걸로 되어 있다.

이번에 난리난 취약점 때문에 일부 회사에서는 1.x 버전대를 사용하고 있어도 

1.x 버전은 2015년 EOS(기술지원종료) 되었기 때문에 최신버전으로 업데이트 하라는 조치사항이 나오기도 하여 

 

2.16버전이 아닌 2.15버전에 대한 URL을 찾아보았다.

 

https://downloads.apache.org/logging/log4j/2.15.0/

 

Index of /logging/log4j/2.15.0

 

downloads.apache.org

 

 

ES6이다 뭐다... 모든브라우저에서 작성한 코드가 동작을 안하는 경우 난감한 상황이 발생 할 수 있다.

그중에 하나가 javascript 작성시 중복제거 코드를 작성했는데 IE에서 동작하지 않는 경우를 볼 수 있다.

 

findindex나 화살표함수(ES6) 문법을 사용하는 코드의 경우 문제가 될 수 있다.

아직까지 IE가 사라지지 않았으므로.. jQuery를 이용한 중복제거 함수를 작성해 보았다.

1
2
3
4
5
6
7
8
9
var valueArr = ["11","22","33","44","11","55","66"]; // 원본배열
var uniqueArr = []; // 중복이 제거된 배열이 생성될 변수
$.each(valueArr, function(k, val){ 
    if($.inArray(val, uniqueArr) === -1){
        uniqueArr.push(val); 
    }
});
 
console.log(uniqueArr);
cs

 

일반적으로 테이블을 생성할 때 아래와 같이 인덱스를 생성하게 된다.

ALTER TABLE [dbo].[REGION_MGMT] ADD  CONSTRAINT [PK_REGION_MGMT] PRIMARY KEY CLUSTERED 
(
	[REGION_CD] ASC,
	[NATION_CD] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

WITH 다음에 오는 ON/OFF가 무슨 뜻인지 알아보도록 한다.

 

 

LOB_COMPACTION = { ON | OFF }

LOB(Large Object) 데이터가 포함된 모든 페이지를 압축하도록 지정합니다. 
LOB 데이터 형식은 image, text, ntext, varchar(max), nvarchar(max), varbinary(max) 및 xml입니다. 이 데이터를 압축하면 디스크 공간을 더 효율적으로 사용할 수 있습니다. 기본값은 ON입니다.

  • OFF
    큰 개체 데이터가 포함된 페이지가 압축되지 않습니다.
    OFF를 지정해도 힙에는 아무 영향이 없습니다.
    LOB 열이 없는 경우 LOB_COMPACTION 절은 무시됩니다.

PAD_INDEX = { ON | OFF }

인덱스 패딩을 지정합니다. 기본값은 OFF입니다.

  • ON
    FILLFACTOR로 지정된 사용 가능한 공간의 비율이 인덱스의 중간 수준 페이지에 적용됩니다. FILLFACTOR를 지정함과 동시에 PAD_INDEX를 ON으로 설정하지 않으면 sys.indexes에 저장된 채우기 비율 값이 사용됩니다.

  • OFF 또는 fillfactor가 지정되지 않았습니다.
    중간 수준 페이지는 용량 한도 가까이 채워집니다. 이로 인해 중간 페이지의 키 집합을 기준으로 인덱스에 포함될 수 있는 최대 크기의 행 하나 이상을 위한 충분한 공간이 남겨집니다.

SORT_IN_TEMPDB = { ON | OFF }

tempdb에 정렬 결과를 저장할지 여부를 지정합니다. 기본값은 OFF입니다.

  • ON
    인덱스 작성에 사용된 중간 정렬 결과가 tempdb에 저장됩니다. tempdb가 사용자 데이터베이스와는 다른 디스크 세트에 있으면 인덱스를 만드는 데 필요한 시간이 줄어들 수 있습니다. 그러나 인덱스 작성 중에 사용되는 디스크 공간의 크기는 커집니다.

  • OFF
    중간 정렬 결과가 인덱스와 같은 데이터베이스에 저장됩니다.
    정렬 작업이 필요하지 않거나 메모리에서 정렬을 수행할 수 있으면 SORT_IN_TEMPDB 옵션이 무시됩니다.

 

IGNORE_DUP_KEY = { ON | OFF }

데이터 입력 시 PK(UNIQUE) 중복 오류가 발생할 경우 정상적인 데이터만 입력할 것인가 전부 롤백 할 것인가에 대한 설정입니다. 기본값은 OFF입니다.

 

  • ON
    중복된 키 값이 고유 인덱스에 삽입되는 경우 경고 메시지가 나타나고 고유성 제약 조건을 위반하는 행만 실패합니다.

  • OFF
    중복된 키 값이 고유 인덱스에 삽입되는 경우 오류 메시지가 나타나고 전체 INSERT 작업이 롤백됩니다.
    뷰, 고유하지 않은 인덱스, XML 인덱스, 공간 인덱스 및 필터링된 인덱스에 생성된 인덱스의 경우 IGNORE_DUP_KEY를 ON으로 설정할 수 없습니다.

    IGNORE_DUP_KEY를 보려면 sys.indexes를 사용하십시오.

    이전 버전과 호환되는 구문에서 WITH IGNORE_DUP_KEY는 WITH IGNORE_DUP_KEY = ON과 같습니다.

 

STATISTICS_NORECOMPUTE = { ON | OFF }

배포 통계를 다시 계산할지 여부를 지정합니다.
통계가 자동 생성 되지 않으면 데이터 증가 및 분포에 따라 인덱스의 영향도가 줄어 들 수 있으므로 OFF로 설정하는것이 일반적입니다.  기본값은 OFF입니다.

 

  • ON
    이전 통계가 자동으로 다시 계산되지 않습니다.
  • OFF
    자동 통계 업데이트가 설정됩니다.
    자동 통계 업데이트를 복원하려면 STATISTICS_NORECOMPUTE를 OFF로 설정하거나 NORECOMPUTE 절 없이 UPDATE STATISTICS를 실행합니다.
    배포 통계 자동 재계산 기능을 해제하면 쿼리 최적화 프로그램에서 테이블과 관련된 쿼리에 대해 최적의 실행 계획을 선택할 수 없습니다.

ONLINE = { ON | OFF }

인덱스 작업 중에 쿼리 및 데이터 수정에 기본 테이블과 관련 인덱스를 사용할 수 있는지 여부를 지정합니다. 
기본값은 OFF입니다.

XML 인덱스 또는 공간 인덱스의 경우 ONLINE = OFF만 지원되며 ONLINE을 ON으로 설정하면 오류가 발생합니다.

참고
온라인 인덱스 작업은 SQL Server Enterprise, Developer 및 Evaluation Edition에서만 사용할 수 있습니다.

  • ON
    인덱스 작업 중에 장기 테이블 잠금이 유지되지 않습니다. 인덱스 작업의 주 단계 중 내재된 공유(IS) 잠금만 원본 테이블에 유지됩니다. 따라서 기본 테이블 및 인덱스를 계속 쿼리 또는 업데이트할 수 있습니다. 작업이 시작될 때 아주 짧은 기간 동안 S(공유) 잠금이 원본 개체에서 유지됩니다. 작업이 끝날 때 짧은 기간 동안 비클러스터형 인덱스가 생성되는 경우에는 원본에 대해 S(공유) 잠금이 유지되고, 온라인 상태에서 클러스터형 인덱스가 생성 또는 삭제될 때나 클러스터형 또는 비클러스터형 인덱스가 다시 작성될 때는 SCH-M(스키마 수정) 잠금이 획득됩니다. 로컬 임시 테이블에서 인덱스를 생성하는 경우에는 ONLINE을 ON으로 설정할 수 없습니다.

  • OFF
    인덱스 작업 중에 테이블 잠금이 적용됩니다. 클러스터형 인덱스, 공간 인덱스 또는 XML 인덱스를 생성, 다시 작성 또는 삭제하거나 비클러스터형 인덱스를 다시 작성 또는 삭제하는 오프라인 인덱스 작업은 테이블에 대해 SCH-M(스키마 수정) 잠금을 획득합니다. 이 경우 작업 중에 모든 사용자가 기본 테이블에 액세스할 수 없게 됩니다. 비클러스터형 인덱스를 만드는 오프라인 인덱스 작업을 통해 테이블의 S(공유) 잠금을 획득합니다. 따라서 기본 테이블을 업데이트할 수 없지만 SELECT 문과 같은 읽기 작업은 허용됩니다.

ALLOW_ROW_LOCKS = { ON | OFF }

행 잠금의 허용 여부를 지정합니다. 기본값은 ON입니다.

  • ON
    인덱스에 액세스할 때 행 잠금이 허용됩니다. 행 잠금을 사용하는 시점은 데이터베이스 엔진이 결정합니다.

  • OFF
    행 잠금이 사용되지 않습니다.

ALLOW_PAGE_LOCKS = { ON | OFF }

페이지 잠금의 허용 여부를 지정합니다. 기본값은 ON입니다.

  • ON
    인덱스에 액세스할 때 페이지 잠금이 허용됩니다. 페이지 잠금을 사용하는 시점은 데이터베이스 엔진이 결정합니다.

  • OFF
    페이지 잠금이 사용되지 않습니다.

참고
ALLOW_PAGE_LOCKS가 OFF로 설정되면 인덱스를 다시 구성할 수 없습니다.

* SQL Server 2008 이후버전에서 테스트 되었습니다.

 

 

기본적으로 사용법은 아래와 같다.

 

CONVERT( [포맷(길이)], [날짜 값], [변환형식] )

select convert(varchar, getdate(), 120)       -->  2021-01-12 21:23:16
select convert(varchar(10), getdate(), 120)  -->  2021-01-12
select convert(varchar(16), getdate(), 120)  -->  2021-01-12 21:25

 

 

그외 변환형식

convert(varchar, getdate(), 100) mon dd yyyy hh:miAM (or PM) convert(varchar, getdate(), 110) mm-dd-yyyy
convert(varchar, getdate(), 101) mm/dd/yyyy onvert(varchar, getdate(), 111) yyyy/mm/dd
convert(varchar, getdate(), 102) yyyy.mm.dd convert(varchar, getdate(), 112) yyyymmdd
convert(varchar, getdate(), 103)  dd/mm/yyyy convert(varchar, getdate(), 113) mon yyyy hh:mi:ss:mmm (24h)
convert(varchar, getdate(), 104) dd.mm.yyyy convert(varchar, getdate(), 114) hh:mi:ss:mmm (24h)
convert(varchar, getdate(), 105) dd-mm-yyyy convert(varchar, getdate(), 120)  yyyy-mm-dd hh:mi:ss (24h)
convert(varchar, getdate(), 106) dd mon yyyy convert(varchar, getdate(), 121) yyyy-mm-dd hh:mi:ss.mmm (24h)
convert(varchar, getdate(), 107) Mon dd, yyyy convert(varchar, getdate(), 126)  yyyy-mm-ddThh:mi:ss.mmm
convert(varchar, getdate(), 108) hh:mm:ss convert(varchar, getdate(), 130) dd mon yyyy hh:mi:ss:mmmAM
convert(varchar, getdate(), 109) mon dd yyyy hh:mi:ss:mmmAM (or PM) convert(varchar, getdate(), 131)  dd/mm/yyyy hh:mi:ss:mmmAM

 

매번 느끼는 것 이지만.. MS쓰는 쓸때마다 불편하다..

Quartz Scheduler를 사용하면 console log에 아래와 같은 로그가 주기적으로 나타나는 경우가 있다.

[org.quartz.core.QuartzSchedulerThread] batch acquisition of 0 triggers

이 로그가 보기 싫은 경우 logger를 설정하여 해결 할 수 있다.

 

  • org.quartz.core.QuartzSchedulerThread 클래스에 대한 로거를 작성 후 레벨을 error로 설정합니다.
  • root의 priority를 value를 debug로 설정합니다.
	<root>
		<priority value="debug" />   <-- 출력 로그 레벨 설정
        ....
        ...
        ..
		<appender-ref ref="console" />
	</root>

 

Log4j 2 XML Configuration

Xml 파일 위치

XML 파일 (log4j2.xml)을 작성하고, WEB-INF/classes 하위에 포함될 수 있도록 위치시킨다.
Log4j 2가 초기화될 때 자동으로 위 설정 파일을 읽어들인다

 

Xml 파일 정의 Sample

파일 (log4j.xml)을 작성 시 Log4j 2에서는 최상의 요소가 <Configuration>으로 변경 되었음을 기억해야 합니다.

<Configuration>요소 아래에 Logger, Appender, Layout 설정 등과 관련한 하위 요소를 정의

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%-5p: %d] %m [%c]%n" />
		</layout>
	</appender>

	<logger name="jdbc.audit" additivity="false">
		<level value="warn" />
		<appender-ref ref="console" />
	</logger>
	<logger name="jdbc.resultset" additivity="false">
		<level value="warn" />
		<appender-ref ref="console" />
	</logger>
	<logger name="jdbc.resultsettable" additivity="false">
		<level value="info" />
		<appender-ref ref="console" />
	</logger>
	...
    
	<root>
		<priority value="debug" />
		<appender-ref ref="console" />
	</root>
</log4j:configuration>

관련/참고 사이트

http://logging.apache.org/log4j/2.x/manual/configuration.html

 

Log4j – Configuring Log4j 2

Configuration Inserting log requests into the application code requires a fair amount of planning and effort. Observation shows that approximately 4 percent of code is dedicated to logging. Consequently, even moderately sized applications will have thousan

logging.apache.org

http://logging.apache.org/log4j/2.x/manual/configuration.html#XML

 

Log4j – Configuring Log4j 2

Configuration Inserting log requests into the application code requires a fair amount of planning and effort. Observation shows that approximately 4 percent of code is dedicated to logging. Consequently, even moderately sized applications will have thousan

logging.apache.org

 

Logger의 사용

public class SampleClass extends HandlerInterceptorAdapter {

    protected Logger logger = LoggerFactory.getLogger(SampleClass.class);
    public String sampleMethod(Object obj) throws Exception {
    	logger.debug("logger 내용");
    }

    	

log Level

Log Level에 따라 log의 출력여부를 지정할 수 있다.

Log Level DESC
FATAL 아주 심각한 에러가 발생한 상태를 나타냄. 시스템적으로 심각한 문제가 발생해서 어플리케이션 작동이 불가능할 경우가 해당하는데, 일반적으로는 어플리케이션에서는 사용할 일이 없음.
ERROR 요청을 처리하는중 문제가 발생한 상태를 나타냄.
WARN 처리 가능한 문제이지만, 향후 시스템 에러의 원인이 될 수 있는 경고성 메시지를 나타냄.
INFO 로그인, 상태변경과 같은 정보성 메시지를 나타냄.
DEBUG 개발시 디버그 용도로 사용한 메시지를 나타냄.
TRACE 디버그 레벨이 너무 광범위한 것을 해결하기 위해서 좀더 상세한 상태를 나타냄.

 

Appender 설정

ConsoleAppender : 이클립스 console 같은곳에 로그를 출력하기 위해 사용합니다.

 <Console name="console" target="SYSTEM_OUT">
  <PatternLayout pattern="%d %5p [%c] %m%n" />
 </Console>

FileAppender ; 로그를 파일에 저장할 때 사용합니다.

<File name="file" fileName="./log file path/sample.log" append="false">
  <PatternLayout pattern="%d %5p [%c] %m%n" />
</File>	

 

log를 File과 Console에 동시에 쌓는 코드

<root>
	<priority value="debug" />
	<appender-ref ref="console" />
</root>

 

본 작성글은 PL/SQL Developer 11 64bit 버전을 기준으로 작성되었습니다.

 

해당 패키지 또는 프로시저에 디버깅을 위해 Step Into를 했으나 진입하지 못하고 end; 로 빠져나가는 현상이 있다.

 

 

패키지나 프로시저를 우클릭하여 아래 그림과 같이 Add debug information을 체크해 준다.

 

Start Debug를 클릭하여 Step Into를 누르면 정상적으로 진입이 가능한 것을 확인 할 수 있다.

+ Recent posts