728x90

개요

  log4j2를 사용하면서 특정 로그만 특정 파일로 분리하고 싶었습니다. 기본적으로는 패키지 단위로 설정 가능하지만, 동일 패키지 내에서도 기본 로그와 특정 로그로 분리해서 동작하게 하고 싶었습니다.

  기존에 한 번 해본 경험이 있는 작업이었는데, 어렵지 않아서 별도로 기록하지는 않았었습니다. 그런데, 오랜만에 다시 쓸 일이 있어서 했더니 생각지 못한 부분에서 시간이 허비해버렸습니다. 다시 시간낭비 하지 않도록 기재합니다.

예제코드

</ExampleProject/src/main/resources/log4j2.xml>

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitoringInterval="30" shutdownHook="disable">
    <Properties>
        <Property name="basic_format">[%d{yyyy-MM-dd HH:mm:ss}][%5p][%c %L] %m%n</Property>
        <Property name="basic_dir">/DEV/PRJ/webapp/example/logs/</Property> 
    </Properties>
    <Appenders>
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="${basic_format}" />
        </Console>


		<!-- <분리로그어펜더> -->
		<RollingFile name="TmpLogFileAppender" append="true" 
			ignoreExceptions="false"
		>
            <FileName>${basic_dir}/example-tmp.log</FileName>
            <FilePattern>${basic_dir}/backup_logs/example-tmp-%d{yyyyMMdd}.log.zip</FilePattern>
			<PatternLayout pattern="${basic_format}" />
			<Policies>
				<TimeBasedTriggeringPolicy interval="1"
					modulate="true" />
			</Policies>
		</RollingFile>
		<!-- </분리로그어펜더> -->
    </Appenders>


    <Loggers>
		<!-- <분리로그> -->
		<Logger name="TmpLog-com.cafe24.twilightsh.standardexample.log.ExampleLogController" level="INFO" additivity="false"><AppenderRef ref="TmpLogFileAppender" /></Logger>
		<!-- </분리로그> -->
        <Root level="INFO">
            <AppenderRef ref="console" />
        </Root>
    </Loggers>
</Configuration>

 

<ExampleLogController.java>

@Controller
public class ExampleLogController {
	/**
	 * 로그설정.
	 */
	protected Log log = LogFactory.getLog(this.getClass());
	/**
	 * 임시로그설정.
	 */
	protected Log tmpLog = LogFactory.getLog("TmpLog-"+this.getClass().getName());
	
	…생략…


	@RequestMapping(value = "/example/log/writeExampleLog.do")	
	public ModelAndView writeExampleLog(final HttpServletRequest request, final ModelMap model) {
		final String pattern = "yyMMddHHmmss";
		final String logKeyForm = "[LogKey:" + DateFormatUtils.format(new Date(), pattern) + Integer.toHexString(new Random().nextInt(255)) + "]";
		try {
			// <분리로그>임시로그
			if (tmpLog.isInfoEnabled()) {
				tmpLog.info(logKeyForm + "로그남기기");
			}
			// </분리로그>


			final JSONObject responseBody = new JSONObject();
			responseBody.put("resultCd", "SUCCESS");
			return responseBody.toString();
		} catch (final Throwable t) {
			final String commonMsg = "예제API로그 생성 실패.";
			throw new RuntimeException(
					logKeyForm + commonMsg
					, t);
		}
	}
}

 

해설

어펜더를 사용하여 로그 분리

  기본 로그파일 외에 별도의 로그파일을 생성하기 위해 Java 파일 내에서 Log를 2개 선언했습니다.

  1. Log log = LogFactory.getLog(this.getClass());
  2. Log tmpLog = LogFactory.getLog("TmpLog-"+this.getClass().getName());

 

  log는 일반적으로 선언하는 평범한 방식으로 선언했지만, tmpLog는 접두어"TmpLog-"를 붙여주었습니다. 이 분리된 tmp로그객체를 위해 xml 파일 내에서는 의 name 속성을 선언할 때 접두어"TmpLog-"를 붙여주었습니다.

<Logger name="TmpLog-com.cafe24.twilightsh.standardexample.log.ExampleLogController" level="INFO" additivity="false"><AppenderRef ref="TmpLogFileAppender" /></Logger>

  name="TmpLog-com.cafe24.twilightsh.standardexample.log.ExampleLogController"에서 접두어"TmpLog-"를 붙여서 로그 남길 클래스명을 기재했습니다.

  ‘ <AppenderRef ref="TmpLogFileAppender" /> ’로 설정했으므로 ‘ <Appenders> ’에서 ‘name="TmpLogFileAppender"’인 어펜더를 사용합니다.

분리된 로그파일 설정

  이 분리된 로그파일 어펜더(‘name="TmpLogFileAppender"’)를 이용해 일별로 로그파일을 남기고자 했습니다.

		<RollingFile name="TmpLogFileAppender" append="true" 
			ignoreExceptions="false"
		>
            <FileName>${basic_dir}/example-tmp.log</FileName>
            <FilePattern>${basic_dir}/backup_logs/example-tmp-%d{yyyyMMdd}.log.zip</FilePattern>
			<PatternLayout pattern="${basic_format}" />
			<Policies>
				<TimeBasedTriggeringPolicy interval="1"
					modulate="true" />
			</Policies>
		</RollingFile>

 

  이를 위해 다음 3가지 설정을 했습니다.

  1. 어펜더 종류는 ‘RollingFile’
  2. <TimeBasedTriggeringPolicy interval="1" modulate="true" /> ’ 정책
  3. 로그파일 패턴을 일별설정인 ‘%d{yyyyMMdd}’. 이는 하루가 바뀔 때마다 날짜로 백업파일이 생성됨을 의미합니다.(‘/example-tmp.log’는 오늘(현재) 파일 이름)

주의점

  name="TmpLog-com.cafe24.twilightsh.standardexample.log.ExampleLogController"에서 접두어"TmpLog-"를 제외한 나머지 부분은 정확한 팩키지 또는 클래스명이어야 합니다. 정확한 이름이 아니면 로그가 기록되지 않습니다.

참고자료

  • 일별 로그 설정방법은 Copilot에 ‘log4j2 일별 로그’로 조회하여 나온 방법을 사용했습니다.
반응형
728x90

  요즘 수면시간이 5시간도 안 될 정도로 수면부족이었는데, 오늘 간만에 6시간 조금 넘게 잤더니 바로 차이를 느꼈다.

 

  똑같은 시간에 일어나서 아침 출근 준비를 하는데, 평소보다 시간이 여유로웠다.

  뭐랄까? 시간이 천천히 가는 느낌?

  평소에 10분 이상 걸리는 행동이, 끝나고 시간을 보면 7분 정도 지나 있다. 3분 정도 빨리 움직이고 있다고 할 수 있다.

 

  예전에 수면 관련 책을 읽었을 때, 이런 내용이 있었다. 하루 8시간을 자야 하는 사람이 7시간만 자면, 일주일 후에는 24시간을 못 잔 것과 비슷한 인지상태가 된다는 것이었다.

  나는 7시간은 커녕 5시간 정도 수면이었으니 내 인지상태가 말도 안 되게 망가져 있었을 것이다. 그러니 나는 못 느끼지만 굉장히 느릿느릿 움직이고 있었을 듯.

 

  앞으로도 8시간 수면을 목표를 지킬 수 있게 노력해야겠다.

반응형
728x90

개요

  EasyUI의 textbox에는 원래의 <input>에 적용할 수 있는 이벤트 중에 onChange만 설정할 수 있습니다. 그 외에는 지원을 하지 않기 때문에 직접 textbox 객체를 받아서 설정하는 방법을 사용합니다.

예제코드


$('#box').textbox('textbox').on('keyup', function(event) {
	const $box = $('#box');
	const text = $box.textbox('getText');
	
	// 숫자, 영문, 한글 가능. 특수문자 ;:,.?!-_()*%#만 가능.
	const regExp = /[^\s\wㄱ-힣;:,.?!\-()*%#]/g;
	let safeText = text.replace(regExp, '');
	
	// 최대 60자.
	const max = 60;
	if (max < safeText.length) {
		safeText = safeText.substring(0, max);
	}
	$box.textbox('setValue', safeText);
});

해설

  textbox라는 메서드 호출을 통해 얻은 객체에 이벤트를 붙일 수 있습니다. 이를 통해 EasyUI가 지원하지 않는 이벤트도 사용 가능합니다. numberbox에도 동일한 방식으로 사용 가능합니다.

  참고로 위 방식을 몰랐을 때는 아래처럼 복잡한 방식으로 구현하기도 했습니다.

$('#box1').numberbox({
	inputEvents:$.extend({},$.fn.numberbox.defaults.inputEvents,{
		keyup : function(event) {
			const text = $('#box1').numberbox('getText');
			if (3 <= text.length) {
				$('#box2').textbox('textbox').focus();
			}
		},
	})
});
반응형

+ Recent posts